Skip to main content

Blue green container deployment with CodeDeploy

Project description

cloudcomponents Logo

@cloudcomponents/cdk-blue-green-container-deployment

Build Status cdkdx typescript python Mentioned in Awesome CDK

Blue green container deployment with CodeDeploy

Install

TypeScript/JavaScript:

npm i @cloudcomponents/cdk-blue-green-container-deployment

Python:

pip install cloudcomponents.cdk-blue-green-container-deployment

How to use

# Example automatically generated from non-compiling source. May contain errors.
import { Construct, Duration, Stack, StackProps } from '@aws-cdk/core';
import { Repository } from '@aws-cdk/aws-codecommit';
import { Pipeline, Artifact } from '@aws-cdk/aws-codepipeline';
import { Vpc, Port } from '@aws-cdk/aws-ec2';
import { Cluster } from '@aws-cdk/aws-ecs';
import {
  ApplicationLoadBalancer,
  ApplicationTargetGroup,
  TargetType,
} from '@aws-cdk/aws-elasticloadbalancingv2';
import {
  CodeBuildAction,
  CodeCommitSourceAction,
  CodeDeployEcsDeployAction,
} from '@aws-cdk/aws-codepipeline-actions';

import { ImageRepository } from '@cloudcomponents/cdk-container-registry';
import {
  EcsService,
  DummyTaskDefinition,
  EcsDeploymentConfig,
  EcsDeploymentGroup,
  PushImageProject,
} from '@cloudcomponents/cdk-blue-green-container-deployment';

export class BlueGreenContainerDeploymentStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const vpc = new Vpc(this, 'Vpc', {
      maxAzs: 2,
    });

    const cluster = new Cluster(this, 'Cluster', {
      vpc,
      clusterName: 'blue-green-cluster',
    });

    const loadBalancer = new ApplicationLoadBalancer(this, 'LoadBalancer', {
      vpc,
      internetFacing: true,
    });

    const prodListener = loadBalancer.addListener('ProdListener', {
      port: 80,
    });

    const testListener = loadBalancer.addListener('TestListener', {
      port: 8080,
    });

    const prodTargetGroup = new ApplicationTargetGroup(
      this,
      'ProdTargetGroup',
      {
        port: 80,
        targetType: TargetType.IP,
        vpc,
      },
    );

    prodListener.addTargetGroups('AddProdTg', {
      targetGroups: [prodTargetGroup],
    });

    const testTargetGroup = new ApplicationTargetGroup(
      this,
      'TestTargetGroup',
      {
        port: 8080,
        targetType: TargetType.IP,
        vpc,
      },
    );

    testListener.addTargetGroups('AddTestTg', {
      targetGroups: [testTargetGroup],
    });

    // Will be replaced by CodeDeploy in CodePipeline
    const taskDefinition = new DummyTaskDefinition(
      this,
      'DummyTaskDefinition',
      {
        image: 'nginx',
        family: 'blue-green',
      },
    );

    const ecsService = new EcsService(this, 'EcsService', {
      cluster,
      serviceName: 'blue-green-service',
      desiredCount: 2,
      taskDefinition,
      prodTargetGroup,
      testTargetGroup,
    });

    ecsService.connections.allowFrom(loadBalancer, Port.tcp(80));
    ecsService.connections.allowFrom(loadBalancer, Port.tcp(8080));

    const deploymentConfig = new EcsDeploymentConfig(
      this,
      'DeploymentConfig',
      {
        deploymentConfigName: 'Canary20Percent5Minute',
        trafficRoutingConfig: {
          type: 'TimeBasedCanary',
          timeBasedCanary: {
            canaryInterval: 5,
            canaryPercentage: 20,
          },
        },
      }
    );

    const deploymentGroup = new EcsDeploymentGroup(this, 'DeploymentGroup', {
      applicationName: 'blue-green-application',
      deploymentGroupName: 'blue-green-deployment-group',
      ecsServices: [ecsService],
      targetGroups: [prodTargetGroup, testTargetGroup],
      prodTrafficListener: prodListener,
      testTrafficListener: testListener,
      terminationWaitTime: Duration.minutes(100),
      deploymentConfig, // If you want to use default DeploymentConfig name, use static method as "EcsDeploymentConfig.CANARY_10PERCENT_15MINUTES".
    });

    // @see https://github.com/cloudcomponents/cdk-constructs/tree/master/examples/blue-green-container-deployment-example/blue-green-repository
    const repository = new Repository(this, 'CodeRepository', {
      repositoryName: 'blue-green-repository',
    });

    const imageRepository = new ImageRepository(this, 'ImageRepository', {
      forceDelete: true, //Only for tests
    });

    const sourceArtifact = new Artifact();

    const sourceAction = new CodeCommitSourceAction({
      actionName: 'CodeCommit',
      repository,
      output: sourceArtifact,
    });

    const imageArtifact = new Artifact('ImageArtifact');
    const manifestArtifact = new Artifact('ManifestArtifact');

    const pushImageProject = new PushImageProject(this, 'PushImageProject', {
      imageRepository,
      taskDefinition,
    });

    const buildAction = new CodeBuildAction({
      actionName: 'PushImage',
      project: pushImageProject,
      input: sourceArtifact,
      outputs: [imageArtifact, manifestArtifact],
    });

    const deployAction = new CodeDeployEcsDeployAction({
      actionName: 'CodeDeploy',
      taskDefinitionTemplateInput: manifestArtifact,
      appSpecTemplateInput: manifestArtifact,
      containerImageInputs: [
        {
          input: imageArtifact,
          taskDefinitionPlaceholder: 'IMAGE1_NAME',
        },
      ],
      deploymentGroup,
    });

    new Pipeline(this, 'Pipeline', {
      pipelineName: 'blue-green-pipeline',
      stages: [
        {
          stageName: 'Source',
          actions: [sourceAction],
        },
        {
          stageName: 'Build',
          actions: [buildAction],
        },
        {
          stageName: 'Deploy',
          actions: [deployAction],
        },
      ],
    });
  }
}

API Reference

See API.md.

Example

See more complete examples.

License

MIT

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file cloudcomponents.cdk-blue-green-container-deployment-1.49.0.tar.gz.

File metadata

File hashes

Hashes for cloudcomponents.cdk-blue-green-container-deployment-1.49.0.tar.gz
Algorithm Hash digest
SHA256 2acd422d1730a279a21ba5682aad2d9139d67aebe11cf58b53970ea9c425892f
MD5 4cf88629aec40918270a7c830ab4afa1
BLAKE2b-256 7528f8bcf9793a8a5fc24d87f75bb0da5901512950ecd775b8323a0543212661

See more details on using hashes here.

File details

Details for the file cloudcomponents.cdk_blue_green_container_deployment-1.49.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cloudcomponents.cdk_blue_green_container_deployment-1.49.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3af8413957e7c8ae7add71d755bcfdda840cfa821e0f614611cbfc4507ee23a6
MD5 6861914ddd0c1bfee2916d8d294d45cf
BLAKE2b-256 089c1bfb6bba837444dd3fc72eaf3ca0ebafa7ad8f1eaa6a645594d664b8366e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page