Package Exports
- @cloudcomponents/cdk-blue-green-container-deployment
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@cloudcomponents/cdk-blue-green-container-deployment) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@cloudcomponents/cdk-blue-green-container-deployment
Blue green container deployment with CodeDeploy
Install
TypeScript/JavaScript:
npm i @cloudcomponents/cdk-blue-green-container-deploymentPython:
pip install cloudcomponents.cdk-blue-green-container-deploymentHow to use
import { Construct, 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('ProfListener', {
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,
});
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],
targetGroupNames: [
prodTargetGroup.targetGroupName,
testTargetGroup.targetGroupName,
],
prodTrafficListener: prodListener,
testTrafficListener: testListener,
terminationWaitTimeInMinutes: 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.
