Skip to content
Open
56 changes: 56 additions & 0 deletions docs/developer-docs/6.x/infrastructure/ci-cd.ai.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
AI Context: CI/CD (ci-cd.mdx)

## Source of Information

1. `docs/developer-docs/5.x/core-development-concepts/ci-cd/introduction.mdx` — overview and phases
2. `docs/developer-docs/5.x/core-development-concepts/ci-cd/environments.mdx` — shared/isolated environments, AWS accounts
3. `docs/developer-docs/5.x/core-development-concepts/ci-cd/version-control.mdx` — GitHub flow, branching
4. `docs/developer-docs/5.x/core-development-concepts/ci-cd/cloud-infrastructure-state-files.mdx` — Pulumi backends
5. `docs/developer-docs/5.x/core-development-concepts/ci-cd/workflows.mdx` — merging strategies, release cycle

## Key Documentation Decisions

1. Six v5 articles collapsed into one — target audience is experienced AWS/DevOps engineers who don't need CI/CD explained
2. Removed: what is CI/CD, CI/CD phases diagram, what is Git/GitHub, what is Pulumi (assumed knowledge)
3. Removed: references to v5 scaffold (`yarn webiny scaffold`) — not relevant in v6
4. Removed: "Can I bring additional tools?" FAQ — too basic
5. Removed: testing article content — not in scope for this article
6. Kept: environment table, AWS accounts recommendation, branching strategy, Pulumi state backend options, deployment flow, hot fix pattern
7. GitHub Actions is a separate article (`github-actions.mdx`)
8. Staging merge strategy: kept the recommended "PR against staging, then sync back to dev" approach
9. No version references anywhere

## Understanding

### Environment structure
- 3 shared long-lived: dev, staging, prod
- Isolated: per developer, per developer AWS account
- Each shared env: own AWS account, own S3 bucket for Pulumi state

### Pulumi state backends
- Local `.pulumi` folder: developer environments only, not in VCS
- S3: recommended for shared envs; one bucket per env/account; set via `WEBINY_PULUMI_BACKEND=s3://...`
- Pulumi Service: managed option with locking/history; set via `WEBINY_PULUMI_BACKEND=https://api.pulumi.com` + `PULUMI_ACCESS_TOKEN`
- When using Pulumi Service: remove `PULUMI_SECRETS_PROVIDER` and `PULUMI_CONFIG_PASSPHRASE`

### Deployment flow
feature branch → PR → dev → PR → staging → PR → prod

### Hot fix flow
PR directly to prod → merge prod → staging → dev

### Staging merge strategy (recommended)
Fix bugs found in staging by PRing against staging (not dev). At end of cycle, merge staging back to dev.

## Related Documents

- `infrastructure/github-actions.mdx` — GitHub Actions workflow setup
- `infrastructure/deploy-webiny-project-cf-template.mdx` — IAM permissions for CI/CD
- `infrastructure/deployment-modes.mdx` — dev vs prod infrastructure differences

## Tone Guidelines

- Assumes experienced AWS/DevOps audience — no hand-holding on basic concepts
- Prescriptive: "the recommended setup is..." not "you could consider..."
- Table-driven where possible for environment/backend comparison
- FAQ section for edge cases only
131 changes: 131 additions & 0 deletions docs/developer-docs/6.x/infrastructure/ci-cd.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
id: infra6cicd
title: CI/CD
description: Best practices for structuring environments, branches, Pulumi state, and deployment workflows for a Webiny project.
---

import { Alert } from "@/components/Alert";

<Alert type="success" title="WHAT YOU'LL LEARN">

- How to organize environments and AWS accounts
- How to structure Git branches to mirror environments
- How to store Pulumi state files for shared environments
- How deployments flow from `dev` → `staging` → `prod`

</Alert>

## Overview

This article covers the recommended CI/CD setup for a Webiny project. It assumes you are already familiar with CI/CD concepts and focuses on the decisions that are specific to Webiny — environments, branching, Pulumi state management, and deployment workflow.

## Environments

### Shared Environments

The recommended minimum is three long-lived shared environments:

| Environment | Purpose |
| ----------- | ------------------------------------------------------------ |
| `dev` | Integration target for all feature branches; may be unstable |
| `staging` | Production-like environment for release candidate testing |
| `prod` | Live system used by real users; must remain stable |

Each push to a shared branch should automatically trigger a deployment into its respective environment.

### Isolated Environments

Developers deploy their own short-lived isolated environments for local development and testing. These are deployed from a developer's machine and destroyed when no longer needed. Each developer should use their own AWS account to avoid interfering with shared environments.

### AWS Accounts

The recommended setup is one AWS account per environment — one for `dev`, one for `staging`, one for `prod`, and one per developer for isolated work. [AWS Organizations](https://aws.amazon.com/organizations/) makes managing multiple accounts easier.

Using separate accounts means AWS credentials, Pulumi state buckets, and permissions are fully isolated between environments.

**Consider a dedicated account for ephemeral environments.** If you run ephemeral PR environments in the same AWS account as your long-lived `dev` environment, the account may accumulate orphaned resources over time. Tools like [aws-nuke](https://github.com/ekristen/aws-nuke) can clean these up, but they cannot safely run against an account that also holds a live environment. By routing all ephemeral environments into a dedicated fourth account — separate from `dev`, `staging`, and `prod` — you can safely run aws-nuke or similar tools against that account on a schedule without risking your long-lived environments.

## Branching Strategy

Mirror your environments with long-lived Git branches: `dev`, `staging`, and `prod`. Protect all three against direct pushes — all changes should go through pull requests.

Set `dev` as the default branch. All feature branches are created from `dev` and pull requests target `dev`.

Short-lived branches follow this flow:

```
feature/my-change → (PR) → dev → (PR) → staging → (PR) → prod
```

### Hot Fixes

If a critical bug needs an immediate fix in production, a PR can be raised directly against `prod`. Once merged, sync the fix back down: merge `prod` → `staging` → `dev`.

## Pulumi State Files

Webiny uses [Pulumi](https://www.pulumi.com/) for infrastructure deployments. Pulumi records the state of all deployed resources in state files — these must not be lost.

### Local File System (default)

By default, state files are stored in `.pulumi` folders within the project. This is suitable for individual developer environments only. The `.pulumi` folder is not checked into version control.

### Amazon S3 (recommended for shared environments)

For `dev`, `staging`, and `prod`, store state files in an S3 bucket within the same AWS account used for that environment. Create the bucket manually before the first deployment, then set:

```bash
WEBINY_PULUMI_BACKEND=s3://your-bucket-name
```

Since each environment uses its own AWS account, you end up with one S3 bucket per environment.

### Pulumi Service

Alternatively, use the [Pulumi Service](https://www.pulumi.com/product/pulumi-cloud/) for managed state storage with built-in locking, history, and secret encryption:

```bash
WEBINY_PULUMI_BACKEND=https://api.pulumi.com
PULUMI_ACCESS_TOKEN=pul-xyzabc123
```

When using Pulumi Service, remove `PULUMI_SECRETS_PROVIDER` and `PULUMI_CONFIG_PASSPHRASE` — the service provides its own secrets handling.

<Alert type="warning">

Do not lose your `PULUMI_CONFIG_PASSPHRASE` when using the passphrase secrets provider. Without it, you cannot redeploy or destroy existing infrastructure.

</Alert>

## Deployment Workflow

### 1. Feature development

A developer branches from `dev`, makes changes, and opens a PR back to `dev`. Tests run against a short-lived ephemeral environment. On approval, the branch is merged and the `dev` environment is redeployed.

### 2. Release to staging

When `dev` is ready for a release, open a PR from `dev` → `staging`. Once merged, `staging` is redeployed. QA and stakeholders test the release candidate.

If bugs are found in `staging`, raise fixes as PRs against `staging` directly (not `dev`). At the end of the release cycle, merge `staging` back into `dev` to keep them in sync.

### 3. Release to production

Once `staging` is approved, open a PR from `staging` → `prod`. Once merged, `prod` is redeployed and the release is live.

## GitHub Actions

Everything outlined in this article is implemented in the ready-made GitHub Actions workflow files Webiny provides. See [GitHub Actions](/{version}/infrastructure/github-actions) for the full setup guide — workflow files, OIDC authentication, and required repository secrets.

## FAQ

### Can I have more than three shared environments?

Yes. Add additional long-lived branches and environments as needed — a common addition is a `uat` environment between `staging` and `prod`.

### Are environment names fixed?

No. `dev`, `staging`, and `prod` are conventions, not hard-coded values. Use whatever naming your organization follows.

### What happens if two deployments are triggered simultaneously?

Pulumi locks state during a deployment. The second deployment will be rejected with an error until the first completes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
AI Context: "Deploy Webiny Project" AWS CloudFormation Template (deploy-webiny-project-cf-template.mdx)

## Source of Information

1. `docs/developer-docs/5.x/infrastructure/aws/configure-aws-credentials.mdx` lines 116-149 — the "Deploy Webiny Project" section extracted from the v5 credentials article

## Key Documentation Decisions

1. This is a standalone article scoped only to the CloudFormation template — credential setup is out of scope
2. Kept short: the template does one thing (provisions least-privilege IAM groups), one click to launch it
3. Removed the commented-out screenshots from v5 (outdated, explicitly commented out in source)
4. ExternalLink component not used — standard markdown links are sufficient for external URLs
5. Prerequisite (IAM user with programmatic access) noted via Alert rather than linking back to a credential setup article

## Understanding

### What the template does

- Provisions three IAM user groups with least-privilege permissions scoped to what Webiny deployment requires
- Links the groups to a preexisting IAM user of the deployer's choosing
- Alternative to granting full AdministratorAccess

### Launch URL

https://console.aws.amazon.com/cloudformation/home?#/stacks/create/review?templateURL=https://webiny-public.s3.us-east-2.amazonaws.com/cloudformation/DEPLOY_WEBINY_PROJECT_CF_TEMPLATE.yaml&stackName=DeployWebinyProject

### Template source

- GitHub: https://github.com/webiny/webiny-js/blob/next/docs/DEPLOY_WEBINY_PROJECT_CF_TEMPLATE.yaml
- S3: https://webiny-public.s3.us-east-2.amazonaws.com/cloudformation/DEPLOY_WEBINY_PROJECT_CF_TEMPLATE.yaml

## Related Documents

- `infrastructure/introduction.mdx` — infrastructure overview
- `infrastructure/deployment-modes.mdx` — deployment modes

## Tone Guidelines

- Practical and brief — this is a how-to with a single action
- No step-by-step AWS console walkthrough (out of scope)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
id: infra6cft1
title: AWS CloudFormation Template
description: Use the official AWS CloudFormation template to deploy Webiny with a least-privilege IAM role.
---

import { Alert } from "@/components/Alert";

<Alert type="success" title="WHAT YOU'LL LEARN">

- What the "Deploy Webiny Project" CloudFormation template is
- How to deploy it into your AWS account

</Alert>

## Overview

The **Deploy Webiny Project** AWS CloudFormation template is the recommended way to set up the IAM permissions needed to deploy Webiny. It creates an IAM role with three attached managed policies that follow the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege).

You can inspect the full template before deploying: [view on GitHub](https://github.com/webiny/webiny-js/blob/next/docs/DEPLOY_WEBINY_PROJECT_CF_TEMPLATE_V6.yaml).

## Deploying the Template

Before deploying, create an IAM role in your AWS account that will be used for Webiny deployments. The template does not create the role itself — it attaches the required managed policies to a role you provide.

Once the role exists, click the link below to open the AWS CloudFormation console with the template pre-loaded. When prompted, enter the name of the IAM role you created:

[Launch "Deploy Webiny Project" stack](https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?templateURL=https://webiny-public.s3.us-east-2.amazonaws.com/cloudformation/DEPLOY_WEBINY_PROJECT_CF_TEMPLATE_V6.yaml&stackName=DeployWebinyProject)
75 changes: 75 additions & 0 deletions docs/developer-docs/6.x/infrastructure/github-actions.ai.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
AI Context: GitHub Actions (github-actions.mdx)

## Source of Information

1. `~/dev/wby-next4/docs/gh-actions-workflows/pushDev.yml` — dev push workflow
2. `~/dev/wby-next4/docs/gh-actions-workflows/pushStaging.yml` — staging push workflow
3. `~/dev/wby-next4/docs/gh-actions-workflows/pushProd.yml` — prod push workflow
4. `~/dev/wby-next4/docs/gh-actions-workflows/pullRequest.yml` — PR workflow (ephemeral env)
5. `~/dev/wby-next4/docs/gh-actions-workflows/pullRequestClosed.yml` — PR closed (destroy env)
6. `docs/developer-docs/5.x/core-development-concepts/ci-cd/setup.mdx` — v5 reference

## Key Documentation Decisions

1. No scaffold — users copy workflow files manually from GitHub
2. OIDC authentication is the central new concept vs v5; no static AWS_ACCESS_KEY_ID/SECRET in these workflows
3. `AWS_ROLE_ARN` replaces `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`
4. Pull request environments documented as a first-class feature (not mentioned in previous version)
5. `WEBINY_PROJECT_ID` and `WEBINY_PROJECT_API_KEY` are new secrets not in v5 docs
6. `DEV_WEBINY_PULUMI_BACKEND_PULL_REQUESTS` is separate from `DEV_WEBINY_PULUMI_BACKEND`
7. OpenSearch secrets documented as conditional (only for DynamoDB + OpenSearch setup)
8. `concurrency` setting documented — prevents parallel deploys to same environment

## Understanding

### Workflow files (5 total)

- pushDev.yml — triggered on push to `dev`; format + lint + `yarn webiny deploy --env dev`
- pushStaging.yml — triggered on push to `staging`; format + lint + deploy staging
- pushProd.yml — triggered on push to `prod`; format + lint + deploy prod
- pullRequest.yml — triggered on PR to `dev`; static analysis job + deploy job (deploys core + api + admin to `pr{number}` env)
- pullRequestClosed.yml — triggered on PR closed to `dev`; destroys `pr{number}` env

### OIDC authentication

- `permissions: id-token: write` enables OIDC token generation
- `aws-actions/configure-aws-credentials@v4` with `role-to-assume: ${{ secrets.DEV_AWS_ROLE_ARN }}`
- No static AWS credentials stored — short-lived token assumed per run
- Requires IAM role in each AWS account that trusts the GitHub OIDC provider

### Full secrets list

AWS:
- DEV/STAGING/PROD_AWS_ROLE_ARN
- DEV/STAGING/PROD_AWS_REGION

Pulumi:
- DEV/STAGING/PROD_PULUMI_SECRETS_PROVIDER
- DEV/STAGING/PROD_PULUMI_CONFIG_PASSPHRASE
- DEV/STAGING/PROD_WEBINY_PULUMI_BACKEND
- DEV_WEBINY_PULUMI_BACKEND_PULL_REQUESTS (PR environments only)

Webiny:
- DEV/STAGING/PROD_WEBINY_PROJECT_ID
- DEV/STAGING/PROD_WEBINY_PROJECT_API_KEY

OpenSearch (conditional):
- DEV_OPENSEARCH_DOMAIN_NAME
- OPENSEARCH_INDEX_PREFIX is set inline as `pr${{ github.event.pull_request.number }}` — not a secret

### PR environment naming

Env name: `pr{number}` e.g. `pr42`
Set via: `--env pr${{ github.event.pull_request.number }}`
Destroyed via: `yarn webiny destroy --env pr{number} --confirm-destroy-env pr{number} --debug`

## Related Documents

- `infrastructure/ci-cd.mdx` — environment strategy, Pulumi backend guidance
- `infrastructure/deploy-webiny-project-cf-template.mdx` — IAM role permissions

## Tone Guidelines

- Setup guide — action-oriented, not conceptual
- Secrets lists as code blocks for easy copy-paste
- OIDC section should explain why (no static credentials) not just how
Loading