AWS Code Star with Fargate — 2

Multiple environment setup

  • Development cluster
  • ECR Repository
  • Target groups for each environment
  • Load balancer security group
  • Listeners and ALB
  • Build projects which is used in build stage of the codepipeline.
  1. Development-stack.yml
    In this template, we are adding resources for dev, intg and staging
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::CodeStar
Conditions:
UseSubnet: !Not [!Equals [!Ref 'SubnetId', subnet-none]]
Parameters:
VpcId:
Type: String
Description: The ID of the Amazon Virtual Private Cloud (VPC) used for the new Amazon EC2 Linux instances.
Default: vpc-<id>
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: The name of the VPC subnet used for the new Amazon EC2 Linux instances launched for this project.
Default: subnet-<id1>
SubnetB:
Type: AWS::EC2::Subnet::Id
Default: subnet-<id2>
DevPort:
Type: Number
Default: 3000
IntgPort:
Type: Number
Default: 3001
StagingPort:
Type: Number
Default: 3002
ProjectId:
Type: String
Default: poc-spring-app
HealthCheckIntervalSeconds:
Type: Number
Default: 30
ServiceName:
Type: String
Default: codestar
LoadBalancerPortHTTP:
Type: Number
Default: 80
LoadBalancerPortHTTPS:
Type: Number
Default: 443
HealthCheckPath:
Type: String
Default: /health
CertificateARN:
Type: String
Description: The ARN of the Amazon Certificate Manager
Default: arn:aws:acm:us-west-2:<id>:certificate/eea725ed-77c6-47b8-bac8-730b3d29b39e
ServiceRole:
Type: String
Description: The ARN of the AWS IAM role that enables AWS CodeBuild to interact with dependent AWS services
Default: arn:aws:iam::<id>:role/CodeStarWorker-poc-spring-app-ToolChain
ArtifactEncryptionKey:
Type: String
Description: Artifact encryption key
# This value is present in codebuild project and used the same value present in codebuild project created by Codestar
Default: arn:aws:kms:us-west-2:<id>:alias/aws/s3
BuildEnvironmentComputeType:
Type: String
AllowedValues:
- BUILD_GENERAL1_SMALL
- BUILD_GENERAL1_MEDIUM
- BUILD_GENERAL1_LARGE
Default: BUILD_GENERAL1_MEDIUM
BuildEnvironmentImage:
Type: String
Default: aws/codebuild/amazonlinux2-x86_64-standard:3.0
S3Bucket:
Type: String
Default: aws-codestar-us-west-2-<id>-poc-spring-app-pipe
AccountId:
Type: String
Default: <id>
BuildSpecFilePath:
Type: String
Default: config/buildspec
Resources:
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Join ['-', [!Ref ServiceName, 'development']]

DevRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Join ['-', [!Ref ProjectId, 'dev', 'repo']]
ImageScanningConfiguration:
ScanOnPush: "true"

IntgRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Join ['-', [!Ref ProjectId, 'integration', 'repo']]
ImageScanningConfiguration:
ScanOnPush: "true"
StagingRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Join ['-', [!Ref ProjectId, 'staging', 'repo']]
ImageScanningConfiguration:
ScanOnPush: "true"
ProdRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Join ['-', [!Ref ProjectId, 'production', 'repo']]
ImageScanningConfiguration:
ScanOnPush: "true"

TargetGroupDev:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
# will look for a 200 status code by default unless specified otherwise
HealthCheckPath: !Ref HealthCheckPath
HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2
HealthyThresholdCount: 2
Name: !Join ['-', [!Ref ServiceName, tg, 'dev']]
Port: !Ref DevPort
Protocol: HTTP
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300
TargetType: ip
VpcId: !Ref VpcId
TargetGroupIntg:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
# will look for a 200 status code by default unless specified otherwise
HealthCheckPath: !Ref HealthCheckPath
HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2
HealthyThresholdCount: 2
Name: !Join ['-', [!Ref ServiceName, tg, 'integration']]
Port: !Ref IntgPort
Protocol: HTTP
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300
TargetType: ip
VpcId: !Ref VpcId
TargetGroupStaging:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
# will look for a 200 status code by default unless specified otherwise
HealthCheckPath: !Ref HealthCheckPath
HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2
HealthyThresholdCount: 2
Name: !Join ['-', [!Ref ServiceName, tg, 'staging']]
Port: !Ref StagingPort
Protocol: HTTP
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300
TargetType: ip
VpcId: !Ref VpcId

LoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup
# This security group is w.r.t Development(Dev,Integration) ALB
Properties:
GroupName: !Join ['-', [!Ref ServiceName, alb, sg, development]]
GroupDescription: !Join [' ', [!Ref ServiceName, alb, sg, development]]
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTP
ToPort: !Ref LoadBalancerPortHTTP
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTP
ToPort: !Ref LoadBalancerPortHTTP
CidrIpv6: ::/0
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTPS
ToPort: !Ref LoadBalancerPortHTTPS
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTPS
ToPort: !Ref LoadBalancerPortHTTPS
CidrIpv6: ::/0
- IpProtocol: tcp
FromPort: !Ref DevPort
ToPort: !Ref DevPort
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref DevPort
ToPort: !Ref DevPort
CidrIpv6: ::/0
- IpProtocol: tcp
FromPort: !Ref IntgPort
ToPort: !Ref IntgPort
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref IntgPort
ToPort: !Ref IntgPort
CidrIpv6: ::/0
- IpProtocol: tcp
FromPort: !Ref StagingPort
ToPort: !Ref StagingPort
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref StagingPort
ToPort: !Ref StagingPort
CidrIpv6: ::/0

ListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: 443
Host: "#{host}"
Path: "/#{path}"
Query: "#{query}"
StatusCode: "HTTP_301"
LoadBalancerArn: !Ref LoadBalancer
Port: !Ref LoadBalancerPortHTTP
Protocol: HTTP
ListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref TargetGroupDev
Type: forward
Certificates:
- CertificateArn: !Ref CertificateARN
LoadBalancerArn: !Ref LoadBalancer
Port: !Ref LoadBalancerPortHTTPS
Protocol: HTTPS
ListenerRule1:
Type: 'AWS::ElasticLoadBalancingV2::ListenerRule'
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref TargetGroupDev
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- "*/dev/*"
ListenerArn: !Ref ListenerHTTPS
Priority: 1
ListenerRule2:
Type: 'AWS::ElasticLoadBalancingV2::ListenerRule'
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref TargetGroupIntg
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- "*/intg/*"
ListenerArn: !Ref ListenerHTTPS
Priority: 2
ListenerRule3:
Type: 'AWS::ElasticLoadBalancingV2::ListenerRule'
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref TargetGroupStaging
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- "*/staging/*"
ListenerArn: !Ref ListenerHTTPS
Priority: 3

LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: 60
Name: !Join ['-', [!Ref ServiceName, alb, development]]
Scheme: internet-facing
SecurityGroups:
- !Ref LoadBalancerSecurityGroup
Subnets:
- !Ref SubnetId
- !Ref SubnetB

#Creating Dev Build project
DevBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Join ['-', [!Ref ProjectId, 'dev']]
Description: AWS CodeStar created CodeBuild Project for the project
ServiceRole: !Ref ServiceRole
ConcurrentBuildLimit: 1
Artifacts:
Type: CODEPIPELINE
Packaging: ZIP
EncryptionKey: !Ref ArtifactEncryptionKey
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: !Ref BuildEnvironmentImage
ImagePullCredentialsType: CODEBUILD
#PrivilegedMode is required to pull the images from ECR
PrivilegedMode: true
EnvironmentVariables:
- Name: S3_BUCKET
Type: PLAINTEXT
Value: !Ref S3Bucket
- Name: WEBSITE_S3_PREFIX
Value: NoVal
Type: PLAINTEXT
- Name: WEBSITE_S3_BUCKET
Value: NoVal
Type: PLAINTEXT
- Name: PROJECT_ID
Value: !Ref ProjectId
Type: PLAINTEXT
- Name: ACCOUNT_ID
Value: !Ref AccountId
Type: PLAINTEXT
- Name: PARTITION
Value: aws
Type: PLAINTEXT
- Name: DOCKER_REPOSITORY_URI
Value: !Select [0, !Split [ '/', !GetAtt DevRepository.RepositoryUri]]
Type: PLAINTEXT
- Name: REPOSITORY_NAME
Value: !Join ['-', [!Ref ProjectId, 'dev', 'repo']]
Type: PLAINTEXT
Source:
Type: CODEPIPELINE
#Don't specify BuildSpec key if the file is named as buildspec.yml in the source code root directory
BuildSpec: !Join ['-', [!Ref BuildSpecFilePath, 'dev.yml']]
TimeoutInMinutes: 60
Tags:
- Key: awscodestar:projectArn
Value: arn:aws:codestar:us-west-2:755242612616:project/poc-spring-app

#Creating Integration Build project
IntgBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Join ['-', [!Ref ProjectId, 'integration']]
Description: AWS CodeStar created CodeBuild Project for the project
ServiceRole: !Ref ServiceRole
ConcurrentBuildLimit: 1
Artifacts:
Type: CODEPIPELINE
Packaging: ZIP
EncryptionKey: !Ref ArtifactEncryptionKey
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: !Ref BuildEnvironmentImage
ImagePullCredentialsType: CODEBUILD
#PrivilegedMode is required to pull the images from ECR
PrivilegedMode: true
EnvironmentVariables:
- Name: S3_BUCKET
Type: PLAINTEXT
Value: !Ref S3Bucket
- Name: WEBSITE_S3_PREFIX
Value: NoVal
Type: PLAINTEXT
- Name: WEBSITE_S3_BUCKET
Value: NoVal
Type: PLAINTEXT
- Name: PROJECT_ID
Value: !Ref ProjectId
Type: PLAINTEXT
- Name: ACCOUNT_ID
Value: !Ref AccountId
Type: PLAINTEXT
- Name: PARTITION
Value: aws
Type: PLAINTEXT
- Name: DOCKER_REPOSITORY_URI
Value: !Select [0, !Split [ '/', !GetAtt IntgRepository.RepositoryUri]]
Type: PLAINTEXT
- Name: REPOSITORY_NAME
Value: !Join ['-', [!Ref ProjectId, 'integration', 'repo']]
Type: PLAINTEXT
Source:
Type: CODEPIPELINE
#Don't specify BuildSpec key if the file is named as buildspec.yml in the source code root directory
BuildSpec: !Join ['-', [!Ref BuildSpecFilePath, 'integration.yml']]
TimeoutInMinutes: 60
Tags:
- Key: awscodestar:projectArn
Value: arn:aws:codestar:us-west-2:755242612616:project/poc-spring-app
#Creating Staging Build project
StagingBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: !Join ['-', [!Ref ProjectId, 'staging']]
Description: AWS CodeStar created CodeBuild Project for the project
ServiceRole: !Ref ServiceRole
ConcurrentBuildLimit: 1
Artifacts:
Type: CODEPIPELINE
Packaging: ZIP
EncryptionKey: !Ref ArtifactEncryptionKey
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: !Ref BuildEnvironmentImage
ImagePullCredentialsType: CODEBUILD
#PrivilegedMode is required to pull the images from ECR
PrivilegedMode: true
EnvironmentVariables:
- Name: S3_BUCKET
Type: PLAINTEXT
Value: !Ref S3Bucket
- Name: WEBSITE_S3_PREFIX
Value: NoVal
Type: PLAINTEXT
- Name: WEBSITE_S3_BUCKET
Value: NoVal
Type: PLAINTEXT
- Name: PROJECT_ID
Value: !Ref ProjectId
Type: PLAINTEXT
- Name: ACCOUNT_ID
Value: !Ref AccountId
Type: PLAINTEXT
- Name: PARTITION
Value: aws
Type: PLAINTEXT
- Name: DOCKER_REPOSITORY_URI
Value: !Select [0, !Split [ '/', !GetAtt StagingRepository.RepositoryUri]]
Type: PLAINTEXT
- Name: REPOSITORY_NAME
Value: !Join ['-', [!Ref ProjectId, 'staging', 'repo']]
Type: PLAINTEXT
Source:
Type: CODEPIPELINE
#Don't specify BuildSpec key if the file is named as buildspec.yml in the source code root directory
BuildSpec: !Join ['-', [!Ref BuildSpecFilePath, 'staging.yml']]
TimeoutInMinutes: 60
Tags:
- Key: awscodestar:projectArn
Value: arn:aws:codestar:us-west-2:755242612616:project/poc-spring-app
  • Production-stack.yml
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::CodeStar
Conditions:
UseSubnet: !Not [!Equals [!Ref 'SubnetId', subnet-none]]
Parameters:
VpcId:
Type: String
Description: The ID of the Amazon Virtual Private Cloud (VPC) used for the new Amazon EC2 Linux instances.
Default: vpc-<id>
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: The name of the VPC subnet used for the new Amazon EC2 Linux instances launched for this project.
Default: subnet-<id1>
SubnetB:
Type: AWS::EC2::Subnet::Id
Default: subnet-<id2>
ProdPort:
Type: Number
Default: 3003
ProjectId:
Type: String
Default: poc-spring-app
HealthCheckIntervalSeconds:
Type: Number
Default: 30
ServiceName:
Type: String
Default: codestar
LoadBalancerPortHTTP:
Type: Number
Default: 80
LoadBalancerPortHTTPS:
Type: Number
Default: 443
HealthCheckPath:
Type: String
Default: /health
CertificateARN:
Type: String
Description: The ARN of the Amazon Certificate Manager
Default: arn:aws:acm:us-west-2:<id>:certificate/eea725ed-77c6-47b8-bac8-730b3d29b39e
Resources:
TargetGroupProd:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
# will look for a 200 status code by default unless specified otherwise
HealthCheckPath: !Ref HealthCheckPath
HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2
HealthyThresholdCount: 2
Name: !Join ['-', [!Ref ServiceName, tg, production]]
Port: !Ref ProdPort
Protocol: HTTP
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300
TargetType: ip
VpcId: !Ref VpcId
LoadBalancerSecurityGroupProd:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join ['-', [!Ref ServiceName, alb, sg, production]]
GroupDescription: !Join [' ', [!Ref ServiceName, alb, sg, production]]
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTP
ToPort: !Ref LoadBalancerPortHTTP
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTP
ToPort: !Ref LoadBalancerPortHTTP
CidrIpv6: ::/0
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTPS
ToPort: !Ref LoadBalancerPortHTTPS
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPortHTTPS
ToPort: !Ref LoadBalancerPortHTTPS
CidrIpv6: ::/0
- IpProtocol: tcp
FromPort: !Ref ProdPort
ToPort: !Ref ProdPort
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: !Ref ProdPort
ToPort: !Ref ProdPort
CidrIpv6: ::/0
ListenerHTTPProd:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: 443
Host: "#{host}"
Path: "/#{path}"
Query: "#{query}"
StatusCode: "HTTP_301"
LoadBalancerArn: !Ref LoadBalancerProd
Port: !Ref LoadBalancerPortHTTP
Protocol: HTTP
ListenerHTTPSProd:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref TargetGroupProd
Type: forward
Certificates:
- CertificateArn: !Ref CertificateARN
LoadBalancerArn: !Ref LoadBalancerProd
Port: !Ref LoadBalancerPortHTTPS
Protocol: HTTPS
LoadBalancerProd:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: 60
Name: !Join ['-', [!Ref ServiceName, alb, production]]
Scheme: internet-facing
SecurityGroups:
- !Ref LoadBalancerSecurityGroupProd
Subnets:
- !Ref SubnetId
- !Ref SubnetB
  • Run the above 2 templates in Cloudformation cli
  • Store buildspec-dev.yml file in the config folder at the root level. Add Dockerfile.dev file at the root level. So the buildspec path will be config/buildspec-dev.yml

CodePipeline changes

  • Open the codepipeline and click on clone pipeline. Update project name and service role and click on clone which will automatically trigger the build. Stop the execution and let’s do necessary changes in the pipeline. We have removed the permission boundary for the build role CodeStarWorker-<project-Id>-ToolChain
  • Edit the source stage branch name and output artifact. Click on Edit → Edit source stage
  • Edit the build stage. Update Input artifacts, build project name and build output artifact.
  • Edit deploy stage. Open GenerateChangeSet action group. Here we are going to create new stack in the cloudformation for the given branch.
  • Override the parameter values specific to each branch as we have seen in the Deploy stage changes section.
  • Update the ExecutionChangeSet action group. Update the stack name and change set name which is same as GenerateChangeSet action group.
  • Save the changes and release the pipeline. This will create resources specific to each branch.

Conclusion

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Top Features to Look for in a Codeless Test Automation Tool

IOEX Biweekly Report: Jun 15th — Jun 28th

Synchronizer Token Pattern

Machine relearning

Seeding a Google Compute Engine instance with SSH HostKeys

Unity: how to debug crashed app on android device

Google Summer of Code 2021 -Week #1

Does Your Company Speak the Same Data Language?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Pooja G Bhat

Pooja G Bhat

More from Medium

Backup & Archive with AWS

AWS IAM —  Access Key Rotation and Notification using Boto3

SAP Monitoring using AWS Data Provider for SAP

Cloud Platforms like AWS and more….!!!!!