Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

s3-deployment: blue/green #954

Open
eladb opened this issue Oct 17, 2018 · 15 comments
Open

s3-deployment: blue/green #954

eladb opened this issue Oct 17, 2018 · 15 comments
Labels
@aws-cdk/aws-s3-deployment effort/medium Medium work item – several days of effort feature/enhancement A new API to make things easier or more intuitive. A catch-all for general feature requests. feature-request A feature should be added or improved. p1

Comments

@eladb
Copy link
Contributor

eladb commented Oct 17, 2018

See #936 for context. There may be use cases where users would want to deploy each update to a new subfolder in the destination bucket to support "blue/green" deployments (old users can still access the old contents and new users are directed to the new content).

This can be achieved by allocating a unique ID during deployment and returning it as resource attribute so it can be used downstream (e.g. by CloudFront).

eladb pushed a commit that referenced this issue Oct 19, 2018
This new library allows deploying contents to S3 buckets as part of a CDK app from a .zip file in another bucket or from a local asset (directory or a .zip file).

This is how it's used:

    new BucketDeployment(this, 'DeployMe', {
      source: Source.asset('/local/directory'),
      destinationBucket: dest
    });

"source" can either be a local directory, a local zip file or another
bucket+key.

This library is backed by a custom CloudFormation resource which uses the
AWS CLI to invoke "aws s3 sync". 

By default, when the resource is deleted, the contents of the destination are deleted. The `RetainOnDelete` option can be used to disable this behavior.

Fixes #952.


Future plans:

- The current version will always use "--delete" which means destination files will be deleted if they don't exist on the source (will be addressed in #953).
- Another mode of operation that we plan to add is blue/green deployments (#954).

�
eladb pushed a commit that referenced this issue Oct 19, 2018
This new library allows deploying contents to S3 buckets as part of a CDK app from a .zip file in another bucket or from a local asset (directory or a .zip file).

This is how it's used:

    new BucketDeployment(this, 'DeployMe', {
      source: Source.asset('/local/directory'),
      destinationBucket: dest
    });

"source" can either be a local directory, a local zip file or another
bucket+key.

This library is backed by a custom CloudFormation resource which uses the
AWS CLI to invoke "aws s3 sync". 

By default, when the resource is deleted, the contents of the destination are deleted. The `RetainOnDelete` option can be used to disable this behavior.

Fixes #952.

Misc:
- Change travis CI environment to allow running python3 (as well as node.js).
- Add "!!!!!" markers when build/test fails so it will be easier to locate errors in build logs.

Future plans:

- The current version will always use "--delete" which means destination files will be deleted if they don't exist on the source (will be addressed in #953).
- Another mode of operation that we plan to add is blue/green deployments (#954).
eladb pushed a commit that referenced this issue Oct 19, 2018
### Highlights

 - __A new construct library for AWS Step Functions__
   ([docs](https://github.com/awslabs/aws-cdk/blob/master/packages/%40aws-cdk/aws-stepfunctions/README.md)).
   The library provides rich APIs for modeling state machines by exposing a
   programmatic interface for [Amazon State
   Language](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-amazon-states-language.html).
 - __A new construct library for Amazon S3 bucket deployments__
   ([docs](https://github.com/awslabs/aws-cdk/blob/master/packages/%40aws-cdk/aws-s3-deployment/README.md)).
   You can use now automatically populate an S3 Bucket from a .zip file or a
   local directory. This is a building block for end-to-end support for static
   websites in the AWS CDK.

### Bug Fixes

* **aws-apigateway:** make LambdaRestApi proxy by default ([#963](#963)) ([a5f5e2c](a5f5e2c)), closes [#959](#959)
* **aws-cdk:** Allow use of assumed roles behind a proxy ([#898](#898)) ([f2b1048](f2b1048))
* **aws-cdk:** Auto-delete stacks that failed creating before new attempt ([#917](#917)) ([2af8309](2af8309))
* **aws-cloudfront:** expose distributionId ([#938](#938)) ([f58d98c](f58d98c))
* **aws-dynamodb:** don't emit empty array properties ([#909](#909)) ([841975a](841975a))
* **docs:** use ..code to display file structure in "writing constructs" ([#935](#935)) ([b743362](b743362))

### Features

* **assets:** isZipArchive indicates if this is a zip asset ([#944](#944)) ([65190f9](65190f9))
* **aws-cdk:** deploy supports CloudFormation Role ([#940](#940)) ([393be6f](393be6f)), closes [#735](#735)
* **aws-cloudformation:** allow specifying custom resource type ([#943](#943)) ([9de3a84](9de3a84))
* **aws-cloudformation:** correctly handle the templateConfiguration property in the CreateUpdateStack Pipeline Action. ([#923](#923)) ([d251a46](d251a46))
* **aws-cloudfront:** add support for "webAclId" ([#969](#969)) ([3ec9d76](3ec9d76))
* **aws-codedeploy:** add auto rollback configuration to server Deployment Group. ([#925](#925)) ([7ee91cf](7ee91cf))
* **aws-codedeploy:** add instance tag filter support for server Deployment Groups. ([#824](#824)) ([e6e8c51](e6e8c51))
* **aws-codedeploy:** add support for setting CloudWatch alarms on a server Deployment Group. ([#926](#926)) ([27b26b1](27b26b1))
* add support for Step Functions ([#827](#827)) ([81b533c](81b533c))
* **aws-lambda:** add grantInvoke() method ([#962](#962)) ([1ee8135](1ee8135)), closes [#961](#961)
* **aws-lambda:** improvements to the code and runtime APIs ([#945](#945)) ([36f29b6](36f29b6)), closes [#902](#902) [#188](#188) [#947](#947) [#947](#947) [#664](#664)
* **aws-logs:** extractMetric() returns Metric object ([#939](#939)) ([5558fff](5558fff)), closes [#850](#850)
* **aws-s3:** initial support for website hosting ([#946](#946)) ([2d3661c](2d3661c))
* **aws-s3-deployment:** bucket deployments ([#971](#971)) ([84d6876](84d6876)), closes [#952](#952) [#953](#953) [#954](#954)
* **docs:** added link to CloudFormation concepts ([#934](#934)) ([666bbba](666bbba))

### BREAKING CHANGES

* **aws-apigateway:** specifying a path no longer works. If you used to
provide a '/', remove it. Otherwise, you will have to supply `proxy: false`
and construct more complex resource paths yourself.
* **aws-lambda:** The construct `lambda.InlineJavaScriptLambda` is no longer supported. Use `lambda.Code.inline` instead; `lambda.Runtime.NodeJS43Edge` runtime is removed. CloudFront docs [stipulate](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-lambda-function-configuration) that you should use node6.10 or node8.10. It is always possible to use any value by instantiating a `lambda.Runtime` object.
@eladb eladb mentioned this issue Oct 19, 2018
eladb pushed a commit that referenced this issue Oct 19, 2018
### Highlights

 - __A new construct library for AWS Step Functions__
   ([docs](https://github.com/awslabs/aws-cdk/blob/master/packages/%40aws-cdk/aws-stepfunctions/README.md)).
   The library provides rich APIs for modeling state machines by exposing a
   programmatic interface for [Amazon State
   Language](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-amazon-states-language.html).
 - __A new construct library for Amazon S3 bucket deployments__
   ([docs](https://github.com/awslabs/aws-cdk/blob/master/packages/%40aws-cdk/aws-s3-deployment/README.md)).
   You can use now automatically populate an S3 Bucket from a .zip file or a
   local directory. This is a building block for end-to-end support for static
   websites in the AWS CDK.

### Bug Fixes

* **aws-apigateway:** make LambdaRestApi proxy by default ([#963](#963)) ([a5f5e2c](a5f5e2c)), closes [#959](#959)
* **aws-cdk:** Allow use of assumed roles behind a proxy ([#898](#898)) ([f2b1048](f2b1048))
* **aws-cdk:** Auto-delete stacks that failed creating before new attempt ([#917](#917)) ([2af8309](2af8309))
* **aws-cloudfront:** expose distributionId ([#938](#938)) ([f58d98c](f58d98c))
* **aws-dynamodb:** don't emit empty array properties ([#909](#909)) ([841975a](841975a))
* **docs:** use ..code to display file structure in "writing constructs" ([#935](#935)) ([b743362](b743362))

### Features

* **assets:** isZipArchive indicates if this is a zip asset ([#944](#944)) ([65190f9](65190f9))
* **aws-cdk:** deploy supports CloudFormation Role ([#940](#940)) ([393be6f](393be6f)), closes [#735](#735)
* **aws-cloudformation:** allow specifying custom resource type ([#943](#943)) ([9de3a84](9de3a84))
* **aws-cloudformation:** correctly handle the templateConfiguration property in the CreateUpdateStack Pipeline Action. ([#923](#923)) ([d251a46](d251a46))
* **aws-cloudfront:** add support for "webAclId" ([#969](#969)) ([3ec9d76](3ec9d76))
* **aws-codedeploy:** add auto rollback configuration to server Deployment Group. ([#925](#925)) ([7ee91cf](7ee91cf))
* **aws-codedeploy:** add instance tag filter support for server Deployment Groups. ([#824](#824)) ([e6e8c51](e6e8c51))
* **aws-codedeploy:** add support for setting CloudWatch alarms on a server Deployment Group. ([#926](#926)) ([27b26b1](27b26b1))
* add support for Step Functions ([#827](#827)) ([81b533c](81b533c))
* **aws-lambda:** add grantInvoke() method ([#962](#962)) ([1ee8135](1ee8135)), closes [#961](#961)
* **aws-lambda:** improvements to the code and runtime APIs ([#945](#945)) ([36f29b6](36f29b6)), closes [#902](#902) [#188](#188) [#947](#947) [#947](#947) [#664](#664)
* **aws-logs:** extractMetric() returns Metric object ([#939](#939)) ([5558fff](5558fff)), closes [#850](#850)
* **aws-s3:** initial support for website hosting ([#946](#946)) ([2d3661c](2d3661c))
* **aws-s3-deployment:** bucket deployments ([#971](#971)) ([84d6876](84d6876)), closes [#952](#952) [#953](#953) [#954](#954)
* **docs:** added link to CloudFormation concepts ([#934](#934)) ([666bbba](666bbba))

### BREAKING CHANGES

* **aws-apigateway:** specifying a path no longer works. If you used to
provide a '/', remove it. Otherwise, you will have to supply `proxy: false`
and construct more complex resource paths yourself.
* **aws-lambda:** The construct `lambda.InlineJavaScriptLambda` is no longer supported. Use `lambda.Code.inline` instead; `lambda.Runtime.NodeJS43Edge` runtime is removed. CloudFront docs [stipulate](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-lambda-function-configuration) that you should use node6.10 or node8.10. It is always possible to use any value by instantiating a `lambda.Runtime` object.
@rix0rrr rix0rrr added the feature-request A feature should be added or improved. label Nov 6, 2018
@eladb eladb added the @aws-cdk/aws-s3 Related to Amazon S3 label Sep 8, 2019
@eladb eladb self-assigned this Sep 8, 2019
@eladb
Copy link
Contributor Author

eladb commented Oct 2, 2019

Still releavnt

@eladb eladb assigned iliapolo and unassigned eladb Jan 23, 2020
@iliapolo iliapolo added the effort/medium Medium work item – several days of effort label Mar 9, 2020
@gavindoughtie-aon
Copy link

was about to implement this myself, so yes. Please do it for me.

@iliapolo iliapolo added @aws-cdk/aws-s3-deployment and removed @aws-cdk/aws-s3 Related to Amazon S3 labels Jun 14, 2020
@eladb eladb assigned njlynch and unassigned iliapolo Aug 5, 2020
@eladb
Copy link
Contributor Author

eladb commented Aug 5, 2020

We can combine something like S3File combined with toJsonString with this to allow web apps to find AWS resources defined in the same CDK apps and referenced through attributes.

@ericzbeard
Copy link
Contributor

This feature will help with the difficulties around configuring a single page web app. If your stack has resources like an API Gateway or Cognito User Pools, you have to use a custom resource to create a config file with environment-specific variables that is copied into the site bucket after deployment. This can lead to downtime since there is a small window between the deployment of the static resources and the addition of configuration file. Doing a blue green deployment would solve this part of the problem.

@njlynch njlynch added the p1 label Aug 11, 2020
@sholtomaud
Copy link

Any update?

@shivatalwar
Copy link

Is there an ETA on this, if this is in progress or not?

@eladb
Copy link
Contributor Author

eladb commented Mar 1, 2021

We don't have a concrete plan for this at this point, but your comments and +1s can help us prioritize.

@sholtomaud
Copy link

Thanks for the response @eladb - it could work like the Lambda b/g deployment (which requires a description for blue/green)

@ericzbeard ericzbeard added the feature/enhancement A new API to make things easier or more intuitive. A catch-all for general feature requests. label Apr 6, 2021
@misterjoshua
Copy link
Contributor

misterjoshua commented Aug 22, 2021

FYI, I'm doing this kind of blue/green with s3-deployment right now, but I generate the key prefix in my construct and provide it to both the BucketDeployment and the resource responsible for routing HTTP requests. Here's an example using HttpApi:

// Produce the key prefix
const destinationKeyPrefix = new Date().toISOString();

// Instruct BucketDeployment to upload into the key prefix
const deployment = new s3_deployment.BucketDeployment(this, 'BucketDeployment', {
  destinationBucket: bucket,
  destinationKeyPrefix: destinationKeyPrefix,
  sources: [s3_deployment.Source.asset(__dirname)],
});

// Create a route to the new destination key prefix
const httpRoute = new apigw2.HttpRoute(this, 'ApiRoute', {
  httpApi,
  routeKey: apigw2.HttpRouteKey.with('/{proxy+}'),
  integration: new apigv2_int.HttpProxyIntegration({
    url: `${bucket.bucketWebsiteUrl}/${destinationKeyPrefix}/{proxy}`,
  }),
});

// But, change the route only after the bucket deployment is finished.
httpRoute.node.addDependency(deployment);

I use a scheduled lambda to clean out the old files.

YMMV with this example because API GatewayV2's L2 constructs are experimental, but the L1 constructs are also available.

@DharmSonariya
Copy link

+1

@TheRealAmazonKendra TheRealAmazonKendra added p2 and removed p1 labels Jan 24, 2023
@github-actions github-actions bot added p1 and removed p2 labels Jan 29, 2023
@github-actions
Copy link

This issue has received a significant amount of attention so we are automatically upgrading its priority. A member of the community will see the re-prioritization and provide an update on the issue.

@JamesRamm
Copy link

JamesRamm commented Oct 11, 2023

Can anyone give any info on how this might be achieved currently?
I am looking at this but run against the following stumbling blocks:

  • We are considering using lambda@edge to route users to one of two buckets (blue and green), but have seen comments (specifically here) advising against this. If not a lambda function what would be the way to implement this?

  • The logistics of a CI/CD pipeline (we are using Gitlab) to facilitate zero-downtime switching between the buckets. My main idea is to update an environment variable of the lambd@edge function in a pipeline job in order to switch the default routing from bucket A to B, however how to actually achieve this in the context of CDK is confusing me. In my understanding, issuing cdk deploy will deploy the whole stack, resulting in downtime, What we want to be able to do is:

    1. Update bucket 'B' with the new contents in a CI job. (Bucket 'A' is the 'live' bucket at this point)
    2. Manual testing
    3. In a second CI job, automatically update the lambda@edge so bucket 'B' is now the live bucket. (There shouldn't be any manual updates of the lambda code at this point - it should be automatically handled by the CI job and/or CDK)

Is this possible with CDK?

@misterjoshua
Copy link
Contributor

misterjoshua commented Oct 11, 2023

Can anyone give any info on how this might be achieved currently?
I am looking at this but run against the following stumbling blocks:

  • We are considering using lambda@edge to route users to one of two buckets (blue and green), but have seen comments (specifically here) advising against this. If not a lambda function what would be the way to implement this?

  • The logistics of a CI/CD pipeline (we are using Gitlab) to facilitate zero-downtime switching between the buckets. My main idea is to update an environment variable of the lambd@edge function in a pipeline job in order to switch the default routing from bucket A to B, however how to actually achieve this in the context of CDK is confusing me. In my understanding, issuing cdk deploy will deploy the whole stack, resulting in downtime, What we want to be able to do is:

    1. Update bucket 'B' with the new contents in a CI job. (Bucket 'A' is the 'live' bucket at this point)
    2. Manual testing
    3. In a second CI job, automatically update the lambda@edge so bucket 'B' is now the live bucket. (There shouldn't be any manual updates of the lambda code at this point - it should be automatically handled by the CI job and/or CDK)

Is this possible with CDK?

We're using the key prefix approach I mentioned above and a cloudfront function (not Lambda at edge) to rewrite the request uri to the new key prefix.

We've been using this approach for quite some time now. The only major issue we've had was with CloudFront timing out when updating the function, so we replace the function instead of updating it whenever we deploy a change.

To handle your manual testing part, perhaps you could use a staging cloudfront distribution to send your test traffic to the new bucket location. For us, we usually have an entirely different environment for manual testing. The only place we're using the staging distribution approach is in a canary situation while doing a "test in prod" experiment.

@andreialecu
Copy link
Contributor

I believe this could be relevant. CloudFront got blue/green support directly a while ago, which I haven't seen mentioned here:
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/continuous-deployment.html

@sholtomaud
Copy link

did aws provide any cdk code? seems pretty dead here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-s3-deployment effort/medium Medium work item – several days of effort feature/enhancement A new API to make things easier or more intuitive. A catch-all for general feature requests. feature-request A feature should be added or improved. p1
Projects
None yet
Development

No branches or pull requests