기술 심층 탐구: Terraform 및 OPA로 ‘Golden Path’ 모듈 구축
Source: Dev.to

소개
대규모 인프라스트럭처를 코드(IaC)로 관리하려면 “복사‑붙여넣기” Terraform에서 모듈화되고 정책‑기반 아키텍처로 전환해야 합니다. 개발자가 50명 이상이면 모든 S3 버킷이나 RDS 인스턴스를 수동으로 검토하는 것은 현실적이지 않으며, 기본적으로 보안이 보장되고 자동으로 적용되는 시스템이 필요합니다.
“골든 패스” 모듈 패턴
개발자가 aws_s3_bucket 리소스를 직접 사용하도록 두는 대신, 회사의 보안 표준(암호화, 버전 관리, 공개 접근 차단)을 캡슐화한 골든 패스 모듈을 제공합니다. 개발자는 모듈을 참조하기만 하면 되며, 기본적인 보호 조치를 따로 고민할 필요가 없습니다.
“시니어” 모듈 구조
# modules/secure-s3/main.tf
resource "aws_s3_bucket" "this" {
bucket = var.bucket_name
# Hard‑coded security – developers can’t override these to false
}
resource "aws_s3_bucket_public_access_block" "this" {
bucket = aws_s3_bucket.this.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
bucket = aws_s3_bucket.this.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
코드로서의 정책 (Guardrail)
모듈을 사용하더라도 누군가가 이를 우회하거나 원시 리소스를 사용할 수 있습니다. Open Policy Agent(OPA) 또는 Terraform Cloud Sentinel을 사용해 가드레일을 강제할 수 있습니다. 다음 Rego 정책은 공개‑읽기 접근 권한이 설정된 S3 버킷이 포함된 모든 플랜을 거부합니다:
package terraform.policies
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
resource.change.after.acl == "public-read"
msg = sprintf("Resource %v has a public-read ACL. This is forbidden.", [resource.address])
}
“프로모션” 워크플로우 구현
프로모션 파이프라인은 소프트웨어 개발 라이프사이클을 그대로 반영합니다:
| 단계 | 작업 | 검증 내용 |
|---|---|---|
| Commit | tflint & terraform fmt | 구문 및 린트 검사 |
| Plan | terraform plan | OPA 정책 검사 (보안) |
| Staging | terraform apply | 통합 테스트 (Infracost) |
| Production | 수동 게이트 / 프로모션 | 최종 정상 여부 확인 |
대규모 상태 관리
프로젝트당 로컬 상태나 개별 S3 백엔드를 피하십시오. 시니어 엔지니어는 다음을 구현해야 합니다:
- 원격 상태 관리 – Terraform Cloud, Spacelift, 혹은 엔터프라이즈급 S3/DynamoDB 설정에 중앙 집중화.
- 상태 잠금 – 동시 적용으로 인한 손상을 방지.
- 디커플링 – 큰 상태 파일을 환경별 작은 스택으로 분리해 실패한 적용이 미치는 “폭발 반경”을 최소화.
정리
시니어십은 팀원의 인지 부하를 줄이는 데 있습니다. 사전 강화된 모듈과 자동화된 정책 검사를 제공함으로써, 개발자는 데이터 유출 위험 없이 빠르게 작업할 수 있습니다.
여러분의 “골든 패스”는 어떤 모습인가요? OPA, Terragrunt, 혹은 기본 Terraform 모듈 중 어느 것을 선호하시나요? 아래에 의견을 공유해 주세요.