Loading...
Loading...
Best-practice authoring guidance AND a read-only policy gate for AWS Terraform generated by a migration skill. Load during any phase that writes a terraform/ directory — first as the "what to emit" posture rules + security-baseline spec, then after writing as the deterministic policy verdict. Read-only: it reports whether the generated Terraform passes; it never edits .tf files, never touches .phase-status.json, and never decides phase completion. Complements (does not replace) terraform fmt/init/validate.
npx skill4agent add awslabs/startups tf-best-practicesterraform/baseline.tfterraform/| Caller context | Load | Why |
|---|---|---|
About to author | Part 1 → | The "what to emit" AWS authoring rules (gate-enforced + authoring-only + compliance-conditional). |
| Part 2 → | The |
references/security-posture-rules.md.tf.phase-status.json.tfterraform fmt.phase-status.jsonConsumers (v1):only. The contract is source-agnostic and designed to be adopted bygcp-to-awslater, but that wiring is intentionally out of scope for now.heroku-to-aws
terraform/references/security-posture-rules.mdScope.covers, in three tiers:security-posture-rules.md
- Gate-enforced (Part 2 verifies statically): ALB TLS, no-public-database, RDS + ElastiCache encryption-at-rest, no-public-DB-port ingress, no-public admin/datastore-port ingress, no-wildcard-IAM.
- Authoring-only (not gate-checkable, still required):
, master-password-via-Secrets-Manager, S3 hardening, Fargate/EKS/ECR settings, private-subnet placement, backups, baseline monitoring.deletion_protection- Compliance-conditional (emitted when the caller declares
/soc2/pci/hipaa): VPC flow logs, S3 access logging, secret rotation, customer-managed KMS.fedrampStill the caller's own generation concern (candidates to migrate here later): the account-hardeninglayer (CloudTrail, GuardDuty, Config, Security Hub).baseline.tf
terraform/$PLUGIN_ROOT/skills/tf-best-practices/scripts/...python3 "$PLUGIN_ROOT/skills/tf-best-practices/scripts/validate-terraform-policy.py" "$TERRAFORM_DIR" --json "$VERDICT_PATH"$TERRAFORM_DIRterraform/$MIGRATION_DIR/terraform--json $VERDICT_PATHvalidation-report.jsonfmt → init → validate → policyvalidation-report.jsonreferences/terraform-validation.md| Exit | stdout | Meaning | Caller does |
|---|---|---|---|
| | posture satisfied | proceed |
| | violations present | read |
| (usage error) | bad path / IO | surface to user; do not treat as pass |
--json{
"check": "policy",
"policy_status": "POLICY_OK | POLICY_FAIL",
"violations": [
{
"check": "policy",
"rule": "alb_https_listener | alb_http_redirect | no_tf_files",
"file": "compute.tf",
"line": 7,
"severity": "error",
"summary": "human-readable violation",
"fix_hint": "concrete remediation the caller can apply"
}
]
}violations[]filelinefix_hintPOLICY_FAILinternalfalsealb_https_listener443certificate_arnforwardalb_http_redirect:80redirectforwardinternal = trueaws_db_instanceaws_rds_clusterrds_not_publicpublicly_accessible = truerds_encryption_at_reststorage_encrypted = truefalseaws_elasticache_replication_groupelasticache_encryption_at_restat_rest_encryption_enabled = truefalseaws_elasticache_clusterdb_sg_no_public_ingressaws_security_group543233060.0.0.0/0::/0sg_no_public_admin_ingress223389637911211270179200930056010.0.0.0/0::/080443cidr_blocksipv6_cidr_blocksaws_security_group_ruleaws_vpc_security_group_ingress_ruleaws_iam_policyaws_iam_role_policyaws_iam_group_policyaws_iam_user_policyno_wildcard_iamAllowActionResource"*"aws_iam_policy_documentThe checker is a zero-dependency static HCL reader (no, no provider download) — it runs even when the registry is unreachable. It uses brace-depth matching for nested blocks, so a valid HTTPS listener written with a nestedterraform initblock is not a false failure.forward { ... }
fixtures/terraform-policy/scripts/test_validate_terraform_policy.pybad-http-forward/POLICY_FAILinternal-alb-only/POLICY_OKgood-https-redirect/POLICY_OKcheckov.checkov.yamlskip-path# from skills/tf-best-practices/
uv run --python 3.12 --with pytest python -m pytest scripts/test_validate_terraform_policy.py -q