{
  "AWSTemplateFormatVersion": "2010-09-09",

  "Description": "AWS CloudFormation Sample Template OpsWorksVPCELB: Launches OpsWorks stack, layer, instances and associated resources to run a PHP application. The application runs inside an Amazon VPC and uses ELB to load balance ** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.",

  "Mappings": {
    "SubnetConfig": {
      "VPC"    : { "CIDR": "10.0.0.0/16" },
      "Public" : { "CIDR": "10.0.0.0/24" },
      "Private": { "CIDR": "10.0.1.0/24" }
    },
    "AWSInstanceType2Arch" : {
      "c1.medium"   : { "Arch" : "HVM64"  },
      "c1.xlarge"   : { "Arch" : "HVM64"  },
      "c3.2xlarge"  : { "Arch" : "HVM64"  },
      "c3.4xlarge"  : { "Arch" : "HVM64"  },
      "c3.8xlarge"  : { "Arch" : "HVM64"  },
      "c3.large"    : { "Arch" : "HVM64"  },
      "c3.xlarge"   : { "Arch" : "HVM64"  },
      "c4.2xlarge"  : { "Arch" : "HVM64"  },
      "c4.4xlarge"  : { "Arch" : "HVM64"  },
      "c4.8xlarge"  : { "Arch" : "HVM64"  },
      "c4.large"    : { "Arch" : "HVM64"  },
      "c4.xlarge"   : { "Arch" : "HVM64"  },
      "cc2.8xlarge" : { "Arch" : "HVM64"  },
      "cr1.8xlarge" : { "Arch" : "HVM64"  },
      "d2.2xlarge"  : { "Arch" : "HVM64"  },
      "d2.4xlarge"  : { "Arch" : "HVM64"  },
      "d2.8xlarge"  : { "Arch" : "HVM64"  },
      "d2.xlarge"   : { "Arch" : "HVM64"  },
      "g2.2xlarge"  : { "Arch" : "HVMG2"  },
      "g2.8xlarge"  : { "Arch" : "HVMG2"  },
      "hi1.4xlarge" : { "Arch" : "HVM64"  },
      "hs1.8xlarge" : { "Arch" : "HVM64"  },
      "i2.2xlarge"  : { "Arch" : "HVM64"  },
      "i2.4xlarge"  : { "Arch" : "HVM64"  },
      "i2.8xlarge"  : { "Arch" : "HVM64"  },
      "i2.xlarge"   : { "Arch" : "HVM64"  },
      "m1.large"    : { "Arch" : "HVM64"  },
      "m1.medium"   : { "Arch" : "HVM64"  },
      "m1.small"    : { "Arch" : "HVM64"  },
      "m1.xlarge"   : { "Arch" : "HVM64"  },
      "m2.2xlarge"  : { "Arch" : "HVM64"  },
      "m2.4xlarge"  : { "Arch" : "HVM64"  },
      "m2.xlarge"   : { "Arch" : "HVM64"  },
      "m3.2xlarge"  : { "Arch" : "HVM64"  },
      "m3.large"    : { "Arch" : "HVM64"  },
      "m3.medium"   : { "Arch" : "HVM64"  },
      "m3.xlarge"   : { "Arch" : "HVM64"  },
      "m4.10xlarge" : { "Arch" : "HVM64"  },
      "m4.2xlarge"  : { "Arch" : "HVM64"  },
      "m4.4xlarge"  : { "Arch" : "HVM64"  },
      "m4.large"    : { "Arch" : "HVM64"  },
      "m4.xlarge"   : { "Arch" : "HVM64"  },
      "r3.2xlarge"  : { "Arch" : "HVM64"  },
      "r3.4xlarge"  : { "Arch" : "HVM64"  },
      "r3.8xlarge"  : { "Arch" : "HVM64"  },
      "r3.large"    : { "Arch" : "HVM64"  },
      "r3.xlarge"   : { "Arch" : "HVM64"  },
      "t1.micro"    : { "Arch" : "HVM64"  },
      "t2.large"    : { "Arch" : "HVM64"  },
      "t2.medium"   : { "Arch" : "HVM64"  },
      "t2.micro"    : { "Arch" : "HVM64"  },
      "t2.nano"     : { "Arch" : "HVM64"  },
      "t2.small"    : { "Arch" : "HVM64"  }
    },

    "AWSInstanceType2NATArch" : {
      "c1.medium"   : { "Arch" : "NATHVM64"  },
      "c1.xlarge"   : { "Arch" : "NATHVM64"  },
      "c3.2xlarge"  : { "Arch" : "NATHVM64"  },
      "c3.4xlarge"  : { "Arch" : "NATHVM64"  },
      "c3.8xlarge"  : { "Arch" : "NATHVM64"  },
      "c3.large"    : { "Arch" : "NATHVM64"  },
      "c3.xlarge"   : { "Arch" : "NATHVM64"  },
      "c4.2xlarge"  : { "Arch" : "NATHVM64"  },
      "c4.4xlarge"  : { "Arch" : "NATHVM64"  },
      "c4.8xlarge"  : { "Arch" : "NATHVM64"  },
      "c4.large"    : { "Arch" : "NATHVM64"  },
      "c4.xlarge"   : { "Arch" : "NATHVM64"  },
      "cc2.8xlarge" : { "Arch" : "NATHVM64"  },
      "cr1.8xlarge" : { "Arch" : "NATHVM64"  },
      "d2.2xlarge"  : { "Arch" : "NATHVM64"  },
      "d2.4xlarge"  : { "Arch" : "NATHVM64"  },
      "d2.8xlarge"  : { "Arch" : "NATHVM64"  },
      "d2.xlarge"   : { "Arch" : "NATHVM64"  },
      "g2.2xlarge"  : { "Arch" : "NATHVMG2"  },
      "g2.8xlarge"  : { "Arch" : "NATHVMG2"  },
      "hi1.4xlarge" : { "Arch" : "NATHVM64"  },
      "hs1.8xlarge" : { "Arch" : "NATHVM64"  },
      "i2.2xlarge"  : { "Arch" : "NATHVM64"  },
      "i2.4xlarge"  : { "Arch" : "NATHVM64"  },
      "i2.8xlarge"  : { "Arch" : "NATHVM64"  },
      "i2.xlarge"   : { "Arch" : "NATHVM64"  },
      "m1.large"    : { "Arch" : "NATHVM64"  },
      "m1.medium"   : { "Arch" : "NATHVM64"  },
      "m1.small"    : { "Arch" : "NATHVM64"  },
      "m1.xlarge"   : { "Arch" : "NATHVM64"  },
      "m2.2xlarge"  : { "Arch" : "NATHVM64"  },
      "m2.4xlarge"  : { "Arch" : "NATHVM64"  },
      "m2.xlarge"   : { "Arch" : "NATHVM64"  },
      "m3.2xlarge"  : { "Arch" : "NATHVM64"  },
      "m3.large"    : { "Arch" : "NATHVM64"  },
      "m3.medium"   : { "Arch" : "NATHVM64"  },
      "m3.xlarge"   : { "Arch" : "NATHVM64"  },
      "m4.10xlarge" : { "Arch" : "NATHVM64"  },
      "m4.2xlarge"  : { "Arch" : "NATHVM64"  },
      "m4.4xlarge"  : { "Arch" : "NATHVM64"  },
      "m4.large"    : { "Arch" : "NATHVM64"  },
      "m4.xlarge"   : { "Arch" : "NATHVM64"  },
      "r3.2xlarge"  : { "Arch" : "NATHVM64"  },
      "r3.4xlarge"  : { "Arch" : "NATHVM64"  },
      "r3.8xlarge"  : { "Arch" : "NATHVM64"  },
      "r3.large"    : { "Arch" : "NATHVM64"  },
      "r3.xlarge"   : { "Arch" : "NATHVM64"  },
      "t1.micro"    : { "Arch" : "NATHVM64"  },
      "t2.large"    : { "Arch" : "NATHVM64"  },
      "t2.medium"   : { "Arch" : "NATHVM64"  },
      "t2.micro"    : { "Arch" : "NATHVM64"  },
      "t2.nano"     : { "Arch" : "NATHVM64"  },
      "t2.small"    : { "Arch" : "NATHVM64"  }
    }
,
    "AWSRegionArch2AMI" : {
      "af-south-1"       : {"HVM64" : "ami-0412806bd0f2cf75f", "HVMG2" : "NOT_SUPPORTED"},
      "ap-east-1"        : {"HVM64" : "ami-0e0a21f8bd5195698", "HVMG2" : "NOT_SUPPORTED"},
      "ap-northeast-1"   : {"HVM64" : "ami-0c3e3e7af817ad732", "HVMG2" : "NOT_SUPPORTED"},
      "ap-northeast-2"   : {"HVM64" : "ami-0f8dbbf156e3a5cc6", "HVMG2" : "NOT_SUPPORTED"},
      "ap-northeast-3"   : {"HVM64" : "ami-02a371c41f08cc499", "HVMG2" : "NOT_SUPPORTED"},
      "ap-south-1"       : {"HVM64" : "ami-0f4ab3c8db917e421", "HVMG2" : "NOT_SUPPORTED"},
      "ap-south-2"       : {"HVM64" : "ami-008b9c53bb1dcd29c", "HVMG2" : "NOT_SUPPORTED"},
      "ap-southeast-1"   : {"HVM64" : "ami-0c3189395e5b39df7", "HVMG2" : "NOT_SUPPORTED"},
      "ap-southeast-2"   : {"HVM64" : "ami-040d698318c0b1575", "HVMG2" : "NOT_SUPPORTED"},
      "ap-southeast-3"   : {"HVM64" : "ami-065dcca47dde26602", "HVMG2" : "NOT_SUPPORTED"},
      "ap-southeast-4"   : {"HVM64" : "ami-043e25432cf94e107", "HVMG2" : "NOT_SUPPORTED"},
      "il-central-1"     : {"HVM64" : "ami-0054be7d7d9d65a1d", "HVMG2" : "NOT_SUPPORTED"},
      "ca-central-1"     : {"HVM64" : "ami-05f40104305a2cdf7", "HVMG2" : "NOT_SUPPORTED"},
      "cn-north-1"       : {"HVM64" : "ami-03f1e08d409b1e5fd", "HVMG2" : "NOT_SUPPORTED"},
      "cn-northwest-1"   : {"HVM64" : "ami-00093746b9a0e272a", "HVMG2" : "NOT_SUPPORTED"},
      "eu-central-1"     : {"HVM64" : "ami-0f454ec961da9a046", "HVMG2" : "NOT_SUPPORTED"},
      "eu-north-1"       : {"HVM64" : "ami-0e78cd18c67fcf512", "HVMG2" : "NOT_SUPPORTED"},
      "eu-south-1"       : {"HVM64" : "ami-07d048788725b9602", "HVMG2" : "NOT_SUPPORTED"},
      "eu-west-1"        : {"HVM64" : "ami-0db5ca3e5748fb7e2", "HVMG2" : "NOT_SUPPORTED"},
      "eu-west-2"        : {"HVM64" : "ami-07baf6b15b7387f24", "HVMG2" : "NOT_SUPPORTED"},
      "eu-west-3"        : {"HVM64" : "ami-05a13fbd8aa57eedc", "HVMG2" : "NOT_SUPPORTED"},
      "me-south-1"       : {"HVM64" : "ami-0007de3fdcaba7e44", "HVMG2" : "NOT_SUPPORTED"},
      "me-central-1"     : {"HVM64" : "ami-06ce88defa3fc74ed", "HVMG2" : "NOT_SUPPORTED"},
      "eu-south-2"       : {"HVM64" : "ami-051306f4e885d6de4", "HVMG2" : "NOT_SUPPORTED"},
      "eu-central-2"     : {"HVM64" : "ami-0fcd532574732cb0f", "HVMG2" : "NOT_SUPPORTED"},
      "sa-east-1"        : {"HVM64" : "ami-07f6e9fce0e888425", "HVMG2" : "NOT_SUPPORTED"},
      "us-east-1"        : {"HVM64" : "ami-01989ebfd388ea377", "HVMG2" : "NOT_SUPPORTED"},
      "us-east-2"        : {"HVM64" : "ami-0de69dde1945155da", "HVMG2" : "NOT_SUPPORTED"},
      "us-west-1"        : {"HVM64" : "ami-08fe20a82dcaa1c92", "HVMG2" : "NOT_SUPPORTED"},
      "us-west-2"        : {"HVM64" : "ami-05848d23360f5edfe", "HVMG2" : "NOT_SUPPORTED"}
    }
,
    "AWSNATRegionArch2AMI" : {
      "af-south-1"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-east-1"        : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-northeast-1"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-northeast-2"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-northeast-3"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-south-1"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-south-2"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-southeast-1"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-southeast-2"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-southeast-3"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "ap-southeast-4"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "il-central-1"     : {"NATHVM64" : "NOT_SUPPORTED"},
      "ca-central-1"     : {"NATHVM64" : "NOT_SUPPORTED"},
      "cn-north-1"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "cn-northwest-1"   : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-central-1"     : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-north-1"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-south-1"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-west-1"        : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-west-2"        : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-west-3"        : {"NATHVM64" : "NOT_SUPPORTED"},
      "me-south-1"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "me-central-1"     : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-south-2"       : {"NATHVM64" : "NOT_SUPPORTED"},
      "eu-central-2"     : {"NATHVM64" : "NOT_SUPPORTED"},
      "sa-east-1"        : {"NATHVM64" : "NOT_SUPPORTED"},
      "us-east-1"        : {"NATHVM64" : "ami-45fe0f3f"},
      "us-east-2"        : {"NATHVM64" : "NOT_SUPPORTED"},
      "us-west-1"        : {"NATHVM64" : "NOT_SUPPORTED"},
      "us-west-2"        : {"NATHVM64" : "NOT_SUPPORTED"}
    }
,
    "Region2Principal" : {
      "ap-east-1"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-northeast-1" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-northeast-2" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-northeast-3" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-south-1"     : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-south-2"     : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-southeast-1" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-southeast-2" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-southeast-3" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ap-southeast-4" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "il-central-1" : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "ca-central-1"   : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "cn-north-1"     : { "EC2Principal" : "ec2.amazonaws.com.cn", "OpsWorksPrincipal" : "opsworks.amazonaws.com.cn" },
      "cn-northwest-1" : { "EC2Principal" : "ec2.amazonaws.com.cn", "OpsWorksPrincipal" : "opsworks.amazonaws.com.cn" },
      "eu-central-1"   : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "eu-north-1"     : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "eu-west-1"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "eu-west-2"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "eu-west-3"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "me-south-1"     : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "me-central-1"   : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "eu-south-2"     : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "eu-central-2"   : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "sa-east-1"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "us-east-1"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "us-east-2"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "us-west-1"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" },
      "us-west-2"      : { "EC2Principal" : "ec2.amazonaws.com", "OpsWorksPrincipal" : "opsworks.amazonaws.com" }
    }

  },

  "Resources": {
    "OpsWorksStack": {
      "Type": "AWS::OpsWorks::Stack",
      "Properties": {
        "Name": { "Ref": "AWS::StackName" },
        "ServiceRoleArn": { "Fn::GetAtt": [ "OpsWorksServiceRole", "Arn" ] },
        "DefaultInstanceProfileArn": { "Fn::GetAtt": [ "OpsWorksInstanceProfile", "Arn" ] },
        "VpcId": { "Ref": "VPC" },
        "DefaultSubnetId": { "Ref": "PrivateSubnet" }
      }
    },

    "OpsWorksLayer": {
      "Type": "AWS::OpsWorks::Layer",
      "Metadata" : {
        "Comment" : "OpsWorks instances require outbound Internet access. Using DependsOn to make sure outbound Internet Access is estlablished before creating instances in this layer."
      },
      "DependsOn": [ "NATIPAddress", "PublicRoute", "PublicSubnetRouteTableAssociation", "PrivateRoute", "PrivateSubnetRouteTableAssociation", "OpsWorksApp"],
      "Properties": {
        "StackId": { "Ref": "OpsWorksStack" },
        "Name": "MyPHPApp",
        "Type": "php-app",
        "Shortname": "php-app",
        "EnableAutoHealing": "true",
        "AutoAssignElasticIps": "false",
        "AutoAssignPublicIps": "true",
        "CustomSecurityGroupIds": [ { "Ref": "OpsWorksSecurityGroup" } ]
      }
    },

    "OpsWorksInstance1": {
      "Type": "AWS::OpsWorks::Instance",
      "Properties": {
        "StackId": { "Ref": "OpsWorksStack" },
        "LayerIds": [ { "Ref": "OpsWorksLayer" } ],
        "InstanceType": "t2.small",
        "RootDeviceType" : "ebs"
      }
    },

    "OpsWorksInstance2": {
      "Type": "AWS::OpsWorks::Instance",
      "Properties": {
        "StackId": { "Ref": "OpsWorksStack" },
        "LayerIds": [ { "Ref": "OpsWorksLayer" } ],
        "InstanceType": "t2.small",
        "RootDeviceType" : "ebs"
      }
    },
    "OpsWorksApp": {
      "Type": "AWS::OpsWorks::App",
      "Properties": {
        "StackId": { "Ref": "OpsWorksStack" },
        "Name": "MyPHPApp",
        "Type": "php",
        "AppSource": {
          "Type": "git",
          "Url": "git://github.com/amazonwebservices/opsworks-demo-php-simple-app.git",
          "Revision": "version1"
        },
        "Attributes": {
          "DocumentRoot": " "
        }
      }
    },
    "OpsWorksServiceRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": { "Service": [{ "Fn::FindInMap" : ["Region2Principal", {"Ref" : "AWS::Region"}, "OpsWorksPrincipal"]}] },
            "Action": [ "sts:AssumeRole" ]
          }]
        },
        "Path": "/",
        "Policies": [
          {
            "PolicyName": "opsworks-service",
            "PolicyDocument": {
              "Statement": [{
                "Effect": "Allow",
                "Action": [ "ec2:*", "iam:PassRole", "cloudwatch:GetMetricStatistics", "elasticloadbalancing:*" ],
                "Resource": "*"
              }]
            }
          }
        ]
      }
    },
    "OpsWorksInstanceRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": { "Service": [{ "Fn::FindInMap" : ["Region2Principal", {"Ref" : "AWS::Region"}, "EC2Principal"]}] },
            "Action": [ "sts:AssumeRole" ]
          }]
        },
        "Path": "/"
      }
    },
    "OpsWorksInstanceProfile": {
      "Type": "AWS::IAM::InstanceProfile",
      "Properties": {
        "Path": "/",
        "Roles": [ { "Ref": "OpsWorksInstanceRole" } ]
      }
    },
    "OpsWorksSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription" : "Allow inbound requests from the ELB to the OpsWorks instances",
        "VpcId": { "Ref": "VPC" },
        "SecurityGroupIngress": [
          { "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "SourceSecurityGroupId": { "Ref": "ELBSecurityGroup" } }
        ]
      }
    },

    "ELB": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties": {
        "CrossZone" : "true",
        "SecurityGroups": [ { "Ref": "ELBSecurityGroup" } ],
        "Subnets": [ { "Ref": "PublicSubnet" } ],
        "Listeners": [ {
          "LoadBalancerPort": "80",
          "InstancePort": "80",
          "Protocol": "HTTP"
        } ],
        "HealthCheck": {
          "Target": "HTTP:80/",
          "HealthyThreshold": "3",
          "UnhealthyThreshold": "5",
          "Interval": "90",
          "Timeout": "60"
        }
      }
    },

    "ELBAttachment": {
      "Type": "AWS::OpsWorks::ElasticLoadBalancerAttachment",
      "Properties": {
        "ElasticLoadBalancerName": { "Ref": "ELB" },
        "LayerId": { "Ref": "OpsWorksLayer" }
      }
    },

    "ELBSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription" : "Allow inbound access to the ELB",
        "VpcId": { "Ref": "VPC" },
        "SecurityGroupIngress": [ {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        } ],
        "SecurityGroupEgress": [ {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        } ]
      }
    },

    "VPC": {
      "Type": "AWS::EC2::VPC",
      "DependsOn": "OpsWorksServiceRole",
      "Properties": {
        "CidrBlock": { "Fn::FindInMap": [ "SubnetConfig", "VPC", "CIDR" ] },
        "Tags": [ 
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Network", "Value": "Public" }
        ]
      }
    },

    "PublicSubnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "CidrBlock": { "Fn::FindInMap": [ "SubnetConfig", "Public", "CIDR" ] },
        "Tags": [
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Network", "Value": "Public" } 
        ]
      }
    },

    "InternetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "Properties": {
        "Tags": [
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Network", "Value": "Public" }
        ]
      }
    },

    "VPCGatewayAttachment": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "InternetGatewayId": { "Ref": "InternetGateway" }
      }
    },

    "PublicRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "Tags": [
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Network", "Value": "Public" }
        ]
      }
    },

    "PublicRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": "VPCGatewayAttachment",
      "Properties": {
        "RouteTableId": { "Ref": "PublicRouteTable" },
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": { "Ref": "InternetGateway" }
      }
    },

    "PublicSubnetRouteTableAssociation": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": { "Ref": "PublicSubnet" },
        "RouteTableId": { "Ref": "PublicRouteTable" }
      }
    },

    "PublicNetworkAcl": {
      "Type": "AWS::EC2::NetworkAcl",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "Tags": [
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Network", "Value": "Public" }
        ]
      }
    },
    "InboundHTTPPublicNetworkAclEntry": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "PublicNetworkAcl" },
        "RuleNumber": "100",
        "Protocol": "6",
        "RuleAction": "allow",
        "Egress": "false",
        "CidrBlock": "0.0.0.0/0",
        "PortRange": { "From": "80", "To": "80" }
      }
    },
    "InboundHTTPSPublicNetworkAclEntry": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "PublicNetworkAcl" },
        "RuleNumber": "101",
        "Protocol": "6",
        "RuleAction": "allow",
        "Egress": "false",
        "CidrBlock": "0.0.0.0/0",
        "PortRange": { "From": "443", "To": "443" }
      }
    },
    "InboundSSHPublicNetworkAclEntry": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "PublicNetworkAcl" },
        "RuleNumber": "102",
        "Protocol": "6",
        "RuleAction": "allow",
        "Egress": "false",
        "CidrBlock": "0.0.0.0/0",
        "PortRange": { "From": "22", "To": "22" }
      }
    },
    "InboundEphemeralPublicNetworkAclEntry": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "PublicNetworkAcl" },
        "RuleNumber": "103",
        "Protocol": "6",
        "RuleAction": "allow",
        "Egress": "false",
        "CidrBlock": "0.0.0.0/0",
        "PortRange": { "From": "1024", "To": "65535"
        }
      }
    },
    "OutboundPublicNetworkAclEntry": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "PublicNetworkAcl" },
        "RuleNumber": "100",
        "Protocol": "6",
        "RuleAction": "allow",
        "Egress": "true",
        "CidrBlock": "0.0.0.0/0",
        "PortRange": { "From": "0", "To": "65535" }
      }
    },
    "PublicSubnetNetworkAclAssociation": {
      "Type": "AWS::EC2::SubnetNetworkAclAssociation",
      "Properties": {
        "SubnetId": { "Ref": "PublicSubnet" },
        "NetworkAclId": { "Ref": "PublicNetworkAcl" }
      }
    },
    "PrivateSubnet": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "CidrBlock": { "Fn::FindInMap": [ "SubnetConfig", "Private", "CIDR" ] },
        "Tags": [
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Name", "Value": "Private" }
        ]
      }
    },
    "PrivateRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "Tags": [
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Network", "Value": "Private" }
        ]
      }
    },
    "PrivateSubnetRouteTableAssociation": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": { "Ref": "PrivateSubnet" },
        "RouteTableId": { "Ref": "PrivateRouteTable" }
      }
    },
    "PrivateRoute": {
      "Type": "AWS::EC2::Route",
      "Properties": {
        "RouteTableId": { "Ref": "PrivateRouteTable" },
        "DestinationCidrBlock": "0.0.0.0/0",
        "InstanceId": { "Ref": "NATDevice" }
      }
    },
    "PrivateNetworkAcl": {
      "Type": "AWS::EC2::NetworkAcl",
      "Properties": {
        "VpcId": { "Ref": "VPC" },
        "Tags": [
          { "Key": "Application", "Value": { "Ref": "AWS::StackName" } },
          { "Key": "Network", "Value": "Private" }
        ]
      }
    },
    "InboundPrivateNetworkAclEntry": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "PrivateNetworkAcl" },
        "RuleNumber": "100",
        "Protocol": "6",
        "RuleAction": "allow",
        "Egress": "false",
        "CidrBlock": "0.0.0.0/0",
        "PortRange": { "From": "0", "To": "65535" }
      }
    },
    "OutBoundPrivateNetworkAclEntry": {
      "Type": "AWS::EC2::NetworkAclEntry",
      "Properties": {
        "NetworkAclId": { "Ref": "PrivateNetworkAcl" },
        "RuleNumber": "100",
        "Protocol": "6",
        "RuleAction": "allow",
        "Egress": "true",
        "CidrBlock": "0.0.0.0/0",
        "PortRange": { "From": "0", "To": "65535" }
      }
    },
    "PrivateSubnetNetworkAclAssociation": {
      "Type": "AWS::EC2::SubnetNetworkAclAssociation",
      "Properties": {
        "SubnetId": { "Ref": "PrivateSubnet" }, 
        "NetworkAclId": { "Ref": "PrivateNetworkAcl"
        }
      }
    },
    "NATIPAddress": {
      "Type": "AWS::EC2::EIP",
      "Properties": {
        "Domain": "vpc",
        "InstanceId": { "Ref": "NATDevice" }
      }
    },
    "NATDevice": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
        "InstanceType": "t2.small",
        "SubnetId": { "Ref": "PublicSubnet" },
        "SourceDestCheck": "false",
        "ImageId" : { "Fn::FindInMap" : [ "AWSNATRegionArch2AMI", { "Ref" : "AWS::Region" },
                          { "Fn::FindInMap" : [ "AWSInstanceType2NATArch", "t2.small", "Arch" ] } ] },
        "SecurityGroupIds": [ { "Ref": "NATSecurityGroup" } ]
      }
    },
    "NATSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupDescription" : "Allow OpsWorks instances to access the NAT Device",
        "VpcId": { "Ref": "VPC" },
        "SecurityGroupIngress": [ {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "SourceSecurityGroupId": { "Ref": "OpsWorksSecurityGroup" }
        }, {
          "IpProtocol": "tcp",
          "FromPort": "9418",
          "ToPort": "9418",
          "SourceSecurityGroupId": { "Ref": "OpsWorksSecurityGroup" }
        }, {
          "IpProtocol": "tcp",
          "FromPort": "443",
          "ToPort": "443",
          "SourceSecurityGroupId": { "Ref": "OpsWorksSecurityGroup" }
        } ],
        "SecurityGroupEgress": [ {
          "IpProtocol": "tcp",
          "FromPort": "80",
          "ToPort": "80",
          "CidrIp": "0.0.0.0/0"
        }, {
          "IpProtocol": "tcp",
          "FromPort": "9418",
          "ToPort": "9418",
          "CidrIp": "0.0.0.0/0"
        }, {
          "IpProtocol": "tcp",
          "FromPort": "443",
          "ToPort": "443",
          "CidrIp": "0.0.0.0/0"
        } ]
      }
    }
  },
  "Outputs": {
    "StackId": {
      "Description": "Stack Id of newly created OpsWorks stack",
      "Value": { "Ref": "OpsWorksStack" }
    },
    "AppId": {
      "Description" : "Application Id of newly created OpsWorks application",
      "Value": { "Ref": "OpsWorksApp" }
    },
    "VPC": {
      "Description": "VPC Id of newly created Virtual Private Cloud",
      "Value": { "Ref": "VPC" }
    },
    "URL": {
      "Description" : "URL for newly created application",
      "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "ELB", "DNSName" ]}]] }
    }
  }
}
