두 Terraform 작업 디렉터리 조정하기

AWSBeginner
지금 연습하기

소개

두 유지관리 담당자가 동일한 환경의 작업 복사본을 가지고 있습니다. 실제로 공유 상태에 쓰는 프로세스, 해당 프로세스가 보유한 Terraform 자체 잠금 때문에 거부되는 경쟁 계획, 정상적인 잠금 해제 후 다른 디렉터리에서 성공하는 작업을 관찰합니다.

원격 S3 상태와 일반적인 Terraform 계획 및 적용 작업을 알고 있어야 합니다. 이 새로운 환경에는 초기화된 두 작업 복사본, 정해진 시간 동안 실행되는 통제된 변경, 보고서 스토리지, 재무 참조 리소스가 제공됩니다. 이전 VM이나 개인 AWS 계정은 필요하지 않습니다.

관련 자격증 시험 항목

자격증 시험 과제 실습 내용
CloudOps Engineer – Associate (SOA-C03) Task 3.1, Skill 3.1.6 사용 중인 리소스를 보존하면서 검토된 구성 및 상태 변경으로 인프라를 유지관리하는 Terraform 기초 실습입니다.

실습 개요

개념도: 유지관리 작업은 구성, 상태, 기존 보고서 스토리지 사이의 관계를 보존합니다.

하나의 환경에 대한 두 복사본 식별하기

이 단계에서는 두 작업 디렉터리가 의도적으로 같은 환경을 관리한다는 사실을 확인합니다. 별도의 dev 및 preview 배포가 아닙니다. 두 백엔드 구성 모두 coordination-team-state의 reports/shared.tfstate를 선택합니다.

cd /home/labex/project/shared-state-operators
cat operator-a/shared.s3.tfbackend
cat operator-b/shared.s3.tfbackend

둘 다 use_lockfile = true를 사용합니다. Terraform은 쓰기 프로세스가 작업하는 동안 이 상태와 나란히 자체 S3 잠금 객체를 생성하여, 다른 쓰기 프로세스가 충돌하는 스냅샷을 바탕으로 작업하지 못하게 합니다.

terraform -chdir=operator-a state show aws_s3_bucket.reports
terraform -chdir=operator-b state show aws_s3_bucket.reports

둘 다 coordinated-daily-reports를 식별합니다. 실제 보고서를 읽고 재무 참조 리소스는 변경하지 마세요.

aws s3 \
  cp s3://coordinated-daily-reports/report.txt -

Daily sales: 120 orders가 표시되어야 합니다. 제공된 통제된 변경을 살펴봅니다.

cat operator-a/pending-change.tf

이 연습에서만 terraform_data 리소스는 local-exec를 통해 생성 중 30초 동안 대기합니다. 이 대기로 실제 쓰기 프로세스의 잠금을 관찰할 수 있습니다. 일반적인 리소스 업데이트도 잠금을 보유합니다. 인위적인 대기는 프로덕션 배포에 권장되는 방법이 아닙니다. 이 통제된 상태 변경은 두 구성에 모두 있지만 아직 적용되지 않았습니다.

실제 잠금 경합과 정상 해제 관찰하기

이 단계에서는 실제 쓰기 프로세스 하나를 실행하고 두 번째 디렉터리에서 경쟁하는 계획을 실행합니다. 읽는 동안 멈추어 관찰 시간이 지나가지 않도록 다음 블록 전체를 하나의 작업으로 실행하세요.

&는 작업자 A를 백그라운드에서 시작하고, $!는 해당 프로세스 ID를 캡처합니다. 두 번째 작업자의 오류를 읽을 수 있도록 첫 번째 작업자의 출력은 로그에 기록됩니다. 횟수가 제한된 루프는 시작 시간을 고정해서 가정하지 않고 실제 S3 잠금을 기다립니다. if 문은 예상된 계획 실패를 확인할 수 있게 하고, wait는 쓰기 프로세스의 실제 완료 상태를 반환합니다. 하나의 Terminal에서 시작하더라도 서로 독립적인 두 Terraform 프로세스입니다.

terraform -chdir=operator-a apply -auto-approve > /tmp/operator-a.log 2>&1 &
WRITER_PID=$!
echo "$WRITER_PID"
for attempt in $(seq 1 60); do
  if aws s3api head-object \
    --bucket coordination-team-state \
    --key reports/shared.tfstate.tflock > /dev/null 2>&1; then
    break
  fi
  sleep 1
done
aws s3api get-object \
  --bucket coordination-team-state \
  --key reports/shared.tfstate.tflock \
  /tmp/current-lock.json
cat /tmp/current-lock.json
if terraform -chdir=operator-b plan -lock-timeout=0s; then
  echo 'Unexpected: the competing plan acquired the lock.'
  false
else
  PLAN_EXIT=$?
  echo "$PLAN_EXIT"
fi
wait "$WRITER_PID"
cat /tmp/operator-a.log

경쟁하는 계획은 Error acquiring the state lock과 함께 종료 코드 1로 끝나야 합니다. 인증이나 연결 오류는 잠금 경합을 입증하지 않습니다. 잠금 정보는 실제 쓰기 프로세스의 것이어야 합니다. 잠금과 같은 이름의 파일을 업로드하는 것으로는 쓰기 프로세스 간 조정이 이루어졌다고 볼 수 없습니다.

작업자 A는 통제된 생성 작업을 성공적으로 마치고 정상적으로 잠금을 해제해야 합니다. 두 번째 작업자를 진행시키기 위해 잠금을 비활성화하거나, 실행 중인 쓰기 프로세스의 잠금을 삭제하거나, force-unlock을 사용하지 마세요. AWS View에서는 실습 내내 보고서 저장소를 사용할 수 있습니다. 잠금은 관리 작업을 조정하며 보고서 읽기 접근을 제어하지 않습니다.

잠금 해제 후 다른 작업 복사본에서 계속하기

이 단계에서는 쓰기 프로세스가 완료된 뒤 작업자 B가 백엔드 잠금을 정상적으로 획득하도록 합니다. 이제 두 번째 작업 복사본은 리소스 복사본을 독립적으로 새로 만드는 대신 업데이트된 공유 상태를 읽어야 합니다.

terraform -chdir=operator-b plan -lock-timeout=5s

No changes가 표시되어야 합니다. 쓰기 중에 차단되었던 동일한 명령이 이제는 정상적으로 잠금을 획득하고 해제할 수 있습니다.

두 디렉터리에서 완료된 상태를 확인합니다.

terraform -chdir=operator-a state list
terraform -chdir=operator-b state list

각 목록에는 aws_s3_bucket.reports와 terraform_data.coordination이 표시됩니다. 두 배포가 아니라, 같은 환경과 공유 관리 기록을 나타냅니다.

aws s3 \
  cp s3://coordinated-daily-reports/report.txt -

원래 보고서 내용을 계속 읽을 수 있습니다. 상태 버전 기록을 확인합니다.

aws s3api \
  list-object-versions \
  --bucket coordination-team-state \
  --prefix reports/shared.tfstate

실제 상태에는 기록이 있으며, 현재 객체 목록에 활성 상태의 .tflock이 남아 있어서는 안 됩니다. 과거 잠금 버전이나 삭제 마커는 활성 쓰기 잠금이 아닙니다.

terraform -chdir=operator-a plan

여기서도 No changes가 표시되어야 합니다. 백그라운드 검사는 실제 Terraform 프로세스의 잠금 경합과 수동으로 제공한 잠금을 구분하고, 원래 보고서 버전, 정상적인 잠금 해제, 이후의 성공적인 접근을 확인합니다. 공유 스토리지와 백엔드는 소유자를 위해 유지하세요.

요약

하나의 환경에 대한 두 작업 복사본과 별도 환경을 구분하고, 실제 Terraform 자체 잠금의 경합을 관찰하며, 활성 잠금을 삭제하지 않고 쓰기 프로세스의 정상적인 잠금 해제 후 안전하게 작업을 이어갔습니다.