iac_modules/terraform-hcl-standard/aws-cloud
google-labs-jules[bot] a2c2b95558 Standardize cloud bootstrap destroy process
- Added bootstrap destroy module structure for aws, ali, azure, gcp, and vultr.
- Moved AWS force destroy script to `terraform-hcl-standard/aws-cloud/modules/bootstrap-destroy/destroy.sh`.
- Updated `iac-pipeline-mutli-cloud-bootstrap..yaml` to dynamically invoke the destroy script based on the cloud provider.
- Added placeholders for other cloud providers.
2026-01-02 02:14:20 +00:00
..
bootstrap Use BOOTSTRAP_CONFIG_PATH only for bootstrap config 2025-12-24 15:32:04 +08:00
component refactor(iac): standardize terraform modules and pipelines across clouds 2025-12-24 12:24:49 +08:00
modules Standardize cloud bootstrap destroy process 2026-01-02 02:14:20 +00:00
scripts refactor(iac): standardize terraform modules and pipelines across clouds 2025-12-24 12:24:49 +08:00
templates refactor: reorganize IaC modules and examples structure 2025-12-22 13:40:01 +08:00
README.md refactor(iac): standardize terraform modules and pipelines across clouds 2025-12-24 12:24:49 +08:00

Terraform Bootstrap for S3 Backend & DynamoDB Lock Table

This repository provides bootstrap Terraform modules that must be applied before enabling a Terraform remote backend on AWS. It creates:

  • IAM artifacts — a deploy role plus a dedicated DevOps/automation user for Terraform
  • S3 bucket — to store Terraform remote state
  • DynamoDB table — to store Terraform state locks

Both modules can be run independently.

  • bootstrap/state/ # S3 state bucket (versioning + SSE)
  • bootstrap/lock/ # DynamoDB lock table (LockID)
  • bootstrap/identity/ # IAM roles, policies and bootstrap users

** Note: S3 bucket must be emptied before deletion. **

Config Source of Truth (GitOps)

All AWS config YAML now lives in the external GitOps repo:

https://github.com/cloud-neutral-workshop/gitops.git

Clone it next to this repo (default path used in Terraform), or override with TF_VAR_config_root:

git clone https://github.com/cloud-neutral-workshop/gitops.git ../gitops
export TF_VAR_config_root="$(cd ../gitops && pwd)"

1. AWS Credentials Setup

Terraform reads AWS credentials through the standard AWS credential chain. You may use either A or B.

If your shell or CI job is already running under the target IAM role, set AWS_CLOUD_SKIP_ASSUME_ROLE=true before rendering/running Terraform to avoid a nested AssumeRole call:

export AWS_CLOUD_SKIP_ASSUME_ROLE=true

This prevents errors like AccessDenied when re-assuming the same deploy role.

export AWS_ACCESS_KEY_ID="AKIAxxxxxxxxxxxx"
export AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxx"
export AWS_DEFAULT_REGION="ap-northeast-1"

Terraform will automatically detect them.

B. AWS CLI Credentials File (~/.aws/credentials)

  • Run: aws configure
  • Credentials file: ~/.aws/credentials
Example:
[default]
aws_access_key_id     = AKIAxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxx
region                = ap-northeast-1

Select profile if needed: export AWS_PROFILE=default

2. Bootstrap: Create S3 Bucket

cd bootstrap/state
terraform init
terraform apply \
  -var="bucket_name=svc-plus-iac-state" \
  -var="region=ap-northeast-1"

This creates:

  • S3 bucket for Terraform state
  • Versioning enabled
  • Server-side encryption (AES256) enabled

3. Bootstrap: Create DynamoDB Lock Table

cd bootstrap/lock
terraform init
terraform plan \
  -var="region=ap-northeast-1" \
  -var="table_name=svc-plus-iac-state-dynamodb-lock"
terraform apply \
  -var="region=ap-northeast-1" \
  -var="table_name=svc-plus-iac-state-dynamodb-lock"
terraform output

This creates:

  • DynamoDB table: terraform-locks
  • Primary key: LockID

PAY_PER_REQUEST billing mode Compatible with Terraform backend locking

4. Bootstrap IAM Role

cd bootstrap/identity
terraform init
terraform apply \
  -var="account_name=dev" \
  -var="role_name=TerraformDeployRole-Dev"

By default the deploy role attaches the AWS managed **AdministratorAccess** policy so
subsequent Terraform runs can create infrastructure resources (e.g., VPCs, EIPs). You
can override this by passing `-var='managed_policy_arns=["arn:aws:iam::aws:policy/PowerUserAccess"]'`
or another list of managed policy ARNs when tighter permissions are required.

5. Use in Terraform Backend

After both bootstrap steps are completed:

terraform { backend "s3" { bucket = "my-terraform-state" key = "envs/dev/terraform.tfstate" region = "ap-northeast-1" encrypt = true dynamodb_table = "terraform-locks" } }

Then run:

terraform init -migrate-state

  1. Security Notes

Never store AWS credentials in Terraform variables Never commit credentials to Git

Prefer:

  • environment variables
  • AWS CLI profiles
  • IAM Role / SSO / OIDC (recommended)
  • S3 bucket has: Versioning ON

Server-side encryption ON

6. Cleanup

To remove bootstrap resources:

terraform destroy

Resource names (bucket, DynamoDB table, IAM role/user) are defined in the GitOps repo at config/accounts/bootstrap.yaml. When tearing down the S3 backend, empty the configured bucket with AWS CLI first:

aws s3 rb "s3://$(python -c "import os,yaml;root=os.environ.get('TF_VAR_config_root','../gitops');print(yaml.safe_load(open(f'{root}/config/accounts/bootstrap.yaml'))['state']['bucket_name'])")" --force

Access Key + STS 的执行流程(内部机制)

你的 Terraform 执行流程变成:

Terraform 读取你的 Access Key → 用 GET CALLER IDENTITY 验证身份 调用 sts:AssumeRole 获得临时凭证Session Token Terraform 使用临时凭证执行所有资源创建

AccessKey → STS → AssumeRole → 临时 Token → Terraform apply