AWS CodeDeploy and ECS Blue-Green Deployment Hands-on Tutorial

Creating the Target

Task 2: Create a Security Group for the Load balancer

bashCopy code# Create a Security Group
aws ec2 create-security-group \
  --group-name ALB-SG \
  --description "Security group for the load balancer" \
  --vpc-id your-vpc-id  # Replace with your VPC ID

# Add inbound rules
aws ec2 authorize-security-group-ingress \
  --group-id your-security-group-id  # Replace with the Security Group ID
  --protocol tcp \
  --port 80 \
  --source 0.0.0.0/0

aws ec2 authorize-security-group-ingress \
  --group-id your-security-group-id  # Replace with the Security Group ID
  --protocol tcp \
  --port 443 \
  --source 0.0.0.0/0

Task 3: Creating the Target Group and Load Balancer

bashCopy code# Create a Target Group
aws elbv2 create-target-group \
  --name ecs-TG \
  --protocol HTTP \
  --port 80 \
  --target-type ip \
  --vpc-id your-vpc-id  # Replace with your VPC ID

# Create an Application Load Balancer
aws elbv2 create-load-balancer \
  --name httpd-LB \
  --subnets subnet-xxxxxxxx subnet-xxxxxxxx subnet-xxxxxxxx  # Replace with your subnet IDs
  --scheme internet-facing \
  --ip-address-type ipv4

# Attach Security Group to the Load Balancer
aws elbv2 set-security-groups \
  --load-balancer-arn your-load-balancer-arn  # Replace with the Load Balancer ARN
  --security-groups your-security-group-id  # Replace with the Security Group ID

Task 4: Create the second Target Group

bashCopy code# Create a Second Target Group
aws elbv2 create-target-group \
  --name ecs-TG-2 \
  --protocol HTTP \
  --port 8080 \
  --target-type ip \
  --vpc-id your-vpc-id  # Replace with your VPC ID

Task 5: Create an Environment in CloudShell

No AWS CLI commands are required for this task as it’s done interactively in the AWS Management Console.

Task 6: Create an ECS Cluster, Register task definition, and Create an ECS service

bashCopy code# Create an ECS Cluster
aws ecs create-cluster \
  --cluster-name tutorial-bluegreen-cluster \
  --region us-east-1

# Register a Task Definition
# You should replace <your-task-definition-json> with your task definition JSON file.
aws ecs register-task-definition \
  --family tutorial-task-def \
  --container-definitions file://your-task-definition.json

# Create an ECS Service
# Replace <your-subnet-ids> and <your-security-group-id> with your subnet IDs and security group ID.
aws ecs create-service \
  --cluster tutorial-bluegreen-cluster \
  --service-name service-bluegreen \
  --task-definition tutorial-task-def \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxxxxx, subnet-xxxxxxxx],securityGroups=[your-security-group-id]}"

# Ensure to replace <your-load-balancer-arn> with your Load Balancer ARN.
aws ecs update-service \
  --cluster tutorial-bluegreen-cluster \
  --service service-bluegreen \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxxxxx, subnet-xxxxxxxx],securityGroups=[your-security-group-id]}" \
  --force-new-deployment \
  --region us-east-1

Task 7: Create a new revision of the task definition and add tags

bashCopy code# Create a new revision of the task definition
# Replace <your-new-revision-arn> with the ARN of the new revision.
aws ecs register-task-definition \
  --family tutorial-task-def \
  --container-definitions file://your-updated-task-definition.json \
  --tags Key=Name,Value=CodeDeploy

# Update your application to use the new task definition revision.

Task 8: Update the appspec.yml file and upload it back to the S3 bucket

bashCopy code# Download the appspec.yml file from S3
aws s3 cp s3://your-bucket/appspec.yml .

# Update the appspec.yml file
# Replace <your-arn> with the ARN of the new task definition revision.
# Use a text editor to make the necessary changes.

# Upload the updated appspec.yml file back to S3
aws s3 cp appspec.yml s3://your-bucket/

Task 9: Create a CodeDeploy application and deployment group

bashCopy code# Create a CodeDeploy application
aws deploy create-application --application-name ECS-App --compute-platform ECS

# Create a deployment group
# Replace <your-service-role-arn> with the ARN of the service role.
aws deploy create-deployment-group \
  --application-name ECS-App \
  --deployment-group-name ecs-dg \
  --deployment-config-name CodeDeployDefault.ECSAllAtOnce \
  --ec2-tag-filters Key=tag:Name,Value=YourEC2InstanceTag \
  --service-role-arn <your-service-role-arn> \
  --ecs-services service-bluegreen

Using boto3 to create AWS CodeDeploy app

Create a new CodeDeploy application. You can specify the name of your application and any other optional parameters.

After executing the script, the create_application method will create a new AWS CodeDeploy application with the specified name and platform. You can then use this application to manage deployments for your ECS services.

Task 10: Update the ECS task definition by adding another tag

bashCopy code# Create a new revision of the task definition with an additional tag
# Replace <your-new-revision-arn> with the ARN of the new revision.
aws ecs register-task-definition \
  --family tutorial-task-def \
  --container-definitions file://your-updated-task-definition.json \
  --tags Key=Name,Value=CodeDeploy Key=Team,Value=Tech

Task 11: Create a listener for the new port

bashCopy code# Create a listener for the new port (e.g., 8080)
# Replace <your-load-balancer-arn> with your Load Balancer ARN,
# and <your-target-group-arn> with your Target Group ARN.
aws elbv2 create-listener \
  --load-balancer-arn <your-load-balancer-arn> \
  --protocol HTTP \
  --port 8080 \
  --default-actions Type=forward,TargetGroupArn=<your-target-group-arn>

Task 12: Create a Lambda function for the AfterAllowTestTraffic event

bashCopy code# Copy the Lambda function code from S3
aws s3 cp s3://your-bucket/AfterAllowTestTraffic.zip .

# Create a Lambda function
# Replace <your-iam-role-arn> with the ARN of the IAM role.
aws lambda create-function \
  --function-name AfterAllowTestTraffic \
  --runtime nodejs14.x \
  --handler AfterAllowTestTraffic.handler \
  --role <your-iam-role-arn> \
  --zip-file fileb://AfterAllowTestTraffic.zip

Task 13: Update the appspec.yml file

You have already updated the appspec.yml file in Task 8. No additional CLI commands are required.

Task 14: Modify the deployment group and add test listener port

bashCopy code# Update the deployment group to add the test listener port (e.g., 8080)
aws deploy update-deployment-group \
  --application-name ECS-App \
  --current-deployment-group-name ecs-dg \
  --deployment-config-name CodeDeployDefault.ECSAllAtOnce \
  --ecs-services service-bluegreen \
  --load-balancer-info "targetGroupPairInfoList=[{targetGroups=[{name=ecs-TG-2}],prodTrafficRoute={listenerArns=[<your-production-listener-arn>]},testTrafficRoute={listenerArns=[<your-test-listener-arn>]}}]"

Task 15: Check your final output in the CloudWatch log

No additional CLI commands are required for this task. You can check the CloudWatch log in the AWS Management Console as in

Group and Load Balance

{
    "family": "lab-task-def",
        "networkMode": "awsvpc",
        "containerDefinitions": [
            {
                "name": "sample-app",
                "image": "httpd:2.4",
                "portMappings": [
                    {
                        "containerPort": 80,
                        "hostPort": 80,
                        "protocol": "tcp"
                    }
                ],
                "essential": true,
                "entryPoint": [
                    "sh",
                    "-c"
                ],
                "command": [
                    "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
                ]
            }
        ],
        "requiresCompatibilities": [
            "FARGATE"
        ],
        "cpu": "256",
        "memory": "512",
        "executionRoleArn": "arn:aws:iam::679770537133:role/ecsTaskExecutionRole"
}
version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:us-east-1:679770537133:task-definition/lab-task-def:2"
        LoadBalancerInfo:
          ContainerName: "sample-app"
          ContainerPort: 80
{
    "cluster": "lab-bluegreen-cluster",
    "serviceName": "service-bluegreen",
    "taskDefinition": "tutorial-task-def",
    "loadBalancers": [
        {
            "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:679770537133:targetgroup/test/a0dc5fd9f81d8983",
            "containerName": "sample-app",
            "containerPort": 80
        }
    ],
    "launchType": "FARGATE",
    "schedulingStrategy": "REPLICA",
    "deploymentController": {
        "type": "CODE_DEPLOY"
    },
    "platformVersion": "LATEST",
    "networkConfiguration": {
       "awsvpcConfiguration": {
          "assignPublicIp": "ENABLED",
          "securityGroups": [ "sg-043a9fd13c8ee4ae7" ],
          "subnets": [ "subnet-19db4e38", "subnet-b7da85fa", "subnet-f2c14aad" ]
       }
    },
    "desiredCount": 1
}

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top