Copy and run from the repository root. Each step is one talking point.
export AWS_PROFILE=demo CTF_REGISTRY_TOKEN=... # registry token from compliance.tf
make check-tools login init
curl -s -o /dev/null -w '%{http_code}\n' "$(terraform -chdir=infra output -raw api_url)" # expect 200The running stack is branch baseline: plain terraform-aws-modules with insecure inputs.
git diff master baseline -- infra | head -60git checkout baseline && make scan; git checkout masterOne error per module: the source is not a compliance.tf endpoint.
make demo-prOpen the PR. The terraform plan comment names each control and its fix
(KMS rotation, SNS encryption, public IPs, log retention and encryption, IMDSv2).
The same check offline:
make verify-failmake demo-fixThe PR plan turns green: 0 to add, 0 to destroy, only the insecure attributes flip.
The same check offline (on master):
make verifymake exception-pr30-day container logs: ?disable=cloudwatch_log_group_retention_period_365 on one module.
The plan passes, but ctfkit scan fails and names the disabled control.
make record-exceptionAn entry in .github/ctfkit/exceptions.yaml with owner, approver and review date turns the scan green.
.github/ needs a code owner review, so nobody approves their own exception.
make reportThe same table is in the README, updated by the readme report workflow on every merge.
gh pr close demo/log-retention-exception --delete-branch
gh pr close demo/iso27001 --delete-branch