Skip to content

Add -ProjectTag to the AWS coverage script - #225

Merged
ale210 merged 1 commit into
masterfrom
197-project-tag-coverage
Sep 10, 2026
Merged

Add -ProjectTag to the AWS coverage script#225
ale210 merged 1 commit into
masterfrom
197-project-tag-coverage

Conversation

@ale210

@ale210 ale210 commented Sep 10, 2026

Copy link
Copy Markdown
Member

Delivers the re-runnable check asked for by hackforla/incubator#197, under epic hackforla/incubator#206.

-ProjectTag audits the project tag over the eight resource types the tag standard names, and classifies each resource four ways:

  • conforming — a value the standard recognises
  • shared — deliberately belongs to no single project
  • nonconforming — a value that is not in the standard
  • missing — no project tag at all

nonconforming is the bucket that matters, not missing, 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

default run -ProjectTag
Tag managed-by project
Scope ~30 resource types the 8 the standard names
Question does anything manage this? which project owns this?
A gap means a hygiene problem an outage

Bolting 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-Resource call 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 as nonconforming without being told to look for them — the civic-tech-index / civictechindex split now tracked as hackforla/incubator#217.

Status        Resources          Kind                   Total Conforming Nonconforming Missing
------        ---------          ----                   ----- ---------- ------------- -------
conforming           60          ecr-repository             8          8             0       0
shared                0          ecs-service               10         10             0       0
nonconforming         4          ecs-task-definition       10         10             0       0
missing              41          ssm-parameter             36         32             4       0
                                 cognito-user-pool          3          0             0       3
60 of 105 (57.1%)                log-group                 18          0             0      18
                                 s3-bucket                  5          0             0       5
                                 iam-role-*                15          0             0      15

The existing managed-by report is unaffected. Full sweep run on this branch and diffed against coverage-2026-09-06.csv: zero ARNs changed bucket, unmanaged still 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 not describe-*, list-* or get-*.

One trap documented in the README

aws ssm list-tags-for-resource accepts 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 with InvalidResourceId, and a sweep discarding stderr reads that as an untagged parameter.

That is what produced the "0 of 37 SSM parameters carry a project tag" 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.

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`.
@ale210
ale210 merged commit ea64aa4 into master Sep 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant