Darnel Project
Darnel Project
Darnel Project
Dockerfile
FROM alpine:3.11
ENV TZ=America/Bogota
RUN apk update && apk add --no-cache jq php7-fpm php7-zip nginx nginx-mod-http-headers-more \
php7 php7-pdo php7-dom php7-xml php7-tokenizer php7-curl php7-pdo_mysql php7-json php7-cli \
php7-mbstring php7-gd php7-simplexml php7-fileinfo php7-xmlwriter php7-session \
nodejs npm supervisor composer make g++ gcc libgcc curl \
&& rm -rf /var/cache/apk/*
WORKDIR /var/www/html/darnel
WORKDIR /var/www/html/darnel
COPY . .
WORKDIR /var/www/html/darnel
ARG APP_ENV
ENV APP_ENV $APP_ENV
WORKDIR /var/www/html/darnel
RUN rm /etc/nginx/conf.d/default.conf \
&& rm /etc/php7/php-fpm.d/www.conf
1.2 nginx
server {
listen 80;
listen [::]:80;
#server_name _;
root /var/www/html/darnel;
index index.php index.html;
# add_header X-Cached $upstream_cache_status;
# expires 5m;
location / {
# try to serve file directly, fallback to app.php
try_files $uri $uri/ /index.php?q=$uri&$args;
}
# DEV
# This rule should only be placed on your development environment
# In production, don't include this and don't deploy app_dev.php or config.php
location ~ ^/(app_dev|config)\.php(/|$) {
#include conf.d/cache5m.inc;
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
include fastcgi_params;
#internal;
}
# PROD
location ~ ^/index\.php(/|$) {
#include conf.d/cache5m.inc;
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
#internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
}
AvailabilityZone1:
Description: The first availability zone in the region
Type: AWS::EC2::AvailabilityZone::Name
ConstraintDescription: Must be a valid availability zone
AvailabilityZone2:
Description: The second availability zone in the region
Type: AWS::EC2::AvailabilityZone::Name
ConstraintDescription: Must be a valid availability zone
AvailabilityZone3:
Description: The second availability zone in the region
Type: AWS::EC2::AvailabilityZone::Name
ConstraintDescription: Must be a valid availability zone
SSHFrom:
Description: Limit SSH access to bastion hosts to a CIDR IP block
Type: String
MinLength: 9
MaxLength: 18
Default: 0.0.0.0/0
ELBIngressPort:
Description: The ELB ingress port used by security groups
Type: Number
MinValue: 0
MaxValue: 65535
ConstraintDescription: TCP ports must be between 0 - 65535
Default: 80
ELBIngressPortSSL:
Description: The ELB ingress ssl port used by security groups
Type: Number
MinValue: 0
MaxValue: 65535
ConstraintDescription: TCP ports must be between 0 - 65535
Default: 443
AppIngressPort:
Description: The application ingress port used by security groups
Type: Number
MinValue: 0
MaxValue: 65535
ConstraintDescription: TCP ports must be between 0 - 65535
Default: 80
SingleNatGateway:
Description: Set to true to only install one NAT gateway
Type: String
ConstraintDescription: Value must be true or false
Default: true
AllowedValues:
- true
- false
PrefixCIDR:
Description: "PrefixCIDR example : 10.52.0"
Type: String
#Default: 10.65.25
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Region Availability Zones
Parameters:
- AvailabilityZone1
- AvailabilityZone2
- AvailabilityZone3
- Label:
default: Ingress Ports
Parameters:
- ELBIngressPort
- ELBIngressPortSSL
- AppIngressPort
ParameterLabels:
AvailabilityZone1:
default: Availability Zone 1
AvailabilityZone2:
default: Availability Zone 2
AvailabilityZone3:
default: Availability Zone 3
ELBIngressPort:
default: Load Balancer Port
ELBIngressPortSSL:
default: Load Balancer Port SSL
AppIngressPort:
default: Application Port
Conditions:
CreateSingleNatGateway: !Equals [ !Ref SingleNatGateway, true ]
CreateMultipleNatGateways: !Not [ Condition: CreateSingleNatGateway ]
Mappings:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [CIDRMap, VPC, CIDR]
- ""
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Ref "AWS::StackName"
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [ CIDRMap, Public1, CIDR ]
AvailabilityZone: !Ref AvailabilityZone1
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PublicSubnet1"
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [ CIDRMap, Public2, CIDR ]
AvailabilityZone: !Ref AvailabilityZone2
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PublicSubnet2"
PublicSubnet3:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [ CIDRMap, Public3, CIDR ]
AvailabilityZone: !Ref AvailabilityZone3
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PublicSubnet3"
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [ CIDRMap, Private1, CIDR ]
AvailabilityZone: !Ref AvailabilityZone1
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PrivateSubnet1"
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [ CIDRMap, Private2, CIDR ]
AvailabilityZone: !Ref AvailabilityZone2
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PrivateSubnet2"
PrivateSubnet3:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [ CIDRMap, Private3, CIDR ]
AvailabilityZone: !Ref AvailabilityZone3
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PrivateSubnet3"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-igw"
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-public-igw"
PublicRoute:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet1
RouteTableId: !Ref PublicRouteTable
PublicSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet2
RouteTableId: !Ref PublicRouteTable
PublicSubnetRouteTableAssociation3:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet3
RouteTableId: !Ref PublicRouteTable
PublicSubnetNetworkAclAssociation1:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet1
NetworkAclId: !GetAtt VPC.DefaultNetworkAcl
PublicSubnetNetworkAclAssociation2:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet2
NetworkAclId: !GetAtt VPC.DefaultNetworkAcl
PublicSubnetNetworkAclAssociation3:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet3
NetworkAclId: !GetAtt VPC.DefaultNetworkAcl
ELBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable HTTP/HTTPs ingress
VpcId: !Ref VPC
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
ToPort: !Ref ELBIngressPort
FromPort: !Ref ELBIngressPort
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
ToPort: !Ref ELBIngressPortSSL
FromPort: !Ref ELBIngressPortSSL
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-ELBSecurityGroup"
ELBSecurityGroupToAppEgress:
Type: AWS::EC2::SecurityGroupEgress # prevent security group circular references
Properties:
GroupId: !Ref ELBSecurityGroup
IpProtocol: tcp
ToPort: !Ref AppIngressPort
FromPort: !Ref AppIngressPort
DestinationSecurityGroupId: !Ref AppSecurityGroup
AppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable access from ELB to app
VpcId: !Ref VPC
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref ELBSecurityGroup
IpProtocol: tcp
ToPort: !Ref AppIngressPort
FromPort: !Ref AppIngressPort
- SourceSecurityGroupId: !Ref BastionSecurityGroup
IpProtocol: tcp
ToPort: 22
FromPort: 22
SecurityGroupEgress:
- CidrIp: 0.0.0.0/0
IpProtocol: -1
ToPort: 65535
FromPort: 0
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-AppSecurityGroup"
AppSecurityGroupFromELBIngress:
Type: AWS::EC2::SecurityGroupIngress # prevent security group circular references
Properties:
GroupId: !Ref AppSecurityGroup
IpProtocol: tcp
ToPort: !Ref AppIngressPort
FromPort: !Ref AppIngressPort
SourceSecurityGroupId: !Ref ELBSecurityGroup
AppSecurityGroupFromBastionIngress:
Type: AWS::EC2::SecurityGroupIngress # prevent security group circular references
Properties:
GroupId: !Ref AppSecurityGroup
IpProtocol: tcp
ToPort: 22
FromPort: 22
SourceSecurityGroupId: !Ref BastionSecurityGroup
BastionSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable access to the bastion host
VpcId: !Ref VPC
SecurityGroupIngress:
- CidrIp: !Ref SSHFrom
IpProtocol: tcp
ToPort: 22
FromPort: 22
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-BastionSecurityGroup"
MongoSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable access from ELB to app
VpcId: !Ref VPC
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref BastionSecurityGroup
IpProtocol: tcp
ToPort: 22
FromPort: 22
- SourceSecurityGroupId: !Ref BastionSecurityGroup
IpProtocol: tcp
ToPort: 27017
FromPort: 27017
- SourceSecurityGroupId: !Ref AppSecurityGroup
IpProtocol: tcp
ToPort: 27017
FromPort: 27017
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-MongoSecurityGroup"
BastionSecurityGroupToAppEgress:
Type: AWS::EC2::SecurityGroupEgress # prevent security group circular references
Properties:
GroupId: !Ref BastionSecurityGroup
IpProtocol: tcp
ToPort: 22
FromPort: 22
DestinationSecurityGroupId: !Ref AppSecurityGroup
BastionSecurityGroupToAllEgress:
Type: AWS::EC2::SecurityGroupEgress # prevent security group circular references
Properties:
GroupId: !Ref BastionSecurityGroup
IpProtocol: -1
ToPort: 65535
FromPort: 0
CidrIp: 0.0.0.0/0
# NAT-related resources
#
# NAT is used to allow instances in private subnets to communicate with AWS
# services, and pull down code and updates.
NatGateway1:
DependsOn: VPCGatewayAttachment
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatEIP1.AllocationId
SubnetId: !Ref PublicSubnet1
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-NatGateway1"
NatGateway2:
DependsOn: VPCGatewayAttachment
Condition: CreateMultipleNatGateways
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatEIP2.AllocationId
SubnetId: !Ref PublicSubnet2
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-NatGateway2"
NatGateway3:
DependsOn: VPCGatewayAttachment
Condition: CreateMultipleNatGateways
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatEIP2.AllocationId
SubnetId: !Ref PublicSubnet3
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-NatGateway3"
NatEIP1:
DependsOn: VPCGatewayAttachment
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-NatEIP1"
NatEIP2:
DependsOn: VPCGatewayAttachment
Condition: CreateMultipleNatGateways
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-NatEIP2"
NatEIP3:
DependsOn: VPCGatewayAttachment
Condition: CreateMultipleNatGateways
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-NatEIP3"
NatRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-private-nat-1"
NatRouteTable2:
Type: AWS::EC2::RouteTable
Condition: CreateMultipleNatGateways
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-private-nat-2"
NatRouteTable3:
Type: AWS::EC2::RouteTable
Condition: CreateMultipleNatGateways
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-private-nat-3"
NatRoute1:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref NatRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway1
NatRoute2:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Condition: CreateMultipleNatGateways
Properties:
RouteTableId: !Ref NatRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway2
NatRoute3:
Type: AWS::EC2::Route
DependsOn: VPCGatewayAttachment
Condition: CreateMultipleNatGateways
Properties:
RouteTableId: !Ref NatRouteTable3
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway2
PrivateSubnetRouteTableAssociation1:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
RouteTableId: !Ref NatRouteTable1
PrivateSubnetRouteTableAssociation1a:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateSingleNatGateway
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref NatRouteTable1
PrivateSubnetRouteTableAssociation1b:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateSingleNatGateway
Properties:
SubnetId: !Ref PrivateSubnet3
RouteTableId: !Ref NatRouteTable1
PrivateSubnetRouteTableAssociation2:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateMultipleNatGateways
Properties:
SubnetId: !Ref PrivateSubnet2
RouteTableId: !Ref NatRouteTable2
PrivateSubnetRouteTableAssociation3:
Type: AWS::EC2::SubnetRouteTableAssociation
Condition: CreateMultipleNatGateways
Properties:
SubnetId: !Ref PrivateSubnet3
RouteTableId: !Ref NatRouteTable3
Outputs:
Name:
Description: VPC Stack Name
Value: !Ref AWS::StackName
Export:
Name: !Sub ${AWS::StackName}-Name
VPCId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}-VpcID"
VpcCidr:
Description: Vpc cidr block
Value:
!Join
- ''
- - !Sub "${PrefixCIDR}"
- !FindInMap [ CIDRMap, VPC, CIDR ]
Export:
Name: !Sub "${AWS::StackName}-vpc-cidr"
PublicSubnet1:
Description: Public subnet 1 ID
Value: !Ref PublicSubnet1
Export:
Name: !Sub "${AWS::StackName}-PublicSubnet1ID"
PublicSubnet2:
Description: Public subnet 2 ID
Value: !Ref PublicSubnet2
Export:
Name: !Sub "${AWS::StackName}-PublicSubnet2ID"
PublicSubnet3:
Description: Public subnet 3 ID
Value: !Ref PublicSubnet3
Export:
Name: !Sub "${AWS::StackName}-PublicSubnet3ID"
PrivateSubnet1:
Description: Private subnet 1 ID
Value: !Ref PrivateSubnet1
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnet1ID"
PrivateSubnet2:
Description: Private subnet 2 ID
Value: !Ref PrivateSubnet2
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnet2ID"
PrivateSubnet3:
Description: Private subnet 3 ID
Value: !Ref PrivateSubnet3
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnet3ID"
ELBSecurityGroup:
Description: Security group ID for Internet-facing ELB
Value: !GetAtt ELBSecurityGroup.GroupId
Export:
Name: !Sub "${AWS::StackName}-ELBSecurityGroupID"
AppSecurityGroup:
Description: Security group ID for app behind ELB
Value: !GetAtt AppSecurityGroup.GroupId
Export:
Name: !Sub "${AWS::StackName}-AppSecurityGroupID"
BastionSecurityGroup:
Description: Security group ID for bastion host
Value: !GetAtt BastionSecurityGroup.GroupId
Export:
Name: !Sub "${AWS::StackName}-BastionGroupID"
ELBIngressPort:
Description: ELB ingress port
Value: !Ref ELBIngressPort
Export:
Name: !Sub "${AWS::StackName}-ELBIngressPort"
ELBIngressPortSSL:
Description: ELB ingress port
Value: !Ref ELBIngressPortSSL
Export:
Name: !Sub "${AWS::StackName}-ELBIngressPortSSL"
AppIngressPort:
Description: App ingress port
Value: !Ref AppIngressPort
Export:
Name: !Sub "${AWS::StackName}-AppIngressPort"
Parameters:
NetworkStackName:
Type: String
Description: Name of an active Startup Kit CloudFormation stack that contains networking resources
MinLength: 1
MaxLength: 255
AllowedPattern: "^[a-zA-Z][-a-zA-Z0-9]*$"
AppProtocol:
Type: String
Description: The application server protocol
Default: HTTP
AllowedValues:
- HTTP
- HTTPS
ConstraintDescription: Specify either HTTTP or HTTPS
SSLCertificateId:
Type: String
Description: The SSL/TLS certificate ID (abcdef01-abcd-abcd-abcd-abcdef012345)
MinLength: 0
MaxLength: 36
Default: ""
EnvironmentName:
Type: String
Description: Environment name - dev, qa or prod
Default: dev
AllowedValues:
- dev
- qa
- pre
- prod
- proy
ConstraintDescription: Specify dev, test or prod
AppEnvironment:
Type: String
Description: App Environment for the build time
Default: dev
AllowedValues:
- dev
- qa
- pre
- prod
- proy
LoadBalancerAlarmEvaluationPeriods:
Description: The number of periods over which data is compared to the specified threshold
Type: Number
Default: 2
MinValue: 2
ConstraintDescription: Must be at least two
LoadBalancerAlarmEvaluationPeriodSeconds:
Description: The time over which the specified statistic is applied. Specify time in seconds, in multiples of 60.
Type: Number
Default: 300
MinValue: 60
ConstraintDescription: Must be at least 60 seconds
LoadBalancerLatencySeconds:
Description: LoadBalancer latency threshold, in seconds
Type: Number
Default: 2
MinValue: 1
ConstraintDescription: Must be at least one second
EnableLBAlarm:
Description: Set to true to enable load balancer latency alarm
Type: String
ConstraintDescription: Value must be true or false
Default: false
AllowedValues:
- true
- false
Conditions:
Resources:
# The ALB lives in two public subnets. See the existing vpc.cfn.yml stack
# for ELB/ALB and application security groups which define ingress ports.
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Ref AWS::StackName
Subnets:
- Fn::ImportValue: !Sub ${NetworkStackName}-PublicSubnet1ID
- Fn::ImportValue: !Sub ${NetworkStackName}-PublicSubnet2ID
- Fn::ImportValue: !Sub ${NetworkStackName}-PublicSubnet3ID
SecurityGroups:
- Fn::ImportValue: !Sub ${NetworkStackName}-ELBSecurityGroupID
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: 600
Tags:
- Key: Stack
Value: !Ref AWS::StackName
- Key: Environment
Value: !Ref EnvironmentName
- Key: AppEnvironment
Value: !Ref AppEnvironment
LoadBalancerListenerRedirect:
Type: AWS::ElasticLoadBalancingV2::Listener
Condition: IsTlsEnabled
Properties:
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port:
Fn::ImportValue: !Sub ${NetworkStackName}-ELBIngressPort
Protocol: HTTP
DefaultActions:
- Type: redirect
RedirectConfig:
Port:
Fn::ImportValue: !Sub ${NetworkStackName}-ELBIngressPortSSL
Protocol: 'HTTPS'
StatusCode: 'HTTP_301'
LoadBalancerListenerSSL:
Type: AWS::ElasticLoadBalancingV2::Listener
Condition: IsTlsEnabled
Properties:
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port:
Fn::ImportValue: !Sub ${NetworkStackName}-ELBIngressPortSSL
Protocol: HTTPS
Certificates:
- CertificateArn: !Sub "arn:aws:acm:${AWS::Region}:${AWS::AccountId}:certificate/${SSLCertificateId}"
DefaultActions:
- Type: forward
TargetGroupArn: !Ref DefaultTargetGroup
DependsOn: ApplicationLoadBalancer
FargateEcsCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref AWS::StackName
CapacityProviders:
- FARGATE
- FARGATE_SPOT
DefaultCapacityProviderStrategy:
- CapacityProvider: FARGATE_SPOT
Weight: 1
- CapacityProvider: FARGATE
Weight: 1
Outputs:
Name:
Description: Stack Name
Value: !Ref AWS::StackName
Export:
Name: !Sub ${AWS::StackName}-Name
EnvironmentName:
Description: Environment Name
Value: !Ref EnvironmentName
Export:
Name: !Sub ${AWS::StackName}-EnvironmentName
ApplicationLoadBalancerArn:
Value: !Ref ApplicationLoadBalancer
Export:
Name: !Sub ${AWS::StackName}-ApplicationLoadBalancerArn
ApplicationLoadBalancerBaseDnsName:
Value: !GetAtt ApplicationLoadBalancer.DNSName
Export:
Name: !Sub ${AWS::StackName}-ApplicationLoadBalancerBaseDnsName
ApplicationLoadBalancerName:
Value: !GetAtt ApplicationLoadBalancer.LoadBalancerName
Export:
Name: !Sub ${AWS::StackName}-ApplicationLoadBalancerName
ApplicationLoadBalancerListenerArn:
Value: !If [IsNotTlsEnabled, !Ref LoadBalancerListener, !Ref LoadBalancerListenerSSL]
Export:
Name: !Sub ${AWS::StackName}-ApplicationLoadBalancerListenerArn
FargateEcsClusterName:
Value: !Ref FargateEcsCluster
Export:
Name: !Sub ${AWS::StackName}-FargateEcsClusterName
FargateEcsClusterArn:
Value: !GetAtt FargateEcsCluster.Arn
Export:
Name: !Sub ${AWS::StackName}-FargateEcsClusterArn
Parameters:
NetworkStackName:
Type: String
Description: Name of an active Startup Kit CloudFormation stack that contains networking resources
MinLength: 1
MaxLength: 255
AllowedPattern: "^[a-zA-Z][-a-zA-Z0-9]*$"
ELBStackName:
Type: String
Description: Name of an active Startup Kit CloudFormation stack that contains networking resources
MinLength: 1
MaxLength: 255
AllowedPattern: "^[a-zA-Z][-a-zA-Z0-9]*$"
ELBRuleHostHeader:
Type: List<String>
Description: ELB Rule Host Header
MinLength: 1
ELBRulePathPattern:
Type: String
Description: ELB Rule Path Pattern
AllowedPattern: "^(/[a-zA-Z][a-zA-Z0-9]*)|(\\s*)$"
Default: ""
ELBRulePriority:
Type: Number
MinValue: 1
Default: 1
AppProtocol:
Type: String
Description: The application server protocol
Default: HTTP
AllowedValues:
- HTTP
- HTTPS
ConstraintDescription: Specify either HTTTP or HTTPS
GitHubRepo:
Type: String
Description: CodeCommit or GitHub source repository - must contain a Dockerfile in the base
GitHubBranch:
Type: String
Description: CodeCommit or GitHub git repository branch - change triggers a new build
GitHubToken:
Type: String
Description: "GitHub API token - see: https://github.com/blog/1509-personal-api-tokens"
GitHubUser:
Type: String
Description: GitHub username or organization - leave blank if using CodeCommit
CodeBuildDockerImage:
Type: String
Default: aws/codebuild/docker:18.09.0
#Default: aws/codebuild/amazonlinux2-x86_64-standard:3.0
SeedDockerImage:
Type: String
Default: registry.hub.docker.com/library/nginx:1.13
Description: Initial image before CodePipeline is executed. Existing application images in ECR should override this
parameter
DefaultContainerCpu:
Type: Number
Description: "Amount of CPU for the container - options available: https://aws.amazon.com/fargate/pricing/"
Default: 1024
MinValue: 256
MaxValue: 4096
ConstraintDescription: "Value must be between 256 and 4096 - see:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size"
DefaultContainerMemory:
Type: Number
Description: "Amount of memory for the container - options available: https://aws.amazon.com/fargate/pricing/"
Default: 2048
MinValue: 512
MaxValue: 30720
ConstraintDescription: "Value must be between 512 and 30720 - see: https://aws.amazon.com/fargate/pricing/"
DefaultTaskMinContainerCount:
Type: Number
Description: Minimum number of containers to run for the service
Default: 1
MinValue: 1
ConstraintDescription: Value must be at least one
DefaultTaskMaxContainerCount:
Type: Number
Description: Maximum number of containers to run for the service when auto scaling out
Default: 2
MinValue: 1
ConstraintDescription: Value must be at least one
ContainerLogRetentionInDays:
Type: Number
Default: 7
MaxTaggedContainerImagesToRetain:
Type: Number
Description: The number of tagged container images to retain before expiring
MinValue: 1
MaxValue: 100
ConstraintDescription: Value must be between 1 and 100
Default: 20
DaysToRetainUntaggedContainerImages:
Type: Number
Description: The number days to retain untagged container images before expiring
MinValue: 1
MaxValue: 100
ConstraintDescription: Value must be between 1 and 100
Default: 7
EnvironmentName:
Type: String
Description: Environment name - dev, stg , prod, pre
Default: dev
AllowedValues:
- dev
- stg
- pre
- prod
- test
- qa
ConstraintDescription: Specify dev, stg , prod, pre
AppEnvironment:
Type: String
Description: App Environment for the build time
Default: dev
AllowedValues:
- dev
- stg
- pre
- prod
- qa
- test
CreateECSRole:
Description: Set to true to create the service linked role for ECS - Fargate
Type: String
ConstraintDescription: Value must be true or false
Default: false
AllowedValues:
- true
- false
EFSStackName:
Type: String
MinLength: 0
MaxLength: 255
AllowedPattern: "^[a-zA-Z][-a-zA-Z0-9]*$"
Default: "none"
EFSPath:
Type: String
MinLength: 0
MaxLength: 255
Default: ""
EFSContainerPath:
Type: String
MinLength: 0
MaxLength: 255
Default: ""
Conditions:
IsGitHub: !And
- !Not [ !Equals [ !Ref GitHubToken, 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 ] ]
- !Not [ !Equals [ !Ref GitHubUser, info@quadi.co ] ]
HasEFS: !And
- !Not [ !Equals [ !Ref EFSStackName, "" ] ]
- !Not [ !Equals [ !Ref EFSPath, "" ] ]
- !Not [ !Equals [ !Ref EFSContainerPath, "" ] ]
Resources:
DefaultContainerBucket:
Type: AWS::S3::Bucket
CodePipelineArtifactBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
Properties:
LifecycleConfiguration:
Rules:
- Id: delete-rule
Status: Enabled
ExpirationInDays: 1
NoncurrentVersionExpirationInDays: 1
AbortIncompleteMultipartUpload:
DaysAfterInitiation: 1
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource: "*"
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- ecr:GetAuthorizationToken
- Resource: "*"
Effect: Allow
Action:
- secretsmanager:GetSecretValue
- Resource: "*"
Effect: Allow
Action:
- ec2:CreateNetworkInterface
- ec2:DescribeDhcpOptions
- ec2:DescribeNetworkInterfaces
- ec2:DeleteNetworkInterface
- ec2:DescribeSubnets
- ec2:DescribeSecurityGroups
- ec2:DescribeVpcs
- ec2:CreateNetworkInterfacePermission
- Resource: !Sub arn:aws:s3:::${CodePipelineArtifactBucket}/*
Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketVersioning
- s3:DeleteObject
- s3:DeleteObjectVersion
- s3:PutObjectAcl
- Resource: !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/$
{EcrDockerRepository}
Effect: Allow
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:BatchCheckLayerAvailability
- ecr:PutImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
# By default, the build specification is defined in this template, but you can also add buildspec.yml
# files in your repos to allow for customization.
# See:
# https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-source.html
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Source:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Type: LINUX_CONTAINER
Image: !Ref CodeBuildDockerImage
EnvironmentVariables:
- Name: REPOSITORY_URI
Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EcrDockerRepository}
- Name: ENVIRONMENT_NAME
Value: !Ref EnvironmentName
- Name: REPOSITORY_NAME
Value: !Ref GitHubRepo
- Name: REPOSITORY_BRANCH
Value: !Ref GitHubBranch
- Name: AWS_DEFAULT_REGION
Value: !Ref AWS::Region
- Name: IMAGE_TAG
Value: latest
- Name: BUILD_ENV
Value: !Ref AppEnvironment
- Name: APP_ENVIRONMENT
Value: !Ref AppEnvironment
Name: !Ref AWS::StackName
ServiceRole: !Ref CodeBuildServiceRole
VpcConfig:
VpcId:
Fn::ImportValue: !Sub ${NetworkStackName}-VpcID
Subnets:
- Fn::ImportValue: !Sub ${NetworkStackName}-PrivateSubnet1ID
- Fn::ImportValue: !Sub ${NetworkStackName}-PrivateSubnet2ID
SecurityGroupIds:
- Fn::ImportValue: !Sub ${NetworkStackName}-AppSecurityGroupID
CodePipelineServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: codepipeline-access
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource: "*"
Effect: Allow
Action:
- ecs:List*
- ecs:Describe*
- ecs:RegisterTaskDefinition
- ecs:UpdateService
- codebuild:StartBuild
- codebuild:BatchGetBuilds
- codecommit:GetBranch
- codecommit:GetCommit
- codecommit:UploadArchive
- codecommit:GetUploadArchiveStatus
- codecommit:CancelUploadArchive
- iam:PassRole
- Resource: !Sub arn:aws:s3:::${CodePipelineArtifactBucket}/*
Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketVersioning
- s3:DeleteObject
- s3:DeleteObjectVersion
- s3:PutObjectAcl
DependsOn:
- CodePipelineArtifactBucket
# This CodePipeline is used for CodeCommit repos. It triggers on a commit to the Git branch passed,
# builds the Docker image and then deploys the container in the Fargate Cluster. CodePipeline can support N stages.
# For example, you may want to add a stage to test your build and/or container.
CodePipelineCodeCommit:
Type: AWS::CodePipeline::Pipeline
Condition: IsCodeCommit
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
Name: !Sub ${AWS::StackName}
ArtifactStore:
Type: S3
Location: !Ref CodePipelineArtifactBucket
Stages:
- Name: Source
Actions:
- Name: App
ActionTypeId:
Category: Source
Owner: ThirdParty
Version: '1'
Provider: GitHub
Configuration:
Owner: !Ref GitHubUser
Repo: !Ref GitHubRepo
Branch: !Ref GitHubBranch
OAuthToken: !Ref GitHubToken
OutputArtifacts:
- Name: App
RunOrder: 1
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: App
OutputArtifacts:
- Name: BuildOutput
RunOrder: 1
- Name: Deploy
Actions:
- Name: Deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: ECS
Configuration:
ClusterName:
Fn::ImportValue: !Sub ${ELBStackName}-FargateEcsClusterName
ServiceName: !GetAtt DefaultFargateService.Name
FileName: imagedefinitions.json
InputArtifacts:
- Name: BuildOutput
RunOrder: 1
DependsOn:
- CodePipelineArtifactBucket
- CodeBuildProject
- CodePipelineServiceRole
- DefaultFargateService
# Simple Amazon ECR Lifecycle Policies to try and reduce storage costs
# See: https://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html
EcrDockerRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Sub ${AWS::StackName}
LifecyclePolicy:
LifecyclePolicyText: !Sub
-|
{
"rules": [
{
"rulePriority": 1,
"description": "Only keep untagged images for ${DaysToRetainUntaggedContainerImages}
days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": ${DaysToRetainUntaggedContainerImages}
},
"action": { "type": "expire" }
},
{
"rulePriority": 2,
"description": "Keep only ${MaxTaggedContainerImagesToRetain} tagged images, expire all
others",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": [ "${EnvironmentName}" ],
"countType": "imageCountMoreThan",
"countNumber": ${MaxTaggedContainerImagesToRetain}
},
"action": { "type": "expire" }
}
]
}
- DaysToRetainUntaggedContainerImages: !Ref DaysToRetainUntaggedContainerImages
MaxTaggedContainerImagesToRetain: !Ref MaxTaggedContainerImagesToRetain
EnvironmentName: !Ref EnvironmentName
ListenerRuleHostHeader:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Condition: IsListenerRuleHostHeaderOnly
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
Conditions:
- Field: host-header
HostHeaderConfig:
Values: !Ref ELBRuleHostHeader
ListenerArn:
Fn::ImportValue: !Sub ${ELBStackName}-ApplicationLoadBalancerListenerArn
Priority: !Ref ELBRulePriority
ListenerRulePathPattern:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Condition: IsListenerRulePathPattern
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
Conditions:
- Field: host-header
HostHeaderConfig:
Values: !Ref ELBRuleHostHeader
- Field: path-pattern
PathPatternConfig:
Values:
- !Sub "${ELBRulePathPattern}"
- !Sub "${ELBRulePathPattern}/"
- !Sub "${ELBRulePathPattern}/*"
ListenerArn:
Fn::ImportValue: !Sub ${ELBStackName}-ApplicationLoadBalancerListenerArn
Priority: !Ref ELBRulePriority
DefaultTaskRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: default-s3-bucket-and-ecs-readonly
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: s3:*
Resource: !GetAtt DefaultContainerBucket.Arn
- Resource: '*'
Effect: Allow
Action:
- ecs:ListAttributes
- ecs:DescribeTaskSets
- ecs:DescribeTaskDefinition
- ecs:DescribeClusters
- ecs:ListServices
- ecs:ListAccountSettings
- ecs:DescribeCapacityProviders
- ecs:ListTagsForResource
- ecs:ListTasks
- ecs:ListTaskDefinitionFamilies
- ecs:DescribeServices
- ecs:ListContainerInstances
- ecs:DescribeContainerInstances
- ecs:DescribeTasks
- ecs:ListTaskDefinitions
- ecs:ListClusters
DependsOn: DefaultContainerBucket
DefaultTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
DefaultFargateTaskDefinition:
Condition: NotHasEFS
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref AWS::StackName
RequiresCompatibilities:
- FARGATE
Cpu: !Ref DefaultContainerCpu
Memory: !Ref DefaultContainerMemory
NetworkMode: awsvpc
TaskRoleArn: !GetAtt DefaultTaskRole.Arn
ExecutionRoleArn: !GetAtt DefaultTaskExecutionRole.Arn
ContainerDefinitions:
- Name: !Ref GitHubRepo
Image: !Ref SeedDockerImage
Essential: true
Ulimits:
- HardLimit: 10240
Name: nofile
SoftLimit: 10240
PortMappings:
- ContainerPort:
Fn::ImportValue: !Sub ${NetworkStackName}-AppIngressPort
DefaultFargateTaskDefinitionEFS:
Condition: HasEFS
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Ref AWS::StackName
RequiresCompatibilities:
- FARGATE
Cpu: !Ref DefaultContainerCpu
Memory: !Ref DefaultContainerMemory
NetworkMode: awsvpc
TaskRoleArn: !GetAtt DefaultTaskRole.Arn
ExecutionRoleArn: !GetAtt DefaultTaskExecutionRole.Arn
Volumes:
- Name: efshtml
EfsVolumeConfiguration:
FileSystemId:
Fn::ImportValue: !Sub ${EFSStackName}-FileSystemId
RootDirectory: !Sub ${EFSPath}
ContainerDefinitions:
- Name: !Ref GitHubRepo
Image: !Ref SeedDockerImage
Essential: true
Ulimits:
- HardLimit: 10240
Name: nofile
SoftLimit: 10240
PortMappings:
- ContainerPort:
Fn::ImportValue: !Sub ${NetworkStackName}-AppIngressPort
SLRWaitCondition:
Type: "AWS::CloudFormation::WaitCondition"
Properties:
Handle: !If [ECSRoleTobeCreated, !Ref SLRWaitHandle, !Ref SLRNoWaitHandle]
Timeout: "1"
Count: 0
SLRNoWaitHandle:
Type: "AWS::CloudFormation::WaitConditionHandle"
SLRWaitHandle:
Condition: ECSRoleTobeCreated
DependsOn: DefaultFargateServiceSLR
Type: "AWS::CloudFormation::WaitConditionHandle"
DefaultFargateServiceSLR:
Type: "AWS::IAM::ServiceLinkedRole"
Condition: ECSRoleTobeCreated
Properties:
AWSServiceName: "ecs.amazonaws.com"
Description: "Role to enable Amazon ECS to manage your cluster."
DefaultFargateService:
Type: AWS::ECS::Service
Properties:
Cluster:
Fn::ImportValue: !Sub ${ELBStackName}-FargateEcsClusterName
#ServiceName: !Ref AWS::StackName
DesiredCount: !Ref DefaultTaskMinContainerCount
CapacityProviderStrategy:
- Base: 1
CapacityProvider: FARGATE_SPOT
Weight: 1
# - Base: 1
# CapacityProvider: FARGATE
# Weight: 1
#LaunchType: FARGATE
PlatformVersion: 1.4.0
TaskDefinition: !If [HasEFS, !Ref DefaultFargateTaskDefinitionEFS, !Ref DefaultFargateTaskDefinition]
LoadBalancers:
- ContainerName: !Ref GitHubRepo
ContainerPort:
Fn::ImportValue: !Sub ${NetworkStackName}-AppIngressPort
TargetGroupArn: !Ref TargetGroup
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
SecurityGroups:
- Fn::ImportValue: !Sub ${NetworkStackName}-AppSecurityGroupID
Subnets:
- Fn::ImportValue: !Sub ${NetworkStackName}-PrivateSubnet1ID
- Fn::ImportValue: !Sub ${NetworkStackName}-PrivateSubnet2ID
# - Fn::ImportValue: !Sub ${NetworkStackName}-PrivateSubnet3ID
DependsOn:
- SLRWaitCondition
- TargetGroup
CommitEventRole:
Type: AWS::IAM::Role
Condition: CreateEventRule
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: !Sub ${AWS::StackName}-codepipeline-execution
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: codepipeline:StartPipelineExecution
Resource: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:$
{CodePipelineCodeCommit}
DependsOn: CodePipelineCodeCommit
CommitEvent:
Type: AWS::Events::Rule
Condition: CreateEventRule
Properties:
Description: "Amazon CloudWatch Events rule to automatically start your pipeline when a change occurs in the
AWS CodeCommit source repository and branch. Deleting this may prevent changes from being detected in that pipeline.
Read more: http://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-about-starting.html"
EventPattern:
source:
- aws.codecommit
detail-type:
- CodeCommit Repository State Change
resources:
- !Ref GitHubRepo
detail:
event:
- referenceCreated
- referenceUpdated
referenceType:
- branch
referenceName:
- !Ref GitHubBranch
Name: !Sub ${AWS::StackName}
State: "ENABLED"
Targets:
-
RoleArn: !GetAtt CommitEventRole.Arn
Id: !Ref CodePipelineCodeCommit
Arn: !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:${CodePipelineCodeCommit}
DependsOn: CommitEventRole
Outputs:
Name:
Description: Fargate Stack Name
Value: !Ref AWS::StackName
Export:
Name: !Sub ${AWS::StackName}-Name
EnvironmentName:
Description: Environment Name
Value: !Ref EnvironmentName
Export:
Name: !Sub ${AWS::StackName}-EnvironmentName
EcrDockerRepositoryName:
Value: !Ref EcrDockerRepository
Export:
Name: !Sub ${AWS::StackName}-EcrDockerRepositoryName
EcrDockerRepositoryArn:
Value: !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/${EcrDockerRepository}
Export:
Name: !Sub ${AWS::StackName}-EcrDockerRepositoryArn
EcrDockerRepositoryUri:
Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EcrDockerRepository}
Export:
Name: !Sub ${AWS::StackName}-EcrDockerRepositoryUri
DefaultFargateServiceArn:
Value: !Ref DefaultFargateService
Export:
Name: !Sub ${AWS::StackName}-DefaultFargateServiceArn
DefaultFargateServiceName:
Value: !GetAtt DefaultFargateService.Name
Export:
Name: !Sub ${AWS::StackName}-DefaultFargateServiceName
CodePipelineArtifactBucketName:
Value: !Ref CodePipelineArtifactBucket
Export:
Name: !Sub ${AWS::StackName}-CodePipelineArtifactBucket
CodePipelineArtifactBucketArn:
Value: !GetAtt CodePipelineArtifactBucket.Arn
Export:
Name: !Sub ${AWS::StackName}-CodePipelineArtifactBucketArn
3 Diagramas infraestructura