Add -ProjectTag to the AWS coverage script - #225
Merged
Conversation
Audits the project tag over the resource types the tag standard names, classifying each as conforming, shared, nonconforming or missing and validating values against the standard's list. Separate from the managed-by sweep rather than a second dimension on it: the two cover different resource types and a gap means different things. A missing managed-by tag is a hygiene problem; a missing or wrong project tag denies access, because the policies conditioning on it fail closed.
ale210
added a commit
to hackforla/incubator
that referenced
this pull request
Sep 10, 2026
Part of #197, under epic #206. Adds the `project` tag to the three untagged resource types that Terraform can actually reach: | Resource | Where | Covers | |---|---|---| | ECS log group | `modules/container/main.tf` — the `tags` block was there but empty | all 10 `/ecs/*` groups | | Cognito user pools | `projects/home-unite-us/cognito-{prod,qa}.tf` | 2 of the account's 3 pools | | Website bucket | `projects/civic-tech-index/s3.tf` | `civictechindex.org` | ### What to look for in the plan **Tags-only changes, nothing added, destroyed or replaced.** In particular both Cognito pools must show a tag change and nothing else — `cognito-prod.tf` carries a header comment stating that a proposed change to that file is a defect rather than drift, and this PR is the intended exception to it. ### The bucket's tag value is written literally on purpose `local.project_name` in `projects/civic-tech-index/` is `civic-tech-index`, but the tag standard's value is `civictechindex` — the same reason `ecr.tf` hardcodes it. Using the local there would have added a fifth resource to the wrong side of that split. The two spellings are reconciled in #217; the comment in `s3.tf` says not to switch it back before then. ### Not in this PR These are untagged and stay untagged, because none of them is in Terraform — tagging them would mean a hand-applied change to a resource whose import ticket is already open: - Cognito pool `us-west-2_Fn4rkZpuB` (#17) - `/aws/rds/instance/incubator-prod-database/{postgresql,upgrade}` (#214) - `RDSOSMetrics`, `ecs/homeuniteus`, and the four `/aws/lambda/*` log groups - the CloudTrail and Terraform state buckets - the 15 machine IAM roles, which are #198 and #199 ### Verification `terraform init -backend=false` and `terraform validate` pass locally on Terraform 1.16.0, the pinned version. `terraform fmt -check` is clean on all four changed files. After this merges and applies, `./aws-terraform-coverage.ps1 -ProjectTag` (added in hackforla/devops#225) should move 13 resources out of `missing`.
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.
Delivers the re-runnable check asked for by hackforla/incubator#197, under epic hackforla/incubator#206.
-ProjectTagaudits theprojecttag over the eight resource types the tag standard names, and classifies each resource four ways:conforming— a value the standard recognisesshared— deliberately belongs to no single projectnonconforming— a value that is not in the standardmissing— noprojecttag at allnonconformingis the bucket that matters, notmissing, so it is printed in full on every run. Tag-based access control fails closed: a resource carrying an unrecognised value looks correctly tagged in the console and is still denied.Why a separate sweep rather than a second column on the existing one
-ProjectTagmanaged-byprojectBolting a project dimension onto all ~30 collectors would report a project tag for KMS keys and route tables, inventing gaps the standard never asked for — and would have meant editing all 43
Add-Resourcecall sites in a script whose value is being trustworthy.Verification
Run live against
035866691871. It independently reproduces the incubator#197 audit, including flagging four SSM parameters asnonconformingwithout being told to look for them — thecivic-tech-index/civictechindexsplit now tracked as hackforla/incubator#217.The existing
managed-byreport is unaffected. Full sweep run on this branch and diffed againstcoverage-2026-09-06.csv: zero ARNs changed bucket,unmanagedstill 19. The only row differences are real churn — rolling RDS snapshots, a cycled ENI and ECS task, and the security group rule deleted by hackforla/incubator#213.Still read-only: the new collectors go through the same
Invoke-AwsCli, which refuses any subcommand that is notdescribe-*,list-*orget-*.One trap documented in the README
aws ssm list-tags-for-resourceaccepts a parameter name with its leading slash — but Git Bash rewrites any argument starting with/into a Windows path, so the same call there fails withInvalidResourceId, and a sweep discarding stderr reads that as an untagged parameter.That is what produced the "0 of 37 SSM parameters carry a
projecttag" figure in incubator#197 and in the decision record. It was wrong — every parameter was tagged the whole time. This script is PowerShell and unaffected, but anyone spot-checking one of its results from Git Bash will hit it.