Repository navigation
Description
Overview
We need to bring the account's two CloudTrail trails and their two log buckets into devops-security/terraform, because audit logging is a security control that currently exists only as console configuration — no issue or file in any of our repos so much as mentions CloudTrail. It is also the largest cluster of unmanaged resources left in 035866691871: 4 of the 19 in the 2026-09-06 coverage run.
Action Items
- Add a
cloudtrail.tfunderterraform/declaring both trails and both buckets, and put theimportblocks in the existingterraform/imports.tfalongside the IAM ones. - Import the two trails.
aws_cloudtrailimports by the trail's full ARN, not its name -- corrected 2026-09-11 after the name failed against the pinned provider (~> 6.64.0) withcould not parse import ID "management-events" as ARN: arn: invalid prefix. Usearn:aws:cloudtrail:us-west-2:035866691871:trail/<name>. Both are multi-region and both are currently logging:
-devops-security-tf-backend-logs— log file validation on, one advanced event selector for S3 data events (resources.ARN = arn:aws:s3:::hfla-ops-terraform-state/,resources.type = AWS::S3::Object)
-management-events— log file validation off, one advanced event selector named "Management events selector" foreventCategory = Management - Import the two buckets. A bucket is not one resource. In AWS provider v4 and later the policy, public access block, encryption and ownership controls are each their own resource with their own import, all taking the bucket name — the same trap
terraform/import.tfinhackforla/incubatordocuments for the civictechindex bucket. Verified live 2026-09-07:
-aws-cloudtrail-logs-035866691871-4b8654bf→ bucket, bucket policy, public access block (all four settingstrue), server-side encryption (AES256), ownership controls (BucketOwnerEnforced)
-aws-cloudtrail-logs-035866691871-6539ef03→ the same minus ownership controls, which this bucket does not have. Do not declare that resource for this bucket; declaring it would create one rather than import one, which is a live change. - Get both bucket policies in verbatim. Each carries the
AWSCloudTrailAclCheck20150319andAWSCloudTrailWrite20150319statements that let CloudTrail deliver to the bucket at all. A policy that drifts on apply stops log delivery, and it fails silently — nothing alerts, the trail simply stops writing. - Do not add a lifecycle configuration, KMS encryption or a CloudWatch Logs destination in this PR, even though all three are missing on both buckets. Adopt as-is so the plan stays reviewable; each of those changes live behaviour and belongs in its own ticket.
- Confirm the plan meets the adoption bar and state that bar in the PR body: 0 to add, 0 to destroy, no replacements, every change tags-only. Three of the four are untagged today and gain only
managed-by = terraform-devops-securityfrom the provider'sdefault_tags. The exception, corrected 2026-09-11:devops-security-tf-backend-logsalready carriesproject = devops-security, so that tag must be declared on the resource ordefault_tagswill plan to remove it. With it declared the trail keepsprojectand gainsmanaged-by, which still meets the bar. - After the PR merges, run
scripts/aws-terraform-coverage.ps1fromhackforla/devopsand confirm the four resources have moved out ofunmanaged. - Also after the merge, run
aws cloudtrail get-trail-statuson both trails and confirmIsLogging: truewith aLatestDeliveryTimeafter the apply. The plan cannot tell you the trails are still delivering; only this can.
Resources/Instructions
-
Precedent for an adoption PR of exactly this shape, including how the 0-add/0-destroy bar is stated for a reviewer: hackforla/incubator#186 (Cognito) and hackforla/incubator#193 (shared platform).
-
The multi-resource S3 import trap is written up in
terraform/import.tfinhackforla/incubator. -
Live state verified 2026-09-07; values may drift.
Trail Bucket What it captures Log file validation devops-security-tf-backend-logsaws-cloudtrail-logs-035866691871-4b8654bfS3 data events on hfla-ops-terraform-stateonlyon management-eventsaws-cloudtrail-logs-035866691871-6539ef03account management events off -
devops-security-tf-plancarriesReadOnlyAccess, which coverscloudtrail:DescribeTrails/GetEventSelectorsand the S3 getters, so the plan job needs no new permissions.devops-security-tf-applyhasAdministratorAccess. -
Two questions already answered, so nobody re-investigates them:
-devops-security-tf-backend-logswatcheshfla-ops-terraform-state, the livedevops-securityTerraform backend bucket — not thehlfa-incubator-terragruntbucket that was deleted under hackforla/incubator#170. That bucket exists and the trail is delivering, so the trail is worth importing rather than deleting.
- The two trails do not overlap. With advanced event selectors, a trail logs only what its selectors name, and the first trail has noManagementselector at all. So the account is not paying to record the same events twice — the trails are complementary, and importing both encodes a real design rather than a duplication. -
Deliberately out of scope, each worth its own ticket: neither trail is KMS-encrypted (
KmsKeyId: nullon both — they use SSE-S3); neither ships to CloudWatch Logs (CloudWatchLogsLogGroupArn: null, so there is no alerting path off either); neither bucket has a lifecycle configuration, so logs accumulate indefinitely and the storage bill only grows (the smaller bucket already holds 413,363 objects); and the two trails disagree on log file validation, which is an inconsistency to resolve rather than reproduce. -
Both trails have
IsOrganizationTrail: false, so neither covers the payer account504695638931. Whether org-level trail coverage is wanted is a separate decision, and it would live in an account that has no Terraform at all.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity