iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
☕️

ecspresso advent calendar 2020 day 17 - Integration with CodeDeploy

に公開

This is Day 17 of the ecspresso Advent calendar, a series of posts summarizing how to use ecspresso, a deployment tool for Amazon ECS.

ECS Deployment Methods

Currently, there are three types of deployment methods for ECS.

Reference: Amazon ECS deployment types

  • Rolling update via ECS
  • Blue/Green deployment via AWS CodeDeploy
  • Deployment via an external controller

Here, I will explain the rolling update and Blue/Green deployment via CodeDeploy, which are the deployment methods supported by ecspresso.

Rolling Update

In a rolling update, ECS itself performs the deployment. When you set a new task definition for an ECS service, ECS performs the deployment by launching new tasks using the new task definition and stopping the old tasks.

With this method, there is a period during the deployment where new and old tasks temporarily coexist. If the ECS service is registered with a load balancer, requests may be routed to either the new or old tasks during the deployment.

Blue/Green Deployment via CodeDeploy

In a rolling update, there is a period where both new and old tasks coexist, and if you want to perform a rollback, it similarly takes time until the tasks are replaced with ones using the old task definition. Blue/Green deployment is a solution for cases where such behavior is an issue.

Blue/Green deployment is a technique that minimizes the period where new and old task groups process requests simultaneously and allows for an immediate rollback by controlling tasks as follows:

  1. Launch a group of tasks using the new task definition.
  2. Route requests to the new task group by switching the load balancer configuration.
  3. If there are no issues, stop the old task group.
  4. If an issue occurs, revert the load balancer configuration and route requests back to the old task group.

ECS supports Blue/Green deployment through integration with CodeDeploy.

As a constraint, a load balancer (ALB or NLB) is mandatory. ECS services that are not associated with a load balancer (target group) cannot perform Blue/Green deployments.

CodeDeploy Support in ecspresso

In ecspresso, the behavior of ecspresso deploy changes depending on the deploymentController.type attribute in the service definition.

If the value is ECS (or not specified), it performs a rolling update. If the value is CODE_DEPLOY, it performs a deployment in coordination with CodeDeploy.

Since ecspresso is specialized in managing ECS, it does not create or manage CodeDeploy resources. You need to prepare the CodeDeploy application and deployment group separately.

Practical Example of Deployment via CodeDeploy

Here, I will explain an example of performing a Blue/Green deployment via CodeDeploy for the ECS service that was codified in Day 3: Importing an Existing Service.

Since the deployment method can only be configured when creating an ECS service, if the ECS service already exists, you must delete the service once. For instructions on how to delete a service, please refer to Day 16: delete.

Creating the Service

Edit ecs-service-def.json and add deploymentController.

--- a/ecspresso-demo/ecs-service-def.json
+++ b/ecspresso-demo/ecs-service-def.json
@@ -1,13 +1,12 @@
 {
   "createdBy": "arn:aws:iam::314472643515:role/KayacInfraTeam",
   "deploymentConfiguration": {
-    "deploymentCircuitBreaker": {
-      "enable": false,
-      "rollback": false
-    },
     "maximumPercent": 200,
     "minimumHealthyPercent": 100
   },
+  "deploymentController": {
+    "type": "CODE_DEPLOY"
+  },
   "desiredCount": 1,
   "enableECSManagedTags": false,
   "healthCheckGracePeriodSeconds": 0,

At this time, if the deploymentConfiguration.deploymentCircuitBreaker element is defined, please delete the entire element. The deploymentCircuitBreaker feature can only be used with ECS rolling updates.

After that, create the service using ecspresso create.

$ ecspresso --config config.yaml create

Creating Target Groups

In Blue/Green deployment, you need to prepare two target groups for the ELB.

This is because different groups of new and old tasks will belong to each target group, and traffic will be switched by changing the ELB listener rules.

The created service has one target group defined, so please create a new target group with the same settings.

CodeDeploy Configuration

Create an application in CodeDeploy from the AWS console. Select Amazon ECS as the compute platform.

Next, create a deployment group within that application.

  • Specify the ECS cluster and ECS service that are described in the ecspresso configuration file (the ones for the service you just created).
  • For the load balancer, specify two target groups (the original one and the newly created one).
  • Keep the deployment settings as the default ECSAllAtOnce for now.
    • Changing it is not a problem.

With this, the CodeDeploy preparation is complete.

Performing a Deployment with ecspresso

Perform the deployment with ecspresso.

Executing ecspresso deploy against a service configured for CodeDeploy deployment will perform the following processes:

  • Registration of a new task definition
  • Updating the service definition (if there are items to update)
  • Creation of a CodeDeploy AppSpec and starting the deployment with CodeDeploy
    • The CodeDeploy application and deployment group capable of deploying the service itself are automatically selected.
  • Displaying the URL to the AWS console for CodeDeploy
    • If ecspresso is running in a terminal and the open command is available, it will open the URL.
$ ecspresso --config config.yaml deploy
2020/12/16 23:35:04 nginx-service/ecspresso-demo Starting deploy
Service: nginx-service
Cluster: ecspresso-demo
TaskDefinition: first-run-task-definition:10
TaskSets:
   PRIMARY first-run-task-definition:10 desired:1 pending:0 running:1
Events:
2020/12/16 23:35:05 nginx-service/ecspresso-demo Registering a new task definition...
2020/12/16 23:35:05 nginx-service/ecspresso-demo Task definition is registered first-run-task-definition:12
2020/12/16 23:35:05 nginx-service/ecspresso-demo Updating service attributes...
2020/12/16 23:35:08 nginx-service/ecspresso-demo desired count: 1
2020/12/16 23:35:08 nginx-service/ecspresso-demo updating desired count to 1
2020/12/16 23:35:09 nginx-service/ecspresso-demo Deployment d-34OS110T7 is created on CodeDeploy:
2020/12/16 23:35:09 nginx-service/ecspresso-demo https://ap-northeast-1.console.aws.amazon.com/codesuite/codedeploy/deployments/d-MAX8DF0T7?region=ap-northeast-1

Opening the displayed URL will show that the deployment has started in CodeDeploy.

Running ecspresso status in this state reveals that both the new and old tasks are running.

$ ecspresso --config config.yaml status
Service: nginx-service
Cluster: ecspresso-demo
TaskDefinition: first-run-task-definition:12
TaskSets:
   PRIMARY first-run-task-definition:12 desired:1 pending:0 running:1
    ACTIVE first-run-task-definition:11 desired:1 pending:0 running:1

Subsequent deployment progress, rollbacks, etc., are performed within CodeDeploy.

Once the deployment is fully complete, ecspresso status will show that only the new task is running.

$ ecspresso --config config.yaml status
Service: nginx-service
Cluster: ecspresso-demo
TaskDefinition: first-run-task-definition:12
TaskSets:
   PRIMARY first-run-task-definition:12 desired:1 pending:0 running:1

CodeDeploy Specific Considerations

Blue/Green Deployment Constraints

Compared to rolling updates, Blue/Green deployment via CodeDeploy has several constraints. Please refer to the documentation.
https://docs.aws.amazon.com/AmazonECS/latest/userguide/deployment-type-bluegreen.html#deployment-type-bluegreen-considerations

Deploy Option --suspend-autoscaling

Services configured with Blue/Green deployment cannot perform deployments while auto-scaling is active.

By specifying ecspresso deploy --suspend-autoscaling, you can temporarily stop Application Auto Scaling before deployment.

However, as of v1.2.1, ecspresso cannot perform the resume operation for auto-scaling.

Deploy Option --rollback-events

You can register event names to automatically perform a rollback if a deployment fails.
https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_AutoRollbackConfiguration.html

Specify values like DEPLOYMENT_FAILURE, DEPLOYMENT_STOP_ON_ALARM, or DEPLOYMENT_STOP_ON_REQUEST. To specify multiple values, concatenate them with a comma (,).

Waiting for Deployment Completion

In the case of a CodeDeploy deployment, ecspresso deploy terminates once the CodeDeploy deployment has started, without waiting for its completion.

By using the ecspresso wait command separately, you can wait until the currently ongoing CodeDeploy deployment is complete.

Rolling Back Services Using CodeDeploy

If a service is using CodeDeploy, you cannot perform a rollback using ecspresso rollback. Please perform the rollback using CodeDeploy's features.

Adding Hooks

In CodeDeploy, you can invoke Lambda functions at various phases of the deployment operation.
https://docs.aws.amazon.com/codedeploy/latest/userguide/tutorial-ecs-with-hooks-create-hooks.html

To configure hooks in ecspresso, define the appspec.Hooks element in your configuration file.

cluster: default
service: test
service_definition: ecs-service-def.json
task_definition: ecs-task-def.json
appspec:
  Hooks:
    - BeforeInstall: "LambdaFunctionToValidateBeforeInstall"
    - AfterInstall: "LambdaFunctionToValidateAfterTraffic"
    - AfterAllowTestTraffic: "LambdaFunctionToValidateAfterTestTrafficStarts"
    - BeforeAllowTraffic: "LambdaFunctionToValidateBeforeAllowingProductionTraffic"
    - AfterAllowTraffic: "LambdaFunctionToValidateAfterAllowingProductionTraffic"

On Day 18, I will explain the feature for generating CodeDeploy AppSpec files.

https://zenn.dev/fujiwara/articles/ecspresso-20201218

Discussion