{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "AWS CloudFormation Sample Template: 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": { "AWSNATAMI": { "us-east-1": { "AMI": "ami-c6699baf" }, "us-west-2": { "AMI": "ami-52ff7262" }, "us-west-1": { "AMI": "ami-3bcc9e7e" }, "eu-west-1": { "AMI": "ami-0b5b6c7f" }, "ap-southeast-1": { "AMI": "ami-02eb9350" }, "ap-northeast-1": { "AMI": "ami-14d86d15" }, "sa-east-1": { "AMI": "ami-0439e619" } }, "SubnetConfig": { "VPC": { "CIDR": "10.0.0.0/16" }, "Public": { "CIDR": "10.0.0.0/24" }, "Private": { "CIDR": "10.0.1.0/24" } } }, "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": "m1.small" } }, "OpsWorksInstance2": { "Type": "AWS::OpsWorks::Instance", "Properties": { "StackId": { "Ref": "OpsWorksStack" }, "LayerIds": [ { "Ref": "OpsWorksLayer" } ], "InstanceType": "m1.small" } }, "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": [ "opsworks.amazonaws.com" ] }, "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": [ "ec2.amazonaws.com" ] }, "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": { "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" } } }, "InboundEmphemeralPublicNetworkAclEntry": { "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": "m1.small", "SubnetId": { "Ref": "PublicSubnet" }, "SourceDestCheck": "false", "ImageId": { "Fn::FindInMap": [ "AWSNATAMI", { "Ref": "AWS::Region" }, "AMI" ] }, "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": { "Value": { "Ref": "OpsWorksStack" } }, "AppId": { "Value": { "Ref": "OpsWorksApp" } }, "VPC": { "Description": "VPC", "Value": { "Ref": "VPC" } }, "PublicSubnet": { "Value": { "Ref": "PublicSubnet" } }, "PrivateSubnet": { "Value": { "Ref": "PrivateSubnet" } }, "ELB": { "Value": { "Ref": "ELB" } } } }