Skip to content

Commit ea64aa4

Browse files
authored
Add -ProjectTag to the AWS coverage script (#225)
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.
1 parent 46c4b34 commit ea64aa4

2 files changed

Lines changed: 469 additions & 1 deletion

File tree

‎scripts/README.md‎

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4849
A 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

108184
The 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

Comments
 (0)