{"id":13473961,"url":"https://github.com/DigitalOptimizationGroup/blue-green-cloudflare-workers","last_synced_at":"2025-03-26T20:30:28.397Z","repository":{"id":96723389,"uuid":"176008207","full_name":"DigitalOptimizationGroup/blue-green-cloudflare-workers","owner":"DigitalOptimizationGroup","description":"Blue / Green Deployments for Cloudflare Workers","archived":false,"fork":false,"pushed_at":"2019-03-16T18:22:55.000Z","size":58,"stargazers_count":33,"open_issues_count":0,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-19T04:01:38.964Z","etag":null,"topics":["ab-testing","blue-green-deployments","canary-release","cloudflare-workers","edge-computing","infrastructure-as-code","terraform"],"latest_commit_sha":null,"homepage":"https://edge-stack.org","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DigitalOptimizationGroup.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-16T18:17:30.000Z","updated_at":"2024-11-07T15:55:58.000Z","dependencies_parsed_at":"2024-01-02T23:04:39.044Z","dependency_job_id":"44783679-a08e-4eb0-b85c-44d8f0426aa1","html_url":"https://github.com/DigitalOptimizationGroup/blue-green-cloudflare-workers","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalOptimizationGroup%2Fblue-green-cloudflare-workers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalOptimizationGroup%2Fblue-green-cloudflare-workers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalOptimizationGroup%2Fblue-green-cloudflare-workers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DigitalOptimizationGroup%2Fblue-green-cloudflare-workers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DigitalOptimizationGroup","download_url":"https://codeload.github.com/DigitalOptimizationGroup/blue-green-cloudflare-workers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245731090,"owners_count":20663115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ab-testing","blue-green-deployments","canary-release","cloudflare-workers","edge-computing","infrastructure-as-code","terraform"],"created_at":"2024-07-31T16:01:08.351Z","updated_at":"2025-03-26T20:30:27.937Z","avatar_url":"https://github.com/DigitalOptimizationGroup.png","language":"HCL","funding_links":[],"categories":["Workers"],"sub_categories":["Recipes"],"readme":"# Blue / Green Deployments for Cloudflare Workers\n\nThis is a working example of Blue / Green deployments with Canary releasing for Cloudflare Workers.\n\nFeatures:\n\n- Blue / Green workers\n- Proxy worker implementing Canary releasing and A/B testing with [`cloudflare-edge-proxy`](https://github.com/DigitalOptimizationGroup/cloudflare-edge-proxy)\n- Optional release versioning and history with AWS S3 bucket\n- Infrastructure as code - deployed with Terraform (you just need to manually point your nameservers at Cloudflare) - nothing is done through the Cloudflare UI\n- Convenient bash scripts for deploying\n\n## Example\n\nA running demo is currently deployed at https://edge-stack.org/. When visiting the site you will be assigned to either the blue or green backend. If you continue to delete your cookies and refresh the page you will, at some random point, also become assigned to the other backend. Without deleting your cookies you will continue to be assigned to the same backend.\n\nThe high level domain, in this case `edge-stack.org`, hosts a Worker proxy and two other domains are used to deploy the blue / green versions of the app.\n\nThe app in this example is a simple Hello World rendered in a Worker, but could easily be replaced with a full Worker rendered Progressive Web App like this one: https://github.com/DigitalOptimizationGroup/cloudflare-worker-preact-pwa\n\n## Usage\n\n#### Initial Configuration and Setup\n\nYou can run your own version of this setup by following the instructions below.\n\n#### Setup a `.env` file in the project root\n\nIf you do not already have a Cloudflare account, you will need to create one. You will also need to enable Workers in your account (min $5.00 per month)\n\nYou will then need to get you Cloudflare Global API Key. This is available in your account under My Profile \u003e API Keys \u003e Global API Key. Add this in your `.env` file as `ACCOUNT_AUTH_KEY`. You will also need your account email address, add that as `ACCOUNT_EMAIL`.\n\nYou will need three domains to run this setup. The free plan on Cloudflare does not allow workers to be run on subdomains, so you'll need three high level domains. We use domains like `edge-stack.org`, `blue-edge-stack.org`, and `green-edge-stack.org`. You will also need some origin, even an s3 bucket works fine, to set a root level CNAME. Cloudflare seems to need this to enable Workers for a domain. No traffic should ever hit this domain (maybe we're wrong that this is needed?).\n\n```bash\n# Domains - replace with your domains\nPROXY_DOMAIN=edge-stack.org\nBLUE_DOMAIN=blue-edge-stack.org\nGREEN_DOMAIN=green-edge-stack.org\nDEFAULT_ORIGIN=\n\n# Cloudflare Keys\nACCOUNT_AUTH_KEY=\nACCOUNT_EMAIL=\n\n# Optional S3 Bucket for Release History - create your own bucket name\nS3_BUCKET_NAME=edge-stack-org-demo\nWORKER_VERSION=0.0.1\nPROXY_VERSION=0.0.1\n```\n\n#### Setup Terraform\n\nYou don't need to know anything about Terraform to use this stack. You'll just need to run the commands. All you have to do is make sure you have it installed.\n\nIf you do not already have Terraform installed, you'll need to install it.\nhttps://learn.hashicorp.com/terraform/getting-started/install.html\n\n#### Running the scripts\n\nThere are two bash script with all the needed commands for deploying. You may need to give them executable permissions `chmod u+x commands.sh` and `chmod u+x s3deploy.sh`. The second script you will only use if you choose to save versioned releases to s3.\n\n**Initialize the Terraform files** by running\n\n```\n./commands.sh init\n```\n\n**Deploy the three domains** into Cloudflare\n\n```\n./commands.sh setup_cloudflare\n```\n\nThis command should take less than a minute to complete and will create Cloudflare zones for each of your domains.\n\nWhen this command runs it will output (into the console) the nameservers that Cloudflare has assigned to your zones. You will need to update your domains with these nameservers before continuing. You can check if the nameserver updates have propagated by running something like `dig your-domain.com`.\n\n**Deploy the root records** into your Cloudflare zones.\n\nThis seems to be needed to enable workers, no traffic should ever go to this record as workers will be responding to all requests. The command will fail if the nameservers have not been updated. You can keep trying to run it without any problems, once they are updated it will succeed.\n\n```\n./command.sh records\n```\n\n### Deploy your workers\n\nThere are two options for deploying workers. The first version just deploys from the local build script. The second version uses an s3 bucket to version and save each release (see docs further down this page).\n\n#### Deploy Blue / Green worker\n\nRun the `deploy_worker` command passing it one argument of your desired deployment target, either `blue` or `green`. If you're just testing this out, deploy both. For demonstration purposes, the app is configured to take in the color as a variable, so you'll be able to see a difference between the two deploys.\n\n```\n./command.sh deploy_worker blue\n```\n\n```\n./command.sh deploy_worker green\n```\n\n#### Deploy / Update Proxy\n\nUpdate the Proxy config here: `/worker-proxy/src/config.js`. You can refer to the documentation for `cloudflare-edge-proxy` to enable A/B Testing and Gatekeeping: https://github.com/DigitalOptimizationGroup/cloudflare-edge-proxy\n\n```js\n// canary config\nexport const config = {\n  defaultBackend: `https://${process.env.BLUE_DOMAIN}`,\n\n  // turn on canary deployment\n  canary: true,\n\n  // set the percent of traffic to send to the canary from 0-100\n  // note that you should only increase this number when shifting traffic to assure\n  // that your users do not \"jump around\" between backends\n  weight: 30,\n  canaryBackend: `https://${process.env.GREEN_DOMAIN}`,\n\n  // you should change this salt for every new canary release so that users are\n  // not allocated in the same manner as previous deployments\n  salt: \"canary-abc-123\",\n\n  // default is false, if true proxy will set _vq cookie for consistent assignment to same backend\n  setCookie: true\n};\n```\n\nDeploy the proxy:\n\n```\n./commands.sh deploy_proxy\n```\n\nNow you can go to your main domain and if you delete your cookies you should see the app switching randomly between blue or green each time you delete cookies and refresh.\n\n### Destroying\n\nYou can destroy any of this with Terraform by running the following commands.\n\n```\n./commands.sh destroy_blue\n./commands.sh destroy_green\n./commands.sh destroy_proxy\n./commands.sh destroy_records\n./commands.sh destroy_cloudflare\n```\n\nOr\n\n```\n./commands.sh destroy_all\n```\n\n### Using S3 to save every release (immutable deployments)\n\nOptionally you may choose to save every release by a version number into S3 before deploying to Cloudflare. This will keep an immutable record of all releases and allow you to deploy any past release.\n\nNote: This creates an additional dependency on an AWS S3 bucket.\n\n##### Deploying\n\nFirst you will need to add the following variables to your `.env` file. Remember your `S3_BUCKET_NAME` must be unique across all of AWS, so if creation fails you may need to choose a different name.\n\n```\nS3_BUCKET_NAME=edge-stack-org-demo\nWORKER_VERSION=0.0.1\nPROXY_VERSION=0.0.1\n```\n\nYou will also need to have AWS keys available in your environment with appropriate permissions available to Terraform.\n\nThere is a second script with commands for deploying through s3: `s3deploy.sh`.\n\nFirst initialize Terraform\n\n```\n./s3deploy.sh init\n```\n\nDeploy your s3 bucket. You may also choose to enable versioning on the bucket for even greater security in saving past releases. Choose one of these two commands:\n\n```\n# without versioning\n./s3deploy.sh build_s3_bucket\n\n# or to enable versioning\n./s3deploy.sh build_s3_bucket_with_versioning\n```\n\nOnce the bucket has been created use the deploy commands from `./s3deploy.sh`. You will need to manually bump the versions in your `.env` file before each deploy. If you attempt to deploy to an already deployed version it will not overwrite the s3 file, but will ask if you'd like to rollback to the prior version.\n\n```\n./s3deploy.sh deploy_worker blue\n```\n\n```\n./s3deploy.sh deploy_worker green\n```\n\n```\n./s3deploy.sh deploy_proxy\n```\n\n#### Destroying the s3 version\n\nYou may need to delete everything in your bucket manually before you can destroy the bucket with Terraform.\n\n```sh\n./s3deploy.sh destroy_blue\n./s3deploy.sh destroy_green\n./s3deploy.sh destroy_proxy\n./s3deploy.sh destroy_s3_bucket\n```\n\nor\n\n```sh\n./s3deploy.sh destroy_all\n```\n\n### Terraform Notes\n\nYou may like to take a look at Terraform backends. This example uses a local backend, but for larger teams you may prefer to use a remote backend to store infrastructure state. You can read about the tradeoffs here: https://www.terraform.io/docs/backends/\n\n### About Digital Optimization Group\n\nWe offer a headless CMS built for A/B testing and we are currently accepting requests for private beta access. We also provide full-stack A/B testing services and consulting. Email: info@digitaloptgroup.com\n\n### Licence\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDigitalOptimizationGroup%2Fblue-green-cloudflare-workers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDigitalOptimizationGroup%2Fblue-green-cloudflare-workers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDigitalOptimizationGroup%2Fblue-green-cloudflare-workers/lists"}