feat(terraform-standard): add S3 and DynamoDB bootstrap modules with backend setup
This commit is contained in:
parent
4b7789265c
commit
f7960153fe
132
iac-template/terraform-standard/README.md
Normal file
132
iac-template/terraform-standard/README.md
Normal file
@ -0,0 +1,132 @@
|
||||
# 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:
|
||||
- S3 bucket — to store Terraform remote state
|
||||
- DynamoDB table — to store Terraform state locks
|
||||
|
||||
Both modules can be run independently.
|
||||
|
||||
- bootstrap-s3/ # S3 state bucket (versioning + SSE)
|
||||
- bootstrap-dynamodb/ # DynamoDB lock table (LockID)
|
||||
|
||||
---
|
||||
** Note: S3 bucket must be emptied before deletion. **
|
||||
|
||||
## 1. AWS Credentials Setup
|
||||
|
||||
Terraform reads AWS credentials through the standard AWS credential chain. You may use either A or B.
|
||||
|
||||
### A. Environment Variables (recommended for local / CI)
|
||||
|
||||
```
|
||||
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-s3
|
||||
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-dynamo-db
|
||||
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. 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
|
||||
|
||||
5. 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
|
||||
|
||||
|
||||
# Access Key + STS 的执行流程(内部机制)
|
||||
|
||||
你的 Terraform 执行流程变成:
|
||||
|
||||
Terraform 读取你的 Access Key
|
||||
→ 用 GET CALLER IDENTITY 验证身份
|
||||
调用 sts:AssumeRole
|
||||
获得临时凭证(Session Token)
|
||||
Terraform 使用临时凭证执行所有资源创建
|
||||
|
||||
AccessKey → STS → AssumeRole → 临时 Token → Terraform apply
|
||||
|
||||
8
iac-template/terraform-standard/backend.tf
Normal file
8
iac-template/terraform-standard/backend.tf
Normal file
@ -0,0 +1,8 @@
|
||||
terraform {
|
||||
backend "s3" {
|
||||
bucket = "svc-plus-iac-state"
|
||||
key = "sit/ec2/terraform.tfstate"
|
||||
region = "svc-plus-iac-state-locks"
|
||||
encrypt = true
|
||||
}
|
||||
}
|
||||
25
iac-template/terraform-standard/bootstrap-dynamodb/.gitignore
vendored
Normal file
25
iac-template/terraform-standard/bootstrap-dynamodb/.gitignore
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Local terraform files
|
||||
.terraform/
|
||||
.terraform.lock.hcl
|
||||
terraform.tfstate
|
||||
terraform.tfstate.backup
|
||||
|
||||
# Auto tfvars generated by CI/CD or sensitive data
|
||||
*.tfvars
|
||||
*.auto.tfvars
|
||||
*.tfvars.json
|
||||
|
||||
# IDE / editor files
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
|
||||
# AWS credentials — never commit
|
||||
.aws/
|
||||
credentials
|
||||
config
|
||||
|
||||
# OS-specific
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
16
iac-template/terraform-standard/bootstrap-dynamodb/main.tf
Normal file
16
iac-template/terraform-standard/bootstrap-dynamodb/main.tf
Normal file
@ -0,0 +1,16 @@
|
||||
resource "aws_dynamodb_table" "terraform_locks" {
|
||||
name = var.table_name
|
||||
billing_mode = "PAY_PER_REQUEST"
|
||||
|
||||
hash_key = "LockID"
|
||||
|
||||
attribute {
|
||||
name = "LockID"
|
||||
type = "S"
|
||||
}
|
||||
|
||||
tags = {
|
||||
Name = var.table_name
|
||||
Environment = "bootstrap"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
output "dynamodb_table_name" {
|
||||
description = "The name of the DynamoDB state lock table"
|
||||
value = aws_dynamodb_table.terraform_locks.name
|
||||
}
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
terraform {
|
||||
required_version = ">= 1.2"
|
||||
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.92"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.region
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
variable "table_name" {
|
||||
description = "DynamoDB table name for Terraform state lock"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "AWS region"
|
||||
type = string
|
||||
}
|
||||
13
iac-template/terraform-standard/bootstrap-s3/...
Normal file
13
iac-template/terraform-standard/bootstrap-s3/...
Normal file
@ -0,0 +1,13 @@
|
||||
cd bootstrap-s3
|
||||
|
||||
export AWS_ACCESS_KEY_ID="AKIAxxxxxxxx"
|
||||
export AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxx"
|
||||
export AWS_DEFAULT_REGION="ap-northeast-1"
|
||||
|
||||
terraform init
|
||||
terraform apply \
|
||||
-var="bucket_name=my-terraform-state" \
|
||||
-var="region=ap-northeast-1"
|
||||
|
||||
|
||||
~/.aws/credentials
|
||||
25
iac-template/terraform-standard/bootstrap-s3/.gitignore
vendored
Normal file
25
iac-template/terraform-standard/bootstrap-s3/.gitignore
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Local terraform files
|
||||
.terraform/
|
||||
.terraform.lock.hcl
|
||||
terraform.tfstate
|
||||
terraform.tfstate.backup
|
||||
|
||||
# Auto tfvars generated by CI/CD or sensitive data
|
||||
*.tfvars
|
||||
*.auto.tfvars
|
||||
*.tfvars.json
|
||||
|
||||
# IDE / editor files
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
|
||||
# AWS credentials — never commit
|
||||
.aws/
|
||||
credentials
|
||||
config
|
||||
|
||||
# OS-specific
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
21
iac-template/terraform-standard/bootstrap-s3/main.tf
Normal file
21
iac-template/terraform-standard/bootstrap-s3/main.tf
Normal file
@ -0,0 +1,21 @@
|
||||
resource "aws_s3_bucket" "state" {
|
||||
bucket = var.bucket_name
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_versioning" "versioning" {
|
||||
bucket = aws_s3_bucket.state.id
|
||||
|
||||
versioning_configuration {
|
||||
status = "Enabled"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket_server_side_encryption_configuration" "sse" {
|
||||
bucket = aws_s3_bucket.state.id
|
||||
|
||||
rule {
|
||||
apply_server_side_encryption_by_default {
|
||||
sse_algorithm = "AES256"
|
||||
}
|
||||
}
|
||||
}
|
||||
3
iac-template/terraform-standard/bootstrap-s3/outputs.tf
Normal file
3
iac-template/terraform-standard/bootstrap-s3/outputs.tf
Normal file
@ -0,0 +1,3 @@
|
||||
output "bucket_name" {
|
||||
value = aws_s3_bucket.state.bucket
|
||||
}
|
||||
14
iac-template/terraform-standard/bootstrap-s3/provider.tf
Normal file
14
iac-template/terraform-standard/bootstrap-s3/provider.tf
Normal file
@ -0,0 +1,14 @@
|
||||
terraform {
|
||||
required_version = ">= 1.2"
|
||||
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 5.92"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = var.region
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
variable "bucket_name" {
|
||||
description = "S3 bucket name for Terraform state"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "AWS region"
|
||||
type = string
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user