Skip to content

create a demo app within Fargate container on AWS ECS, via terraform provisioning

Notifications You must be signed in to change notification settings

gkoenig/terraform-aws-ecs-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CI/CD demo pipeline on AWS

Overview

AWS provides certain services to create a fully automated CI/CD pipeline to implement e.g. a blue/green deployment triggered by git push.

  • ECS : Elastic Container Service
    managed docker container environment, compatible with Fargate and EC2. We will use Fargate as container launch type. By that we do not have to take care of underlying cluster resources (in contrast to use EC2 launch type).

  • ECR : Elastic Container Repository
    container repository, like e.g. DockerHub

  • CodeCommit
    source code repository, basically Git by AWS

  • CodeBuild
    CodeBuild is a fully managed continuous integration service that compiles source code, runs tests, and produces software packages that are ready to deploy.

  • CodeDeploy
    CodeDeploy is a fully managed deployment service that automates software deployments to a variety of compute services such as Amazon EC2, AWS Fargate, AWS Lambda, and your on-premises servers

  • CodePipeline
    CodePipeline is the orchestrator which glues together the VCS-,build- and deploy steps. Not only AWS internal services are possible, e.g. you can also integrate GitHub as VCS.

Demo pipeline

This demo CI/CD pipeline will

  • run container on AWS ECS cluster
  • fetch the container from AWS ECR
  • store the container implementation within CodeCommit
  • use CodeBuild to build the container and push it to ECR
  • use CodeDeploy to deploy updated container to ECS cluster, replacing the "old" container

To keep the infrastructure somehow simple, the whole setup uses a VPC with only 2 public subnets (in 2 different AZs) to show HA across availability zones.

Setup

The creation of the following resources is automated via terraform:

  • vpc
  • subnets (2 public)
  • security groups
  • loadbalancer (ALB)
  • ECS cluster
  • ECR (container) repository
  • CodeCommit (code) repository

After those resources are up, the remaining steps are:

  • push the code to CodeCommit repository
  • create the CI/CD pipeline

automated creation of resources via terraform

prerequisites :

  • aws cli installed and configured (by default terraform takes the AWS_ACCESS_KEY and AWS_SECRET_KEY from ~/.aws/credentials , from the profile default )
    • the user you configured needs to have proper permissions to create the resources
  • terraform installed v0.12+ ==> instructions
  • to execute the terratest IaC tests you need to have golang installed. It uses the built-in package testing to run go test xyz_test.go ( details of Terratest here)

create S3 bucket and dynamoDB table

cd terraform/terraform-s3-remote-state
#run once
terraform init
#check your terraform code
terraform validate
terraform plan
#deploy
terraform apply

create core AWS resources

run the tests upfront

cd <repo-root-dir>/terraform/core-aws/terratest
go test terraform-core-aws_test.go
# for verbose output add flag -v
# go test -v terraform-core-aws_test.go

and then create the resources

cd <repo-root-dir>/terraform/core-aws
#run once
terraform init
#check your terraform code
terraform validate
terraform plan
#deploy
terraform apply

create ECS related resources

cd <repo-root-dir>/terraform/services/ecs
#run once
terraform init
#check your terraform code
terraform validate
terraform plan
#deploy
terraform apply

create CICD related resources

cd <repo-root-dir>/terraform/services/cicd
#run once
terraform init
#check your terraform code
terraform validate
terraform plan
#deploy
terraform apply

CodeCommit

prerequisite: you have Git installed

Preparation

official AWS docu

attach the predefined policies AWSCodeCommitPowerUser to your IAM user

setup CodeCommit

  1. grab the sourcecode
git clone [email protected]:gkoenig/go-simplehttp.git
  1. setup ssh and clone CodeCommit repo get instructions from the CodeCommit repo page here , and how to setup ssh ħere
git clone ssh://git-codecommit.eu-central-1.amazonaws.com/v1/repos/aws-cicd-demo-code-repo 
  1. add code to CodeCommit repo
cp ./go-simplehttp/Dockerfile ./go-simplehttp/simpleHTTP.go ./aws-cicd-demo-code-repo
cp ./scripts/buildspec.yml ./aws-cicd-demo-code-repo
cd aws-cicd-demo-code-repo/
git add .
git commit -m "Initial commit"
git push

4.

CodeBuild

Configre a CodeBuild project which builds a new container image and pushes it to ECR, triggered by a code change in our CodeCommit repository.

IAM permissions

Create a dedicated role for CodeBuild. It will assume that role with its certain permissions, especially in our case permissions for ECR.

In IAM section of AWS console

  • click Policies
  • click create Policy ==> choose JSON
  • paste the following JSON as policy content
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudWatchLogsPolicy",
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "CodeCommitPolicy",
      "Effect": "Allow",
      "Action": [
        "codecommit:GitPull"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "S3GetObjectPolicy",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "S3PutObjectPolicy",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "ECRPullPolicy",
      "Effect": "Allow",
      "Action": [
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "ECRAuthPolicy",
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "S3BucketIdentity",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketAcl",
        "s3:GetBucketLocation"
      ],
      "Resource": 
        "*"
    }
  ]
}
  • set CodeBuildServiceRolePolicy as policy name
  • in the main navigation choose Roles
  • click create Role
  • choose CodeBuild as AWS service to add and click Next::Permissions
  • on attach permissions policies page, select CodeBuildServiceRolePolicy and AmazonEC2ContainerRegistryPowerUser to add
  • save the role as CodeBuildServiceRole

CodeBuild project

  • open CodeBuild service page within AWS mgm console Link

  • click Create build project

  • set the Project Name

  • configure the Source provider by linking it to our CodeCommit repository, master branch

  • configure the build environment

    • use the AmazonLinux2 as base
    • use always the latest image of it
    • check the privileged flag
    • choose Existing service role and select the one we created in the previous step (CodeBuildServiceRole)
  • set buildspec

  • keep default settings for sections Artifacts and Logs

  • click Create build project

manually trigger a codebuild run

  • in the Build projects overview click on the previously created project demo-cicd-cb
  • click on Start build in top right corner
  • keep settings, scroll down and click Start build
  • observe the build log output ...

After a successfull build you'll find your new image listed in the ECR repository

CodePipeline

  • Open the CodePipeline page ħere
  • click Create pipeline in the top right corner
  • configure Pipeline settings
    • provide pipeline name: demo-pipeline
    • let the wizard create a Service role for us, with the suggested Role name
    • in the advanced settings, keep the default S3 location and KMS Key
    • click Next
  • configure Source stage
    • choose CodeCommit as source provider and the master branch of our repository
    • let CloudWatch trigger our pipeline (default setting)
    • click Next
  • configure Build stage
    • select CodeBuild as provider
    • choose our previously create CodeBuild project within eu-central-1 region (Frankfurt)
    • click Next
  • configure Deploy stage
    • select Amazon ECS as provider
    • choose our region, ECS cluster and ECS service
    • specify the image definitions file as we called it in the buildspec: imagedefinitions.json
    • click Next
  • on the Review page scroll down and click Create pipeline

the pipeline will start immediately !!

You can ovserve the details of each phase by clicking on the Details link. E.g. for the build phase you'll be forwarded to the build log as we have seen in the CodeBuild chapter.

keep in mind that the deploy phase will take at least 5 minutes, because it waits for the old task(s) to be stopped. This, by default, will take roughly 5 minutes. you can observe this in the ECS service overview, clicking on the tab Events

About

create a demo app within Fargate container on AWS ECS, via terraform provisioning

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published