Skip to main content

Technical FAQ

Technical questions, answered from the repositories and the contributor rules. Deployment procedures are in the AWS Baseline documentation set; this page explains how the repositories behave.

What tools and versions do I need?

OpenTofu 1.12.6, Terragrunt 1.1.5, the AWS provider ~> 6.65 and tflint v0.64.0, pinned in root.hcl and the workflows; use the same versions locally. Python runs the guard scripts; pre-commit runs them before each commit. The full table is on the release notes page.

How do I customize the repositories for my organization?

Search for the tags. git grep "TODO: " lists every value that must be set (namespace, domain, account emails, GitHub organization, SSO group IDs, CI secrets); git grep "@optional: " lists every choice that may be changed (feature switches, compliance packs, sizing, cost-bearing options). The namespace acme, the domain company.com and the home region us-west-2 are each set in one place, common.hcl. Under the deployment tiers, BuiltForProd's team does this customization for you.

How do I add a region?

Add the region to the VPC map, create environments/<ou>/<account>/<region>/ folders with a region.hcl that declares only the region slug (the folder name is the region) and a terragrunt.stack.hcl listing the region's units, and re-apply the ipam unit, which discovers the new region from the tree. The region-restriction policy picks it up the same way. The address plan already reserves space: sixteen regions in the organization's /8.

How do I add a stage or account?

Add it to the account map in the organizations unit with its root email, give it an account.hcl and a region folder with a stack file (a workload account instantiates stacks/plat-account; a core account includes stacks/includes/account-common), add its VPC to the VPC map, place a workload stage in exactly one isolation domain in network.hcl, and add Identity Center assignments and the stage to the blueprint repositories' common.hcl, CI matrices and GitHub Environments. The address plan reserves eight workload stages per region.

Where is state, and how are keys named?

One S3 bucket, acme-use1-root-tfstate, in the management account in us-east-1, versioned, KMS-encrypted, TLS-only, with native locking. Each unit has its own key: environments/<ou>/<account>/<region or global>/<unit>/terraform.tfstate in the landing zone, apps/app-blueprint/... and apps/etl-blueprint/... in the blueprints. The key is the unit's generated path with the .terragrunt-stack/ segments removed, so it is the same whether a stack file lists the unit directly or a template generates it; see Terragrunt units and stacks.

Where do I run Terragrunt from?

From a folder that holds a terragrunt.stack.hcl (terragrunt stack run plan, terragrunt stack output, terragrunt stack clean) or from the repository root with --working-dir environments. Never from the repository root without it: Terragrunt would treat units/ and stacks/ as live configuration and generate into them.

Can I plan an environment before anything exists?

Yes. Every dependency in every unit declares mock outputs allowed for validate and plan, so a brand-new environment plans end to end, and apply always uses real outputs. Two limits: a dependency that has state but lacks a value (Organizations before accounts are enabled) is not helped by mocks, and units whose providers must reach a live resource (the EKS add-on units, Fluent Bit's cluster lookup) need the real dependency applied before their plan is meaningful. The web platform's shared-infra/eks units call get_aws_account_id() and need credentials to render even offline.

Why did my change to one unit plan changes in four accounts?

Because a unit definition is shared. units/vpc-spoke is listed by the plat-account template that all four workload accounts instantiate, so one edit affects all four; the required-inputs guard renders every generated unit for that reason. Per-account or per-stage differences belong in the stack file's values, not in the definition.

How do the blueprints get VPC IDs and subnets from the landing zone?

Through SSM Parameter Store, not through another repository's state. The landing zone's ssm-publish unit writes /acme/usw2/<stage>/vpc/{id,cidr,private_subnet_ids,public_subnet_ids}, /tgw/attachment_id and /account/id per workload account; blueprint modules read them with data sources and publish their own outputs (endpoints, certificate ARNs, CloudFront IDs) the same way.

Why does a workload role get AccessDenied on EBS or KMS?

The MFA statement of the guardrail policy denies roles that are neither acme-* nor tagged mfa-exempt = true. Name IAM roles for workloads within the namespace or add the tag.

How do I upgrade OpenTofu, a provider or a module?

Change the pin in root.hcl (and every module versions.tf the guard lists) or in the module or unit that carries the registry version, plan in dev, then staging, then prod, and revert the pin to roll back. Major module versions are high risk and need the upgrade guide read first. The versioning policy has the risk matrix; the procedures are indexed under upgrade guides.

Can I switch from the EKS address plan to the compact one later?

Not without a rebuild. Every CIDR differs between eks_vpc_map.yaml and non_eks_vpc_map.yaml, so switching destroys and recreates every VPC, subnet, pool, route and the Client VPN endpoint. The choice is made once, before the first deployment.

Do the repositories use Kubernetes for everything?

No. The web platform runs on EKS; the ETL platform is S3, Lake Formation, Glue and a Lambda trigger with no cluster; the landing zone has no Kubernetes at all. The brand note is explicit that BuiltForProd is not a Kubernetes company; the general FAQ covers positioning.