Вы находитесь на странице: 1из 17

{

"Description": "Lab 2: Route53 - Build a Failover Solution",


"Parameters": {
"KeyName": {
"Description": "Name of an existing EC2 KeyPair",
"Type": "String"
}
},
"Conditions": {
"MyRegionA": {
"Fn::Or": [
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"us-east-1"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"us-west-1"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"us-west-2"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"sa-east-1"
]
}
]
},
"MyRegionB": {
"Fn::Or": [
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"eu-west-1"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"eu-central-1"
]
}
]
},
"MyRegionC": {
"Fn::Or": [
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"ap-northeast-1"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"ap-southeast-2"
]
},
{
"Fn::Equals": [
{
"Ref": "AWS::Region"
},
"ap-southeast-1"
]
}
]
}
},
"Mappings": {
"AWSRegionToAMI": {
"us-east-1": {
"AMI": "ami-6869aa05"
},
"us-west-1": {
"AMI": "ami-31490d51"
},
"us-west-2": {
"AMI": "ami-7172b611"
},
"eu-west-1": {
"AMI": "ami-f9dd458a"
},
"eu-central-1": {
"AMI": "ami-ea26ce85"
},
"ap-northeast-1": {
"AMI": "ami-374db956"
},
"ap-northeast-2": {
"AMI": "ami-2b408b45"
},
"ap-southeast-1": {
"AMI": "ami-a59b49c6"
},
"ap-southeast-2": {
"AMI": "ami-dc361ebf"
},
"ap-south-1": {
"AMI": "ami-ffbdd790"
},
"sa-east-1": {
"AMI": "ami-6dd04501"
}
}
},
"Resources": {
"VPC": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.1.0.0/16",
"Tags": [
{
"Key": "Name",
"Value": "lab-vpc"
}
]
}
},
"InternetGateway": {
"Type": "AWS::EC2::InternetGateway",
"Properties": {
"Tags": [
{
"Key": "Name",
"Value": "lab-igw"
}
]
}
},
"AttachGateway": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": {
"Ref": "VPC"
},
"InternetGatewayId": {
"Ref": "InternetGateway"
}
}
},
"PublicSubnet1": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": {
"Fn::Select": [
"0",
{
"Fn::GetAZs": ""
}
]
},
"CidrBlock": "10.1.1.0/24",
"VpcId": {
"Ref": "VPC"
},
"MapPublicIpOnLaunch": "true",
"Tags": [
{
"Key": "Name",
"Value": "lab-subnet-public1"
}
]
}
},
"PublicSubnet2": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": {
"Fn::Select": [
"1",
{
"Fn::GetAZs": ""
}
]
},
"CidrBlock": "10.1.2.0/24",
"VpcId": {
"Ref": "VPC"
},
"MapPublicIpOnLaunch": "true",
"Tags": [
{
"Key": "Name",
"Value": "lab-subnet-public2"
}
]
}
},
"PublicRouteTable": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {
"Ref": "VPC"
},
"Tags": [
{
"Key": "Name",
"Value": "lab-routetable-public"
}
]
}
},
"PublicDefaultRoute": {
"Type": "AWS::EC2::Route",
"DependsOn": "AttachGateway",
"Properties": {
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {
"Ref": "InternetGateway"
},
"RouteTableId": {
"Ref": "PublicRouteTable"
}
}
},
"PublicRouteAssociation1": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PublicRouteTable"
},
"SubnetId": {
"Ref": "PublicSubnet1"
}
}
},
"PublicRouteAssociation2": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PublicRouteTable"
},
"SubnetId": {
"Ref": "PublicSubnet2"
}
}
},
"PrivateSubnet1": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": {
"Fn::Select": [
"0",
{
"Fn::GetAZs": ""
}
]
},
"CidrBlock": "10.1.3.0/24",
"VpcId": {
"Ref": "VPC"
},
"Tags": [
{
"Key": "Name",
"Value": "lab-subnet-private1"
}
]
}
},
"PrivateSubnet2": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": {
"Fn::Select": [
"1",
{
"Fn::GetAZs": ""
}
]
},
"CidrBlock": "10.1.4.0/24",
"VpcId": {
"Ref": "VPC"
},
"Tags": [
{
"Key": "Name",
"Value": "lab-subnet-private2"
}
]
}
},
"PrivateRouteTable": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {
"Ref": "VPC"
},
"Tags": [
{
"Key": "Name",
"Value": "lab-routetable-private"
}
]
}
},
"PrivateRoute": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTable"
},
"DestinationCidrBlock": "0.0.0.0/0",
"InstanceId": {
"Ref": "NATInstance"
}
}
},
"PrivateRouteAssociation1": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTable"
},
"SubnetId": {
"Ref": "PrivateSubnet1"
}
}
},
"PrivateRouteAssociation2": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"RouteTableId": {
"Ref": "PrivateRouteTable"
},
"SubnetId": {
"Ref": "PrivateSubnet2"
}
}
},

"RootRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "vpn-admin",
"PolicyDocument": {
"Statement": [
{
"Action": [
"rds:*",
"elasticbeanstalk:*",
"ec2:*",
"cloudformation:*",
"iam:*",
"s3:*",
"autoscaling:*",
"lambda:*"
],
"Resource": [
"*"
],
"Effect": "Allow"
}
]
}
}
]
}
},
"RootInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [
{
"Ref": "RootRole"
}
]
}
},

"CommandHost": {
"Type": "AWS::EC2::Instance",
"DependsOn":"AttachGateway",
"CreationPolicy": {
"ResourceSignal": {
"Count": "1",
"Timeout": "PT25M"
}
},
"Properties": {
"ImageId": {
"Fn::FindInMap": [
"AWSRegionToAMI",
{
"Ref": "AWS::Region"
},
"AMI"
]
},
"KeyName": {
"Ref": "KeyName"
},
"InstanceType": "t2.micro",
"Tags": [
{
"Key": "Name",
"Value": "CommandHost"
}
],
"IamInstanceProfile": {
"Ref": "RootInstanceProfile"
},
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash -ex\n",
"yum -y update \n",
"SECONDARY_REGION=",{
"Fn::If": [
"MyRegionA",
"eu-west-1",
{
"Fn::If": [
"MyRegionB",
"us-east-1",
{
"Fn::If": [
"MyRegionC",
"us-west-1",
"us-west-2"
]
}
]
}
]
}, "\n",
"aws cloudformation create-stack --stack-name ", {"Ref" :
"AWS::StackName"}, "secondary --template-url https://us-west-2-aws-
training.s3.amazonaws.com/awsu-ilt/AWS-200-ADV/v2.1/lab-2-r53/scripts/lab-2-
secondary-region.template",
" --parameters ParameterKey=KeyName,ParameterValue=", { "Ref" :
"KeyName" },
" --capabilities CAPABILITY_IAM",
" --region $SECONDARY_REGION\n",
"aws cloudformation wait stack-create-complete",
" --stack-name ", {"Ref" : "AWS::StackName"}, "secondary",
" --region $SECONDARY_REGION\n",
"/opt/aws/bin/cfn-signal ",
" --stack ", { "Ref": "AWS::StackName" },
" --resource CommandHost " ,
" --region ", { "Ref" : "AWS::Region" }, "\n",
"\n",
"# wait for primary stack to complete\n",
"aws cloudformation wait stack-create-complete",
" --stack-name ", {"Ref" : "AWS::StackName"},
" --region ", { "Ref" : "AWS::Region" }, "\n",
"DB_ARN=$(aws cloudformation describe-stacks --stack-name ", {"Ref"
: "AWS::StackName"},
" --query 'Stacks[0].Outputs[?
OutputKey==`DatabaseARN`].OutputValue'",
" --output text --region ", { "Ref" : "AWS::Region" }, ")\n",
"DB_SUBNET=$(aws cloudformation describe-stacks --stack-name ",
{"Ref" : "AWS::StackName"}, "secondary",
" --query 'Stacks[0].Outputs[?
OutputKey==`DBSubnetGroup`].OutputValue'",
" --output text --region $SECONDARY_REGION)\n",
"DB_SG=$(aws cloudformation describe-stacks --stack-name ",
{"Ref" : "AWS::StackName"}, "secondary",
" --query 'Stacks[0].Outputs[?
OutputKey==`DBSecurityGroup`].OutputValue'",
" --output text --region $SECONDARY_REGION)\n",
"\n",
"# create the secondary region read replica\n",
"aws rds create-db-instance-read-replica --db-instance-identifier
secondary ",
" --source-db-instance-identifier $DB_ARN ",
" --db-subnet-group-name $DB_SUBNET",
" --no-publicly-accessible ",
" --region $SECONDARY_REGION\n",
"aws rds wait db-instance-available --db-instance-identifier
secondary ",
" --region $SECONDARY_REGION\n",
"echo Replica completed at $(date)\n",
"aws rds modify-db-instance --db-instance-identifier secondary ",
" --vpc-security-group-ids $DB_SG ",
" --apply-immediately ",
" --region $SECONDARY_REGION\n",
]
]
}
},
"SubnetId":{"Ref":"PublicSubnet1"}
}
},
"NATInstance": {
"Type": "AWS::EC2::Instance",
"DependsOn":"AttachGateway",
"Properties": {
"ImageId": {
"Fn::FindInMap": [
"AWSRegionToAMI",
{
"Ref": "AWS::Region"
},
"AMI"
]
},
"KeyName": {
"Ref": "KeyName"
},
"InstanceType": "t2.micro",
"NetworkInterfaces": [
{
"DeviceIndex": "0",
"AssociatePublicIpAddress": "true",
"SubnetId": {
"Ref": "PublicSubnet2"
},
"GroupSet": [
{
"Ref": "NATSecurityGroup"
}
]
}
],
"SourceDestCheck": "false",
"Tags": [
{
"Key": "Name",
"Value": "NAT Server"
}
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash -ex\n",
"yum -y update \n",
"echo 1 > /proc/sys/net/ipv4/ip_forward \n",
"echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects \n",
"/sbin/iptables -t nat -A POSTROUTING -o eth0 -s 0.0.0.0/0 -j
MASQUERADE \n",
"/sbin/iptables-save > /etc/sysconfig/iptables \n",
"mkdir -p /etc/sysctl.d/ \n",
"cat <<EOF > /etc/sysctl.d/nat.conf \n",
"net.ipv4.ip_forward = 1 \n",
"net.ipv4.conf.eth0.send_redirects = 0 \n",
"EOF\n"
]
]
}
}
}
},
"NATSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enable internal access to the NAT device",
"VpcId": {
"Ref": "VPC"
},
"Tags": [
{
"Key": "Name",
"Value": "NATSecurityGroup"
}
],
"SecurityGroupIngress": [
{
"IpProtocol": "-1",
"FromPort": "0",
"ToPort": "1024",
"CidrIp": "10.1.3.0/24"
},
{
"IpProtocol": "-1",
"FromPort": "0",
"ToPort": "1024",
"CidrIp": "10.1.4.0/24"
}
]
}
},
"DBSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "DB Instance Security Group",
"VpcId": {
"Ref": "VPC"
},
"Tags": [{
"Key": "Name",
"Value": "DBSecurityGroup"
}],
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "3306",
"ToPort": "3306",
"SourceSecurityGroupId": {
"Fn::GetAtt": [
"EBSecurityGroup",
"GroupId"
]
}
}
]
}
},
"EBSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Beanstalk Security Group",
"VpcId": {
"Ref": "VPC"
},
"Tags": [{
"Key": "Name",
"Value": "EBSecurityGroup"
}],
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "80",
"ToPort": "80",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"DBSubnetGroup": {
"Type": "AWS::RDS::DBSubnetGroup",
"Properties": {
"DBSubnetGroupDescription": "Lab DB Subnet Group",
"SubnetIds": [{
"Ref": "PrivateSubnet1"
}, {
"Ref": "PrivateSubnet2"
}]
}
},
"Database": {
"Type": "AWS::RDS::DBInstance",
"Properties": {
"DBName": "Airports",
"AllocatedStorage": "5",
"DBInstanceClass": "db.t2.medium",
"Engine": "MySQL",
"MasterUsername": "master",
"MasterUserPassword": "ry245ur6123!",
"MultiAZ": "false",
"DBSubnetGroupName": {
"Ref": "DBSubnetGroup"
},
"VPCSecurityGroups": [{
"Ref": "DBSecurityGroup"
}],
"Tags": [{
"Key": "Name",
"Value": "Airports DB Instance"
}]
}
},
"EBStackInfo": {
"Type": "Custom::EBStackInfo",
"Properties": {
"ServiceToken": { "Fn::GetAtt" : ["EBStackInfoFunction", "Arn"] },
"Match": "64bit Amazon Linux (.*) Python 2.7"
}
},
"EBStackInfoFunction": {
"Type":"AWS::Lambda::Function",
"Properties":{
"Code":{
"ZipFile":{
"Fn::Join":[
"\n",
[
"from __future__ import print_function",
"import boto3",
"import re",
"import cfnresponse",
"def handler(event,context):",
" result = {}",
" try:",
" print(event)",
" if event and 'ResourceProperties' in event and
'Match' in event['ResourceProperties']:",
" match = event['ResourceProperties']['Match']",
" ebn = boto3.client('elasticbeanstalk')",
" response = ebn.list_available_solution_stacks()",
" stacks = [s for s in response['SolutionStacks']
if re.match(match, s)]",
" print(match)",
" print(response['SolutionStacks'])",
" if stacks:",
" result['SolutionStackName'] = stacks[0]",
" except Exception as e:",
" print(e)",
" cfnresponse.send(event, context, cfnresponse.SUCCESS,
result)"
]
]
}
},
"Handler":"index.handler",
"MemorySize":"128",
"Role":{
"Fn::GetAtt":[
"LambdaExecutionRole",
"Arn"
]
},
"Runtime":"python2.7",
"Timeout":"90"
}
},
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": ["lambda.amazonaws.com"]},
"Action": ["sts:AssumeRole"]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action":
["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": ["elasticbeanstalk:ListAvailableSolutionStacks"],
"Resource": "*"
}]
}
}]
}
},
"EBWebTierRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": { "Service": [ "ec2.amazonaws.com" ] },
"Action": [ "sts:AssumeRole" ]
} ]
},
"ManagedPolicyArns" :
[ "arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier" ]
}
},
"EBWebTierInstanceProfile" : {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ { "Ref" : "EBWebTierRole"} ]
}
},
"EBServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": {
"Service": "elasticbeanstalk.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "elasticbeanstalk"
}
}
} ]
},
"ManagedPolicyArns" : [ "arn:aws:iam::aws:policy/service-
role/AWSElasticBeanstalkService", "arn:aws:iam::aws:policy/service-
role/AWSElasticBeanstalkEnhancedHealth" ]
}
},
"AirportsApplication": {
"Type": "AWS::ElasticBeanstalk::Application",
"Properties": {
"Description": "Airports Application"
}
},
"AirportsApplicationVersion": {
"Type": "AWS::ElasticBeanstalk::ApplicationVersion",
"Properties": {
"ApplicationName": {
"Ref": "AirportsApplication"
},
"Description": "AWS ElasticBeanstalk Sample Application Version",
"SourceBundle": {
"S3Bucket" : { "Fn::Join" : ["", [ { "Ref" : "AWS::Region" }, "-aws-
training" ] ] },
"S3Key": "awsu-ilt/AWS-200-ADV/v2.1/lab-2-r53/scripts/app.zip"
}
}
},
"AirportsConfigurationTemplate": {
"Type": "AWS::ElasticBeanstalk::ConfigurationTemplate",
"Properties": {
"ApplicationName": { "Ref": "AirportsApplication" },
"Description": "Airports configuration",
"OptionSettings": [
{
"Namespace": "aws:elasticbeanstalk:environment",
"OptionName": "EnvironmentType",
"Value": "SingleInstance"
},
{
"Namespace": "aws:elasticbeanstalk:environment",
"OptionName": "ServiceRole",
"Value": { "Ref": "EBServiceRole"}
},
{
"Namespace": "aws:ec2:vpc",
"OptionName": "VPCId",
"Value": { "Ref" : "VPC" }
},
{
"Namespace": "aws:ec2:vpc",
"OptionName": "Subnets",
"Value": { "Ref" : "PublicSubnet1" }
},
{
"Namespace": "aws:ec2:vpc",
"OptionName": "AssociatePublicIpAddress",
"Value": "true"
},
{
"Namespace": "aws:autoscaling:launchconfiguration",
"OptionName": "EC2KeyName",
"Value": { "Ref": "KeyName"}
},
{
"Namespace": "aws:autoscaling:launchconfiguration",
"OptionName": "InstanceType",
"Value": "t2.medium"
},
{
"Namespace": "aws:autoscaling:launchconfiguration",
"OptionName": "SecurityGroups",
"Value": { "Ref": "EBSecurityGroup"}
},
{
"Namespace": "aws:autoscaling:launchconfiguration",
"OptionName": "IamInstanceProfile",
"Value": { "Ref": "EBWebTierInstanceProfile"}
},
{
"Namespace": "aws:elasticbeanstalk:application:environment",
"OptionName": "DATABASE_HOST",
"Value": { "Fn::GetAtt" : ["Database", "Endpoint.Address"]}
},
{
"Namespace": "aws:elasticbeanstalk:application:environment",
"OptionName": "DATABASE_USER",
"Value": "master"
},
{
"Namespace": "aws:elasticbeanstalk:application:environment",
"OptionName": "DATABASE_PASSWORD",
"Value": "ry245ur6123!"
},
{
"Namespace": "aws:elasticbeanstalk:application:environment",
"OptionName": "DATABASE_DB_NAME",
"Value": "Airports"
}
],
"SolutionStackName": { "Fn::GetAtt": [ "EBStackInfo", "SolutionStackName" ]
}
}
},
"AirportsEnvironment": {
"Type": "AWS::ElasticBeanstalk::Environment",
"Properties": {
"ApplicationName": { "Ref": "AirportsApplication" },
"EnvironmentName" : "primary",
"Description": "Production Environment",
"TemplateName": { "Ref": "AirportsConfigurationTemplate" },
"VersionLabel": { "Ref": "AirportsApplicationVersion" }
}
}
},
"Outputs": {
"SecondaryRegion": {
"Description": "Secondary Region that this lab is being executed in.",
"Value": {
"Fn::If": [
"MyRegionA",
"eu-west-1 - Ireland",
{
"Fn::If": [
"MyRegionB",
"us-east-1 - N. Virginia",
{
"Fn::If": [
"MyRegionC",
"us-west-1 - N. California",
"us-west-2 - Oregon"
]
}
]
}
]
}
},
"DatabaseARN" : {
"Description" : "Database ARN",
"Value" : { "Fn::Join":
[
"",
[
"arn:aws:rds:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":db:",
{
"Ref": "Database"
}
]
]
}
}
}
}

Вам также может понравиться