572 lines
20 KiB
YAML
572 lines
20 KiB
YAML
AWSTemplateFormatVersion: '2010-09-09'
|
|
Description: A stack for deploying containerized applications onto a cluster of EC2
|
|
hosts using Elastic Container Service. This stack runs containers on
|
|
hosts that are in a private VPC subnet. Outbound network traffic from the
|
|
hosts must go out through a NAT gateway. There are two load balancers, one
|
|
inside the public subnet, which can be used to send traffic to the
|
|
containers in the private subnet, and one in the private subnet, which can
|
|
be used for private internal traffic between internal services.
|
|
Parameters:
|
|
DesiredCapacity:
|
|
Type: Number
|
|
Default: '3'
|
|
Description: Number of EC2 instances to launch in your ECS cluster.
|
|
MaxSize:
|
|
Type: Number
|
|
Default: '6'
|
|
Description: Maximum number of EC2 instances that can be launched in your ECS cluster.
|
|
ECSAMI:
|
|
Description: AMI ID
|
|
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
|
|
Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id
|
|
InstanceType:
|
|
Description: EC2 instance type
|
|
Type: String
|
|
Default: c4.xlarge
|
|
AllowedValues: [t2.micro, t2.small, t2.medium, t2.large, m3.medium, m3.large,
|
|
m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge,
|
|
c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge,
|
|
c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge,
|
|
r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge]
|
|
ConstraintDescription: Please choose a valid instance type.
|
|
Mappings:
|
|
# Hard values for the subnet masks. These masks define
|
|
# the range of internal IP addresses that can be assigned.
|
|
# The VPC can have all IP's from 10.0.0.0 to 10.0.255.255
|
|
# There are four subnets which cover the ranges:
|
|
#
|
|
# 10.0.0.0 - 10.0.0.255
|
|
# 10.0.1.0 - 10.0.1.255
|
|
# 10.0.2.0 - 10.0.2.255
|
|
# 10.0.3.0 - 10.0.3.255
|
|
#
|
|
# If you need more IP addresses (perhaps you have so many
|
|
# instances that you run out) then you can customize these
|
|
# ranges to add more
|
|
SubnetConfig:
|
|
VPC:
|
|
CIDR: '10.0.0.0/16'
|
|
PublicOne:
|
|
CIDR: '10.0.0.0/24'
|
|
PublicTwo:
|
|
CIDR: '10.0.1.0/24'
|
|
PrivateOne:
|
|
CIDR: '10.0.2.0/24'
|
|
PrivateTwo:
|
|
CIDR: '10.0.3.0/24'
|
|
Resources:
|
|
# VPC in which containers will be networked.
|
|
# It has two public subnets, and two private subnets.
|
|
# We distribute the subnets across the first two available subnets
|
|
# for the region, for high availability.
|
|
VPC:
|
|
Type: AWS::EC2::VPC
|
|
Properties:
|
|
EnableDnsSupport: true
|
|
EnableDnsHostnames: true
|
|
CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
|
|
|
|
# Two public subnets, where containers can have public IP addresses
|
|
PublicSubnetOne:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 0
|
|
- Fn::GetAZs: {Ref: 'AWS::Region'}
|
|
VpcId: !Ref 'VPC'
|
|
CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
|
|
MapPublicIpOnLaunch: true
|
|
PublicSubnetTwo:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 1
|
|
- Fn::GetAZs: {Ref: 'AWS::Region'}
|
|
VpcId: !Ref 'VPC'
|
|
CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
|
|
MapPublicIpOnLaunch: true
|
|
|
|
# Two private subnets where containers will only have private
|
|
# IP addresses, and will only be reachable by other members of the
|
|
# VPC
|
|
PrivateSubnetOne:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 0
|
|
- Fn::GetAZs: {Ref: 'AWS::Region'}
|
|
VpcId: !Ref 'VPC'
|
|
CidrBlock: !FindInMap ['SubnetConfig', 'PrivateOne', 'CIDR']
|
|
PrivateSubnetTwo:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 1
|
|
- Fn::GetAZs: {Ref: 'AWS::Region'}
|
|
VpcId: !Ref 'VPC'
|
|
CidrBlock: !FindInMap ['SubnetConfig', 'PrivateTwo', 'CIDR']
|
|
|
|
# Setup networking resources for the public subnets. Containers
|
|
# in the public subnets have public IP addresses and the routing table
|
|
# sends network traffic via the internet gateway.
|
|
InternetGateway:
|
|
Type: AWS::EC2::InternetGateway
|
|
GatewayAttachement:
|
|
Type: AWS::EC2::VPCGatewayAttachment
|
|
Properties:
|
|
VpcId: !Ref 'VPC'
|
|
InternetGatewayId: !Ref 'InternetGateway'
|
|
PublicRouteTable:
|
|
Type: AWS::EC2::RouteTable
|
|
Properties:
|
|
VpcId: !Ref 'VPC'
|
|
PublicRoute:
|
|
Type: AWS::EC2::Route
|
|
DependsOn: GatewayAttachement
|
|
Properties:
|
|
RouteTableId: !Ref 'PublicRouteTable'
|
|
DestinationCidrBlock: '0.0.0.0/0'
|
|
GatewayId: !Ref 'InternetGateway'
|
|
PublicSubnetOneRouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
SubnetId: !Ref PublicSubnetOne
|
|
RouteTableId: !Ref PublicRouteTable
|
|
PublicSubnetTwoRouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
SubnetId: !Ref PublicSubnetTwo
|
|
RouteTableId: !Ref PublicRouteTable
|
|
|
|
# Setup networking resources for the private subnets. Containers
|
|
# in these subnets have only private IP addresses, and must use a NAT
|
|
# gateway to talk to the internet. We launch two NAT gateways, one for
|
|
# each private subnet.
|
|
NatGatewayOneAttachment:
|
|
Type: AWS::EC2::EIP
|
|
DependsOn: GatewayAttachement
|
|
Properties:
|
|
Domain: vpc
|
|
NatGatewayTwoAttachment:
|
|
Type: AWS::EC2::EIP
|
|
DependsOn: GatewayAttachement
|
|
Properties:
|
|
Domain: vpc
|
|
NatGatewayOne:
|
|
Type: AWS::EC2::NatGateway
|
|
Properties:
|
|
AllocationId: !GetAtt NatGatewayOneAttachment.AllocationId
|
|
SubnetId: !Ref PublicSubnetOne
|
|
NatGatewayTwo:
|
|
Type: AWS::EC2::NatGateway
|
|
Properties:
|
|
AllocationId: !GetAtt NatGatewayTwoAttachment.AllocationId
|
|
SubnetId: !Ref PublicSubnetTwo
|
|
PrivateRouteTableOne:
|
|
Type: AWS::EC2::RouteTable
|
|
Properties:
|
|
VpcId: !Ref 'VPC'
|
|
PrivateRouteOne:
|
|
Type: AWS::EC2::Route
|
|
Properties:
|
|
RouteTableId: !Ref PrivateRouteTableOne
|
|
DestinationCidrBlock: 0.0.0.0/0
|
|
NatGatewayId: !Ref NatGatewayOne
|
|
PrivateRouteTableOneAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
RouteTableId: !Ref PrivateRouteTableOne
|
|
SubnetId: !Ref PrivateSubnetOne
|
|
PrivateRouteTableTwo:
|
|
Type: AWS::EC2::RouteTable
|
|
Properties:
|
|
VpcId: !Ref 'VPC'
|
|
PrivateRouteTwo:
|
|
Type: AWS::EC2::Route
|
|
Properties:
|
|
RouteTableId: !Ref PrivateRouteTableTwo
|
|
DestinationCidrBlock: 0.0.0.0/0
|
|
NatGatewayId: !Ref NatGatewayTwo
|
|
PrivateRouteTableTwoAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
RouteTableId: !Ref PrivateRouteTableTwo
|
|
SubnetId: !Ref PrivateSubnetTwo
|
|
|
|
# OPTIONAL: VPC Endpoint for DynamoDB
|
|
# If a container needs to access DynamoDB this allows a container in the private subnet
|
|
# to talk to DynamoDB directly without needing to go via the NAT gateway. This reduces
|
|
# the amount of bandwidth through the gateway, meaning that the gateway is free to serve
|
|
# your other traffic.
|
|
DynamoDBEndpoint:
|
|
Type: AWS::EC2::VPCEndpoint
|
|
Properties:
|
|
PolicyDocument:
|
|
Version: "2012-10-17"
|
|
Statement:
|
|
- Effect: Allow
|
|
Action: "*"
|
|
Principal: "*"
|
|
Resource: "*"
|
|
RouteTableIds:
|
|
- !Ref 'PrivateRouteTableOne'
|
|
- !Ref 'PrivateRouteTableTwo'
|
|
ServiceName: !Join [ "", [ "com.amazonaws.", { "Ref": "AWS::Region" }, ".dynamodb" ] ]
|
|
VpcId: !Ref 'VPC'
|
|
|
|
# ECS Resources
|
|
ECSCluster:
|
|
Type: AWS::ECS::Cluster
|
|
|
|
# A security group for the EC2 hosts that will run the containers.
|
|
# Two rules, allowing network traffic from a public facing load
|
|
# balancer and from other hosts in the security group.
|
|
#
|
|
# Remove any of the following ingress rules that are not needed.
|
|
# If you want to make direct requests to a container using its
|
|
# public IP address you'll need to add a security group rule
|
|
# to allow traffic from all IP addresses.
|
|
EcsHostSecurityGroup:
|
|
Type: AWS::EC2::SecurityGroup
|
|
Properties:
|
|
GroupDescription: Access to the ECS hosts that run containers
|
|
VpcId: !Ref 'VPC'
|
|
EcsSecurityGroupIngressFromPublicALB:
|
|
Type: AWS::EC2::SecurityGroupIngress
|
|
Properties:
|
|
Description: Ingress from the public ALB
|
|
GroupId: !Ref 'EcsHostSecurityGroup'
|
|
IpProtocol: -1
|
|
SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG'
|
|
EcsSecurityGroupIngressFromPrivateALB:
|
|
Type: AWS::EC2::SecurityGroupIngress
|
|
Properties:
|
|
Description: Ingress from the private ALB
|
|
GroupId: !Ref 'EcsHostSecurityGroup'
|
|
IpProtocol: -1
|
|
SourceSecurityGroupId: !Ref 'PrivateLoadBalancerSG'
|
|
EcsSecurityGroupIngressFromSelf:
|
|
Type: AWS::EC2::SecurityGroupIngress
|
|
Properties:
|
|
Description: Ingress from other containers in the same security group
|
|
GroupId: !Ref 'EcsHostSecurityGroup'
|
|
IpProtocol: -1
|
|
SourceSecurityGroupId: !Ref 'EcsHostSecurityGroup'
|
|
|
|
# Autoscaling group. This launches the actual EC2 instances that will register
|
|
# themselves as members of the cluster, and run the docker containers.
|
|
ECSAutoScalingGroup:
|
|
Type: AWS::AutoScaling::AutoScalingGroup
|
|
Properties:
|
|
VPCZoneIdentifier:
|
|
- !Ref PrivateSubnetOne
|
|
- !Ref PrivateSubnetTwo
|
|
LaunchConfigurationName: !Ref 'ContainerInstances'
|
|
MinSize: '1'
|
|
MaxSize: !Ref 'MaxSize'
|
|
DesiredCapacity: !Ref 'DesiredCapacity'
|
|
CreationPolicy:
|
|
ResourceSignal:
|
|
Timeout: PT15M
|
|
UpdatePolicy:
|
|
AutoScalingReplacingUpdate:
|
|
WillReplace: 'true'
|
|
ContainerInstances:
|
|
Type: AWS::AutoScaling::LaunchConfiguration
|
|
Properties:
|
|
ImageId: !Ref 'ECSAMI'
|
|
SecurityGroups: [!Ref 'EcsHostSecurityGroup']
|
|
InstanceType: !Ref 'InstanceType'
|
|
IamInstanceProfile: !Ref 'EC2InstanceProfile'
|
|
UserData:
|
|
Fn::Base64: !Sub |
|
|
#!/bin/bash -xe
|
|
echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config
|
|
yum install -y aws-cfn-bootstrap curl
|
|
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region}
|
|
AutoscalingRole:
|
|
Type: AWS::IAM::Role
|
|
Properties:
|
|
AssumeRolePolicyDocument:
|
|
Statement:
|
|
- Effect: Allow
|
|
Principal:
|
|
Service: [application-autoscaling.amazonaws.com]
|
|
Action: ['sts:AssumeRole']
|
|
Path: /
|
|
Policies:
|
|
- PolicyName: service-autoscaling
|
|
PolicyDocument:
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
- 'application-autoscaling:*'
|
|
- 'cloudwatch:DescribeAlarms'
|
|
- 'cloudwatch:PutMetricAlarm'
|
|
- 'ecs:DescribeServices'
|
|
- 'ecs:UpdateService'
|
|
Resource: '*'
|
|
EC2InstanceProfile:
|
|
Type: AWS::IAM::InstanceProfile
|
|
Properties:
|
|
Path: /
|
|
Roles: [!Ref 'EC2Role']
|
|
|
|
# Role for the EC2 hosts. This allows the ECS agent on the EC2 hosts
|
|
# to communciate with the ECS control plane, as well as download the docker
|
|
# images from ECR to run on your host.
|
|
EC2Role:
|
|
Type: AWS::IAM::Role
|
|
Properties:
|
|
AssumeRolePolicyDocument:
|
|
Statement:
|
|
- Effect: Allow
|
|
Principal:
|
|
Service: [ec2.amazonaws.com]
|
|
Action: ['sts:AssumeRole']
|
|
Path: /
|
|
Policies:
|
|
- PolicyName: ecs-service
|
|
PolicyDocument:
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
- 'ecs:CreateCluster'
|
|
- 'ecs:DeregisterContainerInstance'
|
|
- 'ecs:DiscoverPollEndpoint'
|
|
- 'ecs:Poll'
|
|
- 'ecs:RegisterContainerInstance'
|
|
- 'ecs:StartTelemetrySession'
|
|
- 'ecs:Submit*'
|
|
- 'logs:CreateLogStream'
|
|
- 'logs:PutLogEvents'
|
|
- 'ecr:GetAuthorizationToken'
|
|
- 'ecr:BatchGetImage'
|
|
- 'ecr:GetDownloadUrlForLayer'
|
|
Resource: '*'
|
|
|
|
# Load balancers for getting traffic to containers.
|
|
# This sample template creates two load balancers:
|
|
#
|
|
# - One public load balancer, hosted in public subnets that is accessible
|
|
# to the public, and is intended to route traffic to one or more public
|
|
# facing services.
|
|
# - One private load balancer, hosted in private subnets, that only
|
|
# accepts traffic from other containers in the cluster, and is
|
|
# intended for private services that should not be accessed directly
|
|
# by the public.
|
|
|
|
# A public facing load balancer, this is used for accepting traffic from the public
|
|
# internet and directing it to public facing microservices
|
|
PublicLoadBalancerSG:
|
|
Type: AWS::EC2::SecurityGroup
|
|
Properties:
|
|
GroupDescription: Access to the public facing load balancer
|
|
VpcId: !Ref 'VPC'
|
|
SecurityGroupIngress:
|
|
# Allow access to ALB from anywhere on the internet
|
|
- CidrIp: 0.0.0.0/0
|
|
IpProtocol: -1
|
|
PublicLoadBalancer:
|
|
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
|
|
Properties:
|
|
Scheme: internet-facing
|
|
LoadBalancerAttributes:
|
|
- Key: idle_timeout.timeout_seconds
|
|
Value: '30'
|
|
Subnets:
|
|
# The load balancer is placed into the public subnets, so that traffic
|
|
# from the internet can reach the load balancer directly via the internet gateway
|
|
- !Ref PublicSubnetOne
|
|
- !Ref PublicSubnetTwo
|
|
SecurityGroups: [!Ref 'PublicLoadBalancerSG']
|
|
# A dummy target group is used to setup the ALB to just drop traffic
|
|
# initially, before any real service target groups have been added.
|
|
DummyTargetGroupPublic:
|
|
Type: AWS::ElasticLoadBalancingV2::TargetGroup
|
|
Properties:
|
|
HealthCheckIntervalSeconds: 6
|
|
HealthCheckPath: /
|
|
HealthCheckProtocol: HTTP
|
|
HealthCheckTimeoutSeconds: 5
|
|
HealthyThresholdCount: 2
|
|
Name: !Join ['-', [!Ref 'AWS::StackName', 'drop-1']]
|
|
Port: 80
|
|
Protocol: HTTP
|
|
UnhealthyThresholdCount: 2
|
|
VpcId: !Ref 'VPC'
|
|
PublicLoadBalancerListener:
|
|
Type: AWS::ElasticLoadBalancingV2::Listener
|
|
DependsOn:
|
|
- PublicLoadBalancer
|
|
Properties:
|
|
DefaultActions:
|
|
- TargetGroupArn: !Ref 'DummyTargetGroupPublic'
|
|
Type: 'forward'
|
|
LoadBalancerArn: !Ref 'PublicLoadBalancer'
|
|
Port: 80
|
|
Protocol: HTTP
|
|
|
|
# An internal load balancer, this would be used for a service that is not
|
|
# directly accessible to the public, but instead should only receive traffic
|
|
# from your other services.
|
|
PrivateLoadBalancerSG:
|
|
Type: AWS::EC2::SecurityGroup
|
|
Properties:
|
|
GroupDescription: Access to the internal load balancer
|
|
VpcId: !Ref 'VPC'
|
|
PrivateLoadBalancerIngressFromECS:
|
|
Type: AWS::EC2::SecurityGroupIngress
|
|
Properties:
|
|
Description: Only accept traffic from a container in the container host security group
|
|
GroupId: !Ref 'PrivateLoadBalancerSG'
|
|
IpProtocol: -1
|
|
SourceSecurityGroupId: !Ref 'EcsHostSecurityGroup'
|
|
PrivateLoadBalancer:
|
|
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
|
|
Properties:
|
|
Scheme: internal
|
|
LoadBalancerAttributes:
|
|
- Key: idle_timeout.timeout_seconds
|
|
Value: '30'
|
|
Subnets:
|
|
# This load balancer is put into the private subnet, so that there is no
|
|
# route for the public to even be able to access the private load balancer.
|
|
- !Ref PrivateSubnetOne
|
|
- !Ref PrivateSubnetTwo
|
|
SecurityGroups: [!Ref 'PrivateLoadBalancerSG']
|
|
# This dummy target group is used to setup the ALB to just drop traffic
|
|
# initially, before any real service target groups have been added.
|
|
DummyTargetGroupPrivate:
|
|
Type: AWS::ElasticLoadBalancingV2::TargetGroup
|
|
Properties:
|
|
HealthCheckIntervalSeconds: 6
|
|
HealthCheckPath: /
|
|
HealthCheckProtocol: HTTP
|
|
HealthCheckTimeoutSeconds: 5
|
|
HealthyThresholdCount: 2
|
|
Name: !Join ['-', [!Ref 'AWS::StackName', 'drop-2']]
|
|
Port: 80
|
|
Protocol: HTTP
|
|
UnhealthyThresholdCount: 2
|
|
VpcId: !Ref 'VPC'
|
|
PrivateLoadBalancerListener:
|
|
Type: AWS::ElasticLoadBalancingV2::Listener
|
|
DependsOn:
|
|
- PrivateLoadBalancer
|
|
Properties:
|
|
DefaultActions:
|
|
- TargetGroupArn: !Ref 'DummyTargetGroupPrivate'
|
|
Type: 'forward'
|
|
LoadBalancerArn: !Ref 'PrivateLoadBalancer'
|
|
Port: 80
|
|
Protocol: HTTP
|
|
|
|
# This is an IAM role which authorizes ECS to manage resources on your
|
|
# account on your behalf, such as updating your load balancer with the
|
|
# details of where your containers are, so that traffic can reach your
|
|
# containers.
|
|
ECSRole:
|
|
Type: AWS::IAM::Role
|
|
Properties:
|
|
AssumeRolePolicyDocument:
|
|
Statement:
|
|
- Effect: Allow
|
|
Principal:
|
|
Service: [ecs.amazonaws.com]
|
|
Action: ['sts:AssumeRole']
|
|
Path: /
|
|
Policies:
|
|
- PolicyName: ecs-service
|
|
PolicyDocument:
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
# Rules which allow ECS to attach network interfaces to instances
|
|
# on your behalf in order for awsvpc networking mode to work right
|
|
- 'ec2:AttachNetworkInterface'
|
|
- 'ec2:CreateNetworkInterface'
|
|
- 'ec2:CreateNetworkInterfacePermission'
|
|
- 'ec2:DeleteNetworkInterface'
|
|
- 'ec2:DeleteNetworkInterfacePermission'
|
|
- 'ec2:Describe*'
|
|
- 'ec2:DetachNetworkInterface'
|
|
|
|
# Rules which allow ECS to update load balancers on your behalf
|
|
# with the information sabout how to send traffic to your containers
|
|
- 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer'
|
|
- 'elasticloadbalancing:DeregisterTargets'
|
|
- 'elasticloadbalancing:Describe*'
|
|
- 'elasticloadbalancing:RegisterInstancesWithLoadBalancer'
|
|
- 'elasticloadbalancing:RegisterTargets'
|
|
Resource: '*'
|
|
|
|
# These are the values output by the CloudFormation template. Be careful
|
|
# about changing any of them, because of them are exported with specific
|
|
# names so that the other task related CF templates can use them.
|
|
Outputs:
|
|
ClusterName:
|
|
Description: The name of the ECS cluster
|
|
Value: !Ref 'ECSCluster'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ClusterName' ] ]
|
|
InternalUrl:
|
|
Description: The url of the internal load balancer
|
|
Value: !Join ['', ['http://', !GetAtt 'PrivateLoadBalancer.DNSName']]
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'InternalUrl' ] ]
|
|
ExternalUrl:
|
|
Description: The url of the external load balancer
|
|
Value: !Join ['', ['http://', !GetAtt 'PublicLoadBalancer.DNSName']]
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ExternalUrl' ] ]
|
|
ECSRole:
|
|
Description: The ARN of the ECS role
|
|
Value: !GetAtt 'ECSRole.Arn'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSRole' ] ]
|
|
PublicListener:
|
|
Description: The ARN of the public load balancer's Listener
|
|
Value: !Ref PublicLoadBalancerListener
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicListener' ] ]
|
|
PrivateListener:
|
|
Description: The ARN of the public load balancer's Listener
|
|
Value: !Ref PrivateLoadBalancerListener
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateListener' ] ]
|
|
VPCId:
|
|
Description: The ID of the VPC that this stack is deployed in
|
|
Value: !Ref 'VPC'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'VPCId' ] ]
|
|
PublicSubnetOne:
|
|
Description: Public subnet one
|
|
Value: !Ref 'PublicSubnetOne'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetOne' ] ]
|
|
PublicSubnetTwo:
|
|
Description: Public subnet two
|
|
Value: !Ref 'PublicSubnetTwo'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetTwo' ] ]
|
|
PrivateSubnetOne:
|
|
Description: Private subnet one
|
|
Value: !Ref 'PrivateSubnetOne'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateSubnetOne' ] ]
|
|
PrivateSubnetTwo:
|
|
Description: Private subnet two
|
|
Value: !Ref 'PrivateSubnetTwo'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateSubnetTwo' ] ]
|
|
EcsHostSecurityGroup:
|
|
Description: A security group used to allow containers to receive traffic
|
|
Value: !Ref 'EcsHostSecurityGroup'
|
|
Export:
|
|
Name: !Join [ ':', [ !Ref 'AWS::StackName', 'EcsHostSecurityGroup' ] ]
|