hackforla / hackforla/incubator

Remove the Terragrunt-era tags from the shared platform resources

Open
#222 0 comments 0 reactions 0 assignees View on GitHub
complexity: small feature: project terraform setup good first issue role: DevOps Engineer size: 1pt
Dominant language
HCL
Stars
6
Forks
18
Avg merge
1h 9m
Merged PRs (30d)
42

Description

### Overview

We need to delete the `terraform_managed`, `last_changed` and `terraform_user_arn` tags from the five resources in `terraform/platform/`, because they claim something manages the resource and state when it last changed, and both claims are false. `managed-by = terraform-incubator`, set by the provider's `default_tags`, is the real management signal, and `last_changed` has been frozen for between two and five years while the resources underneath it changed repeatedly.

### Action Items

- [ ] Delete the tags listed below from each resource block. Line numbers were accurate on 2026-09-12 and may drift — find each block by its resource address.

| Resource | File | Live name | Tags to delete |
|---|---|---|---|
| `aws_vpc.this` | `terraform/platform/main.tf:34-36` | `incubator-prod-vpc` | all three |
| `aws_lb.this` | `terraform/platform/ingress.tf:31-32` | `incubator-prod-lb` | `terraform_managed`, `last_changed` |
| `aws_security_group.alb` | `terraform/platform/security.tf:10-11` | `incubator-prod-alb` | `terraform_managed`, `last_changed` |
| `aws_security_group.database` | `terraform/platform/security.tf:50-51` | `incubator-prod-database` | `terraform_managed`, `last_changed` |
| `aws_iam_role.ecs_task_execution` | `terraform/platform/iam.tf:92-93` | `incubator-prod-ecs-task-role` | `terraform_managed`, `last_changed` |

- [ ] Delete the `# Terragrunt-era, from a state file that no longer exists. Adopted, not believed.` comment above each of those tag lines at the same time. It explains why the tags were kept; once they are gone it describes nothing.
- [ ] On `aws_iam_role.ecs_task_execution` the two tags are the **entire** `tags` block. Remove the whole block rather than leaving `tags = {}` behind — the role still gets `managed-by` from `default_tags`, so it does not go untagged. This is the only one of the five where the block itself goes.
- [ ] Keep every `Name` tag. `Name` is real, it is what the console displays, and four of the five resources carry one. Deleting a `Name` renames the resource in every console listing.
- [ ] Decide `terraform_user_arn` explicitly rather than by omission. It is a single occurrence, on the VPC, and it names an individual's IAM user (`.../DarrenP`) as the last person to touch the account's only VPC. It is the one of the three with any residual signal value — and it is wrong anyway, since that user has not applied anything since the Terragrunt platform was retired. The recommendation is that it goes with the other two; say so on the PR either way.
- [ ] Confirm the plan meets the bar before applying: **5 to change, 0 to add, 0 to destroy, no replacements.** Anything proposing to replace the VPC, the load balancer or either security group is wrong and must not be applied. `aws_vpc.this` already carries `prevent_destroy` for exactly this reason, so such a plan will fail rather than proceed — treat that failure as the guard working, not as something to work around.
- [ ] **Leave the 11 legacy module defaults alone.** Each `terraform/modules/legacy/*/variables.tf` declares `default = { terraform_managed = "true" }`. Those modules are unreachable from `main`, so changing them alters nothing live, and the default is echoed into every one of their terraform-docs-generated `README.md` tables — so the change is 11 rewritten READMEs for no live effect. Considered and skipped deliberately; this item exists so a later audit does not re-raise it.
- [ ] **Record a decision on the one manual RDS snapshot, and expect it to be "leave it".** `aws_db_instance.default` sets `copy_tags_to_snapshot = true`, so snapshots inherited `terraform_managed` from the instance. hackforla/incubator#214 removed the tag from the instance on 2026-09-11, which stops new ones inheriting it. The five automated snapshots still carrying it age out on their own (`backup_retention_period = 4`). Only `incubator-prod-database-pre-pg15`, taken 2026-08-10 before the PostgreSQL 15 upgrade, never expires — and retagging it edits a record of what was true at the time. Snapshots are not in Terraform, so any cleanup there is a direct API change and needs the pre-change capture discipline.
- [ ] After the PR merges and applies, confirm the tags are gone from the live resources. The first command returns the four non-IAM resources and the second covers the IAM role, which the first structurally cannot see:

```bash
aws resourcegroupstaggingapi get-resources --tag-filters Key=terraform_managed --region us-west-2 \
--query 'ResourceTagMappingList[].ResourceARN' --output text | tr '\t' '\n' | sort
aws iam list-role-tags --role-name incubator-prod-ecs-task-role --query Tags --output table
```

Expect the first to return only RDS snapshots and the second to return `managed-by` alone.

### Resources/Instructions

- **This is not reversing hackforla/incubator#184.** That issue adopted these tags verbatim so its platform-adoption plan would come out empty, which is the property that made adopting live production infrastructure reviewable. `terraform/platform/main.tf` still carries the comment *"Terragrunt-era, from a state file that no longer exists. Adopted, not believed."* So this is deliberate debt being paid down on schedule, not drift being corrected — a reviewer who reads it the other way will object to the wrong thing.
- **Trap: `resourcegroupstaggingapi` does not cover IAM.** A sweep using only the tagging API returns four resources and silently omits `incubator-prod-ecs-task-role`, which carries both tags — confirmed with `list-role-tags`. The result reads as clean rather than partial. The verification step above uses both calls for this reason.
- **Overlap to check before starting: hackforla/incubator#201** has an action item reading *"Decide what happens to the now-unused shared role `incubator-prod-ecs-task-role`, and to its stale Terragrunt-era tags."* That item is about the role's **fate** — whether it survives at all once per-container execution roles replace it — which is a larger question than its tags and is explicitly deferred there. Removing the tags here does not pre-empt it and does not block it. Whichever moves first, check the other, since both touch the same block.
- Nothing reads these tags. Confirmed by code search across all three repos on 2026-09-11: no policy, filter, workflow or script keys on them, and `scripts/aws-terraform-coverage.ps1` in hackforla/devops keys on `managed-by` alone. The value of this change is that a reader stops seeing two contradictory management claims on the same resource.
- The `terraform_managed` and `last_changed` pair was removed from `terraform/database.tf` in hackforla/incubator#214 for the same reason. That PR is the worked precedent for both the change and the plan bar.
- Validate locally before spending a CI round trip. `incubator` pins `required_version = "~> 1.16.0"`; `terraform init -backend=false` followed by `terraform validate` and `terraform fmt -check -diff` needs no AWS credentials, no backend and no state.

Contributor guide

Open the contributing guide

Research direction

Start with the five resource blocks in terraform/platform/main.tf, ingress.tf, security.tf, and iam.tf, then run terraform init -backend=false, terraform validate, and terraform fmt -check -diff. Remove only the specified legacy tags and comments while preserving Name and managed-by; done means a plan with 5 to change, 0 to add, 0 to destroy, no replacements, followed by both live tag verification commands.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, terraform
Domain
cloud, infrastructure
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.