Here is the whole repository at a glance, grouped by the five layers. The arrows show the order you stand them up.
bootstrap/ → platform/ → modules/ (called by) → envs/dev|staging|prod/
↘ cicd/ (delivers the envs)| Directory | Kind | What it does |
|---|---|---|
bootstrap/ |
root | Creates the remote-state backend (S3 bucket + KMS key) for one account. Local state. Run once per account. |
platform/ |
root | The "landing zone": creates the AWS Organization, the member accounts, guardrail SCPs, org-wide CloudTrail, IAM Identity Center, and budgets. Runs in the management account. |
modules/ |
modules | Reusable building blocks (networking, ecs, rds, …). Not run directly - called by roots. |
envs/dev, envs/staging, envs/prod |
roots | One root per environment/account. Each composes modules into a full environment, with its own state. |
cicd/ |
root | Creates one CodePipeline per environment, so changes deploy automatically. |
Supporting files at the repo root: Makefile (command shortcuts),
.tool-versions (pinned tool versions), .tflint.hcl (linter config),
.pre-commit-config.yaml (git hooks), .gitignore, and the README.md /
SETUP.md guides.
The conventional file split inside a root or module
Across the repo, each root/module splits its code into files by purpose (a
common Terraform/OpenTofu convention). OpenTofu loads all .tf files in a
directory together, so this split is purely for human readability:
| File | Holds |
|---|---|
main.tf |
The actual resources / module calls. |
variables.tf |
Input variables. |
outputs.tf |
Output values. |
versions.tf |
Required OpenTofu + provider versions. |
providers.tf |
Provider configuration (region, account, tags). |
backend.tf |
Remote state backend config (roots only). |
terraform.tfvars.example |
A copy-me template of input values. |
backend.s3.tfbackend.example |
A copy-me template for the generated KMS key id. |
README.md |
Human docs for that piece. |
You will see this same set of filenames in nearly every directory.