학습 목표
Infrastructure as Code(IaC) 의 정의와 snowflake 서버 문제를 설명할 수 있다.
imperative(명령형) 와 declarative(선언형) 접근의 차이를 예시로 구분할 수 있다.
desired state, plan, apply가 왜 함께 쓰이는지 설명할 수 있다.
멱등성(idempotency) 이 재실행·CI·장애 복구에 왜 필요한지 설명할 수 있다.
인프라 변경을 Git·PR·리뷰로 거버넌스하는 이유를 설명할 수 있다.
문제 상황
- prod 서버는 손으로 세팅했고, 문서는 2년 전 wiki — 실제와 문서가 다르다
- snowflake — 서버마다 미세하게 다른 설정
- 장애 복구 runbook: "VPC 만들고, SG 열고, RDS 붙이고…" — 순서 하나 틀리면 반쪽만 복구
- Bash·AWS CLI 스크립트를 돌렸더니 이미 있으면 에러, 없으면 생성 — 스크립트마다
if exists분기가 늘어난다 - staging은 코드로, prod는 콘솔 — "같은 인프라"라고 말하지만 변수·버전이 어긋난다
- 퇴사한 동료만 왜 그 SG rule이 있는지 안다 — 감사·롤백 불가
- K8s manifest는 Git인데 VPC·IAM은 스프레드시트 — 진실의 원천이 둘로 갈라진다
앞서 IaC 오리엔테이션에서 시리즈 축과 desired → plan → apply 루프를 봤다. 이번 편은 IaC가 무엇인지, 왜 선언적·멱등·버전 관리가 핵심인지 원칙부터 고정한다. Terraform 명령·HCL 문법은 다음 편이다.
1. Infrastructure as Code
- Infrastructure as Code
- 데이터센터·클라우드 인프라와 설정을 기계가 읽는 파일로 정의한다
- 사람은 콘솔 클릭 대신 코드 변경 → 리뷰 → 적용한다
- 풀려는 문제
- 재현성 — dev/staging/prod를 같은 레시피로
- 감사 — 누가·언제·무엇을 바꿨는지 commit·PR
- 속도 — 반복 작업 자동화, 실수 감소
- IaC ≠ 앱 배포만
- VPC, IAM, RDS, K8s cluster, Lambda, 정책까지 범위
- 앞서 Platform IaC와 GitOps에서 Terraform·Argo 개요를 봤다 — 본 시리즈는 원칙 → Terraform → CDK → … 순으로 깊게 간다
| 수동·runbook | IaC | |
|---|---|---|
| 정의 | wiki·머릿속 | 파일 |
| 변경 | 즉시 클릭 | PR |
| 재현 | snowflake | 동일 코드 |
| 롤백 | 기억·역순 수동 | revert commit |
2. Imperative vs Declarative
인프라를 다루는 두 가지 사고방식.

Imperative (명령형)
- "어떻게" 할지 순서대로 명령
- AWS CLI, Bash, Ansible task (일부), 초기 CloudFormation 스크립트 스타일
- 장점: 절차가 직관적, 일회성 작업에 빠름
- 단점:
- 순서·분기를 사람이 유지 —
if resource exists누락 시 실패 또는 중복 - 최종 상태가 코드만으로 드러나지 않음
- idempotent 하게 만들려면 추가 로직 필요
- 순서·분기를 사람이 유지 —
# imperative sketch — reruns need guards
aws ec2 create-security-group --group-name app-sg ...
aws ec2 authorize-security-group-ingress --group-id ... --port 443 ...
# already exists? script must handle error codes
Declarative (선언형)
- "최종 상태"를 기술 — 도구가 현재 vs desired diff 계산
- Terraform HCL, Kubernetes YAML, CloudFormation template, CDK synthesis 결과
- 장점:
- plan으로 변경 미리보기
- 멱등 apply — 도구가 create/update/delete 결정
- Git에 의도가 그대로 남음
- 단점:
- 추상화 학습 필요 — provider·resource 모델
- state(다음 편) 없으면 팀 공유가 어려움
# declarative sketch — desired end state
resource "aws_security_group" "app" {
name = "app-sg"
vpc_id = aws_vpc.main.id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
| Imperative | Declarative | |
|---|---|---|
| 초점 | 절차·순서 | 최종 상태 |
| 변경 예측 | 스크립트 추적 | plan diff |
| 재실행 | 직접 guard | 도구가 reconcile |
| 대표 | CLI script | Terraform, K8s manifest |
- Kubernetes도 선언적 —
replicas: 3이 desired; controller가 맞춘다 - 실무 혼합 — Terraform으로 클라우드, Helm/Kustomize로 워크로드 — 둘 다 선언적 쪽
3. Desired state와 reconcile
선언적 IaC의 공통 패턴.
desired state (Git)
↓ plan / diff
actual state (cloud · cluster)
↓ apply / sync
actual ← desired
- Desired state
- "이 VPC에 private subnet 2개, NAT 1개, RDS multi-AZ"
- 의도 — 아직 API에 반영 안 됐을 수 있음
- Actual state
- 지금 클라우드·클러스터에 존재하는 리소스
- Plan
-
- create, ~ update, - destroy 목록 — dry-run
-
- Apply / Sync
- API 호출로 actual을 desired에 수렴
| 도구 | desired | reconcile |
|---|---|---|
| Terraform | .tf |
plan / apply |
| Kubernetes | manifest | controller loop |
| GitOps (Argo CD) | Git repo | sync |
| CloudFormation | template | stack update |
- Drift — actual이 desired와 어긋남 (콘솔 수동 변경)
- 다음 plan에 diff로 드러남 — 코드로 되돌리거나 import (운영 편에서 다룸)
4. 멱등성 (Idempotency)
같은 입력을 여러 번 적용해도 결과가 한 번 적용과 같아야 한다.

- 첫 apply
- 리소스 없음 → create
- 두 번째 apply (코드·desired 동일)
- 이미 맞음 → 0 changes
- 왜 중요한가
- CI가 매 merge마다 apply — 중복 생성되면 안 됨
- 장애 후 재실행 — "이미 만들어진 것" 스킵
- partial failure 후 재시도 — 남은 것만 create/update
| 멱등하지 않은 예 | 멱등한 IaC |
|---|---|
create-bucket 무조건 호출 |
bucket 없으면 create, 있으면 skip |
| runbook "항상 SG 추가" | SG rule desired에 있으면 유지, 없으면 제거 |
| 수동 클릭 2번 | plan이 no-op |
- 멱등성은 도구 + state가 함께 만든다 — Terraform은 state file에 resource ID를 기록 (4편)
- 선언적이라고 자동 멱등은 아님 — 잘못된 lifecycle·
-replace는 파괴적일 수 있음
5. 버전 관리와 거버넌스
인프라를 코드로 두면 앱과 같은 워크플로를 쓴다.
| 관행 | IaC에서 |
|---|---|
| Git | .tf, CDK, SAM, manifest |
| PR | plan output 첨부·리뷰 |
| Branch | feature env, staging promote |
| Tag/Release | module version, prod pin |
| Revert | git revert → apply로 롤백 |
- Plan in CI
- merge 전
terraform plan— 무엇이 바뀌는지 diff 공유 - prod apply는 main merge 또는 승인 게이트 (19편 CD)
- merge 전
- 코드 리뷰 포인트
- SG 0.0.0.0/0 열림, public RDS, 과도한 IAM
* - 파괴적 change (
force_destroy,-replace)
- SG 0.0.0.0/0 열림, public RDS, 과도한 IAM
- 문서 대체
- wiki "대략 이렇게" → 코드가 single source of truth
- ADR·주석은 왜 그 설정인지 보조
6. IaC 도구 스펙트럼
원칙은 같고 표현·state·에코시스템이 다르다. 본 시리즈에서 편별로 깊게 다룬다.
| 유형 | 예 | 특징 |
|---|---|---|
| Terraform | HCL + provider | 멀티 클라우드, state, module |
| CloudFormation | AWS JSON/YAML | AWS 네이티브, stack |
| CDK | TypeScript/Python | synthesis → CloudFormation |
| Pulumi | 일반 purpose 언어 | state, 프로그래밍 |
| K8s manifest | YAML | cluster 내부 desired |
| GitOps | Argo CD, Flux | Git → cluster continuous sync |
| Config management | Ansible (mixed) | 서버 설정 — declarative task도, imperative도 |
- 선택 기준(8편에서 CDK vs Terraform 비교)
- 팀 언어, 클라우드 범위, state 운영 역량, K8s 비중
- 다음 편부터 Terraform — provider, resource,
init/plan/apply, HCL 문법
정리
- IaC — 인프라를 파일로, 변경을 리뷰·plan으로
- Declarative — 최종 상태 + reconcile; imperative — 순서·분기 직접 관리
- 멱등 apply — 재실행·CI·복구에 필수
- Git·PR — snowflake·감사 공백을 줄임
- Terraform은 이 원칙 위의 대표 구현 — 3편부터 hands-on
다음에 다룰 것
- Terraform 기초
- provider·resource,
init/plan/apply, HCL 구조
해당 내용은 HashiCorp Terraform Documentation (Introduction), Brikman — Terraform: Up & Running, 3/E 를 기반으로 합니다.
'Infrastructure as Code' 카테고리의 다른 글
| AWS CDK 개요 (0) | 2026.07.07 |
|---|---|
| 환경과 Workspace (0) | 2026.07.05 |
| State와 Module (0) | 2026.07.03 |
| Terraform 기초 (0) | 2026.07.01 |
| IaC 오리엔테이션 (0) | 2026.06.29 |