학습 목표
IaC(Infrastructure as Code) 로 desired state를 버전·리뷰할 수 있음을 설명할 수 있다.
Terraform plan·apply·state·drift 개념을 설명할 수 있다.
GitOps — Git이 진실의 원천 — 와 push 배포의 차이를 설명할 수 있다.
Argo CD Application·sync·reconcile 루프를 설명할 수 있다.
PR 기반 manifest 변경·승인·자동 sync 흐름을 설계할 수 있다.
문제 상황
- prod VPC·RDS를 콘솔로 만든 뒤 누가 무엇을 바꿨는지 감사 불가
- IaC·PR 없음
- staging
kubectl apply와 prod 수동 apply — manifest가 다름- drift·환경 불일치
terraform applystate 없이 로컬에서만 관리 — 팀원이 같은 리소스 이중 생성- remote state·lock 부재
- CI가
kubectl set image만 하고 YAML은 repo에 없음 — 롤백이 이미지 태그 기억에 의존- GitOps 부재
- Argo CD OutOfSync인데 누가 클러스터에서
kubectl edit했는지 모름- reconcile·self-heal 정책 미설정
- blue-green selector 전환을 Slack에서 수동 — 13편 전략이 코드로 안 남음
앞서 CI/CD·배포 전략까지 봤다. 이번 편은 인프라·manifest 자체를 코드·Git으로 두고 동기화하는 IaC와 GitOps다. 8_IaC 시리즈에서 Terraform·CDK·CD 심화로 이어진다.
1. IaC — 선언적 desired state
IaC — 인프라·설정을 코드 파일로 정의하고 도구가 실제와 맞춘다.

| 수동(콘솔·CLI) | IaC | |
|---|---|---|
| 상태 | 머릿속·문서 | 파일·Git |
| 변경 | 클릭·즉시 | PR·plan |
| 재현 | 어려움 | 동일 코드 → 동일 결과 |
| 감사 | 로그 산재 | commit history |
desired state (HCL / YAML in Git)
↓ plan: diff
actual state (cloud API / K8s API)
↓ apply / sync
actual ← desired
| 범위 | 도구 예 |
|---|---|
| 클라우드 | Terraform, Pulumi, CloudFormation |
| K8s manifest | Kustomize, Helm, GitOps |
| 정책 | OPA, Kyverno (desired policy) |
- 앞서 K8s 선언적 API (5편) — 워크로드 desired state; IaC는 그 위·아래 전체 스택
- immutable artifact(11편) + declarative infra — 이미지 SHA + manifest commit
2. Terraform — plan · apply · state
Terraform — HCL로 리소스 선언, provider가 cloud API 호출.

# code/terraform-minimal.example.tf
terraform {
backend "s3" {
bucket = "my-tf-state"
key = "staging/vpc/terraform.tfstate"
region = "ap-northeast-2"
}
}
resource "aws_s3_bucket" "artifacts" {
bucket = "my-ci-artifacts-staging"
tags = { env = "staging" }
}
| 단계 | |
|---|---|
| init | provider·backend 다운로드 |
| plan | desired vs state → 변경 목록 (dry-run) |
| apply | API 호출·state 갱신 |
| destroy | 리소스 제거 (주의) |
terraform plan → + create ~ update - destroy
terraform apply → state file updated
| state | |
|---|---|
| 역할 | Terraform이 관리하는 리소스 ID·속성 저장 |
| remote | S3 + DynamoDB lock — 팀 공유 |
| 민감 | state에 secret 평문 가능 — 암호화·접근 제어 |
| drift | 콘솔에서 수동 변경 → 다음 plan에 diff |
# drift 감지 후 코드에 반영 (신중)
terraform plan -refresh-only
terraform apply -refresh-only
# 또는 import로 기존 리소스 편입
terraform import aws_s3_bucket.artifacts my-ci-artifacts-staging
| 실무 | |
|---|---|
| PR | terraform plan CI comment |
| apply | main merge 후 전용 pipeline·승인 gate |
| module | VPC·EKS 재사용 — 8_IaC에서 심화 |
| workspace | env별 state 분리 |
- Platform 15~18편 — VPC·RDS는 Terraform 대상; 여기서는 메커니즘
- kubectl apply만으로는 cloud VPC는 안 만듦 — 경계 구분
3. GitOps — Git이 진실
GitOps — 클러스터·배포 desired state가 Git에 있고, operator가 pull·sync.

| Push CD (CI kubectl) | GitOps (Argo CD) | |
|---|---|---|
| 트리거 | pipeline 성공 → apply | Git commit 변경 감지 |
| 진실 | CI 스크립트 + cluster | Git repo |
| 드리프트 | 수동 edit 방치 | OutOfSync 표시 |
| 롤백 | 이전 image tag | git revert |
Git repo (manifests)
→ Argo CD watches
→ kubectl apply (reconcile)
→ cluster actual
← compare → sync / self-heal
| 원칙 (OpenGitOps 요지) | |
|---|---|
| 선언적 | YAML·Helm·Kustomize |
| 버전 | Git immutable history |
| 자동 | 승인된 변경 pull 적용 |
| 지속 검증 | reconcile loop |
- 12편
kubectl apply— 한 번 push; GitOps는 항상 맞춤 - 13편 blue-green — Git에서 overlay·kustomize patch로 promote
4. Argo CD — Application · sync
Argo CD — Git 경로를 Application CR로 클러스터에 연결.
# code/argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api-staging
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/gitops-manifests
targetRevision: main
path: apps/api/overlays/staging
destination:
server: https://kubernetes.default.svc
namespace: api-staging
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
| 필드 | |
|---|---|
| source | repo·branch·path (kustomize/helm) |
| destination | cluster·namespace |
| syncPolicy.automated | commit 시 auto sync |
| selfHeal | 수동 kubectl edit 되돌림 |
| prune | Git에서 삭제된 리소스 제거 |
argocd app get api-staging
argocd app sync api-staging
argocd app rollback api-staging
| 상태 | |
|---|---|
| Synced | Git == cluster |
| OutOfSync | diff 존재 |
| Healthy | 워크로드 probe OK (앱 health) |
| Degraded | 배포 실패·crash loop |
- App of Apps — bootstrap Application이 하위 Application 생성
- multi-cluster — destination 여러 cluster (20편)
5. PR 기반 배포

1. feature branch: image tag / replica / ingress patch
2. PR → terraform plan comment + manifest diff review
3. merge to main
4. Argo CD detects → sync staging (auto)
5. promotion PR: staging overlay → prod overlay (또는 tag)
6. prod sync (manual 또는 approved auto)
| 레이어 | PR 내용 |
|---|---|
| 앱 | CI가 이미지 digest PR (bot) |
| config | kustomize patch — replica·env |
| infra | Terraform module bump |
| 전략 | blue-green selector patch (13편) |
# code/kustomization-overlay.example.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
images:
- name: my/api
newTag: sha-a1b2c3d # CI bot commit
patches:
- path: replicas-staging.yaml
| gate | |
|---|---|
| CODEOWNERS | platform 팀 approve |
| plan only on PR | apply는 main |
| sync window | prod 야간 auto 금지 |
| rollback | git revert + sync |
- CI — build·test·image push; CD — manifest PR (역할 분리)
- Flux — Argo 대안 — GitRepository·Kustomization CR
6. IaC + GitOps 조합
| 계층 | 도구 | 변경 주기 |
|---|---|---|
| 네트워크·DB | Terraform | 드묾 |
| 클러스터 | EKS module / cluster API | 월 |
| 워크로드 | Argo CD + Kustomize | 수시 |
| 런타임 설정 | ConfigMap·Secret (8편) | PR |
Terraform: VPC · EKS · RDS
Argo CD: Deployment · Service · Ingress on EKS
CI: build image → update kustomize image tag in Git
| 함정 | |
|---|---|
| 이중 진실 | CI kubectl set image + GitOps 동시 |
| state 없는 terraform | 충돌 |
| secret in Git | plain 금지 — External Secrets·Sealed Secrets |
| drift 무시 | OutOfSync 방치 |
7. 실무 체크리스트
| 항목 | 권장 |
|---|---|
| Terraform | remote state + lock |
| Plan | PR 필수, apply 분리 |
| K8s | GitOps 단일 경로 |
| Image | digest·SHA tag in kustomize |
| Drift | self-heal on (prod 정책 검토) |
| Rollback | git revert drill |
| 심화 | 8_IaC — module·CDK·CD governance |
8. 정리
- IaC — desired state 코드·버전·plan
- Terraform — state·drift·remote backend
- GitOps — Git 진실, reconcile loop
- Argo CD — Application·sync·selfHeal
- PR — review·promote·rollback = Git
- 다음 — 클라우드 모델 (IaaS/PaaS/SaaS, 책임 공유)
다음에 다룰 것
- IaaS·PaaS·SaaS, 책임 공유 모델
- 리전·AZ, 온프레 vs 클라우드
해당 내용은 Production Kubernetes (Berkus & Box), HashiCorp Terraform Documentation, Argo CD Documentation 를 참고했습니다.
'플랫폼, 데브옵스와 클라우드' 카테고리의 다른 글
| VPC와 네트워킹 (0) | 2026.07.03 |
|---|---|
| 클라우드 모델 (0) | 2026.07.02 |
| 배포 전략 (0) | 2026.06.30 |
| GitHub Actions와 GitLab CI (0) | 2026.06.29 |
| CI/CD 개요 (0) | 2026.06.28 |