운영 환경은 잘 도는데, 스테이징을 새로 만들라는 지시가 떨어졌습니다. 그런데 운영을 만든 사람은 퇴사했고, 콘솔 어디를 어떻게 클릭했는지 기록이 없습니다. 보안그룹 규칙 하나, 서브넷 하나가 다르면 "운영에선 됐는데 스테이징에선 안 되는" 지옥이 시작됩니다. 손으로 만든 인프라는 재현이 안 됩니다. IaC는 인프라를 코드로 적어, 같은 환경을 버튼 하나로 다시 찍어냅니다.
- 1IaC가 인프라를 코드화해 얻는 가치(재현·리뷰·버전관리)를 안다
- 2Terraform의 plan/apply 흐름을 설명할 수 있다
- 3상태(state) 파일의 역할과 안전한 관리법을 이해한다
- 4팀 협업 시 원격 백엔드·상태 잠금이 왜 필요한지 안다
- 5드리프트(코드와 실제의 차이) 개념을 안다
콘솔 클릭을 코드로 바꾸기
IaC — 인프라를 git에 올리는 순간 달라지는 것
IaC는 VPC·서브넷·인스턴스·DB 같은 인프라를 선언적 코드로 적습니다. 그러면:
- 재현: 같은 코드로 dev/stg/prod를 동일하게 생성
- 리뷰: 인프라 변경을 PR로 리뷰(PR과 코드 리뷰)
- 버전 관리: 누가 언제 무엇을 바꿨는지 git에 기록
- 재해 복구: 통째로 날아가도 코드로 재구축
"콘솔에서 누군가 손으로 만든, 아무도 모르는" 스노우플레이크 인프라가 사라집니다.
선언적 — '어떻게'가 아니라 '무엇을'
Terraform 코드는 절차(클릭 순서)가 아니라 원하는 최종 상태를 적습니다. "이 VPC, 이 서브넷 2개, 이 보안그룹이 존재해야 한다"라고 선언하면, Terraform이 현재 상태와 비교해 차이만큼만 만들거나 바꿉니다.
resource "aws_instance" "web" {
ami = "ami-0abc123"
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
tags = { Name = "web", Env = "prod" }
}

plan → apply, 그리고 state
- plan: 코드와 실제 인프라(state 기준)를 비교해
+생성 / ~변경 / -삭제를 미리 보여줌. 적용 안 함. - apply: plan의 변경을 실제로 적용.
- state: Terraform이 만든 자원과 코드의 매핑 기록. 다음 plan의 차이 계산 근거.
핵심 습관: apply 전에 plan을 반드시 읽는다. 특히 -(삭제)나 강제 재생성(replace)이 보이면 의도와 맞는지 확인 — DB 같은 자원이 무심코 재생성되면 데이터가 날아갈 수 있습니다.
terraform apply — plan을 안 보고 실행하지 말 것
안전한 실행 조건: 운영 환경에서는 반드시 terraform plan을 사람이 읽고 -(삭제)·replace 항목을 확인한 뒤 apply. -auto-approve는 plan을 이미 검토한 CI 파이프라인 등 통제된 환경에서만.
실행 전 반드시 확인
- plan 출력에서 -(삭제)·replace 항목이 의도한 것인가
- DB·스토리지 등 상태가 있는 자원이 재생성 대상은 아닌가
- 대상 환경(workspace/계정/리전)이 맞는가 — prod에 dev 코드 적용 아닌가
- state가 최신이고 다른 사람이 동시에 apply 중은 아닌가(잠금)
terraform apply -auto-approve위 항목을 모두 확인한 후 복사할 수 있습니다
무엇이 바뀔지 먼저 봅니다. 숫자(+/-/~)와 특히 삭제·재생성을 확인합니다.
terraform plan
Plan: 2 to add, 1 to change, 0 to destroy.
+ aws_subnet.private_b
~ aws_instance.web (tags 변경)
terraform plan누군가 콘솔에서 손으로 바꾼 변경이 있는지 확인합니다. 차이가 나오면 코드와 실제가 어긋난 것입니다.
terraform plan -refresh-only
Note: Objects have changed outside of Terraform
~ aws_security_group.web ingress(22) 가 콘솔에서 추가됨 ← 드리프트
terraform plan -refresh-only- plan의 'to destroy' 숫자 — 0이 아니면 무엇이 삭제되는지 한 줄씩 확인. DB·스토리지면 특히 경계
- ~replace(강제 재생성) 표시 — 변경이 아니라 삭제 후 재생성. 상태 있는 자원이면 데이터 유실 위험
- refresh-only에서 드리프트 발견 — 콘솔 수동 변경이 있었다는 신호. 코드에 반영하거나 되돌려 일관성 유지
- state 파일이 git/로컬에 평문으로 있는지 — 민감정보 유출 위험. 원격 백엔드+암호화+잠금으로 이전
상황: 여러 명이 같은 인프라에 동시에 apply해 state 충돌·잠금 오류.
원인: state를 공유 원격 백엔드에 두고 잠금을 걸지 않으면, 동시 apply가 같은 자원을 두고 경합합니다. 로컬 state면 서로의 변경을 아예 모릅니다.
진단: 백엔드 설정 확인(원격인지 로컬인지) → 잠금 메커니즘 유무 확인 → 누가 apply 중인지 확인.
해결: state를 원격 백엔드(예: S3)에 두고 상태 잠금(예: DynamoDB lock)을 활성화해 한 번에 한 명만 apply. CI 파이프라인에서만 apply하도록 통제하면 더 안전합니다. 잠금이 비정상 종료로 남았으면 신중히 force-unlock(정말 아무도 실행 안 할 때만).
IaC는 현대 인프라 엔지니어의 필수 역량입니다. 면접에서 "인프라를 어떻게 관리하나요?"에 "콘솔에서 직접"이라 답하면 감점, "Terraform으로 코드화하고 PR 리뷰 후 CI에서 plan/apply, state는 원격+잠금"이면 합격선입니다.
실무 성숙도: ① 모듈화(재사용 가능한 VPC/EKS 모듈), ② 환경별 분리(workspace/디렉터리), ③ CI에서 plan을 PR에 코멘트로 보여주고 머지 시 apply(CI/CD 파이프라인), ④ 드리프트 정기 점검. 이 트랙에서 배운 VPC(VPC와 서브넷)·DB(관리형 데이터베이스(RDS))·컨테이너(매니지드 컨테이너)를 전부 코드로 선언하면 환경 재현이 버튼 하나가 됩니다.
다음 모듈에서는 이렇게 만든 자원들이 새어 나가는 돈 — 클라우드 비용 모델과 최적화 를 다룹니다.