baked in cloud formation template

pull/387/head
Frostebite 2022-04-20 22:59:33 +01:00
parent fe99ed800f
commit 709c102c38
3 changed files with 773 additions and 773 deletions

772
dist/index.js vendored
View File

@ -1409,393 +1409,393 @@ class BaseStackFormation {
} }
exports.BaseStackFormation = BaseStackFormation; exports.BaseStackFormation = BaseStackFormation;
BaseStackFormation.formation = ` AWSTemplateFormatVersion: '2010-09-09' BaseStackFormation.formation = ` AWSTemplateFormatVersion: '2010-09-09'
Description: Game-CI base stack Description: Game-CI base stack
Parameters: Parameters:
EnvironmentName: EnvironmentName:
Type: String Type: String
Default: development Default: development
Description: 'Your deployment environment: DEV, QA , PROD' Description: 'Your deployment environment: DEV, QA , PROD'
Version: Version:
Type: String Type: String
Description: 'hash of template' Description: 'hash of template'
# ContainerPort: # ContainerPort:
# Type: Number # Type: Number
# Default: 80 # Default: 80
# Description: What port number the application inside the docker container is binding to # Description: What port number the application inside the docker container is binding to
Mappings: Mappings:
# Hard values for the subnet masks. These masks define # Hard values for the subnet masks. These masks define
# the range of internal IP addresses that can be assigned. # 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 # 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: # There are four subnets which cover the ranges:
# #
# 10.0.0.0 - 10.0.0.255 # 10.0.0.0 - 10.0.0.255
# 10.0.1.0 - 10.0.1.255 # 10.0.1.0 - 10.0.1.255
# 10.0.2.0 - 10.0.2.255 # 10.0.2.0 - 10.0.2.255
# 10.0.3.0 - 10.0.3.255 # 10.0.3.0 - 10.0.3.255
SubnetConfig: SubnetConfig:
VPC:
CIDR: '10.0.0.0/16'
PublicOne:
CIDR: '10.0.0.0/24'
PublicTwo:
CIDR: '10.0.1.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: VPC:
CIDR: '10.0.0.0/16' Type: AWS::EC2::VPC
PublicOne: Properties:
CIDR: '10.0.0.0/24' EnableDnsSupport: true
PublicTwo: EnableDnsHostnames: true
CIDR: '10.0.1.0/24' CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
Resources: EFSServerSecurityGroup:
# VPC in which containers will be networked. Type: AWS::EC2::SecurityGroup
# It has two public subnets, and two private subnets. Properties:
# We distribute the subnets across the first two available subnets GroupName: 'efs-server-endpoints'
# for the region, for high availability. GroupDescription: Which client ip addrs are allowed to access EFS server
VPC: VpcId: !Ref 'VPC'
Type: AWS::EC2::VPC SecurityGroupIngress:
Properties: - IpProtocol: tcp
EnableDnsSupport: true FromPort: 2049
EnableDnsHostnames: true ToPort: 2049
CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] SourceSecurityGroupId: !Ref ContainerSecurityGroup
#CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
EFSServerSecurityGroup: # A security group for the containers we will run in Fargate.
Type: AWS::EC2::SecurityGroup # Rules are added to this security group based on what ingress you
Properties: # add for the cluster.
GroupName: 'efs-server-endpoints' ContainerSecurityGroup:
GroupDescription: Which client ip addrs are allowed to access EFS server Type: AWS::EC2::SecurityGroup
VpcId: !Ref 'VPC' Properties:
SecurityGroupIngress: GroupName: 'task security group'
- IpProtocol: tcp GroupDescription: Access to the Fargate containers
FromPort: 2049 VpcId: !Ref 'VPC'
ToPort: 2049 # SecurityGroupIngress:
SourceSecurityGroupId: !Ref ContainerSecurityGroup # - IpProtocol: tcp
#CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] # FromPort: !Ref ContainerPort
# A security group for the containers we will run in Fargate. # ToPort: !Ref ContainerPort
# Rules are added to this security group based on what ingress you # CidrIp: 0.0.0.0/0
# add for the cluster. SecurityGroupEgress:
ContainerSecurityGroup: - IpProtocol: -1
Type: AWS::EC2::SecurityGroup FromPort: 2049
Properties: ToPort: 2049
GroupName: 'task security group' CidrIp: '0.0.0.0/0'
GroupDescription: Access to the Fargate containers
VpcId: !Ref 'VPC' # Two public subnets, where containers can have public IP addresses
# SecurityGroupIngress: PublicSubnetOne:
# - IpProtocol: tcp Type: AWS::EC2::Subnet
# FromPort: !Ref ContainerPort Properties:
# ToPort: !Ref ContainerPort AvailabilityZone: !Select
# CidrIp: 0.0.0.0/0 - 0
SecurityGroupEgress: - Fn::GetAZs: !Ref 'AWS::Region'
- IpProtocol: -1 VpcId: !Ref 'VPC'
FromPort: 2049 CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
ToPort: 2049 # MapPublicIpOnLaunch: true
CidrIp: '0.0.0.0/0'
PublicSubnetTwo:
# Two public subnets, where containers can have public IP addresses Type: AWS::EC2::Subnet
PublicSubnetOne: Properties:
Type: AWS::EC2::Subnet AvailabilityZone: !Select
Properties: - 1
AvailabilityZone: !Select - Fn::GetAZs: !Ref 'AWS::Region'
- 0 VpcId: !Ref 'VPC'
- Fn::GetAZs: !Ref 'AWS::Region' CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
VpcId: !Ref 'VPC' # MapPublicIpOnLaunch: true
CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
# MapPublicIpOnLaunch: true # Setup networking resources for the public subnets. Containers
# in the public subnets have public IP addresses and the routing table
PublicSubnetTwo: # sends network traffic via the internet gateway.
Type: AWS::EC2::Subnet InternetGateway:
Properties: Type: AWS::EC2::InternetGateway
AvailabilityZone: !Select GatewayAttachement:
- 1 Type: AWS::EC2::VPCGatewayAttachment
- Fn::GetAZs: !Ref 'AWS::Region' Properties:
VpcId: !Ref 'VPC' VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] InternetGatewayId: !Ref 'InternetGateway'
# MapPublicIpOnLaunch: true
# Attaching a Internet Gateway to route table makes it public.
# Setup networking resources for the public subnets. Containers PublicRouteTable:
# in the public subnets have public IP addresses and the routing table Type: AWS::EC2::RouteTable
# sends network traffic via the internet gateway. Properties:
InternetGateway: VpcId: !Ref 'VPC'
Type: AWS::EC2::InternetGateway PublicRoute:
GatewayAttachement: Type: AWS::EC2::Route
Type: AWS::EC2::VPCGatewayAttachment DependsOn: GatewayAttachement
Properties: Properties:
VpcId: !Ref 'VPC' RouteTableId: !Ref 'PublicRouteTable'
InternetGatewayId: !Ref 'InternetGateway' DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
# Attaching a Internet Gateway to route table makes it public.
PublicRouteTable: # Attaching a public route table makes a subnet public.
Type: AWS::EC2::RouteTable PublicSubnetOneRouteTableAssociation:
Properties: Type: AWS::EC2::SubnetRouteTableAssociation
VpcId: !Ref 'VPC' Properties:
PublicRoute: SubnetId: !Ref PublicSubnetOne
Type: AWS::EC2::Route RouteTableId: !Ref PublicRouteTable
DependsOn: GatewayAttachement PublicSubnetTwoRouteTableAssociation:
Properties: Type: AWS::EC2::SubnetRouteTableAssociation
RouteTableId: !Ref 'PublicRouteTable' Properties:
DestinationCidrBlock: '0.0.0.0/0' SubnetId: !Ref PublicSubnetTwo
GatewayId: !Ref 'InternetGateway' RouteTableId: !Ref PublicRouteTable
# Attaching a public route table makes a subnet public. # ECS Resources
PublicSubnetOneRouteTableAssociation: ECSCluster:
Type: AWS::EC2::SubnetRouteTableAssociation Type: AWS::ECS::Cluster
Properties:
SubnetId: !Ref PublicSubnetOne # A role used to allow AWS Autoscaling to inspect stats and adjust scaleable targets
RouteTableId: !Ref PublicRouteTable # on your AWS account
PublicSubnetTwoRouteTableAssociation: AutoscalingRole:
Type: AWS::EC2::SubnetRouteTableAssociation Type: AWS::IAM::Role
Properties: Properties:
SubnetId: !Ref PublicSubnetTwo AssumeRolePolicyDocument:
RouteTableId: !Ref PublicRouteTable Statement:
- Effect: Allow
# ECS Resources Principal:
ECSCluster: Service: [application-autoscaling.amazonaws.com]
Type: AWS::ECS::Cluster Action: ['sts:AssumeRole']
Path: /
# A role used to allow AWS Autoscaling to inspect stats and adjust scaleable targets Policies:
# on your AWS account - PolicyName: service-autoscaling
AutoscalingRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: - 'application-autoscaling:*'
- Effect: Allow - 'cloudwatch:DescribeAlarms'
Principal: - 'cloudwatch:PutMetricAlarm'
Service: [application-autoscaling.amazonaws.com] - 'ecs:DescribeServices'
Action: ['sts:AssumeRole'] - 'ecs:UpdateService'
Path: / Resource: '*'
Policies:
- PolicyName: service-autoscaling # This is an IAM role which authorizes ECS to manage resources on your
PolicyDocument: # account on your behalf, such as updating your load balancer with the
Statement: # details of where your containers are, so that traffic can reach your
- Effect: Allow # containers.
Action: ECSRole:
- 'application-autoscaling:*' Type: AWS::IAM::Role
- 'cloudwatch:DescribeAlarms' Properties:
- 'cloudwatch:PutMetricAlarm' AssumeRolePolicyDocument:
- 'ecs:DescribeServices' Statement:
- 'ecs:UpdateService' - Effect: Allow
Resource: '*' Principal:
Service: [ecs.amazonaws.com]
# This is an IAM role which authorizes ECS to manage resources on your Action: ['sts:AssumeRole']
# account on your behalf, such as updating your load balancer with the Path: /
# details of where your containers are, so that traffic can reach your Policies:
# containers. - PolicyName: ecs-service
ECSRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: # Rules which allow ECS to attach network interfaces to instances
- Effect: Allow # on your behalf in order for awsvpc networking mode to work right
Principal: - 'ec2:AttachNetworkInterface'
Service: [ecs.amazonaws.com] - 'ec2:CreateNetworkInterface'
Action: ['sts:AssumeRole'] - 'ec2:CreateNetworkInterfacePermission'
Path: / - 'ec2:DeleteNetworkInterface'
Policies: - 'ec2:DeleteNetworkInterfacePermission'
- PolicyName: ecs-service - 'ec2:Describe*'
PolicyDocument: - 'ec2:DetachNetworkInterface'
Statement:
- Effect: Allow # Rules which allow ECS to update load balancers on your behalf
Action: # with the information sabout how to send traffic to your containers
# Rules which allow ECS to attach network interfaces to instances - 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer'
# on your behalf in order for awsvpc networking mode to work right - 'elasticloadbalancing:DeregisterTargets'
- 'ec2:AttachNetworkInterface' - 'elasticloadbalancing:Describe*'
- 'ec2:CreateNetworkInterface' - 'elasticloadbalancing:RegisterInstancesWithLoadBalancer'
- 'ec2:CreateNetworkInterfacePermission' - 'elasticloadbalancing:RegisterTargets'
- 'ec2:DeleteNetworkInterface' Resource: '*'
- 'ec2:DeleteNetworkInterfacePermission'
- 'ec2:Describe*' # This is a role which is used by the ECS tasks themselves.
- 'ec2:DetachNetworkInterface' ECSTaskExecutionRole:
Type: AWS::IAM::Role
# Rules which allow ECS to update load balancers on your behalf Properties:
# with the information sabout how to send traffic to your containers AssumeRolePolicyDocument:
- 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer' Statement:
- 'elasticloadbalancing:DeregisterTargets' - Effect: Allow
- 'elasticloadbalancing:Describe*' Principal:
- 'elasticloadbalancing:RegisterInstancesWithLoadBalancer' Service: [ecs-tasks.amazonaws.com]
- 'elasticloadbalancing:RegisterTargets' Action: ['sts:AssumeRole']
Resource: '*' Path: /
Policies:
# This is a role which is used by the ECS tasks themselves. - PolicyName: AmazonECSTaskExecutionRolePolicy
ECSTaskExecutionRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: # Allow the use of secret manager
- Effect: Allow - 'secretsmanager:GetSecretValue'
Principal: - 'kms:Decrypt'
Service: [ecs-tasks.amazonaws.com]
Action: ['sts:AssumeRole'] # Allow the ECS Tasks to download images from ECR
Path: / - 'ecr:GetAuthorizationToken'
Policies: - 'ecr:BatchCheckLayerAvailability'
- PolicyName: AmazonECSTaskExecutionRolePolicy - 'ecr:GetDownloadUrlForLayer'
PolicyDocument: - 'ecr:BatchGetImage'
Statement:
- Effect: Allow # Allow the ECS tasks to upload logs to CloudWatch
Action: - 'logs:CreateLogStream'
# Allow the use of secret manager - 'logs:PutLogEvents'
- 'secretsmanager:GetSecretValue' Resource: '*'
- 'kms:Decrypt'
DeleteCFNLambdaExecutionRole:
# Allow the ECS Tasks to download images from ECR Type: 'AWS::IAM::Role'
- 'ecr:GetAuthorizationToken' Properties:
- 'ecr:BatchCheckLayerAvailability' AssumeRolePolicyDocument:
- 'ecr:GetDownloadUrlForLayer' Version: '2012-10-17'
- 'ecr:BatchGetImage' Statement:
- Effect: 'Allow'
# Allow the ECS tasks to upload logs to CloudWatch Principal:
- 'logs:CreateLogStream' Service: ['lambda.amazonaws.com']
- 'logs:PutLogEvents' Action: 'sts:AssumeRole'
Resource: '*' Path: '/'
Policies:
DeleteCFNLambdaExecutionRole: - PolicyName: DeleteCFNLambdaExecutionRole
Type: 'AWS::IAM::Role' PolicyDocument:
Properties: Version: '2012-10-17'
AssumeRolePolicyDocument: Statement:
Version: '2012-10-17' - Effect: 'Allow'
Statement: Action:
- Effect: 'Allow' - 'logs:CreateLogGroup'
Principal: - 'logs:CreateLogStream'
Service: ['lambda.amazonaws.com'] - 'logs:PutLogEvents'
Action: 'sts:AssumeRole' Resource: 'arn:aws:logs:*:*:*'
Path: '/' - Effect: 'Allow'
Policies: Action:
- PolicyName: DeleteCFNLambdaExecutionRole - 'cloudformation:DeleteStack'
PolicyDocument: - 'kinesis:DeleteStream'
Version: '2012-10-17' - 'secretsmanager:DeleteSecret'
Statement: - 'kinesis:DescribeStreamSummary'
- Effect: 'Allow' - 'logs:DeleteLogGroup'
Action: - 'logs:DeleteSubscriptionFilter'
- 'logs:CreateLogGroup' - 'ecs:DeregisterTaskDefinition'
- 'logs:CreateLogStream' - 'lambda:DeleteFunction'
- 'logs:PutLogEvents' - 'lambda:InvokeFunction'
Resource: 'arn:aws:logs:*:*:*' - 'events:RemoveTargets'
- Effect: 'Allow' - 'events:DeleteRule'
Action: - 'lambda:RemovePermission'
- 'cloudformation:DeleteStack' Resource: '*'
- 'kinesis:DeleteStream'
- 'secretsmanager:DeleteSecret' ### cloud watch to kinesis role
- 'kinesis:DescribeStreamSummary' CloudWatchIAMRole:
- 'logs:DeleteLogGroup' Type: AWS::IAM::Role
- 'logs:DeleteSubscriptionFilter' Properties:
- 'ecs:DeregisterTaskDefinition' AssumeRolePolicyDocument:
- 'lambda:DeleteFunction' Statement:
- 'lambda:InvokeFunction' - Effect: Allow
- 'events:RemoveTargets' Principal:
- 'events:DeleteRule' Service: [logs.amazonaws.com]
- 'lambda:RemovePermission' Action: ['sts:AssumeRole']
Resource: '*' Path: /
Policies:
### cloud watch to kinesis role - PolicyName: service-autoscaling
CloudWatchIAMRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: - 'kinesis:PutRecord'
- Effect: Allow Resource: '*'
Principal:
Service: [logs.amazonaws.com] #####################EFS#####################
Action: ['sts:AssumeRole'] EfsFileStorage:
Path: / Type: 'AWS::EFS::FileSystem'
Policies: Properties:
- PolicyName: service-autoscaling BackupPolicy:
PolicyDocument: Status: ENABLED
Statement: PerformanceMode: maxIO
- Effect: Allow Encrypted: false
Action:
- 'kinesis:PutRecord' FileSystemPolicy:
Resource: '*' Version: '2012-10-17'
Statement:
#####################EFS##################### - Effect: 'Allow'
EfsFileStorage: Action:
Type: 'AWS::EFS::FileSystem' - 'elasticfilesystem:ClientMount'
Properties: - 'elasticfilesystem:ClientWrite'
BackupPolicy: - 'elasticfilesystem:ClientRootAccess'
Status: ENABLED Principal:
PerformanceMode: maxIO AWS: '*'
Encrypted: false
MountTargetResource1:
FileSystemPolicy: Type: AWS::EFS::MountTarget
Version: '2012-10-17' Properties:
Statement: FileSystemId: !Ref EfsFileStorage
- Effect: 'Allow' SubnetId: !Ref PublicSubnetOne
Action: SecurityGroups:
- 'elasticfilesystem:ClientMount' - !Ref EFSServerSecurityGroup
- 'elasticfilesystem:ClientWrite'
- 'elasticfilesystem:ClientRootAccess' MountTargetResource2:
Principal: Type: AWS::EFS::MountTarget
AWS: '*' Properties:
FileSystemId: !Ref EfsFileStorage
MountTargetResource1: SubnetId: !Ref PublicSubnetTwo
Type: AWS::EFS::MountTarget SecurityGroups:
Properties: - !Ref EFSServerSecurityGroup
FileSystemId: !Ref EfsFileStorage
SubnetId: !Ref PublicSubnetOne Outputs:
SecurityGroups: EfsFileStorageId:
- !Ref EFSServerSecurityGroup Description: 'The connection endpoint for the database.'
Value: !Ref EfsFileStorage
MountTargetResource2: Export:
Type: AWS::EFS::MountTarget Name: !Sub ${'${EnvironmentName}'}:EfsFileStorageId
Properties: ClusterName:
FileSystemId: !Ref EfsFileStorage Description: The name of the ECS cluster
SubnetId: !Ref PublicSubnetTwo Value: !Ref 'ECSCluster'
SecurityGroups: Export:
- !Ref EFSServerSecurityGroup Name: !Sub${' ${EnvironmentName}'}:ClusterName
AutoscalingRole:
Outputs: Description: The ARN of the role used for autoscaling
EfsFileStorageId: Value: !GetAtt 'AutoscalingRole.Arn'
Description: 'The connection endpoint for the database.' Export:
Value: !Ref EfsFileStorage Name: !Sub ${'${EnvironmentName}'}:AutoscalingRole
Export: ECSRole:
Name: !Sub ${'${EnvironmentName}'}:EfsFileStorageId Description: The ARN of the ECS role
ClusterName: Value: !GetAtt 'ECSRole.Arn'
Description: The name of the ECS cluster Export:
Value: !Ref 'ECSCluster' Name: !Sub ${'${EnvironmentName}'}:ECSRole
Export: ECSTaskExecutionRole:
Name: !Sub${' ${EnvironmentName}'}:ClusterName Description: The ARN of the ECS role tsk execution role
AutoscalingRole: Value: !GetAtt 'ECSTaskExecutionRole.Arn'
Description: The ARN of the role used for autoscaling Export:
Value: !GetAtt 'AutoscalingRole.Arn' Name: !Sub ${'${EnvironmentName}'}:ECSTaskExecutionRole
Export:
Name: !Sub ${'${EnvironmentName}'}:AutoscalingRole DeleteCFNLambdaExecutionRole:
ECSRole: Description: Lambda execution role for cleaning up cloud formations
Description: The ARN of the ECS role Value: !GetAtt 'DeleteCFNLambdaExecutionRole.Arn'
Value: !GetAtt 'ECSRole.Arn' Export:
Export: Name: !Sub ${'${EnvironmentName}'}:DeleteCFNLambdaExecutionRole
Name: !Sub ${'${EnvironmentName}'}:ECSRole
ECSTaskExecutionRole: CloudWatchIAMRole:
Description: The ARN of the ECS role tsk execution role Description: The ARN of the CloudWatch role for subscription filter
Value: !GetAtt 'ECSTaskExecutionRole.Arn' Value: !GetAtt 'CloudWatchIAMRole.Arn'
Export: Export:
Name: !Sub ${'${EnvironmentName}'}:ECSTaskExecutionRole Name: !Sub ${'${EnvironmentName}'}:CloudWatchIAMRole
VpcId:
DeleteCFNLambdaExecutionRole: Description: The ID of the VPC that this stack is deployed in
Description: Lambda execution role for cleaning up cloud formations Value: !Ref 'VPC'
Value: !GetAtt 'DeleteCFNLambdaExecutionRole.Arn' Export:
Export: Name: !Sub ${'${EnvironmentName}'}:VpcId
Name: !Sub ${'${EnvironmentName}'}:DeleteCFNLambdaExecutionRole PublicSubnetOne:
Description: Public subnet one
CloudWatchIAMRole: Value: !Ref 'PublicSubnetOne'
Description: The ARN of the CloudWatch role for subscription filter Export:
Value: !GetAtt 'CloudWatchIAMRole.Arn' Name: !Sub ${'${EnvironmentName}'}:PublicSubnetOne
Export: PublicSubnetTwo:
Name: !Sub ${'${EnvironmentName}'}:CloudWatchIAMRole Description: Public subnet two
VpcId: Value: !Ref 'PublicSubnetTwo'
Description: The ID of the VPC that this stack is deployed in Export:
Value: !Ref 'VPC' Name: !Sub ${'${EnvironmentName}'}:PublicSubnetTwo
Export: ContainerSecurityGroup:
Name: !Sub ${'${EnvironmentName}'}:VpcId Description: A security group used to allow Fargate containers to receive traffic
PublicSubnetOne: Value: !Ref 'ContainerSecurityGroup'
Description: Public subnet one Export:
Value: !Ref 'PublicSubnetOne' Name: !Sub ${'${EnvironmentName}'}:ContainerSecurityGroup
Export:
Name: !Sub ${'${EnvironmentName}'}:PublicSubnetOne
PublicSubnetTwo:
Description: Public subnet two
Value: !Ref 'PublicSubnetTwo'
Export:
Name: !Sub ${'${EnvironmentName}'}:PublicSubnetTwo
ContainerSecurityGroup:
Description: A security group used to allow Fargate containers to receive traffic
Value: !Ref 'ContainerSecurityGroup'
Export:
Name: !Sub ${'${EnvironmentName}'}:ContainerSecurityGroup
`; `;

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -1,391 +1,391 @@
export class BaseStackFormation { export class BaseStackFormation {
public static readonly formation: string = ` AWSTemplateFormatVersion: '2010-09-09' public static readonly formation: string = ` AWSTemplateFormatVersion: '2010-09-09'
Description: Game-CI base stack Description: Game-CI base stack
Parameters: Parameters:
EnvironmentName: EnvironmentName:
Type: String Type: String
Default: development Default: development
Description: 'Your deployment environment: DEV, QA , PROD' Description: 'Your deployment environment: DEV, QA , PROD'
Version: Version:
Type: String Type: String
Description: 'hash of template' Description: 'hash of template'
# ContainerPort: # ContainerPort:
# Type: Number # Type: Number
# Default: 80 # Default: 80
# Description: What port number the application inside the docker container is binding to # Description: What port number the application inside the docker container is binding to
Mappings: Mappings:
# Hard values for the subnet masks. These masks define # Hard values for the subnet masks. These masks define
# the range of internal IP addresses that can be assigned. # 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 # 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: # There are four subnets which cover the ranges:
# #
# 10.0.0.0 - 10.0.0.255 # 10.0.0.0 - 10.0.0.255
# 10.0.1.0 - 10.0.1.255 # 10.0.1.0 - 10.0.1.255
# 10.0.2.0 - 10.0.2.255 # 10.0.2.0 - 10.0.2.255
# 10.0.3.0 - 10.0.3.255 # 10.0.3.0 - 10.0.3.255
SubnetConfig: SubnetConfig:
VPC:
CIDR: '10.0.0.0/16'
PublicOne:
CIDR: '10.0.0.0/24'
PublicTwo:
CIDR: '10.0.1.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: VPC:
CIDR: '10.0.0.0/16' Type: AWS::EC2::VPC
PublicOne: Properties:
CIDR: '10.0.0.0/24' EnableDnsSupport: true
PublicTwo: EnableDnsHostnames: true
CIDR: '10.0.1.0/24' CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
Resources: EFSServerSecurityGroup:
# VPC in which containers will be networked. Type: AWS::EC2::SecurityGroup
# It has two public subnets, and two private subnets. Properties:
# We distribute the subnets across the first two available subnets GroupName: 'efs-server-endpoints'
# for the region, for high availability. GroupDescription: Which client ip addrs are allowed to access EFS server
VPC: VpcId: !Ref 'VPC'
Type: AWS::EC2::VPC SecurityGroupIngress:
Properties: - IpProtocol: tcp
EnableDnsSupport: true FromPort: 2049
EnableDnsHostnames: true ToPort: 2049
CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] SourceSecurityGroupId: !Ref ContainerSecurityGroup
#CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
EFSServerSecurityGroup: # A security group for the containers we will run in Fargate.
Type: AWS::EC2::SecurityGroup # Rules are added to this security group based on what ingress you
Properties: # add for the cluster.
GroupName: 'efs-server-endpoints' ContainerSecurityGroup:
GroupDescription: Which client ip addrs are allowed to access EFS server Type: AWS::EC2::SecurityGroup
VpcId: !Ref 'VPC' Properties:
SecurityGroupIngress: GroupName: 'task security group'
- IpProtocol: tcp GroupDescription: Access to the Fargate containers
FromPort: 2049 VpcId: !Ref 'VPC'
ToPort: 2049 # SecurityGroupIngress:
SourceSecurityGroupId: !Ref ContainerSecurityGroup # - IpProtocol: tcp
#CidrIp: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] # FromPort: !Ref ContainerPort
# A security group for the containers we will run in Fargate. # ToPort: !Ref ContainerPort
# Rules are added to this security group based on what ingress you # CidrIp: 0.0.0.0/0
# add for the cluster. SecurityGroupEgress:
ContainerSecurityGroup: - IpProtocol: -1
Type: AWS::EC2::SecurityGroup FromPort: 2049
Properties: ToPort: 2049
GroupName: 'task security group' CidrIp: '0.0.0.0/0'
GroupDescription: Access to the Fargate containers
VpcId: !Ref 'VPC' # Two public subnets, where containers can have public IP addresses
# SecurityGroupIngress: PublicSubnetOne:
# - IpProtocol: tcp Type: AWS::EC2::Subnet
# FromPort: !Ref ContainerPort Properties:
# ToPort: !Ref ContainerPort AvailabilityZone: !Select
# CidrIp: 0.0.0.0/0 - 0
SecurityGroupEgress: - Fn::GetAZs: !Ref 'AWS::Region'
- IpProtocol: -1 VpcId: !Ref 'VPC'
FromPort: 2049 CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
ToPort: 2049 # MapPublicIpOnLaunch: true
CidrIp: '0.0.0.0/0'
PublicSubnetTwo:
# Two public subnets, where containers can have public IP addresses Type: AWS::EC2::Subnet
PublicSubnetOne: Properties:
Type: AWS::EC2::Subnet AvailabilityZone: !Select
Properties: - 1
AvailabilityZone: !Select - Fn::GetAZs: !Ref 'AWS::Region'
- 0 VpcId: !Ref 'VPC'
- Fn::GetAZs: !Ref 'AWS::Region' CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
VpcId: !Ref 'VPC' # MapPublicIpOnLaunch: true
CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
# MapPublicIpOnLaunch: true # Setup networking resources for the public subnets. Containers
# in the public subnets have public IP addresses and the routing table
PublicSubnetTwo: # sends network traffic via the internet gateway.
Type: AWS::EC2::Subnet InternetGateway:
Properties: Type: AWS::EC2::InternetGateway
AvailabilityZone: !Select GatewayAttachement:
- 1 Type: AWS::EC2::VPCGatewayAttachment
- Fn::GetAZs: !Ref 'AWS::Region' Properties:
VpcId: !Ref 'VPC' VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] InternetGatewayId: !Ref 'InternetGateway'
# MapPublicIpOnLaunch: true
# Attaching a Internet Gateway to route table makes it public.
# Setup networking resources for the public subnets. Containers PublicRouteTable:
# in the public subnets have public IP addresses and the routing table Type: AWS::EC2::RouteTable
# sends network traffic via the internet gateway. Properties:
InternetGateway: VpcId: !Ref 'VPC'
Type: AWS::EC2::InternetGateway PublicRoute:
GatewayAttachement: Type: AWS::EC2::Route
Type: AWS::EC2::VPCGatewayAttachment DependsOn: GatewayAttachement
Properties: Properties:
VpcId: !Ref 'VPC' RouteTableId: !Ref 'PublicRouteTable'
InternetGatewayId: !Ref 'InternetGateway' DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
# Attaching a Internet Gateway to route table makes it public.
PublicRouteTable: # Attaching a public route table makes a subnet public.
Type: AWS::EC2::RouteTable PublicSubnetOneRouteTableAssociation:
Properties: Type: AWS::EC2::SubnetRouteTableAssociation
VpcId: !Ref 'VPC' Properties:
PublicRoute: SubnetId: !Ref PublicSubnetOne
Type: AWS::EC2::Route RouteTableId: !Ref PublicRouteTable
DependsOn: GatewayAttachement PublicSubnetTwoRouteTableAssociation:
Properties: Type: AWS::EC2::SubnetRouteTableAssociation
RouteTableId: !Ref 'PublicRouteTable' Properties:
DestinationCidrBlock: '0.0.0.0/0' SubnetId: !Ref PublicSubnetTwo
GatewayId: !Ref 'InternetGateway' RouteTableId: !Ref PublicRouteTable
# Attaching a public route table makes a subnet public. # ECS Resources
PublicSubnetOneRouteTableAssociation: ECSCluster:
Type: AWS::EC2::SubnetRouteTableAssociation Type: AWS::ECS::Cluster
Properties:
SubnetId: !Ref PublicSubnetOne # A role used to allow AWS Autoscaling to inspect stats and adjust scaleable targets
RouteTableId: !Ref PublicRouteTable # on your AWS account
PublicSubnetTwoRouteTableAssociation: AutoscalingRole:
Type: AWS::EC2::SubnetRouteTableAssociation Type: AWS::IAM::Role
Properties: Properties:
SubnetId: !Ref PublicSubnetTwo AssumeRolePolicyDocument:
RouteTableId: !Ref PublicRouteTable Statement:
- Effect: Allow
# ECS Resources Principal:
ECSCluster: Service: [application-autoscaling.amazonaws.com]
Type: AWS::ECS::Cluster Action: ['sts:AssumeRole']
Path: /
# A role used to allow AWS Autoscaling to inspect stats and adjust scaleable targets Policies:
# on your AWS account - PolicyName: service-autoscaling
AutoscalingRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: - 'application-autoscaling:*'
- Effect: Allow - 'cloudwatch:DescribeAlarms'
Principal: - 'cloudwatch:PutMetricAlarm'
Service: [application-autoscaling.amazonaws.com] - 'ecs:DescribeServices'
Action: ['sts:AssumeRole'] - 'ecs:UpdateService'
Path: / Resource: '*'
Policies:
- PolicyName: service-autoscaling # This is an IAM role which authorizes ECS to manage resources on your
PolicyDocument: # account on your behalf, such as updating your load balancer with the
Statement: # details of where your containers are, so that traffic can reach your
- Effect: Allow # containers.
Action: ECSRole:
- 'application-autoscaling:*' Type: AWS::IAM::Role
- 'cloudwatch:DescribeAlarms' Properties:
- 'cloudwatch:PutMetricAlarm' AssumeRolePolicyDocument:
- 'ecs:DescribeServices' Statement:
- 'ecs:UpdateService' - Effect: Allow
Resource: '*' Principal:
Service: [ecs.amazonaws.com]
# This is an IAM role which authorizes ECS to manage resources on your Action: ['sts:AssumeRole']
# account on your behalf, such as updating your load balancer with the Path: /
# details of where your containers are, so that traffic can reach your Policies:
# containers. - PolicyName: ecs-service
ECSRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: # Rules which allow ECS to attach network interfaces to instances
- Effect: Allow # on your behalf in order for awsvpc networking mode to work right
Principal: - 'ec2:AttachNetworkInterface'
Service: [ecs.amazonaws.com] - 'ec2:CreateNetworkInterface'
Action: ['sts:AssumeRole'] - 'ec2:CreateNetworkInterfacePermission'
Path: / - 'ec2:DeleteNetworkInterface'
Policies: - 'ec2:DeleteNetworkInterfacePermission'
- PolicyName: ecs-service - 'ec2:Describe*'
PolicyDocument: - 'ec2:DetachNetworkInterface'
Statement:
- Effect: Allow # Rules which allow ECS to update load balancers on your behalf
Action: # with the information sabout how to send traffic to your containers
# Rules which allow ECS to attach network interfaces to instances - 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer'
# on your behalf in order for awsvpc networking mode to work right - 'elasticloadbalancing:DeregisterTargets'
- 'ec2:AttachNetworkInterface' - 'elasticloadbalancing:Describe*'
- 'ec2:CreateNetworkInterface' - 'elasticloadbalancing:RegisterInstancesWithLoadBalancer'
- 'ec2:CreateNetworkInterfacePermission' - 'elasticloadbalancing:RegisterTargets'
- 'ec2:DeleteNetworkInterface' Resource: '*'
- 'ec2:DeleteNetworkInterfacePermission'
- 'ec2:Describe*' # This is a role which is used by the ECS tasks themselves.
- 'ec2:DetachNetworkInterface' ECSTaskExecutionRole:
Type: AWS::IAM::Role
# Rules which allow ECS to update load balancers on your behalf Properties:
# with the information sabout how to send traffic to your containers AssumeRolePolicyDocument:
- 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer' Statement:
- 'elasticloadbalancing:DeregisterTargets' - Effect: Allow
- 'elasticloadbalancing:Describe*' Principal:
- 'elasticloadbalancing:RegisterInstancesWithLoadBalancer' Service: [ecs-tasks.amazonaws.com]
- 'elasticloadbalancing:RegisterTargets' Action: ['sts:AssumeRole']
Resource: '*' Path: /
Policies:
# This is a role which is used by the ECS tasks themselves. - PolicyName: AmazonECSTaskExecutionRolePolicy
ECSTaskExecutionRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: # Allow the use of secret manager
- Effect: Allow - 'secretsmanager:GetSecretValue'
Principal: - 'kms:Decrypt'
Service: [ecs-tasks.amazonaws.com]
Action: ['sts:AssumeRole'] # Allow the ECS Tasks to download images from ECR
Path: / - 'ecr:GetAuthorizationToken'
Policies: - 'ecr:BatchCheckLayerAvailability'
- PolicyName: AmazonECSTaskExecutionRolePolicy - 'ecr:GetDownloadUrlForLayer'
PolicyDocument: - 'ecr:BatchGetImage'
Statement:
- Effect: Allow # Allow the ECS tasks to upload logs to CloudWatch
Action: - 'logs:CreateLogStream'
# Allow the use of secret manager - 'logs:PutLogEvents'
- 'secretsmanager:GetSecretValue' Resource: '*'
- 'kms:Decrypt'
DeleteCFNLambdaExecutionRole:
# Allow the ECS Tasks to download images from ECR Type: 'AWS::IAM::Role'
- 'ecr:GetAuthorizationToken' Properties:
- 'ecr:BatchCheckLayerAvailability' AssumeRolePolicyDocument:
- 'ecr:GetDownloadUrlForLayer' Version: '2012-10-17'
- 'ecr:BatchGetImage' Statement:
- Effect: 'Allow'
# Allow the ECS tasks to upload logs to CloudWatch Principal:
- 'logs:CreateLogStream' Service: ['lambda.amazonaws.com']
- 'logs:PutLogEvents' Action: 'sts:AssumeRole'
Resource: '*' Path: '/'
Policies:
DeleteCFNLambdaExecutionRole: - PolicyName: DeleteCFNLambdaExecutionRole
Type: 'AWS::IAM::Role' PolicyDocument:
Properties: Version: '2012-10-17'
AssumeRolePolicyDocument: Statement:
Version: '2012-10-17' - Effect: 'Allow'
Statement: Action:
- Effect: 'Allow' - 'logs:CreateLogGroup'
Principal: - 'logs:CreateLogStream'
Service: ['lambda.amazonaws.com'] - 'logs:PutLogEvents'
Action: 'sts:AssumeRole' Resource: 'arn:aws:logs:*:*:*'
Path: '/' - Effect: 'Allow'
Policies: Action:
- PolicyName: DeleteCFNLambdaExecutionRole - 'cloudformation:DeleteStack'
PolicyDocument: - 'kinesis:DeleteStream'
Version: '2012-10-17' - 'secretsmanager:DeleteSecret'
Statement: - 'kinesis:DescribeStreamSummary'
- Effect: 'Allow' - 'logs:DeleteLogGroup'
Action: - 'logs:DeleteSubscriptionFilter'
- 'logs:CreateLogGroup' - 'ecs:DeregisterTaskDefinition'
- 'logs:CreateLogStream' - 'lambda:DeleteFunction'
- 'logs:PutLogEvents' - 'lambda:InvokeFunction'
Resource: 'arn:aws:logs:*:*:*' - 'events:RemoveTargets'
- Effect: 'Allow' - 'events:DeleteRule'
Action: - 'lambda:RemovePermission'
- 'cloudformation:DeleteStack' Resource: '*'
- 'kinesis:DeleteStream'
- 'secretsmanager:DeleteSecret' ### cloud watch to kinesis role
- 'kinesis:DescribeStreamSummary' CloudWatchIAMRole:
- 'logs:DeleteLogGroup' Type: AWS::IAM::Role
- 'logs:DeleteSubscriptionFilter' Properties:
- 'ecs:DeregisterTaskDefinition' AssumeRolePolicyDocument:
- 'lambda:DeleteFunction' Statement:
- 'lambda:InvokeFunction' - Effect: Allow
- 'events:RemoveTargets' Principal:
- 'events:DeleteRule' Service: [logs.amazonaws.com]
- 'lambda:RemovePermission' Action: ['sts:AssumeRole']
Resource: '*' Path: /
Policies:
### cloud watch to kinesis role - PolicyName: service-autoscaling
CloudWatchIAMRole: PolicyDocument:
Type: AWS::IAM::Role Statement:
Properties: - Effect: Allow
AssumeRolePolicyDocument: Action:
Statement: - 'kinesis:PutRecord'
- Effect: Allow Resource: '*'
Principal:
Service: [logs.amazonaws.com] #####################EFS#####################
Action: ['sts:AssumeRole'] EfsFileStorage:
Path: / Type: 'AWS::EFS::FileSystem'
Policies: Properties:
- PolicyName: service-autoscaling BackupPolicy:
PolicyDocument: Status: ENABLED
Statement: PerformanceMode: maxIO
- Effect: Allow Encrypted: false
Action:
- 'kinesis:PutRecord' FileSystemPolicy:
Resource: '*' Version: '2012-10-17'
Statement:
#####################EFS##################### - Effect: 'Allow'
EfsFileStorage: Action:
Type: 'AWS::EFS::FileSystem' - 'elasticfilesystem:ClientMount'
Properties: - 'elasticfilesystem:ClientWrite'
BackupPolicy: - 'elasticfilesystem:ClientRootAccess'
Status: ENABLED Principal:
PerformanceMode: maxIO AWS: '*'
Encrypted: false
MountTargetResource1:
FileSystemPolicy: Type: AWS::EFS::MountTarget
Version: '2012-10-17' Properties:
Statement: FileSystemId: !Ref EfsFileStorage
- Effect: 'Allow' SubnetId: !Ref PublicSubnetOne
Action: SecurityGroups:
- 'elasticfilesystem:ClientMount' - !Ref EFSServerSecurityGroup
- 'elasticfilesystem:ClientWrite'
- 'elasticfilesystem:ClientRootAccess' MountTargetResource2:
Principal: Type: AWS::EFS::MountTarget
AWS: '*' Properties:
FileSystemId: !Ref EfsFileStorage
MountTargetResource1: SubnetId: !Ref PublicSubnetTwo
Type: AWS::EFS::MountTarget SecurityGroups:
Properties: - !Ref EFSServerSecurityGroup
FileSystemId: !Ref EfsFileStorage
SubnetId: !Ref PublicSubnetOne Outputs:
SecurityGroups: EfsFileStorageId:
- !Ref EFSServerSecurityGroup Description: 'The connection endpoint for the database.'
Value: !Ref EfsFileStorage
MountTargetResource2: Export:
Type: AWS::EFS::MountTarget Name: !Sub ${'${EnvironmentName}'}:EfsFileStorageId
Properties: ClusterName:
FileSystemId: !Ref EfsFileStorage Description: The name of the ECS cluster
SubnetId: !Ref PublicSubnetTwo Value: !Ref 'ECSCluster'
SecurityGroups: Export:
- !Ref EFSServerSecurityGroup Name: !Sub${' ${EnvironmentName}'}:ClusterName
AutoscalingRole:
Outputs: Description: The ARN of the role used for autoscaling
EfsFileStorageId: Value: !GetAtt 'AutoscalingRole.Arn'
Description: 'The connection endpoint for the database.' Export:
Value: !Ref EfsFileStorage Name: !Sub ${'${EnvironmentName}'}:AutoscalingRole
Export: ECSRole:
Name: !Sub ${'${EnvironmentName}'}:EfsFileStorageId Description: The ARN of the ECS role
ClusterName: Value: !GetAtt 'ECSRole.Arn'
Description: The name of the ECS cluster Export:
Value: !Ref 'ECSCluster' Name: !Sub ${'${EnvironmentName}'}:ECSRole
Export: ECSTaskExecutionRole:
Name: !Sub${' ${EnvironmentName}'}:ClusterName Description: The ARN of the ECS role tsk execution role
AutoscalingRole: Value: !GetAtt 'ECSTaskExecutionRole.Arn'
Description: The ARN of the role used for autoscaling Export:
Value: !GetAtt 'AutoscalingRole.Arn' Name: !Sub ${'${EnvironmentName}'}:ECSTaskExecutionRole
Export:
Name: !Sub ${'${EnvironmentName}'}:AutoscalingRole DeleteCFNLambdaExecutionRole:
ECSRole: Description: Lambda execution role for cleaning up cloud formations
Description: The ARN of the ECS role Value: !GetAtt 'DeleteCFNLambdaExecutionRole.Arn'
Value: !GetAtt 'ECSRole.Arn' Export:
Export: Name: !Sub ${'${EnvironmentName}'}:DeleteCFNLambdaExecutionRole
Name: !Sub ${'${EnvironmentName}'}:ECSRole
ECSTaskExecutionRole: CloudWatchIAMRole:
Description: The ARN of the ECS role tsk execution role Description: The ARN of the CloudWatch role for subscription filter
Value: !GetAtt 'ECSTaskExecutionRole.Arn' Value: !GetAtt 'CloudWatchIAMRole.Arn'
Export: Export:
Name: !Sub ${'${EnvironmentName}'}:ECSTaskExecutionRole Name: !Sub ${'${EnvironmentName}'}:CloudWatchIAMRole
VpcId:
DeleteCFNLambdaExecutionRole: Description: The ID of the VPC that this stack is deployed in
Description: Lambda execution role for cleaning up cloud formations Value: !Ref 'VPC'
Value: !GetAtt 'DeleteCFNLambdaExecutionRole.Arn' Export:
Export: Name: !Sub ${'${EnvironmentName}'}:VpcId
Name: !Sub ${'${EnvironmentName}'}:DeleteCFNLambdaExecutionRole PublicSubnetOne:
Description: Public subnet one
CloudWatchIAMRole: Value: !Ref 'PublicSubnetOne'
Description: The ARN of the CloudWatch role for subscription filter Export:
Value: !GetAtt 'CloudWatchIAMRole.Arn' Name: !Sub ${'${EnvironmentName}'}:PublicSubnetOne
Export: PublicSubnetTwo:
Name: !Sub ${'${EnvironmentName}'}:CloudWatchIAMRole Description: Public subnet two
VpcId: Value: !Ref 'PublicSubnetTwo'
Description: The ID of the VPC that this stack is deployed in Export:
Value: !Ref 'VPC' Name: !Sub ${'${EnvironmentName}'}:PublicSubnetTwo
Export: ContainerSecurityGroup:
Name: !Sub ${'${EnvironmentName}'}:VpcId Description: A security group used to allow Fargate containers to receive traffic
PublicSubnetOne: Value: !Ref 'ContainerSecurityGroup'
Description: Public subnet one Export:
Value: !Ref 'PublicSubnetOne' Name: !Sub ${'${EnvironmentName}'}:ContainerSecurityGroup
Export:
Name: !Sub ${'${EnvironmentName}'}:PublicSubnetOne
PublicSubnetTwo:
Description: Public subnet two
Value: !Ref 'PublicSubnetTwo'
Export:
Name: !Sub ${'${EnvironmentName}'}:PublicSubnetTwo
ContainerSecurityGroup:
Description: A security group used to allow Fargate containers to receive traffic
Value: !Ref 'ContainerSecurityGroup'
Export:
Name: !Sub ${'${EnvironmentName}'}:ContainerSecurityGroup
`; `;
} }