{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "CloudFormation Blog Activity", "Parameters": { "WebServerKeyName": { "Description": "The key pair to establish a SSH connection to the web servers.", "Type": "AWS::EC2::KeyPair::KeyName" } }, "Resources": { "VPC": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.99.0.0/16", "EnableDnsHostnames": "true", "EnableDnsSupport": "true", "Tags": [ { "Key": "Name", "Value": "BlogVPC" } ] } }, "InternetGateway": { "Type": "AWS::EC2::InternetGateway", "Properties": {} }, "VPCGatewayAttachment": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": { "Ref": "VPC" }, "InternetGatewayId": { "Ref": "InternetGateway" } } }, "DMZ1public": { "Type": "AWS::EC2::Subnet", "Properties": { "AvailabilityZone": { "Fn::Select": [ "0", { "Fn::GetAZs": "" } ] }, "CidrBlock": "10.99.1.0/24", "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "DMZ1public" } ] } }, "DMZ2public": { "Type": "AWS::EC2::Subnet", "Properties": { "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": "" } ] }, "CidrBlock": "10.99.2.0/24", "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "DMZ2public" } ] } }, "AppLayer1private": { "Type": "AWS::EC2::Subnet", "Properties": { "AvailabilityZone": { "Fn::Select": [ "0", { "Fn::GetAZs": "" } ] }, "CidrBlock": "10.99.11.0/24", "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "AppLayer1private" } ] } }, "AppLayer2private": { "Type": "AWS::EC2::Subnet", "Properties": { "AvailabilityZone": { "Fn::Select": [ "1", { "Fn::GetAZs": "" } ] }, "CidrBlock": "10.99.12.0/24", "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "AppLayer2private" } ] } }, "PublicRT": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "PublicRT" } ] } }, "RouteTableAssociationA": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "DMZ1public" }, "RouteTableId": { "Ref": "PublicRT" } } }, "RouteTableAssociationB": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "DMZ2public" }, "RouteTableId": { "Ref": "PublicRT" } } }, "RoutePublicNATToInternet": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "PublicRT" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "InternetGateway" } }, "DependsOn": "VPCGatewayAttachment" }, "NATElasticIP": { "Type": "AWS::EC2::EIP", "Properties": { "Domain": "vpc" }, "DependsOn": "VPCGatewayAttachment" }, "NATGateway": { "Type": "AWS::EC2::NatGateway", "DependsOn": "NATElasticIP", "Properties": { "AllocationId": { "Fn::GetAtt": [ "NATElasticIP", "AllocationId" ] }, "SubnetId": { "Ref": "DMZ2public" } } }, "NATGatewayRoute": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "PrivateRT" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "NATGateway" } } }, "PrivateRT": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "PrivateRT" } ] } }, "RouteTableAssociationC": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "AppLayer1private" }, "RouteTableId": { "Ref": "PrivateRT" } } }, "RouteTableAssociationD": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "SubnetId": { "Ref": "AppLayer2private" }, "RouteTableId": { "Ref": "PrivateRT" } } }, "DMZNACL": { "Type": "AWS::EC2::NetworkAcl", "Properties": { "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "DMZNACL" } ] } }, "SubnetNetworkAclAssociationA": { "Type": "AWS::EC2::SubnetNetworkAclAssociation", "Properties": { "SubnetId": { "Ref": "DMZ1public" }, "NetworkAclId": { "Ref": "DMZNACL" } } }, "SubnetNetworkAclAssociationB": { "Type": "AWS::EC2::SubnetNetworkAclAssociation", "Properties": { "SubnetId": { "Ref": "DMZ2public" }, "NetworkAclId": { "Ref": "DMZNACL" } } }, "DMZNACLEntryIngress100": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "100", "Protocol": "6", "PortRange": { "From": "22", "To": "22" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "0.0.0.0/0" } }, "DMZNACLEntryIngress110": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "110", "Protocol": "6", "PortRange": { "From": "80", "To": "80" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "0.0.0.0/0" } }, "DMZNACLEntryIngress120": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "120", "Protocol": "6", "PortRange": { "From": "443", "To": "443" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "0.0.0.0/0" } }, "DMZNACLEntryIngress130": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "130", "Protocol": "6", "PortRange": { "From": "1024", "To": "65535" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "0.0.0.0/0" } }, "DMZNACLEntryEgress100": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "100", "Protocol": "6", "PortRange": { "From": "22", "To": "22" }, "RuleAction": "allow", "Egress": "true", "CidrBlock": "0.0.0.0/0" } }, "DMZNACLEntryEgress110": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "110", "Protocol": "6", "PortRange": { "From": "80", "To": "80" }, "RuleAction": "allow", "Egress": "true", "CidrBlock": "0.0.0.0/0" } }, "DMZNACLEntryEgress120": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "120", "Protocol": "6", "PortRange": { "From": "443", "To": "443" }, "RuleAction": "allow", "Egress": "true", "CidrBlock": "0.0.0.0/0" } }, "DMZNACLEntryEgress130": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "DMZNACL", "Properties": { "NetworkAclId": { "Ref": "DMZNACL" }, "RuleNumber": "130", "Protocol": "6", "PortRange": { "From": "1024", "To": "65535" }, "RuleAction": "allow", "Egress": "true", "CidrBlock": "0.0.0.0/0" } }, "AppNACL": { "Type": "AWS::EC2::NetworkAcl", "Properties": { "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "AppNACL" } ] } }, "SubnetNetworkAclAssociationC": { "Type": "AWS::EC2::SubnetNetworkAclAssociation", "Properties": { "SubnetId": { "Ref": "AppLayer1private" }, "NetworkAclId": { "Ref": "AppNACL" } } }, "SubnetNetworkAclAssociationD": { "Type": "AWS::EC2::SubnetNetworkAclAssociation", "Properties": { "SubnetId": { "Ref": "AppLayer2private" }, "NetworkAclId": { "Ref": "AppNACL" } } }, "AppNACLEntryIngress100": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "AppNACL", "Properties": { "NetworkAclId": { "Ref": "AppNACL" }, "RuleNumber": "100", "Protocol": "6", "PortRange": { "From": "22", "To": "22" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "10.99.0.0/16" } }, "AppNACLEntryIngress110": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "AppNACL", "Properties": { "NetworkAclId": { "Ref": "AppNACL" }, "RuleNumber": "110", "Protocol": "6", "PortRange": { "From": "80", "To": "80" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "10.99.0.0/16" } }, "AppNACLEntryIngress120": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "AppNACL", "Properties": { "NetworkAclId": { "Ref": "AppNACL" }, "RuleNumber": "120", "Protocol": "6", "PortRange": { "From": "443", "To": "443" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "10.99.0.0/16" } }, "AppNACLEntryIngress130": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "AppNACL", "Properties": { "NetworkAclId": { "Ref": "AppNACL" }, "RuleNumber": "130", "Protocol": "6", "PortRange": { "From": "1024", "To": "65535" }, "RuleAction": "allow", "Egress": "false", "CidrBlock": "0.0.0.0/0" } }, "AppNACLEntryEgress110": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "AppNACL", "Properties": { "NetworkAclId": { "Ref": "AppNACL" }, "RuleNumber": "110", "Protocol": "6", "PortRange": { "From": "80", "To": "80" }, "RuleAction": "allow", "Egress": "true", "CidrBlock": "0.0.0.0/0" } }, "AppNACLEntryEgress120": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "AppNACL", "Properties": { "NetworkAclId": { "Ref": "AppNACL" }, "RuleNumber": "120", "Protocol": "6", "PortRange": { "From": "443", "To": "443" }, "RuleAction": "allow", "Egress": "true", "CidrBlock": "0.0.0.0/0" } }, "AppNACLEntryEgress130": { "Type": "AWS::EC2::NetworkAclEntry", "DependsOn": "AppNACL", "Properties": { "NetworkAclId": { "Ref": "AppNACL" }, "RuleNumber": "130", "Protocol": "6", "PortRange": { "From": "1024", "To": "65535" }, "RuleAction": "allow", "Egress": "true", "CidrBlock": "10.99.0.0/16" } }, "LoadBalancer": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "Subnets": [ { "Ref": "DMZ1public" }, { "Ref": "DMZ2public" } ], "Name": "load-balancer", "Type": "application", "Scheme": "internet-facing", "SecurityGroups": [ { "Ref": "LoadBalancerSecurityGroup" } ], "IpAddressType": "ipv4" } }, "Listener": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "Type": "forward", "TargetGroupArn": { "Ref": "TargetGroup" } } ], "LoadBalancerArn": { "Ref": "LoadBalancer" }, "Port": "80", "Protocol": "HTTP" } }, "TargetGroup": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": "10", "HealthCheckPath": "/phpinfo.php", "HealthCheckPort": "80", "HealthCheckProtocol": "HTTP", "HealthyThresholdCount": "2", "Name": "TG1", "Port": "80", "Protocol": "HTTP", "UnhealthyThresholdCount": "2", "VpcId": { "Ref": "VPC" } } }, "BastionSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "wordpress-bastion", "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "BastionSG" } ], "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", "FromPort": 22, "IpProtocol": "tcp", "ToPort": 22 } ] } }, "LoadBalancerSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "wordpress-elb", "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "LoadBalancerSG" } ], "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", "FromPort": 80, "IpProtocol": "tcp", "ToPort": 80 }, { "CidrIp": "0.0.0.0/0", "FromPort": 443, "IpProtocol": "tcp", "ToPort": 443 } ] } }, "WebServerSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "wordpress-ec2", "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "WebServerSG" } ], "SecurityGroupIngress": [ { "FromPort": 22, "IpProtocol": "tcp", "SourceSecurityGroupId": { "Ref": "BastionSecurityGroup" }, "ToPort": 22 }, { "FromPort": 80, "IpProtocol": "tcp", "SourceSecurityGroupId": { "Ref": "LoadBalancerSecurityGroup" }, "ToPort": 80 } ] } }, "LaunchConfiguration": { "Type": "AWS::AutoScaling::LaunchConfiguration", "DependsOn": "VPCGatewayAttachment", "Properties": { "ImageId": "ami-97785bed", "InstanceType": "t2.micro", "SecurityGroups": [ { "Ref": "WebServerSecurityGroup" } ], "KeyName": { "Ref": "WebServerKeyName" }, "AssociatePublicIpAddress": "false", "UserData": { "Fn::Base64": { "Fn::Join": [ "", [ "#!/bin/bash\n", "yum update -y\n", "yum install -y httpd24 php70 mysql56-server php70-mysqlnd git\n", "cd /var/www/html\n", "wget https://wordpress.org/latest.tar.gz\n", "tar -xzf latest.tar.gz\n", "cp wp-config-sample.php wp-config.php\n", "groupadd www\n", "usermod -a -G www ec2-user\n", "chown -R root:www /var/www\n", "chmod -R 2775 /var/www\n", "echo '' > /var/www/html/phpinfo.php\n", "service httpd start\n", "chkconfig httpd on\n", "service mysqld start\n", "chkconfig mysqld on\n" ] ] } }, "InstanceMonitoring": "true" } }, "AutoScalingGroup": { "Type": "AWS::AutoScaling::AutoScalingGroup", "Properties": { "TargetGroupARNs": [ { "Ref": "TargetGroup" } ], "LaunchConfigurationName": { "Ref": "LaunchConfiguration" }, "MinSize": "2", "MaxSize": "2", "DesiredCapacity": "2", "Cooldown": "300", "HealthCheckGracePeriod": "300", "HealthCheckType": "ELB", "VPCZoneIdentifier": [ { "Ref": "AppLayer1private" }, { "Ref": "AppLayer2private" } ], "Tags": [ { "PropagateAtLaunch": "true", "Value": "instance-wordpress", "Key": "Name" } ] } }, "BastionInstance": { "Type": "AWS::EC2::Instance", "Properties": { "InstanceType": "t2.micro", "ImageId": "ami-97785bed", "KeyName": { "Ref": "WebServerKeyName" }, "NetworkInterfaces": [ { "GroupSet": [ { "Ref": "BastionSecurityGroup" } ], "AssociatePublicIpAddress": "true", "DeviceIndex": "0", "DeleteOnTermination": "true", "SubnetId": { "Ref": "DMZ1public" } } ], "Tags": [ { "Value": "bastion-host", "Key": "Name" } ] } } }, "Outputs": { "PubSub": { "Value": { "Ref": "DMZ1public" }, "Export": { "Name": "Unique-SubnetId" } }, "pubIpAddress1": { "Description": "Public ip address of bastion instance", "Value": { "Fn::GetAtt": [ "BastionInstance", "PublicIp" ] } }, "privIpAddress1": { "Description": "Private ip address of bastion instance", "Value": { "Fn::GetAtt": [ "BastionInstance", "PrivateIp" ] } } } }