riboseinc / terraform-aws-s3-cloudfront-website

Terraform module for creating a static S3 website with CloudFront with an SSL certificate (e.g., from ACM)
Apache License 2.0
74 stars 40 forks source link

Support zero-downtime deployments #30

Closed ronaldtse closed 2 years ago

ronaldtse commented 3 years ago

Due to the issue in #29 , @strogonoff and I discussed about separating the website upload and website activation phases.

Assume that we have this S3 bucket layout:

|--- 20210101000000
       |---  .done
       |--- index.html
       |--- foo
             |--- bar.html
|--- 20210201000000
       |---  .done
       |--- index.html
       |--- foo
             |--- bar.html
|--- 20210301000000
       |---  .done
       |--- index.html
       |--- foo
             |--- bar.html

Then the upload flow would be:

  1. User uploads complete website to a new path, e.g. 20210401000000/.
  2. Once upload is complete, the user creates 20210401000000/.done.
  3. User runs Cloudfront invalidation on the site. This means that new requests will hit the Lambda@Edge function.
  4. A request to / hits Lambda@Edge, and the function detects that the newest (sorted latest) directory is 20210401000000 and it also contains the .done path.
  5. Lambda@Edge returns the S3 file 20210401000000/index.html.
  6. We can have a Lambda function that cleans up previous versions and keep only the latest site with .done or the last two copies every hour or every day.

This would be a good way of doing zero-downtime deployments.

Due to the additional complexity of this solution, this might better be a separate terraform module that builds on the current one.

Thoughts @strogonoff @phuonghuynh ?

ronaldtse commented 3 years ago

Ping @skalee since this is relevant to you too.

ronaldtse commented 3 years ago

@phuonghuynh could you let us know how this is going? Thanks.

phuonghuynh commented 3 years ago

I think we need to update current lambda-redirect code to support this feature An other reference link is

ronaldtse commented 3 years ago

@phuonghuynh what's the lambda-redirect code?

phuonghuynh commented 3 years ago

@ronaldtse this repo, https://github.com/riboseinc/terraform-aws-lambda-redirect-http-index, we can update code to read S3 objects and perform redirect to objects in latest .done file

ronaldtse commented 3 years ago

Sure, let's do that.

phuonghuynh commented 3 years ago

@ronaldtse how about using SQL Select feature of S3? https://docs.aws.amazon.com/AmazonS3/latest/userguide/selecting-content-from-objects.html

This enable us to save S3 cost; but we need to define a JSON object (max 1MB) for querying data we need.

ronaldtse commented 3 years ago

@phuonghuynh do you mean that we can use a CSV file for index and use S3 Select to return the correct path?

phuonghuynh commented 3 years ago

yep, correct, but I think in JSON format would be better for human fast reading?

phuonghuynh commented 3 years ago

@ronaldtse the implement code now using CSV format as bellow

lastUpdatedTimestamp,rootDir
1615877411,dir1
1615875912,dir2

When upload progress done, this S3 Config file need to be appended. Required env variables needed for lambda to load it.

- `BUCKET_NAME` (optional): bucket name to set CSV Config File
- `BUCKET_CSV_CONFIG_KEY` (optional): csv config bucket object, sample as bellow

PR sent, https://github.com/riboseinc/terraform-aws-lambda-redirect-http-index/pull/2 Need someone able to test with staging test site

ronaldtse commented 3 years ago

yep, correct, but I think in JSON format would be better for human fast reading?

Agree.

phuonghuynh commented 3 years ago

@ronaldtse I switch to use CSV because it easier than JSON when appending new line