Deploy an ECS Fargate task with a new image

0

I am trying to find a solid workflow for deploying application changes outside of the cycle of infrastructure deployments.

We manage all of the infra using AWS CDK.

The application is built and published as an artifact into a container registry (GitLab).

These two processes are currently decoupled, as application changes are frequent and infra changes are very infrequent.

What's the most current and, at the same time, ergonomic way to redeploy the ECS task with a new image ID once it is published?

I think the image is baked into the task definition. So, editing task definition by hand, outside of IaC, is a bad idea.

Is there a way, perhaps, to set the image tag in some parameter string and then trigger a rollout?

Thanks.

profile picture
m0ltar
asked 3 months ago926 views
2 Answers
3

Hi,

Set up AWS ECR and ECS: - Before configuring Jenkins, you need to set up your AWS Elastic Container Registry (ECR) to store your Docker images and your AWS ECS cluster and task definitions. Create an ECR repository to store your Docker images. Create an ECS cluster and define your task definitions for Fargate tasks. Implement ECS Task/Service: - Define your ECS task definition with the appropriate container definitions. Create an ECS service to run your task on the ECS cluster. Configure GitLab Integration: - Log in to your Jenkins server and navigate to the Jenkins dashboard. Install the necessary plugins for GitLab integration if not already installed. Go to "Manage Jenkins" > "Configure System" and scroll down to the "GitLab" section. Enter the GitLab connection details, including the GitLab server URL, credentials, etc. Test the connection to ensure that Jenkins can communicate with GitLab successfully. Set up Pipeline Job: - Create a new Pipeline job in Jenkins. Configure the job to use Git as the source code management system and specify the URL of your GitLab repository. Optionally, configure the job to trigger builds automatically when changes are pushed to the repository. Define Parameters: - In the Jenkins job configuration, add parameters to specify the image tag and any other parameters you need for your deployment. For example, you can add a String parameter named IMAGE_TAG to specify the Docker image tag. Write Pipeline Script: Example pipeline { agent any

parameters {
    string(name: 'IMAGE_TAG', defaultValue: 'latest', description: 'Docker image tag')
}

environment {
    AWS_DEFAULT_REGION = 'your-aws-region'
    AWS_ACCESS_KEY_ID = credentials('aws-access-key-id')
    AWS_SECRET_ACCESS_KEY = credentials('aws-secret-access-key')
    ECR_REPO_URL = 'your-ecr-repo-url'
    ECS_CLUSTER_NAME = 'your-ecs-cluster-name'
    ECS_SERVICE_NAME = 'your-ecs-service-name'
    TASK_DEFINITION_FAMILY = 'your-task-definition-family'
}

stages {
    stage('Build and Push Docker Image') {
        steps {
            script {
                // Build and tag Docker image with specified tag
                sh "docker build -t $ECR_REPO_URL:${params.IMAGE_TAG} ."
                
                // Login to ECR
                withCredentials([usernamePassword(credentialsId: 'aws-ecr-credentials-id', usernameVariable: 'AWS_ACCESS_KEY_ID', passwordVariable: 'AWS_SECRET_ACCESS_KEY')]) {
                    sh "aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REPO_URL"
                }
                
                // Push Docker image to ECR
                sh "docker push $ECR_REPO_URL:${params.IMAGE_TAG}"
            }
        }
    }
    
    stage('Update ECS Task Definition') {
        steps {
            script {
                // Retrieve current task definition revision
                def taskDefinition = sh(script: "aws ecs describe-task-definition --task-definition $TASK_DEFINITION_FAMILY", returnStdout: true).trim()
                
                // Update task definition with new image tag
                taskDefinition = taskDefinition.replace("REPLACE_WITH_IMAGE_TAG", "$ECR_REPO_URL:${params.IMAGE_TAG}")
                
                // Register updated task definition
                writeFile file: 'updated-task-definition.json', text: taskDefinition
                
                // Register updated task definition
                sh "aws ecs register-task-definition --cli-input-json file://updated-task-definition.json"
            }
        }
    }
    
    stage('Deploy ECS Service') {
        steps {
            script {
                // Update ECS service with new task definition revision
                sh "aws ecs update-service --cluster $ECS_CLUSTER_NAME --service $ECS_SERVICE_NAME --task-definition $TASK_DEFINITION_FAMILY:${params.IMAGE_TAG}"
            }
        }
    }
}

}

Build and Push Docker Image: - Include a stage in your Jenkins Pipeline to build your Docker image from the source code and push it to your ECR repository. Use Docker commands or Docker plugins in Jenkins to accomplish this. Update ECS Task Definition: - After building and pushing the Docker image, include a stage in your Jenkins Pipeline to update the ECS task definition with the new image tag. Deploy ECS Service: - After updating the task definition, include a stage in your Jenkins Pipeline to trigger the deployment of your ECS service with the new task definition. Test and Run Pipeline Job: - Save the Jenkins Pipeline configuration and trigger a build to test the deployment process. Ensure that the Jenkins job runs successfully and deploys the updated Docker image to your ECS Fargate task.

you can set up a Jenkins Pipeline job with parameters to deploy an EC2 Fargate task with a new Docker image.

EXPERT
answered 3 months ago
EXPERT
reviewed a month ago
1

Hi,

This seems like a task cut out for CodePipeline. Please refer to this tutorial to understand how you can configure CodePipeline so that your Amazon ECS service always runs the Docker image that was created from your code change.

Once you have implemented this for a specific ECS service/task, you can make this a framework for other services/tasks and deploy their corresponding CodePipeline setup via CDK, that way you continue to manage your infrastructure via CDK.

Hope this helps!

Thanks, Rama

profile pictureAWS
Rama
answered 3 months ago
  • Ok, sorry, I must add, unable to use CodePipeline ... for reasons.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions