@@ -43,6 +43,7 @@ This is a **tag sweep, not a Terraform state diff**. Read
4343./aws-terraform-coverage.ps1 -AwsProfile hfla-incubator # pick a named profile
4444./aws-terraform-coverage.ps1 -CsvPath coverage.csv # full classified list as CSV
4545./aws-terraform-coverage.ps1 -Region us-west-2 # narrow the sweep
46+ ./aws-terraform-coverage.ps1 -ProjectTag # audit the project tag instead
4647```
4748
4849A full run makes several hundred read-only API calls and takes a few minutes.
@@ -103,6 +104,81 @@ under-reports.
103104 something stamped a provenance tag that is neither repo's and is not ` exempt ` .
104105 Worth investigating when it shows up.
105106
107+ ### Auditing the ` project ` tag instead (` -ProjectTag ` )
108+
109+ ` -ProjectTag ` runs a ** different sweep against a different tag** , and answers a
110+ different question:
111+
112+ | | Default run | ` -ProjectTag ` |
113+ | ---| ---| ---|
114+ | Tag read | ` managed-by ` | ` project ` |
115+ | Scope | ~ 30 resource types, the whole account | the 8 resource types the tag standard names |
116+ | Question | does anything manage this? | which project owns this? |
117+ | A gap means | a hygiene problem | ** an outage** |
118+
119+ ``` powershell
120+ ./aws-terraform-coverage.ps1 -ProjectTag # summary and every nonconforming value
121+ ./aws-terraform-coverage.ps1 -ProjectTag -ListArns # plus every ARN missing the tag
122+ ./aws-terraform-coverage.ps1 -ProjectTag -CsvPath project-tags.csv
123+ ```
124+
125+ The standard is
126+ [ DR-Machine-to-machine-IAM-scoping] ( https://github.com/hackforla/devops/wiki/DR-Machine-to-machine-IAM-scoping )
127+ on the devops wiki. It defines the tag value as the Hack for LA ** project** name
128+ — ` vrms ` , ` home-unite-us ` , ` people-depot ` , ` civic-tech-jobs ` , ` civictechindex ` —
129+ never an application, environment or repository name, plus ` shared ` for
130+ infrastructure belonging to no single project.
131+
132+ ** Why this matters more than the ` managed-by ` report.** The machine roles in
133+ [ hackforla/incubator #206 ] ( https://github.com/hackforla/incubator/issues/206 ) are
134+ granted access on the basis of this tag matching, and ** tag-based access control
135+ fails closed** . A resource whose tag is missing or wrong is not over-shared; it
136+ becomes unreachable. Run this and read it immediately before any policy change
137+ that conditions on the tag.
138+
139+ Four outcomes per resource:
140+
141+ - ** ` conforming ` ** — carries a value the standard recognises.
142+ - ** ` shared ` ** — carries ` shared ` , i.e. deliberately belongs to no one project.
143+ - ** ` nonconforming ` ** — carries a value that is * not* in the standard. ** This is
144+ the dangerous bucket, not ` missing ` .** Such a resource looks correctly tagged
145+ in the console and still fails to match a policy, so it is always listed in
146+ full rather than summarised.
147+ - ** ` missing ` ** — carries no ` project ` tag at all.
148+
149+ Two things the report deliberately does * not* treat as equivalent:
150+
151+ - ** On the three machine IAM role families the tag is inventory only.** Policies
152+ name the project literally, interpolated by Terraform, rather than
153+ self-referencing ` ${aws:PrincipalTag/project} ` , so a missing tag on a * role*
154+ degrades reporting and cost allocation but breaks no access. A missing tag on
155+ a * resource* does break access.
156+ - ** A gap is not always fixable in a module.** Several untagged resources are
157+ not in Terraform at all, so tagging them means a hand-applied change or
158+ waiting on their import ticket. Check which before proposing where the fix
159+ goes.
160+
161+ The role families are matched by name, because nothing else distinguishes them.
162+ Note the naming is inverted: ` incubator-prod-ecs-task-role ` is the shared
163+ ** execution** role, while the per-container ** task** roles are the
164+ ` ecs-container-* ` ones.
165+
166+ #### A trap worth knowing before you re-check a result by hand
167+
168+ ` aws ssm list-tags-for-resource ` takes the parameter name as its resource id,
169+ leading slash included, and works fine. But ** Git Bash rewrites any argument
170+ beginning with ` / ` into a Windows path** , so the identical command run there
171+ fails with ` InvalidResourceId ` — and a sweep that discards stderr reads that as
172+ an untagged parameter.
173+
174+ That is exactly what produced the "0 of 37 SSM parameters carry a ` project ` tag"
175+ figure in
176+ [ hackforla/incubator #197 ] ( https://github.com/hackforla/incubator/issues/197 ) and
177+ in the decision record. It was wrong: every parameter was tagged the whole time.
178+ This script is unaffected because it is PowerShell, but anyone spot-checking one
179+ of its results from Git Bash will hit it. Drop the leading slash there, or use
180+ PowerShell.
181+
106182### Why it does not just use the Resource Groups Tagging API
107183
108184The obvious implementation is one ` resourcegroupstaggingapi get-resources ` call
@@ -199,3 +275,8 @@ created first. Open a follow-on issue if the report proves worth automating.
199275 added ` managed-by = terraform-incubator ` , for exactly this reporting purpose.
200276- [ hackforla/devops-security #172 ] ( https://github.com/hackforla/devops-security/issues/172 ) —
201277 the devops-security half of the same tagging work.
278+ - [ hackforla/incubator #197 ] ( https://github.com/hackforla/incubator/issues/197 ) —
279+ added ` -ProjectTag ` , and the audit it exists to make repeatable.
280+ - [ hackforla/incubator #206 ] ( https://github.com/hackforla/incubator/issues/206 ) —
281+ the epic whose policies condition on the ` project ` tag, and the reason a gap in
282+ that tag is an outage rather than a reporting defect.
0 commit comments