Parallelism
Terraform run operations แบบ parallel อยู่แล้ว — ปรับ
-parallelismflag เพื่อ tune speed vs API rate limits
Default Parallelism
ทุก plan/apply Terraform รัน 10 operations concurrent:
terraform apply
# → up to 10 resources created in parallel
Adjust Parallelism
# เพิ่มเป็น 20
terraform apply -parallelism=20
# ลดเป็น 5 (สำหรับ provider rate-limited)
terraform apply -parallelism=5
เมื่อไหร่ควรเพิ่ม?
- ✅ Infrastructure ใหญ่ (100+ resources)
- ✅ Apply ช้าและไม่ติด rate limit
- ✅ Cloud provider แข็งแรง (AWS, GCP, Azure)
เมื่อไหร่ควรลด?
- ❌ Hit API rate limits
- ❌ Provider error:
Throttling exception - ❌ Dependent resources race condition
- ❌ Provider ที่ไม่ stable (community)
ดู Parallelism in Action
$ terraform apply -parallelism=20
aws_subnet.public[0]: Creating...
aws_subnet.public[1]: Creating...
aws_subnet.public[2]: Creating...
aws_subnet.private[0]: Creating...
aws_subnet.private[1]: Creating...
aws_subnet.private[2]: Creating...
# 20 resources running concurrently
Rate Limit Errors
ถ้าเจอ:
Error: Throttling: Rate exceeded
status code: 400, request id: ...
แก้:
# 1. ลด parallelism
terraform apply -parallelism=5
# 2. Retry (Terraform retry บางส่วนอัตโนมัติ)
terraform apply
Provider-Specific Rate Limits
AWS
- Most APIs: ~100-500 req/sec ต่อ region
- Some APIs (RDS, IAM): lower
- IAM specifically: 5-20 req/sec
provider "aws" {
region = "ap-southeast-1"
# Custom retry config
max_retries = 25
default_tags { ... }
}
GCP
- Default: 60 req/min (per user)
- Increase via quota requests
Azure
- ARM API: ~1200 req/hour per subscription
Adaptive Strategy
# Start fast
terraform apply -parallelism=20
# If errors, drop to default
terraform apply
# If still errors, drop more
terraform apply -parallelism=5
Per-Operation Tuning
ไม่สามารถตั้งต่อ resource — -parallelism ใช้ทั้ง plan/apply
แต่ใช้ -target แยก apply เป็น phases:
# Phase 1: Network (low parallelism — sensitive)
terraform apply -target=module.network -parallelism=5
# Phase 2: Compute (high parallelism)
terraform apply -target=module.compute -parallelism=20
# Phase 3: Final apply
terraform apply
Concurrency in Provider
ก่อน Terraform parallelism — provider ก็ทำ concurrent calls:
provider "aws" {
# AWS provider จะใช้ http connection pool
}
ลด throttling ระดับ provider:
provider "aws" {
retry_mode = "adaptive" # Adaptive retry (handle rate limit)
max_retries = 25
}
Refresh Parallelism
terraform refresh (และ plan's implicit refresh) ก็ใช้ parallelism:
terraform plan -refresh-only -parallelism=20
ถ้า plan ช้า — มักเป็น refresh phase (อ่าน 100+ resources จาก provider)
แก้:
- เพิ่ม parallelism
- ใช้
-refresh=false(skip refresh — ระวัง drift!)
terraform plan -refresh=false # plan แค่ตาม config + state
Plan Performance Tips
1. Targeted Plan
terraform plan -target=aws_instance.web # plan เฉพาะ resource
2. Skip Refresh
terraform plan -refresh=false # ไม่อ่าน reality (faster but stale)
3. Split State
ถ้า plan > 30s → split state (ดู Splitting Large State)
4. Cache Provider
export TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache
mkdir -p $TF_PLUGIN_CACHE_DIR
→ ลดเวลา init จาก 30s → 5s
ตัวอย่าง: Performance Benchmarks
# Small state (10 resources)
$ time terraform plan
real 0m3.2s # default parallelism = OK
# Large state (200 resources)
$ time terraform plan -parallelism=10
real 0m45s
$ time terraform plan -parallelism=20
real 0m25s # 1.8x faster
$ time terraform plan -parallelism=30
real 0m24s # diminishing returns
Gotchas
1. Order Matters Sometimes
Parallel ≠ unordered. Terraform หา dependency แล้วทำตาม order:
resource "aws_vpc" "main" { ... } # ✅ first
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # depends on VPC
count = 3 # ✅ 3 subnets parallel
}
VPC สร้างก่อน → 3 subnets parallel
2. Dependent Resources Wait
[VPC] → [Subnet A] [Subnet B] [Subnet C] (parallel)
↓ ↓ ↓
[SG A] [SG B] [SG C] (parallel หลัง subnet)
Terraform คำนวณ DAG อัตโนมัติ
3. Implicit Dependency Misses
resource "aws_iam_role" "lambda" { ... }
resource "aws_iam_role_policy" "lambda" { ... }
resource "aws_lambda_function" "x" {
role = aws_iam_role.lambda.arn
# ❌ Missing: depends_on = [aws_iam_role_policy.lambda]
}
Lambda might run before policy attached → fail
แก้:
depends_on = [aws_iam_role_policy.lambda]
Best Practices
✅ DO:
- ใช้ default parallelism (10) ก่อน
- เพิ่มถ้า apply ช้า + ไม่ rate limited
- ลดถ้าเจอ throttling
- ใช้ targeted apply ใน emergency
- Cache provider plugins
❌ DON'T:
- ห้ามตั้ง parallelism สูงเกิน (>50) — มักไม่ช่วย + อันตราย
- ห้ามใช้ -refresh=false ใน prod (drift!)
- ห้าม skip dependency declarations เพื่อหวัง parallel
Concurrency Patterns
Multi-Stack Parallel (ผ่าน Terragrunt)
# Apply ทุก stack ที่ไม่มี dependency กัน — parallel
terragrunt run-all apply --terragrunt-parallelism 10
→ Multiple stack apply พร้อมกัน
Multi-Region Parallel
# Region 1
cd us-east-1 && terraform apply -auto-approve &
# Region 2
cd ap-southeast-1 && terraform apply -auto-approve &
# Wait
wait
(ระวัง state lock + console output mixing)
สรุป
- Default parallelism = 10
- Tune ด้วย
-parallelism=N - เพิ่มเมื่อ apply ช้า + ไม่ rate limit, ลดเมื่อ throttling
-refresh=falseskip refresh (faster but stale)- Cache provider plugins ลดเวลา init
- Use Terragrunt สำหรับ multi-stack parallel
ต่อไป → Deployment Workflow