{ "Description": "This template deploys a VPC, with a pair of public and private subnets spread across two Availability Zones. It deploys an internet gateway, with a default route on the public subnets. It deploys a pair of NAT gateways (one in each AZ), and default routes for them in the private subnets.", "Parameters": { "SSHKeyName": { "Description": "Name of the ec2 key you need one to use this template", "Type": "AWS::EC2::KeyPair::KeyName", "Default": "choose-key" }, "EnvironmentName": { "Description": "An environment name that is prefixed to resource names", "Type": "String", "Default": "Ansible" }, "VpcCIDR": { "Description": "Please enter the IP range (CIDR notation) for this VPC", "Type": "String", "Default": "10.192.0.0/16" }, "PublicSubnet1CIDR": { "Description": "Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone", "Type": "String", "Default": "10.192.10.0/24" }, "PublicSubnet2CIDR": { "Description": "Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone", "Type": "String", "Default": "10.192.11.0/24" }, "PrivateSubnet1CIDR": { "Description": "Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone", "Type": "String", "Default": "10.192.20.0/24" }, "PrivateSubnet2CIDR": { "Description": "Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone", "Type": "String", "Default": "10.192.21.0/24" } }, "Mappings": { "RegionToAmazonAMI": { "us-east-1": { "HVM64": "ami-02e98f78" }, "us-east-2": { "HVM64": "ami-01e36b7901e884a10" }, "us-west-1": { "HVM64": "ami-074e2d6769f445be5" }, "us-west-2": { "HVM64": "ami-01ed306a12b7d1c96" } } }, "Resources": { "VPC": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": { "Ref": "VpcCIDR" }, "EnableDnsSupport": true, "EnableDnsHostnames": true, "Tags": [ { "Key": "Name", "Value": { "Ref": "EnvironmentName" } } ] } }, "InternetGateway": { "Type": "AWS::EC2::InternetGateway", "Properties": { "Tags": [ { "Key": "Name", "Value": { "Ref": "EnvironmentName" } } ] } }, "InternetGatewayAttachment": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "InternetGatewayId": { "Ref": "InternetGateway" }, "VpcId": { "Ref": "VPC" } } }, "PublicSubnet1": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPC" }, "AvailabilityZone": { "Fn::Select": [ 0, { "Fn::GetAZs": "" } ] }, "CidrBlock": { "Ref": "PublicSubnet1CIDR" }, "MapPublicIpOnLaunch": true, "Tags": [ { "Key": "Name", "Value": { "Fn::Sub": "${EnvironmentName} Public Subnet (AZ1)" } } ] } }, "PublicSubnet2": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPC" }, "AvailabilityZone": { "Fn::Select": [ 1, { "Fn::GetAZs": "" } ] }, "CidrBlock": { "Ref": "PublicSubnet2CIDR" }, "MapPublicIpOnLaunch": true, "Tags": [ { "Key": "Name", "Value": { "Fn::Sub": "${EnvironmentName} Public Subnet (AZ2)" } } ] } }, "PrivateSubnet1": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPC" }, "AvailabilityZone": { "Fn::Select": [ 0, { "Fn::GetAZs": "" } ] }, "CidrBlock": { "Ref": "PrivateSubnet1CIDR" }, "MapPublicIpOnLaunch": false, "Tags": [ { "Key": "Name", "Value": { "Fn::Sub": "${EnvironmentName} Private Subnet (AZ1)" } } ] } }, "PrivateSubnet2": { "Type": "AWS::EC2::Subnet", "Properties": { "VpcId": { "Ref": "VPC" }, "AvailabilityZone": { "Fn::Select": [ 1, { "Fn::GetAZs": "" } ] }, "CidrBlock": { "Ref": "PrivateSubnet2CIDR" }, "MapPublicIpOnLaunch": false, "Tags": [ { "Key": "Name", "Value": { "Fn::Sub": "${EnvironmentName} Private Subnet (AZ2)" } } ] } }, "NatGateway1EIP": { "Type": "AWS::EC2::EIP", "DependsOn": "InternetGatewayAttachment", "Properties": { "Domain": "vpc" } }, "NatGateway2EIP": { "Type": "AWS::EC2::EIP", "DependsOn": "InternetGatewayAttachment", "Properties": { "Domain": "vpc" } }, "NatGateway1": { "Type": "AWS::EC2::NatGateway", "Properties": { "AllocationId": { "Fn::GetAtt": [ "NatGateway1EIP", "AllocationId" ] }, "SubnetId": { "Ref": "PublicSubnet1" } } }, "NatGateway2": { "Type": "AWS::EC2::NatGateway", "Properties": { "AllocationId": { "Fn::GetAtt": [ "NatGateway2EIP", "AllocationId" ] }, "SubnetId": { "Ref": "PublicSubnet2" } } }, "PublicRouteTable": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": { "Fn::Sub": "${EnvironmentName} Public Routes" } } ] } }, "DefaultPublicRoute": { "Type": "AWS::EC2::Route", "DependsOn": "InternetGatewayAttachment", "Properties": { "RouteTableId": { "Ref": "PublicRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "InternetGateway" } } }, "PublicSubnet1RouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "PublicRouteTable" }, "SubnetId": { "Ref": "PublicSubnet1" } } }, "PublicSubnet2RouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "PublicRouteTable" }, "SubnetId": { "Ref": "PublicSubnet2" } } }, "PrivateRouteTable1": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": { "Fn::Sub": "${EnvironmentName} Private Routes (AZ1)" } } ] } }, "DefaultPrivateRoute1": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "PrivateRouteTable1" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "NatGateway1" } } }, "PrivateSubnet1RouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "PrivateRouteTable1" }, "SubnetId": { "Ref": "PrivateSubnet1" } } }, "PrivateRouteTable2": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": { "Fn::Sub": "${EnvironmentName} Private Routes (AZ2)" } } ] } }, "DefaultPrivateRoute2": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "PrivateRouteTable2" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "NatGateway2" } } }, "PrivateSubnet2RouteTableAssociation": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "PrivateRouteTable2" }, "SubnetId": { "Ref": "PrivateSubnet2" } } }, "EC2SecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "SSH, Port 80, Database", "VpcId": { "Ref": "VPC" }, "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 5432, "ToPort": 5432, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 8082, "ToPort": 8082, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "SourceSecurityGroupId": { "Ref": "ELBSecurityGroup" } } ] } }, "ELBSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "SSH and Port 80", "VpcId": { "Ref": "VPC" }, "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" } ] } }, "BastionInstance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": { "Fn::FindInMap": [ "RegionToAmazonAMI", { "Ref": "AWS::Region" }, "HVM64" ] }, "InstanceInitiatedShutdownBehavior": "stop", "InstanceType": "t2.medium", "KeyName": { "Ref": "SSHKeyName" }, "Monitoring": "true", "NetworkInterfaces": [ { "AssociatePublicIpAddress": "true", "DeviceIndex": "0", "GroupSet": [ { "Ref": "EC2SecurityGroup" } ], "SubnetId": { "Ref": "PublicSubnet1" } } ], "Tags": [ { "Key": "Name", "Value": "bastion" } ], "Tenancy": "default" } }, "RTPriInstance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": { "Fn::FindInMap": [ "RegionToAmazonAMI", { "Ref": "AWS::Region" }, "HVM64" ] }, "InstanceInitiatedShutdownBehavior": "stop", "InstanceType": "t2.medium", "KeyName": { "Ref": "SSHKeyName" }, "Monitoring": "true", "NetworkInterfaces": [ { "AssociatePublicIpAddress": "false", "DeviceIndex": "0", "GroupSet": [ { "Ref": "EC2SecurityGroup" } ], "SubnetId": { "Ref": "PrivateSubnet1" } } ], "Tags": [ { "Key": "Name", "Value": "rtprimary" } ], "Tenancy": "default" } }, "RTSecInstance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": { "Fn::FindInMap": [ "RegionToAmazonAMI", { "Ref": "AWS::Region" }, "HVM64" ] }, "InstanceInitiatedShutdownBehavior": "stop", "InstanceType": "t2.medium", "KeyName": { "Ref": "SSHKeyName" }, "Monitoring": "true", "NetworkInterfaces": [ { "AssociatePublicIpAddress": "false", "DeviceIndex": "0", "GroupSet": [ { "Ref": "EC2SecurityGroup" } ], "SubnetId": { "Ref": "PrivateSubnet2" } } ], "Tags": [ { "Key": "Name", "Value": "rtsecondary" } ], "Tenancy": "default" } }, "XrayInstance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": { "Fn::FindInMap": [ "RegionToAmazonAMI", { "Ref": "AWS::Region" }, "HVM64" ] }, "InstanceInitiatedShutdownBehavior": "stop", "InstanceType": "t2.medium", "KeyName": { "Ref": "SSHKeyName" }, "Monitoring": "true", "NetworkInterfaces": [ { "AssociatePublicIpAddress": "false", "DeviceIndex": "0", "GroupSet": [ { "Ref": "EC2SecurityGroup" } ], "SubnetId": { "Ref": "PrivateSubnet1" } } ], "Tags": [ { "Key": "Name", "Value": "xray" } ], "Tenancy": "default" } }, "DBInstance": { "Type": "AWS::EC2::Instance", "Properties": { "ImageId": { "Fn::FindInMap": [ "RegionToAmazonAMI", { "Ref": "AWS::Region" }, "HVM64" ] }, "InstanceInitiatedShutdownBehavior": "stop", "InstanceType": "t2.medium", "KeyName": { "Ref": "SSHKeyName" }, "Monitoring": "true", "NetworkInterfaces": [ { "AssociatePublicIpAddress": "false", "DeviceIndex": "0", "GroupSet": [ { "Ref": "EC2SecurityGroup" } ], "SubnetId": { "Ref": "PrivateSubnet1" } } ], "Tags": [ { "Key": "Name", "Value": "database" } ], "Tenancy": "default" } }, "EC2TargetGroup": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 30, "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 15, "HealthyThresholdCount": 2, "Matcher": { "HttpCode": "200,302" }, "Name": "EC2TargetGroup", "Port": 80, "Protocol": "HTTP", "TargetGroupAttributes": [ { "Key": "deregistration_delay.timeout_seconds", "Value": "20" } ], "Targets": [ { "Id": { "Ref": "RTPriInstance" } }, { "Id": { "Ref": "RTSecInstance" }, "Port": 80 } ], "UnhealthyThresholdCount": 3, "VpcId": { "Ref": "VPC" }, "Tags": [ { "Key": "Name", "Value": "EC2TargetGroup" }, { "Key": "Port", "Value": 80 } ] } }, "ALBListener": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "Type": "forward", "TargetGroupArn": { "Ref": "EC2TargetGroup" } } ], "LoadBalancerArn": { "Ref": "ApplicationLoadBalancer" }, "Port": 80, "Protocol": "HTTP" } }, "ApplicationLoadBalancer": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "Scheme": "internet-facing", "Subnets": [ { "Ref": "PublicSubnet1" }, { "Ref": "PublicSubnet2" } ], "SecurityGroups": [ { "Ref": "ELBSecurityGroup" } ] } } }, "Outputs": { "VPC": { "Description": "Virtual Private Cloud", "Value": { "Ref": "VPC" } }, "ALBHostName": { "Description": "Application Load Balancer Hostname", "Value": { "Fn::GetAtt": [ "ApplicationLoadBalancer", "DNSName" ] } }, "BastionInstancePublic": { "Description": "Bastion", "Value": { "Fn::GetAtt" : [ "BastionInstance", "PublicIp" ]} }, "BastionInstancePrivate": { "Description": "Bastion", "Value": { "Fn::GetAtt" : [ "BastionInstance", "PrivateIp" ]} }, "RTPriInstancePrivate": { "Description": "RTPriInstance", "Value": { "Fn::GetAtt" : [ "RTPriInstance", "PrivateIp" ]} }, "RTSecInstancePrivate": { "Description": "RTSecInstance", "Value": { "Fn::GetAtt" : [ "RTSecInstance", "PrivateIp" ]} }, "XrayInstancePrivate": { "Description": "XrayInstance", "Value": { "Fn::GetAtt" : [ "XrayInstance", "PrivateIp" ]} }, "DBInstancePrivate": { "Description": "DBInstance", "Value": { "Fn::GetAtt" : [ "DBInstance", "PrivateIp" ]} } } }