Linux Apache with AutomationΒΆ

This is an example of a template which launches a stack and deploys an Apache Web Server. The Apache Web Server is installed without using Chef or Puppet. This template has auto scaling and auto healing. You can download it at this link apache_web_server_no_cm_automation.yaml. Refer to the Linux Apache with Automation (No Config Mgmt) auto scaling and auto healing tutorial in this document for a detailed step by step hands on tutorial which uses this template.

####################################################################################################################################################
# This sample deploys a single server stack with an Apache Web Server. It does not require Configuration Management (no Chef or Puppet).
# This stack has auto scaling and auto healing.
####################################################################################################################################################
#
# This sample is intended for demonstrating the Blueprint function. It is not intended for "production" use and is unsupported.
# Use it at your own risk.
#
# Note: This Blueprint launches servers from public Ubuntu machine images. You should verify that the machine images still exist before launching.
#
# Refer to the Dell Cloud Manager Blueprint Designer Guide for more details.
# http://blueprint-designer-guide.enstratius.com/tutorials/no_cm/tutorial2/overview.html
#
####################################################################################################################################################
template_name: "Apache Web Server on Linux with automation"
template_author: "Gary Forghetti"
template_version: "1.00"
description: "Deploys an Apache Web Server single server stack with with auto healing and auto scaling, without Chef or Puppet."
long_description: "Deploys a stack with an Apache Web Server. This is a simple example which does not use Configuration Management to install Apache. This blueprint also has auto scaling and auto healing"

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

topology_template:

  inputs:                                                             # Define the inputs
    ################################################################################################################################################
    # 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"]
          "Azure":                                                    # Azure
            "East US": ["East US"]
          "DigitalOcean":                                             # Digital Ocean
            "nyc1": ["nyc1"]
          "Google":                                                   # Google
            "us-east1": ["us-east1-b"]
            "us-central1": ["us-central1-a"]
          "Joyent":                                                   # Joyent
            "us-east-1": ["us-east-1a"]

    ################################################################################################################################################
    # 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

          "Azure":                                                    # Azure cloud
            "East US":                                                # East US Region
              # Machine image identifier in this region
              image: "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_4-LTS-amd64-server-20160406-en-us-30GB"
              products: ['Basic_A1', 'Medium', 'Standard_D1']         # The virtual machine product sizes for this region

          "DigitalOcean":                                             # DigitalOcean Cloud
            "nyc1":                                                   # New York City 1 region
              image: "18173769"                                       # Machine image identifier for an Ubuntu image in this region
              products: ['1gb', '4gb', '8gb']                         # The virtual machine product sizes for this region

          "Google":                                                   # Google cloud
            "us-east1":                                               # us-east1 Region
              image: "ubuntu-os-cloud_ubuntu-1404-trusty-v20160516"   # Machine image identifier for an Ubuntu image in this region
              products: ['g1-small', 'n1-standard-4', 'n1-highmem-4'] # The virtual machine product sizes for this region
            "us-central1":                                            # us-central1 Region
              image: "ubuntu-os-cloud_ubuntu-1404-trusty-v20160516"   # Machine image identifier for an Ubuntu image in this region
              products: ['g1-small', 'n1-standard-4', 'n1-highmem-4'] # The virtual machine product sizes for this region

          "Joyent":                                                   # Joyent cloud
            "us-east-1":                                              # us-east-1 Region
              image: "c864f104-624c-43d2-835e-b49a39709b6b"           # Machine image identifier for an Ubuntu image in this region
              products: ['Medium 4GB', 'Large 8GB']                   # The virtual machine product sizes for this region


  ##################################################################################################################################################
  # This defines the two outputs to appear on the DCM console Stack overview page (IP address and URL of the Apache Web Server)
  ##################################################################################################################################################
  outputs:                                                        # Define outputs

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

    vm_ip:                                                        # Define an output
      type: string                                                # It's a string output
      description: IP of the server                               # Set the description for the string output
      value: {get_attribute: [web_vm, publicIpAddress]}           # Set the value to the public IP address of the server running in the stack
      properties:
        displayName: IP address                                   # Set the display name (label) for the string output
        displayGroup: application_group                           # Place this output in the displayGroup named application_group

    link:                                                         # Define another output
      type: dcm.outputs.Uri                                       # It's a URI output
      value: http://xxxxxxxxxxxxx/index.html                      # Set the initial value
      properties:
        host: {get_attribute: [web_vm, publicIpAddress]}          # Set the hostname/ipaddress of the URI to the public IP address of the server running in the stack
        displayName: Apache Server URL                            # Set the display name (label) for the URI output
        displayGroup: application_group                           # Place this output in the displayGroup named application_group

    tutorial_group:                                               # Create a Group
      type: dcm.outputs.DisplayGroup                              # It's a displayGroup
      properties:
        displayName: "Blueprint Designer Guide"                   # Set the display name for the group

    tutorial_link:                                                # Define an output
      type: dcm.outputs.Uri                                       # It's a URI output
      value: "http://blueprint-designer-guide.enstratius.com/tutorials/no_cm/tutorial2/overview.html"
      properties:
        displayName: "Tutorial Link:"                             # Set the display name (label) for the URI output
        displayGroup: tutorial_group                              # Place this output in the displayGroup named application_group

  node_templates:

    ##################################################################################################################################################
    # This node_template defines a virtual machine named "web_vm" which will host the Apache Web Servers
    ##################################################################################################################################################
    web_vm:
      type: dcm.nodes.Server                                                     # This is a Server node
      properties:
        name: "apache-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

        startupScript:  |                                                    # Startup script with commands to install and start the dcm agent
            #!/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, point it to the Dell Cloud Manager server and configure it to startup at boot time.
            ##########################################################################################################################################
            export DCM_URL=${dcm.callback.url}

            ##########################################################################################################################################
            # 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.
            ##########################################################################################################################################
            curl -L --retry 10 https://linux-stable-agent.enstratius.com/installer.sh | bash -s - --url $DCM_URL --on-boot -Z

            ##########################################################################################################################################
            # Start the Dell Cloud Manager agent.
            ##########################################################################################################################################
            /etc/init.d/dcm-agent start

            if [[ $(which apt-get > /dev/null;echo $?) -eq 0 ]]; then
                ######################################################################################################################################
                # Install Apache
                ######################################################################################################################################
                apt-get install apache2 -y

                ######################################################################################################################################
                # Start Apache
                ######################################################################################################################################
                service apache2 start
            elif [[ $(which yum > /dev/null;echo $?) -eq 0 ]]; then
                ######################################################################################################################################
                # Install Apache
                ######################################################################################################################################
                yum install httpd -y

                ######################################################################################################################################
                # Start Apache
                ######################################################################################################################################
                service httpd start
            else
                echo "Unrecognized Linux distribution!"
                exit 1
            fi

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

            ##########################################################################################################################################
            # Create a home page
            ##########################################################################################################################################
            home_page_location=""
            if [[ -d '/var/www/html' ]]; then
              home_page_location='/var/www/html'
            else
              home_page_location='/var/www'
            fi

            cat <<EOF > "${home_page_location}/index.html"
            <!DOCTYPE html>
            <html>
            <head>
            <title>ACME</title>
            </head>
            <body style='background-color:gainsboro;'>
            <h1><div style="text-align:center;">Welcome to ACME Anvil Corporation!</div></h1>
            <div style="text-align:center;"><img style="box-shadow: 8px 8px 5px #888888;" src="http://blueprint-designer-guide.enstratius.com/_static/acme_logo.jpg"></div>
            <p style='text-align:center;'>Thank you for visiting our website. We look forward to having your business!</p>
            </body>
            </html>
            EOF

      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

    ###################################################################################################################################################
    # This node_template defines a firewall which opens the HTTP port 80 for the Apache Web server
    ###################################################################################################################################################
    vm_firewall_rules:
      type: dcm.nodes.FirewallGroup                                              # This is a firewall
      properties:                                                                # Retrieve the cloud properties from the "inputs"
        name: "fw-apache-server"                                                 # Define a name for the firewall (it will get prefixed with the stack name)
        cloud: { get_input: [account_region_zone_selector, cloud] }              # Retrieve the 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 the region from the AccountRegionSelector
        zone: { get_input: [account_region_zone_selector, zone] }                # Retrieve the zone from the AccountRegionSelector
        rules:
          - remote_ip_prefix: 0.0.0.0/0
            port: 80                                                             # Define a rule to open port 80  (HTTP)

  ###################################################################################################################################################
  # This group defines the auto scaling and auto healing policies for the Apache Web server (web_vm)
  ###################################################################################################################################################
  groups:
    scaling_and_healing_group:
      members: [web_vm]                            # The node_template with the statement named "web_vm" is in this group
      properties:
        instances: 1                               # Launch 1 server when the stack is started
        minInstances: 1                            # The minimum number of servers
        maxInstances: 5                            # The maximum number of servers
        coolDown: 300                              # The number of seconds to wait before performing a auto scale or auto repair operation.

      policies:
        # This scale up policy will perform a scale up when the last 3 periods of idle time reported are < 20%
        scale_up_on_cpu:
          type: dcm.policy.types.BasicPolicy
          actions: [scale_up]                      # The scale_up action is defined in the actions: section of the template
          measurement: cpu_idle_time               # The cpu_idle_time label is defined in the measurements: section of the template
          criterion: less_than_20                  # The less_than_20 is a label defined in the criteria: section of the template

        # This scale down policy will perform a scale down when the last 2 periods of idle time reported are > 80%
        scale_down_on_cpu:
          type: dcm.policy.types.BasicPolicy
          actions: [scale_down]                    # The scale_down action is defined in the actions: section of the template
          measurement: cpu_idle_time               # The cpu_idle_time label is defined in the measurements: section of the template
          criterion: more_than_80                  # The more_than_80 is a label defined in the criteria: section of the template

        # When the cloud status of a resource is marked not healthy, terminate and restart it
        repair_on_status:
          type: dcm.policy.types.BasicPolicy
          measurement: cloud_reported_status
          criterion: check_fails
          actions: [repair]

      # Actions define the details of the various actions that could be taken.
      actions:
        scale_up:                                  # The scale_up action label is referenced in the policy in the actions[] statement
          type: dcm.policy.action.ScaleUpGroup
          properties:
            instances: 1                           # The number of resources to scale up on a scale_up action
            changeType: ADD                        # Add resource(s) on a scale_up action
            recordTask: RESOURCES_CHANGE           # Check to see if the scale up action would actually create a new resource,
                                                   # or a scale-down operation would actually destroy a resource before creating a task to perform the action.

        scale_down:                                # The scale_down action label is referenced in the policy in the actions[] statement
          type: dcm.policy.action.ScaleDownGroup
          properties:
            instances: 1                           # The number of resources to scale down on a scale_down action
            changeType: REMOVE                     # Remove resource(s) on a scale_down action
            recordTask: ALWAYS                     # Always attempt to perform a scale up or scale down action when the policy determines the actions should occur.
                                                   # Do not check the minInstances and maxInstances limits beforehand.

        repair:                                    # This auto healing action will terminate a degraded resource and then create a new resource
          type: dcm.policy.action.ReplaceResource

      # Measurements define the "measurements" used to determine when to perform the actions
      measurements:
        cpu_idle_time:                             # The cpu_idle_time measurements label is referenced in the policy in a measurements: statement
        # The Dell Cloud Manager agent will collect and store the last 15 samples of cpu %idle time measured in 30-second intervals
          type: dcm.policy.measurement.CpuIdle
          properties:
            period: 30                             # Take a measurement every 30 seconds
            count: 15                              # Take 15 measurements

        # You should include this measurement even if it is not used explicitly by a policy to enable UX health status.
        # The status reported by the cloud must be active, and for VMs the agent heartbeat must succeed,
        # otherwise the resource will be marked as DEGRADED
        cloud_reported_status:
          type: dcm.policy.measurement.ResourceActive

        resource_status:
          type: dcm.policy.measurement.ResourceStatus

      # Criteria specify the "criteria" which is used along with the measurements to determine when to perform the actions
      criteria:
        less_than_20:                              # The less_than_20 criteria label is referenced in the policy in a criterion: statement
          type: dcm.policy.criteria.SeriesLessThan
          properties:
            count: 3                               # 3 consecutive periods
            threshold: 20                          # Threshold is 20%

        more_than_80:                              # The more_than_80 criteria label is referenced in the policy in a criterion: statement
          type: dcm.policy.criteria.SeriesMoreThan
          properties:
            count: 2                               # 2 consecutive periods
            threshold: 80                          # Threshold is 80%

        check_fails:                               # This is the criteria for auto healing
          type: dcm.policy.criteria.False          # "False" tells the policy to perform the action in the policy if the measurement result matches "False".