[![cloudcomponents Logo](https://raw.githubusercontent.com/cloudcomponents/cdk-constructs/master/logo.png)](https://github.com/cloudcomponents/cdk-constructs)
# @cloudcomponents/cdk-blue-green-container-deployment
[![Build Status](https://github.com/cloudcomponents/cdk-constructs/workflows/Build/badge.svg)](https://github.com/cloudcomponents/cdk-constructs/actions?query=workflow=Build)
[![cdkdx](https://img.shields.io/badge/buildtool-cdkdx-blue.svg)](https://github.com/hupe1980/cdkdx)
[![typescript](https://img.shields.io/badge/jsii-typescript-blueviolet.svg)](https://www.npmjs.com/package/@cloudcomponents/cdk-blue-green-container-deployment)
[![python](https://img.shields.io/badge/jsii-python-blueviolet.svg)](https://pypi.org/project/cloudcomponents.cdk-blue-green-container-deployment/)
[![Mentioned in Awesome CDK](https://awesome.re/mentioned-badge.svg)](https://github.com/kolomied/awesome-cdk)
> Blue green container deployment with CodeDeploy
## Install
TypeScript/JavaScript:
```bash
npm i @cloudcomponents/cdk-blue-green-container-deployment
```
Python:
```bash
pip install cloudcomponents.cdk-blue-green-container-deployment
```
## How to use
```python
import { EcsService, DummyTaskDefinition, EcsDeploymentGroup, PushImageProject } from '@cloudcomponents/cdk-blue-green-container-deployment';
import { ImageRepository } from '@cloudcomponents/cdk-container-registry';
import { Duration, Stack, StackProps } from 'aws-cdk-lib';
import { Repository } from 'aws-cdk-lib/aws-codecommit';
import { Pipeline, Artifact } from 'aws-cdk-lib/aws-codepipeline';
import { CodeBuildAction, CodeCommitSourceAction, CodeDeployEcsDeployAction } from 'aws-cdk-lib/aws-codepipeline-actions';
import { Vpc, Port } from 'aws-cdk-lib/aws-ec2';
import { Cluster } from 'aws-cdk-lib/aws-ecs';
import { ApplicationLoadBalancer, ApplicationTargetGroup, TargetType } from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import { Construct } from 'constructs';
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,
testTargetGroup,
});
ecsService.connections.allowFrom(loadBalancer, Port.tcp(80));
ecsService.connections.allowFrom(loadBalancer, Port.tcp(8080));
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),
});
// @see files: ./blue-green-repository for example content
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](https://github.com/cloudcomponents/cdk-constructs/tree/master/packages/cdk-blue-green-container-deployment/API.md).
## Example
See more complete [examples](https://github.com/cloudcomponents/cdk-constructs/tree/master/examples).
## License
[MIT](https://github.com/cloudcomponents/cdk-constructs/tree/master/packages/cdk-blue-green-container-deployment//LICENSE)
Raw data
{
"_id": null,
"home_page": "https://github.com/cloudcomponents/cdk-constructs",
"name": "cloudcomponents.cdk-blue-green-container-deployment",
"maintainer": null,
"docs_url": null,
"requires_python": "~=3.8",
"maintainer_email": null,
"keywords": null,
"author": "hupe1980",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/ee/3c/fc1b5fb68556c15d579196db58cbb6e21090df798e7f4896c29134add484/cloudcomponents.cdk-blue-green-container-deployment-2.3.0.tar.gz",
"platform": null,
"description": "[![cloudcomponents Logo](https://raw.githubusercontent.com/cloudcomponents/cdk-constructs/master/logo.png)](https://github.com/cloudcomponents/cdk-constructs)\n\n# @cloudcomponents/cdk-blue-green-container-deployment\n\n[![Build Status](https://github.com/cloudcomponents/cdk-constructs/workflows/Build/badge.svg)](https://github.com/cloudcomponents/cdk-constructs/actions?query=workflow=Build)\n[![cdkdx](https://img.shields.io/badge/buildtool-cdkdx-blue.svg)](https://github.com/hupe1980/cdkdx)\n[![typescript](https://img.shields.io/badge/jsii-typescript-blueviolet.svg)](https://www.npmjs.com/package/@cloudcomponents/cdk-blue-green-container-deployment)\n[![python](https://img.shields.io/badge/jsii-python-blueviolet.svg)](https://pypi.org/project/cloudcomponents.cdk-blue-green-container-deployment/)\n[![Mentioned in Awesome CDK](https://awesome.re/mentioned-badge.svg)](https://github.com/kolomied/awesome-cdk)\n\n> Blue green container deployment with CodeDeploy\n\n## Install\n\nTypeScript/JavaScript:\n\n```bash\nnpm i @cloudcomponents/cdk-blue-green-container-deployment\n```\n\nPython:\n\n```bash\npip install cloudcomponents.cdk-blue-green-container-deployment\n```\n\n## How to use\n\n```python\nimport { EcsService, DummyTaskDefinition, EcsDeploymentGroup, PushImageProject } from '@cloudcomponents/cdk-blue-green-container-deployment';\nimport { ImageRepository } from '@cloudcomponents/cdk-container-registry';\nimport { Duration, Stack, StackProps } from 'aws-cdk-lib';\nimport { Repository } from 'aws-cdk-lib/aws-codecommit';\nimport { Pipeline, Artifact } from 'aws-cdk-lib/aws-codepipeline';\nimport { CodeBuildAction, CodeCommitSourceAction, CodeDeployEcsDeployAction } from 'aws-cdk-lib/aws-codepipeline-actions';\nimport { Vpc, Port } from 'aws-cdk-lib/aws-ec2';\nimport { Cluster } from 'aws-cdk-lib/aws-ecs';\nimport { ApplicationLoadBalancer, ApplicationTargetGroup, TargetType } from 'aws-cdk-lib/aws-elasticloadbalancingv2';\nimport { Construct } from 'constructs';\n\nexport class BlueGreenContainerDeploymentStack extends Stack {\n constructor(scope: Construct, id: string, props?: StackProps) {\n super(scope, id, props);\n\n const vpc = new Vpc(this, 'Vpc', {\n maxAzs: 2,\n });\n\n const cluster = new Cluster(this, 'Cluster', {\n vpc,\n clusterName: 'blue-green-cluster',\n });\n\n const loadBalancer = new ApplicationLoadBalancer(this, 'LoadBalancer', {\n vpc,\n internetFacing: true,\n });\n\n const prodListener = loadBalancer.addListener('ProfListener', {\n port: 80,\n });\n\n const testListener = loadBalancer.addListener('TestListener', {\n port: 8080,\n });\n\n const prodTargetGroup = new ApplicationTargetGroup(this, 'ProdTargetGroup', {\n port: 80,\n targetType: TargetType.IP,\n vpc,\n });\n\n prodListener.addTargetGroups('AddProdTg', {\n targetGroups: [prodTargetGroup],\n });\n\n const testTargetGroup = new ApplicationTargetGroup(this, 'TestTargetGroup', {\n port: 8080,\n targetType: TargetType.IP,\n vpc,\n });\n\n testListener.addTargetGroups('AddTestTg', {\n targetGroups: [testTargetGroup],\n });\n\n // Will be replaced by CodeDeploy in CodePipeline\n const taskDefinition = new DummyTaskDefinition(this, 'DummyTaskDefinition', {\n image: 'nginx',\n family: 'blue-green',\n });\n\n const ecsService = new EcsService(this, 'EcsService', {\n cluster,\n serviceName: 'blue-green-service',\n desiredCount: 2,\n taskDefinition,\n prodTargetGroup,\n testTargetGroup,\n });\n\n ecsService.connections.allowFrom(loadBalancer, Port.tcp(80));\n ecsService.connections.allowFrom(loadBalancer, Port.tcp(8080));\n\n const deploymentGroup = new EcsDeploymentGroup(this, 'DeploymentGroup', {\n applicationName: 'blue-green-application',\n deploymentGroupName: 'blue-green-deployment-group',\n ecsServices: [ecsService],\n targetGroups: [prodTargetGroup, testTargetGroup],\n prodTrafficListener: prodListener,\n testTrafficListener: testListener,\n terminationWaitTime: Duration.minutes(100),\n });\n\n // @see files: ./blue-green-repository for example content\n const repository = new Repository(this, 'CodeRepository', {\n repositoryName: 'blue-green-repository',\n });\n\n const imageRepository = new ImageRepository(this, 'ImageRepository', {\n forceDelete: true, //Only for tests\n });\n\n const sourceArtifact = new Artifact();\n\n const sourceAction = new CodeCommitSourceAction({\n actionName: 'CodeCommit',\n repository,\n output: sourceArtifact,\n });\n\n const imageArtifact = new Artifact('ImageArtifact');\n const manifestArtifact = new Artifact('ManifestArtifact');\n\n const pushImageProject = new PushImageProject(this, 'PushImageProject', {\n imageRepository,\n taskDefinition,\n });\n\n const buildAction = new CodeBuildAction({\n actionName: 'PushImage',\n project: pushImageProject,\n input: sourceArtifact,\n outputs: [imageArtifact, manifestArtifact],\n });\n\n const deployAction = new CodeDeployEcsDeployAction({\n actionName: 'CodeDeploy',\n taskDefinitionTemplateInput: manifestArtifact,\n appSpecTemplateInput: manifestArtifact,\n containerImageInputs: [\n {\n input: imageArtifact,\n taskDefinitionPlaceholder: 'IMAGE1_NAME',\n },\n ],\n deploymentGroup,\n });\n\n new Pipeline(this, 'Pipeline', {\n pipelineName: 'blue-green-pipeline',\n stages: [\n {\n stageName: 'Source',\n actions: [sourceAction],\n },\n {\n stageName: 'Build',\n actions: [buildAction],\n },\n {\n stageName: 'Deploy',\n actions: [deployAction],\n },\n ],\n });\n }\n}\n```\n\n## API Reference\n\nSee [API.md](https://github.com/cloudcomponents/cdk-constructs/tree/master/packages/cdk-blue-green-container-deployment/API.md).\n\n## Example\n\nSee more complete [examples](https://github.com/cloudcomponents/cdk-constructs/tree/master/examples).\n\n## License\n\n[MIT](https://github.com/cloudcomponents/cdk-constructs/tree/master/packages/cdk-blue-green-container-deployment//LICENSE)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Blue green container deployment with CodeDeploy",
"version": "2.3.0",
"project_urls": {
"Homepage": "https://github.com/cloudcomponents/cdk-constructs",
"Source": "https://github.com/cloudcomponents/cdk-constructs.git"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "acfe4180f53fc78749041478c1cb588cb672d5220f5edf82501cd1e777bfe4f8",
"md5": "b33d98f19dad5e53227ee9f3a04143b5",
"sha256": "02520e3aec8f26981b290f96ac8af00e30b7f8f11e8bbdfaaad88f5a68a084bc"
},
"downloads": -1,
"filename": "cloudcomponents.cdk_blue_green_container_deployment-2.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b33d98f19dad5e53227ee9f3a04143b5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "~=3.8",
"size": 3193384,
"upload_time": "2024-04-17T18:35:59",
"upload_time_iso_8601": "2024-04-17T18:35:59.574063Z",
"url": "https://files.pythonhosted.org/packages/ac/fe/4180f53fc78749041478c1cb588cb672d5220f5edf82501cd1e777bfe4f8/cloudcomponents.cdk_blue_green_container_deployment-2.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ee3cfc1b5fb68556c15d579196db58cbb6e21090df798e7f4896c29134add484",
"md5": "c4249c39a0c7a53d564ff85a782fb90b",
"sha256": "8873c314d775b63b88d7e347e5cc5d362f5ec4e63c1b13f3c321b542c65a1999"
},
"downloads": -1,
"filename": "cloudcomponents.cdk-blue-green-container-deployment-2.3.0.tar.gz",
"has_sig": false,
"md5_digest": "c4249c39a0c7a53d564ff85a782fb90b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "~=3.8",
"size": 3194857,
"upload_time": "2024-04-17T18:36:08",
"upload_time_iso_8601": "2024-04-17T18:36:08.448635Z",
"url": "https://files.pythonhosted.org/packages/ee/3c/fc1b5fb68556c15d579196db58cbb6e21090df798e7f4896c29134add484/cloudcomponents.cdk-blue-green-container-deployment-2.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-17 18:36:08",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "cloudcomponents",
"github_project": "cdk-constructs",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "cloudcomponents.cdk-blue-green-container-deployment"
}