Migrate the Terraform S3 backends off dynamodb_table onto use_lockfile and delete the lock tables
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 45/100
- Tipo di issue
- Refactoring
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- aws, terraform
- Ambito
- ci-cd, cloud, databases, devops, documentation, infrastructure
Direzione di ricerca
Inizia dai file backend elencati in hackforla/incubator e hackforla/devops-security, quindi esamina tf-plan-scoped.json, CONTRIBUTING.md e il template della issue di pre-work per tutti i riferimenti alle tabelle di lock. Esegui i piani Terraform del repository e ispeziona i workflow di apply a cui fanno riferimento, interrompendo l’attività se le modifiche differiscono dalle aspettative dichiarate. Il lavoro è completato quando entrambi gli apply vengono eseguiti senza avvisi, la documentazione e la policy sono aggiornate, il template viene renderizzato correttamente ed entrambe le tabelle DynamoDB sono registrate, eliminate e verificate come assenti.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Overview
We need to replace the deprecated dynamodb_table backend parameter with use_lockfile = true in hackforla/incubator and hackforla/devops-security, then delete the two now-unused DynamoDB lock tables, because HashiCorp deprecated DynamoDB-based state locking in Terraform 1.11 and will remove it in a future minor version. Both repos already run 1.16.1, so every plan and apply in both is printing the deprecation warning today.
Action Items
Facts verified 2026-09-07, so you do not have to re-derive them:
- The warning fires 3x per plan run and 4x per apply, in every run sampled in both repos back to 2026-08-08. It reads
Warning: Deprecated Parameter / The parameter "dynamodb_table" is deprecated. Use parameter "use_lockfile" instead.and points atbackend.tf line 7, which is misleading — that line is an emptybackend "s3" {}block. The parameter is interraform/prod.backend.tfvars, which the workflows pass asbackend_config_file. use_lockfilewent generally available in Terraform 1.11, in the same release that deprecated the DynamoDB arguments. Both repos resolverequired_version = "~> 1.16.0"to 1.16.1, so there is no version work.- No new IAM permission is needed. S3-native locking needs
s3:GetObject,s3:PutObjectands3:DeleteObjecton<key>.tflock. The apply roles (incubator-tf-apply,devops-security-tf-apply) holdAdministratorAccess. The plan roles never take a lock at all —dflook/terraform-planpasses-lock=falseunconditionally (image/entrypoints/plan.sh:15, checked at both the pinnedv1.49.0and atmain). That is also why the plan roles work today holding onlyReadOnlyAccessover DynamoDB. - Both state buckets (
hfla-incubator-terraform-state,hfla-ops-terraform-state) have versioning Enabled. - Both lock tables hold exactly one item and it is not a lock — it is the
…/terraform.tfstate-md5digest row. No lock is currently held in either. - Both tables have
DeletionProtectionEnabled: true, so deleting them is a two-call operation. Neither has point-in-time recovery. - These are the only two DynamoDB tables in account
035866691871. After step 3 the account has none.
1. hackforla/incubator — 1 PR, terraform/prod.backend.tfvars:
- Delete the
dynamodb_table = "hfla_incubator_terraform_table"line and adduse_lockfile = true. - Add a no-op comment line to any
.tffile in the same PR. Both workflows filter onpaths: ['**/*.tf', '**/*.yaml'], andprod.backend.tfvarsmatches neither pattern — so a PR that changes only the tfvars triggers no workflow at all, on the PR or on the merge. This is not optional: without it there is nothing to verify against and the merge produces no apply run. - Treat a non-empty plan as a hard gate. A backend change produces zero resource changes. If the plan shows any, stop and raise it rather than merging.
- After the PR merges, confirm the
Terraform apply (OIDC)run succeeds and that noDeprecated Parameterwarning appears anywhere in its log.
2. hackforla/devops-security — 1 PR. This one is bigger than incubator's, because three other things in this repo reference the lock table:
-
terraform/prod.backend.tfvars— deletedynamodb_table = "hfla_ops_terraform_table", adduse_lockfile = true. -
terraform/aws-custom-policies/tf-plan-scoped.json— delete the wholeAllowDynamoDBLockTableAccessForTerraformPlanstatement. This file is live:terraform/aws-custom-policies.tffeeds it tomodules/aws-policies, which deploys it as the IAM policyIncubatorTfPlanSecretsRead, currently attached to theincubator-tf-planrole. Leaving the statement would leave a live policy granting DynamoDB actions on a table that no longer exists.- Do not add
.tflockpermissions to replace it. The statement immediately above it already grantss3:PutObject/s3:DeleteObjectonarn:aws:s3:::hfla-ops-terraform-state/*, which covers the lock file — and the plan role does not lock anyway. - Do not "fix" the fact that a policy named
IncubatorTfPlanSecretsRead, attached to incubator's plan role, grants access to devops-security's backend. That cross-wiring predates this work. If it looks wrong to you, raise it as its own issue.
- Do not add
-
CONTRIBUTING.md— delete the#### Set up DynamoDB to store the backend statesection (lines 157–174, through the***afterBack to Top), and in the Creating Local tfvars file example (~line 251) swapdynamodb_table = "hfla_ops_terraform_table"foruse_lockfile = true. This is the section that tells every new member to create a lock table by hand. -
.github/ISSUE_TEMPLATE/pre-work-template-devops-security.md— delete the- [ ] Create the DynamoDB tablesub-item (line 40) and reword its parent (line 38) so it no longer promises a DynamoDB step. - Same no-op
.tfcomment requirement, and it is worse here: this repo's filter ispaths: ['**/*.tf']only, so.tfvars,.json,.mdand the issue template all fail to trigger it. - The plan gate is different in this repo. Expect exactly one change: an in-place update of
module.aws_custom_policies.aws_iam_policy.custom_policy["IncubatorTfPlanSecretsRead"], from the JSON edit. Anything else — any replacement, any second resource — is a stop-and-raise. - After the PR merges, confirm
Apply Terraform changes on mergesucceeds with noDeprecated Parameterwarning, and that the policy's new default version no longer contains the DynamoDB statement. - After the merge, re-open
/issues/new/chooseand confirm the pre-work template renders without the DynamoDB step. GitHub renders issue templates from the default branch only, so this genuinely cannot be checked from the branch.
3. Delete both tables — only after both PRs have merged and both apply runs are green:
-
Confirm no lock is held in either table.
aws dynamodb scan --table-name <table> --region us-west-2 --query 'Items[].LockID.S'must return only the-md5row. -
Record both table definitions in a comment on this issue before deleting, so the change is reversible without a PR trail to read. Capture
aws dynamodb describe-tableandaws dynamodb list-tags-of-resourcefor each. -
Disable deletion protection, then delete. Both calls need admin in
035866691871— if you do not have it, hand this step off rather than working around it.for t in hfla_incubator_terraform_table hfla_ops_terraform_table; do aws dynamodb update-table --table-name "$t" --region us-west-2 --no-deletion-protection-enabled aws dynamodb delete-table --table-name "$t" --region us-west-2 done -
Verify:
aws dynamodb list-tables --region us-west-2returns an empty list, and the next apply in each repo still succeeds. -
To reverse, recreate the table and re-enable protection. Terraform rewrites the
-md5digest row itself on the next apply, so the row does not need restoring.hfla_ops_terraform_tableadditionally carried tagsmanaged-by=exemptandproject=devops-security;hfla_incubator_terraform_tablecarried none.aws dynamodb create-table --table-name <table> --region us-west-2 \ --attribute-definitions AttributeName=LockID,AttributeType=S \ --key-schema AttributeName=LockID,KeyType=HASH \ --billing-mode PAY_PER_REQUEST aws dynamodb update-table --table-name <table> --region us-west-2 --deletion-protection-enabled
Do the backend swap in one step, not a two-phase migration — but know why:
- Terraform documents that
dynamodb_tableanduse_lockfilemay be set simultaneously, and that is the official migration path. Its only purpose is to keep two clients that disagree about the locking mechanism from both acquiring a lock. Since holding both keeps the deprecation warning firing, a phased migration means four PRs to clear a warning that two will clear. - The risk it covers is real but small here: while this is in flight, a
terraform applyfrom a local checkout that still hasdynamodb_tablewould not see a CI lock taken through S3, or vice versa. Mitigate by not running a local apply against either repo on the day the PRs merge, and by the lock check in step 3. - Note for anyone with an existing local checkout: CI initialises from a clean container every run, so there is no cached backend config and no migration prompt. A local
.terraform/directory will promptBackend configuration changedand needsterraform init -reconfigure.
Out of scope — do not do these here:
- Do not touch the action pins in these repos' workflows.
actions/checkout,aws-actions/configure-aws-credentialsanddflook/terraform-*belong to hackforla/devops#183, hackforla/incubator#158, hackforla/incubator#159 and hackforla/devops-security#170. - Do not tag or otherwise adopt the two state buckets.
hfla-incubator-terraform-stateis still untagged and still shows as unmanaged in the Terraform coverage report; that is separate work.
Resources/Instructions
- Files, all on
mainin both repos. Line numbers were accurate 2026-09-07 and may drift — locate each by its content rather than by position.hackforla/incubator:terraform/prod.backend.tfvarshackforla/devops-security:terraform/prod.backend.tfvars,terraform/aws-custom-policies/tf-plan-scoped.json,CONTRIBUTING.md,.github/ISSUE_TEMPLATE/pre-work-template-devops-security.md
- S3 backend documentation — the
use_lockfileargument, the statement that DynamoDB locking "is deprecated and will be removed in a future minor version", the simultaneous-configuration note, and the.tflockpermission list. - Terraform 1.11 CHANGELOG — "S3 native state locking is now generally available", the release that introduced the deprecation.
dflook/terraform-plan's-lock=falsebehaviour: image/entrypoints/plan.sh line 15.- Runs showing the warning, for comparison after the fix: incubator apply 34061802778, devops-security apply 34009820416.
- Lingua principale
- PowerShell
- Stelle
- 8
- Fork
- 10
- Merge medio
- 7h 30m
- PR unite (30g)
- 22
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di hackforla/devops
-
Fix CONTRIBUTING.md's "Getting write access" section - it contradicts the fork bot and the wiki Apertacomplexity: small feature: Onboarding good first issue role: DevOps Engineer size: 1pt
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
-
complexity: small feature: maintenance role: DevOps Engineer size: 1pt
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
-
complexity: small feature: maintenance role: DevOps Engineer size: 1pt
Difficoltà 3/5 1-2 giorni Idoneità per principianti 58/100
-
complexity: medium feature: security role: DevOps Engineer size: 3pt
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
-
complexity: large epic feature: project terraform setup role: DevOps Engineer size: 13+pt
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
Tutte le issue di hackforla/devops
Issue simili
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 80/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
-
oblt-aw/detector/security
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
trailofbits/skills#330 ·
-
Bug kind/engineering pulumi/pulumi-external Workflow Failure
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
pulumi/pulumi-external#733 ·