You can build an application, create a docker image and upload it to AWS ECR using Azure DevOps build pipeline. Later deploy this image from AWS ECR to AWS ECS Fargate container using the Release pipeline in Azure DevOps.

This article will provide step-by-step details to create build and release pipelines, IAM user and permissions and deploy to AWS ECS Fargate.

Steps:

1. Create a simple project in Azure DevOps. You can download the sample project from github.

2. Create IAM user, role, and policy.

>>Create a Role ecsTaskExecutionRole for ECS service and assign AWS managed policy AmazonECSTaskExecutionRolePolicy

 

>> Create a policy aws_ecr_access [Change the resource]

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListImagesInRepository",
            "Effect": "Allow",
            "Action": [
                "ecr:ListImages"
            ],
            "Resource": "arn:aws:ecr:ap-southeast-2:7063454353588:repository/testworld"
        },
        {
            "Sid": "GetAuthorizationToken",
            "Effect": "Allow",
            "Action": [
                "ecr:GetAuthorizationToken"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ManageRepositoryContents",
            "Effect": "Allow",
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:GetRepositoryPolicy",
                "ecr:DescribeRepositories",
                "ecr:ListImages",
                "ecr:DescribeImages",
                "ecr:BatchGetImage",
                "ecr:InitiateLayerUpload",
                "ecr:UploadLayerPart",
                "ecr:CompleteLayerUpload",
                "ecr:PutImage"
            ],
            "Resource": "arn:aws:ecr:ap-southeast-2:7054543532588:repository/testworld"
        }
    ]
}

 

>> Create a user aws_ecs_user and assign the aws_ecr_access policy and the AWS managed policy AmazonECS_FullAccess.

 

3. Create a service connection (aws_service) in Azure DevOps using the security credentials of user aws_ecr_user.

 

 

4. We will use a build pipeline – azure-pipeline-to-aws-fargate-deploy.yml . Create variable group AWS with the following parameters and values-

 

 

5. The build pipeline will replace the Build.BuildId in fargate-task-definition.json and hello-world.go. This is required to create the new docker image with a tag when the application is built. This image is then uploaded to AWS ECR. Also, the task definition is updated with the new image URL and tag. The task definition is created as artifact output which will be consumed by the release pipeline to deploy it.

 

6. Run the build pipeline and ensure that it generates artifact as shown-

7. Ensure that the image is uploaded to AWS ECR.

 

Release Pipeline:

>> Create a release pipeline with input artifact

 

>> Create variables and assign values as shown

>> Create stage Deploy to AWS ECS with 4 tasks

The first task is to download the artifact in ArtifactStagingDirectory

 

The second task is to create ECS cluster helloworldcluster

# Write your commands here
export AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY)
export AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID)
aws ecs create-cluster --cluster-name helloworldcluster

 

 

The third task is to register the task definition

# Write your commands here
export AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY)
export AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID)

task_version=$(aws ecs register-task-definition --cli-input-json file:///mnt/c/Subodh/agent/_work/4/s/fargate/fargate-task-definition.json | jq --raw-output '.taskDefinition.revision')

echo "##vso[task.setvariable variable=task_version;]$task_version"

 

 

The final task is to create an ECS service

# Write your commands here
export AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY)
export AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID)

echo "a- $(task_version)"

svc_status=$(aws ecs list-services --cluster helloworldcluster | jq --raw-output '.serviceArns[]' )

echo $svc_status

if [ "$svc_status" == "arn:aws:ecs:ap-southeast-2:706949302588:service/helloworldcluster/helloworldsvc" ]

then  
  aws ecs update-service --cluster helloworldcluster  --service helloworldsvc  --task-definition helloworldtask:$(task_version)

else  
  aws ecs create-service --cluster helloworldcluster  --service-name helloworldsvc  --task-definition helloworldtask:$(task_version) --desired-count 1 --launch-type FARGATE  --platform-version LATEST  --network-configuration "awsvpcConfiguration={subnets=[subnet-01ba99d4510418b78],securityGroups=[sg-0bff22bb734b2ef35],assignPublicIp=ENABLED}"

fi

 

 

Execute the release pipeline, it will create a cluster, task definition with revisions and inside cluster, it will create an ECS service with tasks running the container as shown below-

 

Using the public IP you can access the application and check its health as shown below