Windows Apache Web ServerΒΆ

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. You can download it at this link windows_apache_web_server_no_cm.yaml. Refer to the Windows Apache Web Server (No Config Mgmt) 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 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/tutorial5/overview.html
#
####################################################################################################################################################
template_name: "Apache Web Server on Windows"
template_author: Gary Forghetti
template_version: "1.00"
description: "Deploys a Windows Server 2012 and installs the Apache Web Server"
long_description: "This blueprint deploys a stack and installs the Apache Web Server"

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

topology_template:

  inputs:                                                         # Define 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 Cloud
            "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-1b", "eu-west-1c"]

    ################################################################################################################################################
    # 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
      properties:
        accountRegionSelector: account_region_zone_selector       # This connects the AccountRegionSelector to the Product selector
        platform: WINDOWS                                         # Virtual machine images are Windows
        architecture: I64                                         # 64 bit images
        productMappings:
          "Amazon":                                               # Amazon cloud
            "us-east-1":                                          # us-east-1 Region
              image: "ami-3f0c4628"                               # The AWS machine image identitier for the Windows 2012 R2 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-123c7472"                               # The AWS machine image identitier for the Windows 2012 R2 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-b871aad8"                               # The AWS machine image identitier for the Windows 2012 R2 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-55084526"                               # The AWS machine image identitier for the Windows 2012 R2 image in this region
              products: ['t1.micro', 'm1.small', 'm1.medium']     # The virtual machine product sizes for this region

  ##################################################################################################################################################
  # This defines the outputs which appear on the DCM console Stack Overview page
  ##################################################################################################################################################
  outputs:                                                        # Define outputs

    application_group:                                            # Create a Group
      type: dcm.outputs.DisplayGroup                              # It's a displayGroup
      properties:
        displayName: "Web Server"                                 # 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: [windows_wm, publicIpAddress]}       # Set the value to the public IP address of the Web server running in the stack
      properties:
        displayName: Windows Web Server                           # 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 for the URL of the Web server
      type: dcm.outputs.Uri                                       # It's a URI output
      value: http://xxxxxxxxxxxxx                                 # Set the initial value
      properties:
        host: {get_attribute: [windows_wm, publicIpAddress]}      # Set the hostname/ipaddress of the URI to the public IP address of the server running in the stack
        displayName: Windows Web 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/tutorial5/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 "vm" which will host the Web Server
    ##################################################################################################################################################
    windows_wm:
      type: dcm.nodes.Server
      properties:
        name: "web-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:  |
            <powershell>
            ###########################################################################################################################################
            # Download Apache
            ###########################################################################################################################################
            Invoke-WebRequest "http://archive.apache.org/dist/httpd/binaries/win32/httpd-2.2.25-win32-x86-openssl-0.9.8y.msi" `
            -outfile "c:\windows\temp\httpd-2.2.25-win32-x86-openssl-0.9.8y.msi"

            ###########################################################################################################################################
            # Install Apache
            ###########################################################################################################################################
            $computername = $env:COMPUTERNAME
            msiexec /i "c:\windows\temp\httpd-2.2.25-win32-x86-openssl-0.9.8y.msi" `
            /quiet ALLUSERS="1" INSTALLDIR="c:\Apache2.2" SERVICENAME="Apache" `
            SERVERADMIN="admin@localhost.com" SERVERDOMAIN=${computername} `
            SERVERNAME=${computername} SERVERPORT="80" | Out-File c:\windows\temp\apache_install.log

            ###########################################################################################################################################
            # Build Home page index.html
            ###########################################################################################################################################
            $html = '<!DOCTYPE html>'
            $html += '<html>'
            $html += '<head><title>ACME</title></head>'
            $html += '<body style="background-color:gainsboro;">'
            $html += '<h1><div style="text-align:center;">Welcome to ACME Anvil Corporation!</div></h1>'
            $html += '<div style="text-align:center;">'
            $html += '<img style="box-shadow: 8px 8px 5px #888888;" src="http://blueprint-designer-guide.enstratius.com/_static/acme_logo.jpg">'
            $html += '</div>'
            $html += '<p style="text-align:center;">Thank you for visiting our website. We look forward to having your business!</p>'
            $html += '</body>'
            $html += '</html>'
            $html | Out-File C:\Apache2.2\htdocs\index.html

            ###########################################################################################################################################
            # Add startup job to add a Firewall rule to open HTTP port 80 and run at system startup
            ###########################################################################################################################################
            $trigger = New-JobTrigger -AtStartup -RandomDelay 00:01:00

            $netsh_cmd = 'netsh advfirewall firewall add rule name="OpenPort80" description="Firewall rule" `
            localport=80 dir=in protocol=TCP action=allow profile=any interfacetype=any'
            $netsh_cmd | Out-File C:\Apache2.2\netsh_cmd.ps1

            Register-ScheduledJob -Trigger $trigger -FilePath C:\Apache2.2\netsh_cmd.ps1 -Name OpenPort80

            ###########################################################################################################################################
            # Now run the command to add the Firewall rule to open HTTP port 80.
            ###########################################################################################################################################
            invoke-expression $netsh_cmd

            ###########################################################################################################################################
            # Extract the hostname/ip address and port from the DCM variable ${dcm.callback.url}.
            ###########################################################################################################################################
            $callback_url = "${dcm.callback.url}"
            $host_port = ${callback_url}.TrimStart("wss://").TrimEnd("/agentManager").Split(":", 2)
            $host_name = ${host_port}[0]
            $port = ${host_port}[1]
            if (${port} -eq ${null}) {
              $port = 443
            }

            ###########################################################################################################################################
            # Download the DCM Windows Agent
            ###########################################################################################################################################
            Invoke-WebRequest "http://windows.stable.agent.enstratius.com/DCM.Agent.Setup-latest.msi" -OutFile "c:\windows\temp\dcm_agent.msi"

            ###########################################################################################################################################
            # Install the Windows DCM Agent.  Note: the backtick character (`) can be used to split a command in powershell into multiple lines
            ###########################################################################################################################################
            msiexec /i "c:\windows\temp\dcm_agent.msi" /log "c:\windows\temp\dcm_agent_install.log" /q INSTALLFOLDER="c:\Enstratius\" `
            INSTALL_ENVIRONMENT="Staging" SERVER_ADDRESS=${host_name} SERVER_PORT=${port} CLOUD_PROVIDER="Amazon" | Out-Null

            ###########################################################################################################################################
            # Start the DCM Agent
            ###########################################################################################################################################
            start-service DCMAgent
            </powershell>

      requirements:                                                 # This virtual machine node has a requirement on the firewall
        - firewall: vm_firewall_rules
          relationship_type: tosca.relationships.DependsOn

    ###################################################################################################################################################
    # This node_template defines a firewall which opens the HTTP port 80 and HTTPS port 443
    ###################################################################################################################################################
    vm_firewall_rules:
      type: dcm.nodes.FirewallGroup                                              # This is a firewall
      properties:                                                                # Retrieve the cloud properties from the "inputs"
        name: "web-server-firewall"                                              # Set the firewall 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                                                             # Allow port 80 (HTTP) from Anywhere (0.0.0.0/0)
          - remote_ip_prefix: 0.0.0.0/0
            port: 443                                                            # Allow port 443 (HTTPS) from Anywhere (0.0.0.0/0)