[EPAC-2060]: migrate Terraform state to S3 remote backend with bootstrap-from-zero#594
Merged
riddim-developer-bot[bot] merged 1 commit intoMay 25, 2026
Conversation
…rap-from-zero
- Add infra/terraform/bootstrap.sh: idempotent script that creates per-workspace
S3 buckets (versioned, encrypted, public-access-blocked) and DynamoDB lock
tables using PAY_PER_REQUEST billing
- Update backend blocks in core/staging/production versions.tf to use new
per-workspace bucket naming: epac-tfstate-{workspace}-{account_id}
- Remove state-storage resources (S3 bucket + DynamoDB table) from core/main.tf
since bootstrap.sh now owns those resources outside Terraform management
- Update .gitignore with *.tfvars, *.tfplan, and infra/terraform/**/.terraform/
- Rewrite infra/terraform/README.md with remote state table, bootstrap
instructions, local usage guide, and smoke test documentation
- Update core/staging/production README files to reference new backend layout
Account ID (227530433709) is hard-coded in backend blocks because Terraform
loads backend config before variables are available.
Resolves EPAC-2060
riddim-developer-bot
Bot
deleted the
symphony/epac-2060-migrate-terraform-state-to-s3-remote-backend-wit
branch
May 25, 2026 18:02
riddim-developer-bot Bot
added a commit
that referenced
this pull request
May 25, 2026
## Why Terraform local state files were already removed as part of remote-state migration, but the repository still needed explicit hygiene: enforce ignore rules for generated state/plan artifacts and document the operator path after the migration. ## What changed - Updated `infra/terraform/README.md` with the post-migration operator workflow: - state storage and backend reference (A1 bootstrap script + A2 backend declarations) - local run path: `aws sso login` -> `bash infra/terraform/bootstrap.sh <env>` -> `cd infra/terraform/<env> && terraform init && terraform plan` - fresh-account path and note that bootstrap/migration is one-time operational setup - link to migration PR evidence: [EPAC-2060](#594) - Updated root `.gitignore` to ensure Terraform state and plan artifacts are ignored. - Confirmed `.terraform.lock.hcl` is not ignored so provider lockfiles can stay committed. ## Acceptance criteria - �[32mOK�[0m `infra/terraform/staging/terraform.tfstate` deleted if present in git (already absent in this branch at issue time). - �[32mOK�[0m `infra/terraform/staging/terraform.tfstate.backup` deleted if present in git (already absent). - �[32mOK�[0m production/core local state globs similarly absent in git. - �[32mOK�[0m `.gitignore` excludes `*.tfstate`, `*.tfstate.backup`, `*.tfvars`, `*.tfplan`, `.terraform/`. - �[32mOK�[0m `.terraform.lock.hcl` remains tracked when present (pattern removed). - �[32mOK�[0m `infra/terraform/README.md` now documents remote state path, local run commands, fresh-account operator flow, and migration evidence link. ## Verification - `git diff --stat origin/main...HEAD` shows only `.gitignore` and `infra/terraform/README.md` changed. - `gh pr create` performed after rebase + push (branch is clean and rebased). ## Skipped checks - No Terraform runtime commands were executed in this PR (no functional verification requested by ticket). Resolves EPAC-2070 Reviewer-Boundary: review-only Co-authored-by: riddim-developer-bot <developer-bot@riddimsoftware.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
infra/terraform/bootstrap.sh— idempotent script that creates per-workspace S3 state buckets (versioned, encrypted, public-access-blocked) and DynamoDB lock tables (PAY_PER_REQUEST)core/staging/production/versions.tffrom the old sharedepac-terraform-statebucket to per-workspace naming:epac-tfstate-{workspace}-227530433709core/main.tf— bootstrap.sh owns those outside Terraform management to avoid the bootstrap cycle.gitignorewith*.tfvars,*.tfplan, andinfra/terraform/**/.terraform/patternsinfra/terraform/README.mdwith remote state table, bootstrap instructions, local usage, and smoke testDesign decisions
epac-tfstate-core-*,epac-tfstate-staging-*,epac-tfstate-production-*) instead of one shared bucket with key prefixes — isolates blast radius and makes IAM scoping straightforward.coreworkspace resources when bootstrapping staging or production — ensuresterraform initin core always works from a fresh account.Verification
terraform validatepasses for all three modules (core, staging, production) with-backend=falsebootstrap.shshellcheck-clean withset -euo pipefail.tfstateor.tfstate.backupfiles remain in the repooutputs.tf— all outputs are bucket names, ARNs, domain names, or function name lists.github/workflows/infra-validate.ymlunchanged and continues to use-backend=falseState migration (human step)
After this PR merges and bootstrap.sh is run against the target account:
Stranded Aurora resources (
aws_db_cluster.epac_db,aws_db_instance.epac_db_writer) should be removed viaterraform state rmsince the cluster was retired. Production migration requires human execution per the external validation gate.Skipped checks
terraform init -migrate-state): requires AWS credentials and the bootstrap resources to exist. This is a human-gated step documented above and in the README.Resolves EPAC-2060
Reviewer-Boundary: review-only