walkthroughs/howto-mutual-tls-file-provided-by-acm/infrastructure/deploy.yaml (818 lines of code) (raw):
Description: >
This template deploys a VPC, with a pair of public and private subnets spread
across two Availabilty 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:
EnvironmentName:
Description: An environment name that will be prefixed to resource names
Type: String
VpcCIDR:
Description: Please enter the IP range (CIDR notation) for this VPC
Type: String
Default: 10.0.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.0.0.0/19
PublicSubnet2CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
Type: String
Default: 10.0.32.0/19
PrivateSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
Type: String
Default: 10.0.64.0/19
PrivateSubnet2CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
Type: String
Default: 10.0.96.0/19
LogGroupName:
Type: String
Default: "AppMeshExamples/mtls-acm-appmesh"
ECSServiceLogGroupRetentionInDays:
Type: Number
Default: 30
ECSServicesDomain:
Type: String
Description: "Domain name registered under Route-53 that will be used for Service Discovery"
Default: mtls-ec2.svc.cluster.local
TlsState:
Type: String
Default: mtls
Description: State of TLS in AWS App Mesh
AllowedValues:
- no-tls
- 1way-tls
- mtls
AppMeshMeshName:
Type: String
Description: Name of mesh
EnvoyImageName:
Type: String
Description: The image to use for the Envoy container
ColorTellerImageName:
Description: The name for the color teller image
Type: String
EC2Ami:
Description: EC2 AMI ID
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
Conditions:
1wayTls: !Equals
- !Ref TlsState
- 1way-tls
mtls: !Equals
- !Ref TlsState
- mtls
setTls: !Or
- Condition: mtls
- Condition: 1wayTls
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
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: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet1CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Public Subnet (AZ1)
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet2CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Public Subnet (AZ2)
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet1CIDR
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Private Subnet (AZ1)
- Key: "kubernetes.io/role/internal-elb"
Value: "1"
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet2CIDR
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Private Subnet (AZ2)
- Key: "kubernetes.io/role/internal-elb"
Value: "1"
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: !GetAtt NatGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
NatGateway2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGateway2EIP.AllocationId
SubnetId: !Ref PublicSubnet2
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !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: !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: !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
AcmPcaColorTellerRootCA:
Type: AWS::ACMPCA::CertificateAuthority
Properties:
Type: ROOT
KeyAlgorithm: RSA_2048
SigningAlgorithm: SHA256WITHRSA
Subject:
CommonName: "AcmPcaColorTeller"
AcmPcaColorTellerRootCACert:
Type: 'AWS::ACMPCA::Certificate'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorTellerRootCA
CertificateSigningRequest: !GetAtt
- AcmPcaColorTellerRootCA
- CertificateSigningRequest
SigningAlgorithm: SHA256WITHRSA
TemplateArn: 'arn:aws:acm-pca:::template/RootCACertificate/V1'
Validity:
Type: YEARS
Value: 10
AcmPcaColorTellerRootCAActivation:
Type: 'AWS::ACMPCA::CertificateAuthorityActivation'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorTellerRootCA
Certificate: !GetAtt
- AcmPcaColorTellerRootCACert
- Certificate
Status: ACTIVE
AcmPcaColorTellerEndpointCert:
Type: AWS::CertificateManager::Certificate
DependsOn: AcmPcaColorTellerRootCAActivation
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorTellerRootCA
DomainName: !Sub 'colorteller.${ECSServicesDomain}'
AcmPcaColorGatewayRootCA:
Type: AWS::ACMPCA::CertificateAuthority
Properties:
Type: ROOT
KeyAlgorithm: RSA_2048
SigningAlgorithm: SHA256WITHRSA
Subject:
CommonName: "AcmPcaColorGateway"
AcmPcaColorGatewayRootCACert:
Type: 'AWS::ACMPCA::Certificate'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorGatewayRootCA
CertificateSigningRequest: !GetAtt
- AcmPcaColorGatewayRootCA
- CertificateSigningRequest
SigningAlgorithm: SHA256WITHRSA
TemplateArn: 'arn:aws:acm-pca:::template/RootCACertificate/V1'
Validity:
Type: YEARS
Value: 10
AcmPcaColorGatewayRootCAActivation:
Type: 'AWS::ACMPCA::CertificateAuthorityActivation'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorGatewayRootCA
Certificate: !GetAtt
- AcmPcaColorGatewayRootCACert
- Certificate
Status: ACTIVE
AcmPcaColorGatewayEndpointCert:
Type: AWS::CertificateManager::Certificate
DependsOn: AcmPcaColorGatewayRootCAActivation
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorGatewayRootCA
DomainName: !Sub 'colorgateway.${ECSServicesDomain}'
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref EnvironmentName
ECSServiceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Security group for the service"
VpcId: !Ref VPC
SecurityGroupIngress:
- CidrIp: !GetAtt VPC.CidrBlock
IpProtocol: -1
TaskIamRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: [ "ecs-tasks.amazonaws.com" ]
Action: sts:AssumeRole
ManagedPolicyArns:
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/CloudWatchFullAccess'
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/AWSAppMeshEnvoyAccess'
Policies:
- PolicyName: access-to-acm
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: acm:ExportCertificate
Resource:
- !Ref AcmPcaColorTellerEndpointCert
- !Ref AcmPcaColorGatewayEndpointCert
- Effect: Allow
Action: acm-pca:GetCertificateAuthorityCertificate
Resource:
- !Ref AcmPcaColorTellerRootCA
- !Ref AcmPcaColorGatewayRootCA
TaskExecutionIamRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: [ "ecs-tasks.amazonaws.com" ]
Action: sts:AssumeRole
ManagedPolicyArns:
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/CloudWatchFullAccess'
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly'
Policies:
- PolicyName: secretsmanager-access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: 'secretsmanager:GetSecretValue'
Resource: !Ref SecretCert
ECSServiceLogGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
LogGroupName: !Ref LogGroupName
RetentionInDays: !Ref ECSServiceLogGroupRetentionInDays
ECSServiceDiscoveryNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Vpc: !Ref VPC
Name: !Ref ECSServicesDomain
Mesh:
Type: 'AWS::AppMesh::Mesh'
Properties:
MeshName: !Ref AppMeshMeshName
Gateway:
Type: 'AWS::AppMesh::VirtualGateway'
Properties:
MeshName: !GetAtt Mesh.MeshName
VirtualGatewayName: gateway-vgw
Spec: !If
- setTls
- !If
- 1wayTls
-
BackendDefaults:
ClientPolicy:
TLS:
Enforce: true
Validation:
Trust:
ACM:
CertificateAuthorityArns:
- !Ref AcmPcaColorTellerRootCA
Listeners:
- PortMapping:
Port: 9080
Protocol: http
-
BackendDefaults:
ClientPolicy:
TLS:
Certificate:
File:
CertificateChain: /keys/colorgateway_endpoint_cert_chain.pem
PrivateKey: /keys/colorgateway_endpoint_dec_pri_key.pem
Enforce: true
Validation:
Trust:
ACM:
CertificateAuthorityArns:
- !Ref AcmPcaColorTellerRootCA
Listeners:
- PortMapping:
Port: 9080
Protocol: http
- Listeners:
- PortMapping:
Port: 9080
Protocol: http
Service:
Type: 'AWS::AppMesh::VirtualService'
Properties:
MeshName: !GetAtt Mesh.MeshName
VirtualServiceName: !Sub colorteller.${ECSServicesDomain}
Spec:
Provider:
VirtualNode:
VirtualNodeName: !GetAtt Node.VirtualNodeName
Route:
Type: 'AWS::AppMesh::GatewayRoute'
Properties:
MeshName: !GetAtt Mesh.MeshName
VirtualGatewayName: gateway-vgw
GatewayRouteName: colorteller-route
Spec:
HttpRoute:
Action:
Target:
VirtualService:
VirtualServiceName: !GetAtt Service.VirtualServiceName
Match:
Prefix: /
Node:
Type: 'AWS::AppMesh::VirtualNode'
Properties:
MeshName: !GetAtt Mesh.MeshName
VirtualNodeName: colorteller-vn
Spec:
Listeners:
- PortMapping:
Port: 9080
Protocol: http
TLS: !If
- setTls
- !If
- 1wayTls
- Certificate:
ACM:
CertificateArn: !Ref AcmPcaColorTellerEndpointCert
Mode: STRICT
- Certificate:
ACM:
CertificateArn: !Ref AcmPcaColorTellerEndpointCert
Mode: STRICT
Validation:
Trust:
File:
CertificateChain: /keys/colorgateway_endpoint_cert_chain.pem
- !Ref 'AWS::NoValue'
ServiceDiscovery:
AWSCloudMap:
NamespaceName: !Ref ECSServicesDomain
ServiceName: colorteller
SecretCert:
Type: AWS::SecretsManager::Secret
Properties:
SecretString: |
{
"GatewayCertificate": "tempcert",
"GatewayCertificateChain": "tempcertchain",
"GatewayPrivateKey": "privatekey",
"Passphrase": "passphrase"
}
InitCertRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: sts:AssumeRole
ManagedPolicyArns:
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Policies:
- PolicyName: acm-secretsmanager-access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: acm:ExportCertificate
Resource:
- !Ref AcmPcaColorTellerEndpointCert
- !Ref AcmPcaColorGatewayEndpointCert
- Effect: Allow
Action: acm-pca:GetCertificateAuthorityCertificate
Resource:
- !Ref AcmPcaColorTellerRootCA
- !Ref AcmPcaColorGatewayRootCA
- Effect: Allow
Action:
- secretsmanager:GetRandomPassword
Resource: '*'
- Effect: Allow
Action: secretsmanager:PutSecretValue
Resource: !Ref SecretCert
InitCertFunction:
Type: AWS::Lambda::Function
Properties:
Description: Initial function to populate secrets manager from ACM
Handler: index.lambda_handler
Role: !GetAtt InitCertRole.Arn
Runtime: python3.8
Timeout: 900
Environment:
Variables:
COLOR_GATEWAY_ACM_ARN: !Ref AcmPcaColorGatewayEndpointCert
SECRET: !Ref SecretCert
Code:
ZipFile: |
import json
import boto3
import base64
import os
import cfnresponse
sm = boto3.client('secretsmanager')
cm = boto3.client('acm')
gate_cm = os.environ['COLOR_GATEWAY_ACM_ARN']
secret = os.environ['SECRET']
def lambda_handler(event, context):
print (json.dumps(event))
if (event['RequestType'] == 'Delete') or (event['RequestType'] == 'Update'):
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, '')
elif event['RequestType'] == 'Create':
try:
passphrase = sm.get_random_password(ExcludePunctuation=True)['RandomPassword']
passphrase_enc = base64.b64encode(passphrase.encode('utf-8'))
gate_rsp = cm.export_certificate(CertificateArn=gate_cm, Passphrase=passphrase_enc)
sm_value={}
sm_value['GatewayCertificate']=gate_rsp['Certificate']
sm_value['GatewayCertificateChain']=gate_rsp['CertificateChain']
sm_value['GatewayPrivateKey']=gate_rsp['PrivateKey']
sm_value['Passphrase']=passphrase
sm.put_secret_value(SecretId=secret, SecretString=json.dumps(sm_value))
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, '')
except Exception as e:
print(e)
cfnresponse.send(event, context, cfnresponse.FAILED, {}, '')
InitCert:
Type: Custom::InitCert
Properties:
ServiceToken: !GetAtt InitCertFunction.Arn
Secret: !Ref SecretCert
ColorTellerServiceDiscoveryRecord:
Type: 'AWS::ServiceDiscovery::Service'
Properties:
Name: "colorteller"
DnsConfig:
NamespaceId: !Ref ECSServiceDiscoveryNamespace
DnsRecords:
- Type: A
TTL: 300
HealthCheckCustomConfig:
FailureThreshold: 1
ColorTellerTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'colorteller'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !GetAtt TaskIamRole.Arn
ExecutionRoleArn: !GetAtt TaskExecutionIamRole.Arn
ProxyConfiguration:
Type: 'APPMESH'
ContainerName: 'envoy'
ProxyConfigurationProperties:
- Name: 'IgnoredUID'
Value: '1337'
- Name: 'ProxyIngressPort'
Value: '15000'
- Name: 'ProxyEgressPort'
Value: '15001'
- Name: 'AppPorts'
Value: '9080'
- Name: 'EgressIgnoredIPs'
Value: '169.254.170.2,169.254.169.254'
ContainerDefinitions:
- Name: 'app'
Image: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${ColorTellerImageName}'
Essential: true
DependsOn:
- ContainerName: 'envoy'
Condition: 'HEALTHY'
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Ref ECSServiceLogGroup
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: 'colorteller'
PortMappings:
- ContainerPort: 9080
Protocol: 'http'
Environment:
- Name: 'PORT'
Value: 9080
- Name: 'COLOR'
Value: 'yellow'
- Name: envoy
Image: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EnvoyImageName}'
Essential: true
User: '1337'
Ulimits:
- Name: "nofile"
HardLimit: 15000
SoftLimit: 15000
PortMappings:
- ContainerPort: 9901
Protocol: 'tcp'
HealthCheck:
Command:
- 'CMD-SHELL'
- 'curl -s http://localhost:9901/server_info | grep state | grep -q LIVE'
Interval: 5
Timeout: 2
Retries: 3
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Ref ECSServiceLogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'colorteller'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${AppMeshMeshName}/virtualNode/colorteller-vn'
- Name: AWS_REGION
Value: !Ref 'AWS::Region'
- Name: ENVOY_LOG_LEVEL
Value: warning
# Set secret environment variable for the container
Secrets:
- Name: CertSecret
ValueFrom: !Ref SecretCert
ColorTellerService:
Type: 'AWS::ECS::Service'
DependsOn: InitCert
Properties:
Cluster: !Ref ECSCluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: FARGATE
ServiceRegistries:
- RegistryArn:
'Fn::GetAtt': ColorTellerServiceDiscoveryRecord.Arn
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref ECSServiceSecurityGroup
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
TaskDefinition: !Ref ColorTellerTaskDefinition
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the public facing load balancer
VpcId: !Ref VPC
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: 80
ToPort: 80
GatewayServiceDiscoveryRecord:
Type: 'AWS::ServiceDiscovery::Service'
Properties:
Name: "gateway"
DnsConfig:
NamespaceId: !Ref ECSServiceDiscoveryNamespace
DnsRecords:
- Type: A
TTL: 300
HealthCheckCustomConfig:
FailureThreshold: 1
GatewayTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- 'FARGATE'
Family: 'gateway'
NetworkMode: 'awsvpc'
Cpu: 256
Memory: 512
TaskRoleArn: !GetAtt TaskIamRole.Arn
ExecutionRoleArn: !GetAtt TaskExecutionIamRole.Arn
ContainerDefinitions:
- Name: envoy
Image: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EnvoyImageName}'
Essential: true
User: '1337'
Ulimits:
- Name: "nofile"
HardLimit: 15000
SoftLimit: 15000
PortMappings:
- ContainerPort: 9080
Protocol: 'tcp'
- ContainerPort: 9901
Protocol: 'tcp'
HealthCheck:
Command:
- 'CMD-SHELL'
- 'curl -s http://localhost:9901/server_info | grep state | grep -q LIVE'
Interval: 5
Timeout: 2
Retries: 3
LogConfiguration:
LogDriver: 'awslogs'
Options:
awslogs-group: !Ref ECSServiceLogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: 'gateway'
Environment:
- Name: 'APPMESH_RESOURCE_ARN'
Value: !Sub 'mesh/${AppMeshMeshName}/virtualGateway/gateway-vgw'
- Name: AWS_REGION
Value: !Ref 'AWS::Region'
- Name: ENVOY_LOG_LEVEL
Value: warning
# Set secret environment variable for the container
Secrets:
- Name: CertSecret
ValueFrom: !Ref SecretCert
GatewayService:
Type: 'AWS::ECS::Service'
DependsOn: InitCert
Properties:
Cluster: !Ref ECSCluster
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DesiredCount: 1
LaunchType: FARGATE
ServiceRegistries:
- RegistryArn: !GetAtt GatewayServiceDiscoveryRecord.Arn
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- !Ref ECSServiceSecurityGroup
Subnets:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
LoadBalancers:
- ContainerName: envoy
ContainerPort: 9080
TargetGroupArn: !Ref WebTargetGroup
TaskDefinition: !Ref GatewayTaskDefinition
# public NLB for gateway
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Scheme: internet-facing
Type: network
Subnets:
- !Ref PublicSubnet1
- !Ref PublicSubnet2
WebTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
DependsOn:
- PublicLoadBalancer
Properties:
Protocol: TCP
TargetType: ip
Name: !Sub "${EnvironmentName}-web2"
Port: 80
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 120
VpcId: !Ref VPC
PublicLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref WebTargetGroup
Type: 'forward'
LoadBalancerArn: !Ref 'PublicLoadBalancer'
Port: 80
Protocol: TCP
BastionHost:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref EC2Ami
InstanceType: t3.micro
SecurityGroupIds:
- !Ref ECSServiceSecurityGroup
SubnetId: !Ref PrivateSubnet1
IamInstanceProfile: !Ref BastionInstanceProfile
Tags:
- Key: Name
Value: bastion-host
BastionInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles:
- !Ref BastionInstanceRole
BastionInstanceRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: [ec2.amazonaws.com]
Action: sts:AssumeRole
ManagedPolicyArns:
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore'
Outputs:
ColorAppEndpoint:
Description: Public endpoint for Color App service
Value: !Join ['', ['http://', !GetAtt 'PublicLoadBalancer.DNSName']]