Authentication
Use AWS SSO and a named approved profile. Never put credentials in HCL or variable files.
Chapter 8 of 24
Bootstrap encrypted, versioned state once, then let independent roots use it with S3 lockfiles.
Use AWS SSO and a named approved profile. Never put credentials in HCL or variable files.
The bootstrap passes that profile to the AWS provider and fails its plan unless STS resolves to the expected account ID.
The shared S3 backend contract is use_lockfile = true; do not add a DynamoDB lock table.
This backend lab requires Terraform and OpenTofu >= 1.10.
The bootstrap root creates the KMS key and S3 bucket with local state. It has no backend block because it cannot safely store creation state in infrastructure that does not exist. After its reviewed apply, another root copies the backend output into a local uncommitted file and initializes. State flows forward only.
Read the bootstrap resources and backend example. The output supplies the created customer-managed key ARN as kms_key_id, so backend writes use SSE-KMS rather than the default AES256 encryption. Choose exactly one CLI per working directory; do not run Terraform and OpenTofu against the same local bootstrap state.
export COURSE_AWS_PROFILE="replace-with-approved-aws-profile"
export COURSE_AWS_ACCOUNT_ID="123456789012"
cd learn-terraform/labs/08-remote-state
terraform init -backend=false
terraform validate
aws --profile "$COURSE_AWS_PROFILE" --region ap-south-1 sts get-caller-identity --query '{Account:Account,Arn:Arn}' --output table
terraform plan \
-var='aws_region=ap-south-1' \
-var="aws_profile=$COURSE_AWS_PROFILE" \
-var="expected_aws_account_id=$COURSE_AWS_ACCOUNT_ID" \
-var='state_bucket_name=replace-with-a-unique-name'
# In a fresh copy of this lab, use OpenTofu instead:
tofu init -backend=false
tofu validate
aws --profile "$COURSE_AWS_PROFILE" --region ap-south-1 sts get-caller-identity --query '{Account:Account,Arn:Arn}' --output table
tofu plan \
-var='aws_region=ap-south-1' \
-var="aws_profile=$COURSE_AWS_PROFILE" \
-var="expected_aws_account_id=$COURSE_AWS_ACCOUNT_ID" \
-var='state_bucket_name=replace-with-a-unique-name'The displayed STS account and ARN must match the approved profile and expected account ID immediately before every plan or apply; the lab repeats that account check during planning and fails on a mismatch. It accepts no ambient default credentials. Re-run the same STS command immediately before a reviewed apply.
Use init -migrate-state only to move existing state after a backup and reviewed ownership decision. Use init -reconfigure only to discard cached backend settings and initialize the already-selected backend again; it does not migrate state. Neither option makes switching CLIs in a shared directory safe.
| Control | Expected |
|---|---|
| Identity | Named approved profile, STS account and ARN match the expected account, and region is ap-south-1. |
| S3 bucket | Unique input name, versioning enabled, all public access blocked, and prevent_destroy enabled. |
| Encryption | SSE-KMS using the bootstrap customer-managed key ARN; the key also has prevent_destroy. |
| Locking | use_lockfile = true in a separate S3 backend configuration. |
| Recovery | Inspect bucket versions and the last successful plan before state rollback. |
init -migrate-state only after a backup and ownership decision.ap-south-1.kms_key_id and use_lockfile = true.Retain bootstrap local state securely while the backend exists. The KMS key and versioned state bucket use prevent_destroy: remove those guards only through a deliberate reviewed change after every dependent state version has been migrated or removed and recovery has been verified. Never casually destroy the bootstrap or delete local state while its resources remain managed. Remove only generated initialization directories from this repository.
A configuration cannot safely store creation state in infrastructure that does not exist yet.
The shared use_lockfile = true contract.
Use approved identities, provider constraints, KMS permissions, lifecycle guards, and state ownership deliberately. The next phase builds the AWS network foundation on these boundaries.
Next: Chapter 9 will build the three-AZ network foundation.