본문으로 건너뛰기
프로젝트 목록

PF-04 · AWS · Terragrunt

AWS Terragrunt DRY IaC

Terraform 모듈 16개를 루트 설정 하나로 묶고, Terragrunt가 의존성 그래프를 읽어 순서대로 실행하게 한 구조입니다.

역할
설계 · 구현
기간
개인 프로젝트 · 2026.11 공개
CSP
AWS
규모
모듈 16개 · 유닛 16개 · 의존성 4단계
핵심 기술
Terragrunt · Terraform · AWS
GitHub
16
Terraform 모듈 · 유닛
1
복사본 16개를 대체한 루트 설정
- 40 %
배포 시간 단축 (실무 적용 결과, 이 레포에서 측정한 값 아님)

한눈에 보기

iam_custom_policyiam_useriam_custom_roleiam_groupvpcelastic_ipebsinternet_gatewaysecurity_groupvpc_endpointvpc_peeringelasticache_subnet_groupnat_gatewayroute_tableinstance_profileec2_instance

문제

Terraform 루트마다 backend와 provider 블록을 반복해서 썼고, 루트 사이의 실행 순서는 사람이 기억해야 했습니다.

접근

모듈은 일반 Terraform으로 두고 Terragrunt로 감쌌습니다. backend, provider, 공통 inputs는 live/root.hcl 한 곳에서 생성합니다. _envcommon이 모듈 source와 dependency를 맡고, 각 유닛은 자기 inputs만 적습니다. dependency 블록으로 그래프를 만들고 mock_outputs로 클라우드 없이 전체를 검증합니다.

결과

이 레포는 모듈 16개와 유닛 16개를 의존성 4단계로 묶고, 클라우드 자격증명 없이 전체를 검증합니다. 배포 시간 40% 단축은 운영 환경을 이 패턴으로 옮긴 실무 결과이며, 이 레포에서 측정한 값은 아닙니다.

자세히 보기

live/root.hclbackend · provider · 공통 inputslive/dev/account.hcl계정별 값<리전>/region.hcl리전별 값_envcommon/<module>.hclsource · dependency · mock_outputs<리소스>/terragrunt.hcl자기 inputs만 적음backend.tfprovider.tf루트 설정 1개가 복사본 16개를 대체
Terragrunt가 backend.tf와 provider.tf를 생성합니다. 루트 설정 1개가 복사본 16개를 대체합니다.
terragrunt: 모듈 버전 업그레이드 런북$ terragrunt state pull > backup.tfstate$ find . -name '.terragrunt-cache' -type d -prune -exec rm -rf {} +# terraform.source를 새 버전으로 변경$ terragrunt init$ terragrunt state push backup.tfstate$ terragrunt plan# 상태 백업# 캐시 정리# 코드 변경은 이것뿐# 새 모듈 내려받기# 필요할 때만 상태 복원# 변경 없음 확인No changes.
plan이 No changes.를 출력해야 업그레이드가 끝납니다. 변경이 보이면 멈추고 원인을 봅니다.

루트에서 생성하는 provider

이 코드가 하는 일: 유닛마다 쓰지 않고 루트에서 provider와 공통 inputs를 만듭니다.

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<PROVIDER
provider "aws" {
  region = "${local.aws_region}"

  default_tags {
    tags = {
      Environment = "${local.account_name}"
      ManagedBy   = "terragrunt"
    }
  }
}
PROVIDER
}

inputs = merge(local.account_vars.locals, local.region_vars.locals)

dependency와 mock_outputs

이 코드가 하는 일: 모듈 간 출력을 연결하고, plan 전에는 mock 값으로 검증합니다.

dependency "elastic_ip" {
  config_path = "${get_terragrunt_dir()}/../elastic_ip"

  mock_outputs = {
    eip_id = {
      "demo-eip-1" = "eipalloc-00000000000000001"
      "demo-eip-2" = "eipalloc-00000000000000002"
    }
  }
  mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"]
}

배운 점

Terragrunt는 Terraform을 대체하지 않고 코드 배치를 정리합니다. dependency를 코드로 적으면 실행 순서를 사람이 관리하지 않아도 됩니다.

다음에 개선할 점

데모를 위해 state는 로컬에 둡니다. 팀에서 쓰려면 root.hcl에 적어 둔 S3 백엔드로 바꿔야 합니다. us-east-1은 region 파일만 있고, 유닛은 CI에서 검증만 합니다.

관련 현장 노트

Open to work · 클라우드 인프라/보안