학습 목표
dev·staging·prod 환경을 Terraform으로 분리하는 대표 패턴을 비교할 수 있다.
workspace와 directory per environment의 trade-off를 설명할 수 있다.
terraform.tfvars·-var-file·TF_VAR_*로 환경별 변수를 주입할 수 있다.
backend key·state 분리와 환경 전략을 함께 설계할 수 있다.
실무에서 같은 module·다른 env 구조를 잡을 수 있다.
문제 상황
main.tf에bucket = "myapp-prod"하드코딩 — staging apply 시 prod 이름 충돌terraform workspace select prod했는데 VPC가 dev와 공유 — workspace만 바꾸고 backend key는 그대로env/prod,env/staging폴더 복제 — SG rule 수정할 때 3곳 패치- CI가
-var environment=prod만 넘기고 tfvars 없음 — 기본값이 dev라 의도치 않은 리소스 terraform.tfvars를 Git에 올렸다가 account_id·내부 URL 노출- 4편에서 module·remote state까지 했는데 — 환경마다 state·변수를 어떻게 나눌지 미정
앞 편에서 state·module로 협업·재사용 기반을 잡았다. 이번 편은 같은 코드로 dev/staging/prod를 안전히 나누는 환경 전략이다. AWS CDK는 6편부터 Part 2다.
1. 환경 분리가 필요한 이유
| 위험 | 환경 미분리 시 |
|---|---|
| 이름 충돌 | 같은 AWS 계정·리전에서 bucket·SG 중복 |
| state 섞임 | dev destroy가 prod 리소스 참조 |
| 권한 | CI가 prod에 의도치 않은 apply |
| 설정 drift | env마다 다른 .tf 복사본 |
- 목표
- 코드는 하나(또는 module 하나), 상태·변수는 env별
- plan/apply가 어느 환경 대상인지 명확

same modules + same .tf logic
× per env: state key · tfvars · credentials · approval
→ dev / staging / prod isolated
2. Workspace vs Directory
두 가지 대표 패턴. 둘 다 쓸 수 있지만 팀 규모·CI에 따라 선택.

Terraform Workspace
- 한 디렉터리(root module), 여러 workspace — 각 workspace = 별도 state
- 기본 workspace 이름:
default
terraform workspace list
terraform workspace new staging
terraform workspace select staging
terraform plan -var-file=staging.tfvars
terraform apply
| 장점 | 단점 |
|---|---|
| 코드 중복 없음 | terraform.workspace 조건문 유혹 |
| 전환 빠름 | backend key에 workspace 미반영 시 사고 (아래 주의) |
| 소규모·학습에 단순 | backend 설정·provider alias가 env마다 다르면 어색 |
# 가능하지만 남용 주의 — env별 분기가 .tf에 퍼짐
resource "aws_s3_bucket" "logs" {
bucket = "myapp-${terraform.workspace}-logs"
}
- backend와 workspace
- S3 backend는 기본적으로 key에
env:/<workspace>/prefix를 붙일 수 있음 (설정·버전 확인) - 명시적 key 전략:
key = "app/${terraform.workspace}/terraform.tfstate"는 interpolate 불가 — 보통 directory 또는 CI가 key 주입 (-backend-config)
- S3 backend는 기본적으로 key에
Directory per Environment
infra/
├── modules/
└── environments/
├── dev/
│ ├── main.tf
│ ├── backend.tf
│ └── dev.tfvars
├── staging/
└── prod/
- env 폴더마다 backend key·provider·main — state 완전 분리
main.tf는 module 호출만 — 차이는 tfvars·backend
| 장점 | 단점 |
|---|---|
| CI가 폴더만 지정 — 실수 적음 | 초기 보일러플레이트 |
| prod 승인·IAM 폴더 단위 분리 | 공통 변경 시 여러 env touch |
| backend·provider env별 다르기 쉬움 |
실무 추천 (요지)
| 상황 | 추천 |
|---|---|
| 팀·prod·여러 account | directory + remote state key per env |
| 동일 account·소규모·차이 적음 | workspace + tfvars (backend key 설계 필수) |
| 대기업·강한 거버넌스 | 별도 repo/stack + Terragrunt 등 wrapper (본 시리즈는 Terraform core) |
3. tfvars와 변수 주입
환경 차이는 변수로 밀어 넣는다.
# variables.tf
variable "environment" {
type = string
description = "dev | staging | prod"
}
variable "instance_count" {
type = number
default = 1
}
# code/environments/prod.tfvars.example
environment = "prod"
instance_count = 3
vpc_cidr = "10.2.0.0/16"
terraform plan -var-file=prod.tfvars
terraform apply -var-file=prod.tfvars
# 또는
export TF_VAR_environment=prod
terraform plan
| 방법 | 용도 |
|---|---|
terraform.tfvars |
기본값 (자동 로드) |
*.auto.tfvars |
자동 로드·env 파일 분리 |
-var-file |
CI·명시적 env |
-var |
일회성 |
TF_VAR_* |
CI secret·env 주입 |

- 민감 값 — tfvars에 secret 넣지 말 것 → Secrets Manager·CI secret·
TF_VAR_ .gitignore—*.tfvars중 secret 포함 파일;.example만 커밋
4. Backend key 설계 예
4편 remote state와 연결 — 환경 = key 경로.
# environments/prod/backend.tf
terraform {
backend "s3" {
bucket = "my-org-tf-state"
key = "prod/app/terraform.tfstate"
region = "ap-northeast-2"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
# environments/dev/backend.tf — key만 다름
terraform {
backend "s3" {
key = "dev/app/terraform.tfstate"
# bucket, region 등 동일
}
}
| env | state key (예) | 비고 |
|---|---|---|
| dev | dev/app/terraform.tfstate |
넓은 IAM·빠른 실험 |
| staging | staging/app/terraform.tfstate |
prod 유사 설정 |
| prod | prod/app/terraform.tfstate |
승인 apply·좁은 IAM |
- 같은 bucket·다른 key — 흔한 패턴
- 계정 분리 — dev/staging/prod AWS account + assume role (22편)
5. CI·거버넌스
| env | plan | apply |
|---|---|---|
| dev | PR·main | 자동 허용 (팀 정책) |
| staging | main merge | 자동 또는 야간 |
| prod | main + 승인 | 수동 gate·19편 CD |
# CI pseudo — directory per env
cd environments/prod
terraform init -input=false
terraform plan -var-file=prod.tfvars -out=tfplan
# approval step
terraform apply tfplan
- workspace in CI —
terraform workspace select prod전 backend·key 확인 - plan artifact — env 이름·commit·plan 파일 보관
6. 공통 module + env root 예
# environments/staging/main.tf
module "app" {
source = "../../modules/app"
environment = var.environment
instance_count = var.instance_count
vpc_cidr = var.vpc_cidr
}
- module은 env 무관 —
var.environment만 태그·이름에 사용 - root per env — backend·tfvars·IAM role만 다름
정리
- 환경 분리 — state·변수·권한·승인을 env별로
- workspace — 한 디렉터리·다중 state; backend key 설계 필수
- directory — env 폴더·별도 backend; 팀·prod에 흔함
- tfvars — 코드 고정·값만 env별; secret은 Git 밖
- Part 1 Terraform 마무리 — 다음은 AWS CDK (6편)
다음에 다룰 것
- AWS CDK 개요
- App·Stack·Construct, synthesis, CloudFormation 관계
해당 내용은 HashiCorp Terraform Documentation (Workspaces, Input Variables), Brikman — Terraform: Up & Running, 3/E Ch 4 를 기반으로 합니다.
'Infrastructure as Code' 카테고리의 다른 글
| CDK로 인프라 정의 (0) | 2026.07.09 |
|---|---|
| AWS CDK 개요 (0) | 2026.07.07 |
| State와 Module (0) | 2026.07.03 |
| Terraform 기초 (0) | 2026.07.01 |
| Infrastructure as Code란 (0) | 2026.06.30 |