Create the Template

You need to create a template yaml file with the definitions to deploy the Docker Linux Tomcat Wildbook Application.

Refer to the Template Syntax section in this document for reference.

Create a new template file

Using your preferred text editor create a new template yaml file. Add the following statements, feel free to substitute values as appropriate.

template_name: "Docker Tomcat Wildbook 2 container stack on Linux"
template_author: "Gary Forghetti"
template_version: "1.00"
description: "Docker Tomcat Wildbook 2 container stack on Linux"
long_description: "Deploys a Docker single server stack with a container running a Tomcat server with the Wildbook application and a container running a MySQL database server."

imports:
    - base_types.yaml                                                   # Import the DCM base type definitions that are referenced in this template

Define topology_template and inputs

topology_template:

  inputs:

Define AccountRegionSelector

The next step is to define a AccountRegionSelector to allow the Dell Cloud Manager console end user the ability to select the cloud, region and data center for launching the server in the stack.

  ################################################################################################################################################
  # This defines the AccountRegionSelector which allows the user to select the Cloud, Region and Datacenter
  ################################################################################################################################################
  account_region_zone_selector:                                     # Define the section for the Cloud, Region and Datacenter selection boxes
    type: dcm.inputs.AccountRegionSelector                          # Input type is dcm.inputs.accountRegionSelector 
    properties:
      regions:                                                      # Define the Cloud and Regions
        "Amazon":                                                   # Amazon
          "us-east-1": [ ]                                          # All data centers for the us-east-1 region
          "us-west-1": ["us-west-1a", "us-west-1c"]
          "us-west-2": ["us-west-2a", "us-west-2b", "us-west-2c"]
          "eu-west-1": ["eu-west-1a", "eu-west-1c"]

Define Product Selector

The next step is to define a Product selector to allow the Dell Cloud Manager console end user the ability to select the server product for launching the server in the stack. This example will use the Amazon cloud and a subset of the regions and server products. An Ubuntu trusty 14.04 machine image will be defined in the template to be used for creating the server.

Note

If you do not have access to the Amazon cloud or wish to use a different cloud provider’s cloud that Dell Cloud Manager supports, you will need to make the necessary changes below for the cloud, region(s), image(s) and products.

Add the statements to the yaml file to define the inputs product_selector. The inputs: statement must be indented inside the topology_template: statement. Refer to the Product Selector section in this document for reference.

    ################################################################################################################################################
    # This defines the Product selector which allows the user to select the server product size
    ################################################################################################################################################        
    product_selector:                                                 # Define the product selector so the user can select the cloud and region
      type: dcm.inputs.Product                                        # Input type is dcm.inputs.Product
      properties:
        accountRegionSelector: account_region_zone_selector           # This connects the AccountRegionSelector to the Product selector
        platform: UNIX                                                # Virtual machine images are Linux
        architecture: I64                                             # 64 bit images
        productMappings:
          "Amazon":                                                   # Amazon cloud
            "us-east-1":                                              # us-east-1 Region
              image: "ami-c4edc0d3"                                   # Machine image identifier for an Ubuntu image in this region
              products: ['t1.micro', 'm1.small', 'm1.medium']         # The virtual machine product sizes for this region
            "us-west-1":                                              # us-west-1 Region
              image: "ami-e7035687"                                   # Machine image identifier for an Ubuntu image in this region
              products: ['t1.micro', 'm1.small', 'm1.medium']         # The virtual machine product sizes for this region
            "us-west-2":                                              # us-west-2 Region
              image: "ami-578c2f37"                                   # Machine image identifier for an Ubuntu image in this region
              products: ['t1.micro', 'm1.small', 'm1.medium']         # The virtual machine product sizes for this region
            "eu-west-1":                                              # eu-west-1 Region
              image: "ami-e6a1f795"                                   # Machine image identifier for an Ubuntu image in this region
              products: ['t1.micro', 'm1.small', 'm1.medium']         # The virtual machine product sizes for this region

Define outputs

In this tutorial 1 output will be defined and displayed on the Stack Overview page.

  • The Web URL of the Wildbook application.

Add the statements to the yaml file to define the output section. The outputs: statement must be indented inside the topology_template: statement and aligned with the inputs: statement. Refer to the Template Outputs section in this document for reference.

##################################################################################################################################################
# This defines the output to appear on the DCM console Stack overview page (URL of the Tomcat Wildbook Application)
##################################################################################################################################################
outputs:                                                        # Define outputs

  application_group:                                            # Create a Group
    type: dcm.outputs.DisplayGroup                              # It's a displayGroup
    properties:
      displayName: "Tomcat Server Information"                  # Set the display name for the group containing the outputs which appears on the Stack Overview page

  link:                                                         # Define an output
    type: dcm.outputs.Uri                                       # It's a URI output
    value: http://xxxxxxxxxxxxx:8080/wildbook-5.3.0-RELEASE/    # Set the initial value
    properties:
      host: {get_attribute: [docker_vm, publicIpAddress]}       # Set the hostname/ipaddress of the URI to the public IP address of the server running in the stack
      displayName: Wildbook Application URL                     # Set the display name (label) for the string output
      displayGroup: application_group                           # Place this output in the displayGroup named application_group

Define the server

The next step is to define a node_template to create a server to install the DCM agent, Docker and to run the 2 Docker containers.

Add the statements to define the server. In this example the server name will be hardcoded to be tomcat-server. The remaining server properties will be retrieved from the corresponding properties derived from the product_selector and the Dell Cloud Manager console end user’s Launch Blueprint selections. Refer to the Server node section in this document for reference.

##################################################################################################################################################
# This node_template defines a virtual machine named "docker_vm" which will host the Docker Tomcat 2 container stack
##################################################################################################################################################
docker_vm:
  type: dcm.nodes.Server                                                     # This is a Server node
  properties:
    name: "tomcat-server"
    cloud: { get_input: [account_region_zone_selector, cloud] }              # Retrieve cloud from the AccountRegionSelector
    cloudAccountId: { get_input: [account_region_zone_selector, accountId] } # Retrieve the cloud account ID from the AccountRegionSelector
    region: { get_input: [account_region_zone_selector, region] }            # Retrieve region from the AccountRegionSelector
    zone: { get_input: [account_region_zone_selector, zone] }                # Retrieve zone from the AccountRegionSelector
    platform: { get_input: [product_selector, platform] }                    # Retrieve platform from the Product selector
    architecture: { get_input: [product_selector, architecture] }            # Retrieve architecture from the Product selector
    product: { get_input: [product_selector, product] }                      # Retrieve product from the Product selector
    image: { get_input: [product_selector, image] }                          # Retrieve machine from the Product selector
    serverProductId: { get_input: [product_selector, serverProductId] }      # Retrieve server product id from the Product selector

Add the startupScript property statements to install, configure and start the Dell Cloud Manager agent and Docker on the launched server.

startupScript:  |                                                    # Startup script with commands to install the DCM Agent and Docker
  #!/bin/bash
  ##########################################################################################################################################
  # Install curl on Debian/Ubuntu if necessary
  ##########################################################################################################################################
  which apt-get && apt-get update -qq && (which curl || apt-get install curl -y)

  ##########################################################################################################################################
  # Install curl on RHEL/CentOS if necessary
  ##########################################################################################################################################
  which yum && yum -q makecache && (which curl || yum install curl -y)

  ##########################################################################################################################################
  # Install the Dell Cloud Manager agent and Docker
  # The -Z argument configures the Dell Cloud Manager agent and allows it to accept unknown certificates.
  # This is only recommended for testing and should not be done in a production environment.
  ##########################################################################################################################################
  export DCM_URL=${dcm.callback.url}
  curl -L --retry 10 https://linux-stable-agent.enstratius.com/agent_docker-1.0.0-1.sh | bash -s - -Z

  ##########################################################################################################################################
  # Create iptables rule to open http port 80 and save it
  ##########################################################################################################################################
  iptables -I INPUT -p tcp --dport 80 -j ACCEPT
  iptables-save

Add a requirement to the launched server for a firewall which will defer creating the server until after the firewall is created. In this example the firewall section label name is vm_firewall_rules and will be defined later in the template yaml file.

requirements:                                                   # This virtual machine node has a requirement on a firewall
  - firewall: vm_firewall_rules                                 # The firewall statement is named "vm_firewall_rules"
    relationship_type: tosca.relationships.DependsOn

Define the DockerApp Nodes

Define two DockerApp Nodes. One DockerApp node will create and run a container to host the MySQL database. The other DockerApp node will create and run a container to host the Tomcat Wildbook Application. A link will be defined to link the MySQL database container to the Tomcat Wildbook Application container. Refer to the DockerApp section in this document for reference.

    ##################################################################################################################################################
    # This node_template defines a Docker application which will launch a container to run the MySQL server docker image
    ##################################################################################################################################################
    docker_db:
      type: dcm.nodes.DockerApp                                   # This is a DockerApp node
      properties:
        name: "mysql-wildbook"                                    # Name of the container
        image: 'mysql'                                            # Launch the mysql image from the Docker base repository
        tag: 'latest'                                             # Launch the latest image 
        portBindings:
          3306: [['0.0.0.0', 3306]]                               # Bind port 3306 on the container to port 3306 on the launched server from any incoming connection
        environmentVariables:
          MYSQL_ROOT_PASSWORD: "passw0rd"                         # MySQL root password
          MYSQL_DATABASE: "shepherd"                              # MySQL database
          MYSQL_USER: "shepherd"                                  # MySQL database user
          MYSQL_PASSWORD: "shepherd"                              # MySQL database user password

      requirements:
        - host: docker_vm                                         # This DockerApp node has a requirement on the docker_vm node (launched server)

    ##################################################################################################################################################
    # This node_template defines a Docker application which will launch a container to run the Tomcat Wildbook Application docker image
    ##################################################################################################################################################
    docker_app:
      type: dcm.nodes.DockerApp                                   # This is a DockerApp node
      properties:
        name: "tomcat-wildbook"                                   # Name of the container
        image: 'gforghetti/tomcat-wildbook'                       # Launch an image from the Docker user gforghetti repository tomcat-wildbook    
        tag: 'latest'                                             # Launch the latest image in that user repository  
        ports: [8080]                                             # Expose port 8080 (the container will use the http port 8080)
        portBindings:
          8080: [['0.0.0.0', 8080]]                               # Bind port 8080 on the container to port 8080 on the launched server from any incoming connection
        links: 
          mysql-wildbook: "mysql-wildbook"                        # Link this container to the Docker mysql-wildbook container with an link name of mysql-wildbook

      requirements:
        - host: docker_vm                                         # This DockerApp node has a requirement on the docker_vm node (launched server)
        - db: docker_db                                           # This DockerApp node also has a requirement on the docker_db container.
          relationship_type: tosca.relationships.DependsOn        # This DockerApp node has a dependsOn relationship to the docker_db container.

Define the Firewall

Add the statements to define the firewall vm_firewall_rules. Define a rule to open the Tomcat HTTP port 8080.

Refer to the FirewallGroup node section in this document for reference.

###################################################################################################################################################
# This node_template defines a firewall which opens the Tomcat HTTP port 8080 for the Docker server
###################################################################################################################################################
vm_firewall_rules:
  type: dcm.nodes.FirewallGroup                                   # This is a firewall
  properties:                                                     # Retrieve the cloud properties from the "inputs"
    name: "fw-docker-server"                                      # Define a name for the firewall (it will get prefixed with the stack name)
    cloud: { get_input: [product_selector, cloud] }               # Retrieve the cloud from the product selector
    region: { get_input: [product_selector, region] }             # Retrieve the region from the product selector
    zone: { get_input: [product_selector, zone] }                 # Retrieve the zone from the product selector
    cloudAccountId: { get_input: [product_selector, accountId] }  # Retrieve the cloud account ID
    rules:
      - remote_ip_prefix: 0.0.0.0/0
        port: 8080                                                # Define a rule to open port 8080  (HTTP for Tomcat)