본문으로 건너뛰기
대규모 조직에서 Terraform State를 나누는 기준

대규모 조직에서 Terraform State를 나누는 기준

State를 왜 나눠야 하는가

처음에는 하나의 state 파일로 시작하는 것이 간단합니다. 하지만 인프라가 커질수록 단일 state는 심각한 문제를 일으킵니다.

문제영향
plan 시간이 수 분 이상 걸림개발 속도 저하
한 리소스 변경에 모든 팀 영향협업 병목
실수 시 전체 인프라에 영향대형 장애 위험
권한 분리 불가팀별 접근 통제 어려움
Locking 경합동시 작업 불가

Blast Radius 최소화 개념

Blast radius란 변경이 실패했을 때 영향을 받는 범위입니다.

    graph LR
    subgraph 나쁜 예: 단일 State
        A[모든 리소스\nVPC + EKS + RDS + S3 + ...] -->|실수 발생| B[전체 인프라 위험]
    end

    subgraph 좋은 예: 분할된 State
        C[VPC State] --> G[작은 영향]
        D[EKS State] --> G
        E[RDS State] --> G
        F[App State] --> G
    end

    style B fill:#fee2e2
    style G fill:#dcfce7
  

State 분할 기준

분할은 변경 단위팀 경계를 기준으로 합니다.

    graph TD
    A[State 분할 기준] --> B[계층별 분리]
    A --> C[서비스별 분리]
    A --> D[환경별 분리]

    B --> B1[Network Layer\nVPC/Subnet/TGW]
    B --> B2[Platform Layer\nEKS/RDS/Cache]
    B --> B3[Application Layer\n앱별 인프라]

    C --> C1[service-a]
    C --> C2[service-b]
    C --> C3[shared-infra]

    D --> D1[dev]
    D --> D2[stage]
    D --> D3[prod]
  

실전 디렉토리 구조 (계층별 + 환경별 조합):

terraform/
├── global/                  # 리전에 무관한 리소스 (IAM, Route53)
│   └── terraform.tfstate
├── network/                 # VPC, TGW, VPN (변경 빈도 낮음)
│   ├── dev/
│   ├── stage/
│   └── prod/
├── platform/                # EKS, RDS, ElastiCache (변경 빈도 중간)
│   ├── dev/
│   ├── stage/
│   └── prod/
└── services/                # 애플리케이션별 인프라 (변경 빈도 높음)
    ├── service-a/
    │   ├── dev/
    │   └── prod/
    └── service-b/
        ├── dev/
        └── prod/

State 간 데이터 공유: terraform_remote_state

하위 레이어(network)의 출력값을 상위 레이어(platform)에서 참조합니다.

# network/prod/outputs.tf
output "vpc_id" {
  value = aws_vpc.main.id
}
output "private_subnet_ids" {
  value = aws_subnet.private[*].id
}

# platform/prod/main.tf
data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "terraform-state-prod"
    key    = "network/prod/terraform.tfstate"
    region = "ap-northeast-2"
  }
}

resource "aws_eks_cluster" "main" {
  name = "prod-cluster"

  vpc_config {
    # network state의 출력값 참조
    vpc_id     = data.terraform_remote_state.network.outputs.vpc_id
    subnet_ids = data.terraform_remote_state.network.outputs.private_subnet_ids
  }
}
terraform_remote_state는 상태 파일 전체에 대한 읽기 권한이 필요합니다. state에는 민감한 정보가 포함될 수 있으므로, SSM Parameter Store를 대안으로 고려하세요.

변경 단위 최적화

state를 나눌 때 변경 주기가 다른 리소스를 별도 state로 분리하면 효율적입니다.

변경 빈도리소스 예시분리 이유
매우 낮음 (월 1회 이하)VPC, TGW, DNS zone안정적 인프라는 변경 격리
낮음 (월 몇 회)EKS, RDS플랫폼은 서비스와 분리
높음 (주 수회)앱 인프라, Task/Service빠른 개발 속도 필요

실전 분할 예시: 3-Tier 아키텍처

    graph LR
    subgraph network-state
        VPC[VPC]
        Subnet[Subnets]
        SG[Security Groups]
        TGW[Transit GW]
    end

    subgraph platform-state
        EKS[EKS Cluster]
        RDS[(RDS)]
        Cache[ElastiCache]
    end

    subgraph app-a-state
        SvcA[Service A\nECR/IAM/ALB]
    end

    subgraph app-b-state
        SvcB[Service B\nECR/IAM/ALB]
    end

    network-state -->|remote_state| platform-state
    platform-state -->|remote_state| app-a-state
    platform-state -->|remote_state| app-b-state
  

분할 적용 효과:

  • network 변경 → network state만 영향 (EKS/앱 무관)
  • Service A 배포 → app-a state만 영향 (Service B 무관)
  • 팀별로 각자의 state만 apply 권한 부여 가능
  • plan 시간이 수 초 ~ 수십 초로 단축
State를 너무 잘게 쪼개면 오히려 관리 복잡도가 올라갑니다. 처음에는 환경별(dev/prod) + 계층별(network/platform/app) 조합으로 시작하고, 팀 규모와 함께 세분화하는 것이 현실적입니다.