|  | 
| 11 | 11 | 
 | 
| 12 | 12 | <!--END STABILITY BANNER--> | 
| 13 | 13 | 
 | 
|  | 14 | +## Table of Contents | 
|  | 15 | + | 
|  | 16 | +- [Introduction](#introduction) | 
|  | 17 | +- Deploying to Amazon EC2 and on-premise instances | 
|  | 18 | +  - [EC2/on-premise Applications](#ec2on-premise-applications) | 
|  | 19 | +  - [EC2/on-premise Deployment Groups](#ec2on-premise-deployment-groups) | 
|  | 20 | +  - [EC2/on-premise Deployment Configurations](#ec2on-premise-deployment-configurations) | 
|  | 21 | +- Deploying to AWS Lambda functions | 
|  | 22 | +  - [Lambda Applications](#lambda-applications) | 
|  | 23 | +  - [Lambda Deployment Groups](#lambda-deployment-groups) | 
|  | 24 | +  - [Lambda Deployment Configurations](#lambda-deployment-configurations) | 
|  | 25 | +- Deploying to Amazon ECS services | 
|  | 26 | +  - [ECS Applications](#ecs-applications) | 
|  | 27 | +  - [ECS Deployment Groups](#ecs-deployment-groups) | 
|  | 28 | +  - [ECS Deployment Configurations](#ecs-deployment-configurations) | 
|  | 29 | + | 
|  | 30 | +## Introduction | 
|  | 31 | + | 
| 14 | 32 | AWS CodeDeploy is a deployment service that automates application deployments to | 
| 15 | 33 | Amazon EC2 instances, on-premises instances, serverless Lambda functions, or | 
| 16 | 34 | Amazon ECS services. | 
| @@ -98,7 +116,7 @@ To import an already existing Deployment Group: | 
| 98 | 116 | ```ts | 
| 99 | 117 | declare const application: codedeploy.ServerApplication; | 
| 100 | 118 | const deploymentGroup = codedeploy.ServerDeploymentGroup.fromServerDeploymentGroupAttributes( | 
| 101 |  | -  this,  | 
|  | 119 | +  this, | 
| 102 | 120 |   'ExistingCodeDeployDeploymentGroup', { | 
| 103 | 121 |     application, | 
| 104 | 122 |     deploymentGroupName: 'MyExistingDeploymentGroup', | 
| @@ -226,7 +244,7 @@ In order to deploy a new version of this function: | 
| 226 | 244 | 2. Re-deploy the stack (this will trigger a deployment). | 
| 227 | 245 | 3. Monitor the CodeDeploy deployment as traffic shifts between the versions. | 
| 228 | 246 | 
 | 
| 229 |  | -### Rollbacks and Alarms | 
|  | 247 | +### Lambda Deployment Rollbacks and Alarms | 
| 230 | 248 | 
 | 
| 231 | 249 | CodeDeploy will roll back if the deployment fails. You can optionally trigger a rollback when one or more alarms are in a failed state: | 
| 232 | 250 | 
 | 
| @@ -281,7 +299,7 @@ const deploymentGroup = new codedeploy.LambdaDeploymentGroup(this, 'BlueGreenDep | 
| 281 | 299 | deploymentGroup.addPostHook(endToEndValidation); | 
| 282 | 300 | ``` | 
| 283 | 301 | 
 | 
| 284 |  | -### Import an existing Deployment Group | 
|  | 302 | +### Import an existing Lambda Deployment Group | 
| 285 | 303 | 
 | 
| 286 | 304 | To import an already existing Deployment Group: | 
| 287 | 305 | 
 | 
| @@ -373,6 +391,235 @@ const application = codedeploy.EcsApplication.fromEcsApplicationName( | 
| 373 | 391 | ); | 
| 374 | 392 | ``` | 
| 375 | 393 | 
 | 
|  | 394 | +## ECS Deployment Groups | 
|  | 395 | + | 
|  | 396 | +CodeDeploy can be used to deploy to load-balanced ECS services. | 
|  | 397 | +CodeDeploy performs ECS blue-green deployments by managing ECS task sets and load balancer | 
|  | 398 | +target groups.  During a blue-green deployment, one task set and target group runs the | 
|  | 399 | +original version of your ECS task definition ('blue') and another task set and target group | 
|  | 400 | +runs the new version of your ECS task definition ('green'). | 
|  | 401 | + | 
|  | 402 | +CodeDeploy orchestrates traffic shifting during ECS blue-green deployments by using | 
|  | 403 | +a load balancer listener to balance incoming traffic between the 'blue' and 'green' task sets/target groups | 
|  | 404 | +running two different versions of your ECS task definition. | 
|  | 405 | +Before deployment, the load balancer listener sends 100% of requests to the 'blue' target group. | 
|  | 406 | +When you publish a new version of the task definition and start a CodeDeploy deployment, | 
|  | 407 | +CodeDeploy can send a small percentage of traffic to the new 'green' task set behind the 'green' target group, | 
|  | 408 | +monitor, and validate before shifting 100% of traffic to the new version. | 
|  | 409 | + | 
|  | 410 | +To create a new CodeDeploy Deployment Group that deploys to an ECS service: | 
|  | 411 | + | 
|  | 412 | +```ts | 
|  | 413 | +declare const myApplication: codedeploy.EcsApplication; | 
|  | 414 | +declare const cluster: ecs.Cluster; | 
|  | 415 | +declare const taskDefinition: ecs.FargateTaskDefinition; | 
|  | 416 | +declare const blueTargetGroup: elbv2.ITargetGroup; | 
|  | 417 | +declare const greenTargetGroup: elbv2.ITargetGroup; | 
|  | 418 | +declare const listener: elbv2.IApplicationListener; | 
|  | 419 | + | 
|  | 420 | +const service = new ecs.FargateService(this, 'Service', { | 
|  | 421 | +  cluster, | 
|  | 422 | +  taskDefinition, | 
|  | 423 | +  deploymentController: { | 
|  | 424 | +    type: ecs.DeploymentControllerType.CODE_DEPLOY, | 
|  | 425 | +  }, | 
|  | 426 | +}); | 
|  | 427 | + | 
|  | 428 | +new codedeploy.EcsDeploymentGroup(stack, 'BlueGreenDG', { | 
|  | 429 | +  service, | 
|  | 430 | +  blueGreenDeploymentConfig: { | 
|  | 431 | +    blueTargetGroup, | 
|  | 432 | +    greenTargetGroup, | 
|  | 433 | +    listener, | 
|  | 434 | +  }, | 
|  | 435 | +  deploymentConfig: codedeploy.EcsDeploymentConfig.CANARY_10PERCENT_5MINUTES, | 
|  | 436 | +}); | 
|  | 437 | +``` | 
|  | 438 | + | 
|  | 439 | +In order to deploy a new task definition version to the ECS service, | 
|  | 440 | +deploy the changes directly through CodeDeploy using the CodeDeploy APIs or console. | 
|  | 441 | +When the `CODE_DEPLOY` deployment controller is used, the ECS service cannot be | 
|  | 442 | +deployed with a new task definition version through CloudFormation. | 
|  | 443 | + | 
|  | 444 | +For more information on the behavior of CodeDeploy blue-green deployments for ECS, see | 
|  | 445 | +[What happens during an Amazon ECS deployment](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-steps-ecs.html#deployment-steps-what-happens) | 
|  | 446 | +in the CodeDeploy user guide. | 
|  | 447 | + | 
|  | 448 | +Note: If you wish to deploy updates to your ECS service through CDK and CloudFormation instead of directly through CodeDeploy, | 
|  | 449 | +using the [`CfnCodeDeployBlueGreenHook`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnCodeDeployBlueGreenHook.html) | 
|  | 450 | +construct is the recommended approach instead of using the `EcsDeploymentGroup` construct.  For a comparison | 
|  | 451 | +of ECS blue-green deployments through CodeDeploy (using `EcsDeploymentGroup`) and through CloudFormation (using `CfnCodeDeployBlueGreenHook`), | 
|  | 452 | +see [Create an Amazon ECS blue/green deployment through AWS CloudFormation](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-create-ecs-cfn.html#differences-ecs-bg-cfn) | 
|  | 453 | +in the CloudFormation user guide. | 
|  | 454 | + | 
|  | 455 | +### ECS Deployment Rollbacks and Alarms | 
|  | 456 | + | 
|  | 457 | +CodeDeploy will automatically roll back if a deployment fails. | 
|  | 458 | +You can optionally trigger an automatic rollback when one or more alarms are in a failed state during a deployment, or if the deployment stops. | 
|  | 459 | + | 
|  | 460 | +In this example, CodeDeploy will monitor and roll back on alarms set for the | 
|  | 461 | +number of unhealthy ECS tasks in each of the blue and green target groups, | 
|  | 462 | +as well as alarms set for the number HTTP 5xx responses seen in each of the blue | 
|  | 463 | +and green target groups. | 
|  | 464 | + | 
|  | 465 | +```ts | 
|  | 466 | +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; | 
|  | 467 | + | 
|  | 468 | +// Alarm on the number of unhealthy ECS tasks in each target group | 
|  | 469 | +const blueUnhealthyHosts = new cloudwatch.Alarm(stack, 'BlueUnhealthyHosts', { | 
|  | 470 | +  alarmName: stack.stackName + '-Unhealthy-Hosts-Blue', | 
|  | 471 | +  metric: blueTargetGroup.metricUnhealthyHostCount(), | 
|  | 472 | +  threshold: 1, | 
|  | 473 | +  evaluationPeriods: 2, | 
|  | 474 | +}); | 
|  | 475 | + | 
|  | 476 | +const greenUnhealthyHosts = new cloudwatch.Alarm(stack, 'GreenUnhealthyHosts', { | 
|  | 477 | +  alarmName: stack.stackName + '-Unhealthy-Hosts-Green', | 
|  | 478 | +  metric: greenTargetGroup.metricUnhealthyHostCount(), | 
|  | 479 | +  threshold: 1, | 
|  | 480 | +  evaluationPeriods: 2, | 
|  | 481 | +}); | 
|  | 482 | + | 
|  | 483 | +// Alarm on the number of HTTP 5xx responses returned by each target group | 
|  | 484 | +const blueApiFailure = new cloudwatch.Alarm(stack, 'Blue5xx', { | 
|  | 485 | +  alarmName: stack.stackName + '-Http-5xx-Blue', | 
|  | 486 | +  metric: blueTargetGroup.metricHttpCodeTarget( | 
|  | 487 | +    elbv2.HttpCodeTarget.TARGET_5XX_COUNT, | 
|  | 488 | +    { period: cdk.Duration.minutes(1) }, | 
|  | 489 | +  ), | 
|  | 490 | +  threshold: 1, | 
|  | 491 | +  evaluationPeriods: 1, | 
|  | 492 | +}); | 
|  | 493 | + | 
|  | 494 | +const greenApiFailure = new cloudwatch.Alarm(stack, 'Green5xx', { | 
|  | 495 | +  alarmName: stack.stackName + '-Http-5xx-Green', | 
|  | 496 | +  metric: greenTargetGroup.metricHttpCodeTarget( | 
|  | 497 | +    elbv2.HttpCodeTarget.TARGET_5XX_COUNT, | 
|  | 498 | +    { period: cdk.Duration.minutes(1) }, | 
|  | 499 | +  ), | 
|  | 500 | +  threshold: 1, | 
|  | 501 | +  evaluationPeriods: 1, | 
|  | 502 | +}); | 
|  | 503 | + | 
|  | 504 | +new codedeploy.EcsDeploymentGroup(stack, 'BlueGreenDG', { | 
|  | 505 | +  // CodeDeploy will monitor these alarms during a deployment and automatically roll back | 
|  | 506 | +  alarms: [blueUnhealthyHosts, greenUnhealthyHosts, blueApiFailure, greenApiFailure], | 
|  | 507 | +  autoRollback: { | 
|  | 508 | +    // CodeDeploy will automatically roll back if a deployment is stopped | 
|  | 509 | +    stoppedDeployment: true, | 
|  | 510 | +  }, | 
|  | 511 | +  service, | 
|  | 512 | +  blueGreenDeploymentConfig: { | 
|  | 513 | +    blueTargetGroup, | 
|  | 514 | +    greenTargetGroup, | 
|  | 515 | +    listener, | 
|  | 516 | +  }, | 
|  | 517 | +  deploymentConfig: codedeploy.EcsDeploymentConfig.CANARY_10PERCENT_5MINUTES, | 
|  | 518 | +}); | 
|  | 519 | +``` | 
|  | 520 | + | 
|  | 521 | +### Deployment validation and manual deployment approval | 
|  | 522 | + | 
|  | 523 | +CodeDeploy blue-green deployments provide an opportunity to validate the new task definition version running on | 
|  | 524 | +the 'green' ECS task set prior to shifting any production traffic to the new version.  A second 'test' listener | 
|  | 525 | +serving traffic on a different port be added to the load balancer. For example, the test listener can serve | 
|  | 526 | +test traffic on port 9001 while the main listener serves production traffic on port 443. | 
|  | 527 | +During a blue-green deployment, CodeDeploy can then shift 100% of test traffic over to the 'green' | 
|  | 528 | +task set/target group prior to shifting any production traffic during the deployment. | 
|  | 529 | + | 
|  | 530 | +```ts | 
|  | 531 | +declare const myApplication: codedeploy.EcsApplication; | 
|  | 532 | +declare const service: ecs.FargateService; | 
|  | 533 | +declare const blueTargetGroup: elbv2.ITargetGroup; | 
|  | 534 | +declare const greenTargetGroup: elbv2.ITargetGroup; | 
|  | 535 | +declare const listener: elbv2.IApplicationListener; | 
|  | 536 | +declare const testListener: elbv2.IApplicationListener; | 
|  | 537 | + | 
|  | 538 | +new codedeploy.EcsDeploymentGroup(stack, 'BlueGreenDG', { | 
|  | 539 | +  service, | 
|  | 540 | +  blueGreenDeploymentConfig: { | 
|  | 541 | +    blueTargetGroup, | 
|  | 542 | +    greenTargetGroup, | 
|  | 543 | +    listener, | 
|  | 544 | +    testListener, | 
|  | 545 | +  }, | 
|  | 546 | +  deploymentConfig: codedeploy.EcsDeploymentConfig.CANARY_10PERCENT_5MINUTES, | 
|  | 547 | +}); | 
|  | 548 | +``` | 
|  | 549 | + | 
|  | 550 | +Automated validation steps can run during the CodeDeploy deployment after shifting test traffic and before | 
|  | 551 | +shifting production traffic.  CodeDeploy supports registering Lambda functions as lifecycle hooks for | 
|  | 552 | +an ECS deployment.  These Lambda functions can run automated validation steps against the test traffic | 
|  | 553 | +port, for example in response to the `AfterAllowTestTraffic` lifecycle hook.  For more information about | 
|  | 554 | +how to specify the Lambda functions to run for each CodeDeploy lifecycle hook in an ECS deployment, see the | 
|  | 555 | +[AppSpec 'hooks' for an Amazon ECS deployment](https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-ecs) | 
|  | 556 | +section in the CodeDeploy user guide. | 
|  | 557 | + | 
|  | 558 | +After provisioning the 'green' ECS task set and re-routing test traffic during a blue-green deployment, | 
|  | 559 | +CodeDeploy can wait for approval before continuing the deployment and re-routing production traffic. | 
|  | 560 | +During this approval wait time, you can complete additional validation steps prior to exposing the new | 
|  | 561 | +'green' task set to production traffic, such as manual testing through the test listener port or | 
|  | 562 | +running automated integration test suites. | 
|  | 563 | + | 
|  | 564 | +To approve the deployment, validation steps use the CodeDeploy | 
|  | 565 | +[ContinueDeployment API(https://docs.aws.amazon.com/codedeploy/latest/APIReference/API_ContinueDeployment.html). | 
|  | 566 | +If the ContinueDeployment API is not called within the approval wait time period, CodeDeploy will stop the | 
|  | 567 | +deployment and can automatically roll back the deployment. | 
|  | 568 | + | 
|  | 569 | +```ts | 
|  | 570 | +new codedeploy.EcsDeploymentGroup(stack, 'BlueGreenDG', { | 
|  | 571 | +  // The deployment will wait for approval for up to 8 hours before stopping the deployment | 
|  | 572 | +  deploymentApprovalWaitTime: Duration.hours(8), | 
|  | 573 | +  autoRollback: { | 
|  | 574 | +    // CodeDeploy will automatically roll back if the 8-hour approval period times out and the deployment stops | 
|  | 575 | +    stoppedDeployment: true, | 
|  | 576 | +  }, | 
|  | 577 | +  service, | 
|  | 578 | +  blueGreenDeploymentConfig: { | 
|  | 579 | +    blueTargetGroup, | 
|  | 580 | +    greenTargetGroup, | 
|  | 581 | +    listener, | 
|  | 582 | +    testListener, | 
|  | 583 | +  }, | 
|  | 584 | +  deploymentConfig: codedeploy.EcsDeploymentConfig.CANARY_10PERCENT_5MINUTES, | 
|  | 585 | +}); | 
|  | 586 | +``` | 
|  | 587 | + | 
|  | 588 | +### Deployment bake time | 
|  | 589 | + | 
|  | 590 | +You can specify how long CodeDeploy waits before it terminates the original 'blue' ECS task set when a blue-green deployment | 
|  | 591 | +is complete in order to let the deployment "bake" a while. During this bake time, CodeDeploy will continue to monitor any | 
|  | 592 | +CloudWatch alarms specified for the deployment group and will automatically roll back if those alarms go into a failed state. | 
|  | 593 | + | 
|  | 594 | +```ts | 
|  | 595 | +new codedeploy.EcsDeploymentGroup(stack, 'BlueGreenDG', { | 
|  | 596 | +  service, | 
|  | 597 | +  blueGreenDeploymentConfig: { | 
|  | 598 | +    blueTargetGroup, | 
|  | 599 | +    greenTargetGroup, | 
|  | 600 | +    listener, | 
|  | 601 | +    // CodeDeploy will wait for 30 minutes after completing the blue-green deployment before it terminates the blue tasks | 
|  | 602 | +    terminationWaitTime: Duration.minutes(30), | 
|  | 603 | +  }, | 
|  | 604 | +  // CodeDeploy will continue to monitor these alarms during the 30-minute bake time and will automatically | 
|  | 605 | +  // roll back if they go into a failed state at any point during the deployment. | 
|  | 606 | +  alarms: [blueUnhealthyHosts, greenUnhealthyHosts, blueApiFailure, greenApiFailure], | 
|  | 607 | +  deploymentConfig: codedeploy.EcsDeploymentConfig.CANARY_10PERCENT_5MINUTES, | 
|  | 608 | +}); | 
|  | 609 | +``` | 
|  | 610 | + | 
|  | 611 | +### Import an existing ECS Deployment Group | 
|  | 612 | + | 
|  | 613 | +To import an already existing Deployment Group: | 
|  | 614 | + | 
|  | 615 | +```ts | 
|  | 616 | +declare const application: codedeploy.EcsApplication; | 
|  | 617 | +const deploymentGroup = codedeploy.EcsDeploymentGroup.fromEcsDeploymentGroupAttributes(this, 'ExistingCodeDeployDeploymentGroup', { | 
|  | 618 | +  application, | 
|  | 619 | +  deploymentGroupName: 'MyExistingDeploymentGroup', | 
|  | 620 | +}); | 
|  | 621 | +``` | 
|  | 622 | + | 
| 376 | 623 | ## ECS Deployment Configurations | 
| 377 | 624 | 
 | 
| 378 | 625 | CodeDeploy for ECS comes with predefined configurations for traffic shifting. | 
|  | 
0 commit comments