소개
이전 실습에서는 Chef 역할을 맡아 Robot(Terraform) 이 요리 (빌드) 할 메뉴 (구성) 를 작성했습니다. 그렇다면 Robot 은 이미 무엇을 요리했는지 어떻게 기억할까요?
창고가 있는데 재고 목록을 잃어버렸다고 생각해 보세요. 무엇을 가지고 있는지, 어디에 있는지, 무언가 도난당했는지 알 수 없을 것입니다.
Terraform 에서는 이 재고 목록을 **상태 (state)**라고 합니다. 상태는 Terraform 의 기억입니다. Terraform 이 생성한 리소스를 기록하고, 구성 객체와 실제 인프라 객체를 서로 연결합니다.
상태가 있기 때문에 선언적 관리가 실용적입니다. 상태가 없으면 Terraform 은 구성 파일을 읽을 수는 있지만, 어떤 실제 객체가 해당 선언에 대응하는지 안정적으로 기억할 수 없습니다.
상태는 Terraform 의 가장 중요한 개념 중 하나입니다. 상태가 없으면 Terraform 은 무엇이 이미 존재하는지, 무엇이 변경되었는지, 무엇을 업데이트하거나 다시 생성해야 하는지 알 수 없습니다.
이 실습에서는 Terraform 이 이 상태를 사용해 인프라를 정상적으로 유지하는 방법을 확인합니다. 여러분은 "Chaos" 역할을 맡아 리소스를 수동으로 망가뜨리고, Terraform 이 손상을 감지해 시스템을 자동으로 "복구"하는 과정을 관찰합니다.
상태 확인
이 환경은 미리 구성되어 있습니다. main.tf 파일이 이미 존재하고 terraform apply도 이미 실행되었습니다. 따라서 인프라 (Docker 컨테이너) 가 이미 실행 중입니다.
먼저 컨테이너가 실행 중인지 확인합니다.
sudo docker ps
이 명령의 출력에 tutorial이라는 이름의 컨테이너가 표시되어야 합니다.
이제 현재 디렉터리의 파일을 확인합니다. terraform.tfstate 파일이 표시될 것입니다.
ls -l
이 파일은 Terraform 의 "비밀 일기"입니다. Terraform 이 수행하는 모든 작업을 이 파일에 기록합니다. 파일 내용을 확인해 보겠습니다.
cat terraform.tfstate
출력 형식은 JSON입니다. 처음에는 복잡해 보일 수 있지만, 컴퓨터가 정보를 기록하는 구조화된 방식일 뿐입니다.
출력의 어딘가에서 docker_container와 실행 중인 컨테이너의 ID 를 확인할 수 있습니다. 이는 Terraform 이 이 특정 컨테이너를 알고 있다는 뜻입니다.
중요한 규칙: 이 파일을 절대로 직접 편집하지 마세요. 파일을 변경하면 Terraform 의 기억이 사라져 인프라를 실수로 삭제하거나 손상시킬 수 있습니다. 상태 파일은 항상 Terraform 이 직접 관리하도록 해야 합니다.
이 경고가 중요한 이유는 상태가 단순한 로그가 아니라 신뢰할 수 있는 메타데이터이기 때문입니다. 상태가 손상되면 Terraform 이 이후에 파괴적이거나 혼란스러운 결정을 내릴 수 있습니다.
드리프트 만들기
Terraform 은 자신이 이러한 리소스를 관리하는 유일한 주체라고 가정합니다. 하지만 실제 환경에서는 여러 일이 발생합니다. 서버가 중단되거나, 동료가 실수로 무언가를 직접 삭제할 수도 있습니다.
이러한 상황을 **드리프트 (Drift)**라고 합니다. 이는 "현실 (Reality)"이 더 이상 "계획 (The Plan)"과 일치하지 않는다는 뜻입니다.
공유 환경에서는 드리프트가 흔히 발생합니다. 사람, 스크립트, 장애, 외부 시스템이 모두 Terraform 의 일반적인 관리 흐름 밖에서 인프라를 변경할 수 있기 때문입니다.
이제 혼란을 만들어 보겠습니다. Terraform 몰래 Docker 명령을 사용해 컨테이너를 직접 삭제합니다.
sudo docker rm -f tutorial
컨테이너가 실제로 삭제되었는지 확인합니다.
sudo docker ps
이 시점에는 다음과 같은 문제가 발생합니다.
- 현실: 컨테이너가 삭제되었습니다.
- 상태 파일: Terraform 은 아무도 이를 알리지 않았기 때문에 컨테이너가 여전히 실행 중이라고 생각합니다.
드리프트 감지
이제 Terraform 이 컨테이너의 삭제를 알아차리는지 확인합니다.
terraform plan을 실행하면 Terraform 은 먼저 "Refresh" 작업을 수행합니다. Docker 에 컨테이너 ID XYZ 를 가진 컨테이너가 아직 존재하는지 확인합니다.
다음 명령을 실행합니다.
terraform plan
출력을 자세히 확인합니다. 다음과 같은 내용이 표시되어야 합니다. docker_container.nginx: Refreshing state...
그런 다음 녹색 + 기호가 있는 계획 (create) 이 표시됩니다.
Terraform will perform the following actions:
## docker_container.nginx will be created
+ resource "docker_container" "nginx" { ... }
Terraform 이 상황을 파악했습니다. Terraform 은 다음과 같이 판단합니다. "내 계획에는 컨테이너가 있어야 한다. 하지만 현실에는 컨테이너가 없다. 따라서 원하는 상태를 만들려면 새 컨테이너를 **생성 (Create)**해야 한다."
이러한 조정 동작은 Terraform 의 가장 중요한 운영 특성 중 하나입니다. Terraform 은 원하는 상태, 기록된 상태, 실제 실행 상태를 비교해 필요한 수정 작업을 결정합니다.
인프라 복구
이것이 Infrastructure as Code 의 "자동 복구 (Self-Healing)" 기능입니다. 코드가 *원하는 상태 (Desired State)*인 실행 중인 컨테이너를 정의하므로, Terraform 은 발생한 드리프트를 자동으로 수정할 수 있습니다.
문제를 해결하려면 apply를 실행합니다.
terraform apply
프롬프트가 나타나면 yes를 입력합니다.
작업이 완료되면 Docker 상태를 다시 확인합니다.
sudo docker ps
컨테이너가 다시 실행됩니다! 컨테이너 ID 가 새로 발급되거나 새로운 인스턴스가 생성될 수 있지만, 기능적으로는 인프라가 청사진에 정의한 상태로 정확히 복구됩니다.
요약
이 실습에서는 **상태 (State)**의 강력한 기능을 확인했습니다.
다음 내용을 배웠습니다.
- 상태 파일: 현재 존재하는 항목에 대한 Terraform 의 기억입니다 (
terraform.tfstate). - 드리프트 감지: 수동 삭제처럼 Terraform 몰래 변경된 사항을 Terraform 이 알아차리는 방법입니다.
- 자동 복구:
terraform apply가 코드와 일치하도록 누락된 리소스를 자동으로 복원하는 방법입니다.
이러한 안정성 때문에 Terraform 은 중요한 인프라를 관리하는 도구로 신뢰받습니다. 장애가 발생하더라도 Terraform 을 사용하면 인프라를 정상 상태로 신속하게 되돌릴 수 있습니다.



