terraform state mv 커맨드

terraform state mv 커맨드

terraform state mv 커맨드는 Terraform 상태 안의 바인딩을 변경해서, 기존 원격 객체가 새로운 리소스 인스턴스에 바인딩되도록 해줘요. 플랜을 적용하면 Terraform이 상태를 자동으로 갱신하지만, 기존 원격 객체를 유지하면서 Terraform에서 다른 리소스 인스턴스 주소로 추적하고 싶을 때 이 커맨드를 사용할 수 있어요.

출처: 문서

본문

소개 (Introduction)

플랜을 적용하면 Terraform이 상태를 자동으로 갱신해요. 하지만 terraform state mv를 사용하면 기존 원격 객체를 유지하면서 Terraform에서 다른 리소스 인스턴스 주소로 추적할 수 있어요.

사용법 (Usage)

사용법: terraform state mv [options] SOURCE DESTINATION

Terraform은 현재 상태에서 주어진 주소와 일치하는 리소스 인스턴스, 리소스, 또는 모듈을 찾고, 성공하면 소스에 연결된 원격 객체를 목적지가 대신 추적하도록 이동시켜요.

소스와 목적지 주소는 모두 리소스 주소 문법을 사용해야 하고, 둘 다 같은 종류의 객체를 가리켜야 해요. 즉 리소스 인스턴스는 다른 리소스 인스턴스로만, 모듈 인스턴스 전체는 다른 모듈 인스턴스 전체로만 이동할 수 있어요. 또한 리소스 또는 리소스 인스턴스를 이동할 때는 같은 리소스 타입을 가진 새 주소로만 이동할 수 있어요.

terraform state mv의 가장 흔한 용도는 설정에서 리소스 블록의 이름을 바꾸거나, 리소스 블록을 하위 모듈로 옮겼을 때예요. 두 경우 모두 기존 객체를 유지하면서 새 이름으로 추적하려는 의도가 있어요. 기본적으로 Terraform은 리소스 설정의 이동·이름 변경을 기존 객체를 삭제하고 새 주소에 새 객체를 생성하라는 요청으로 이해해요. 그래서 terraform state mv는 기존 객체를 Terraform의 새 주소에 미리 연결해서 그 해석을 재정의할 수 있게 해줘요.

경고: 협업 환경에서 Terraform을 사용한다면, 코드 리팩터링 목적으로 terraform state mv를 사용할 때 동료들과 신중하게 소통해서 설정 변경과 terraform state mv 커맨드 사이에 다른 변경이 없도록 해야 해요. 그렇지 않으면 그들이 실수로 기존 객체를 파괴하고 새 주소에 새 객체를 만드는 플랜을 만들 수 있기 때문이에요.

이 커맨드는 다음 옵션도 받아요:

  • -dry-run - 주어진 주소와 일치하는 모든 리소스 인스턴스를 보고하되, 실제로 "잊지는" 않아요.

  • -var 'NAME=VALUE' - 설정의 루트 모듈에 선언된 단일 입력 변수에 값을 설정해요. 여러 변수를 설정하려면 이 옵션을 여러 번 사용하세요. 자세한 내용은 명령줄의 입력 변수를 참고하세요.

  • -var-file=FILENAME - 설정의 루트 모듈에 선언된 많은 입력 변수.tfvars 파일의 정의를 사용해 값을 설정해요. 여러 파일의 값을 포함하려면 이 옵션을 여러 번 사용하세요. 루트 모듈의 입력 변수에 값을 설정하는 방법은 -var-var-file 옵션 외에도 여러 가지가 있어요. 자세한 내용은 입력 변수에 값 할당을 참고하세요.

  • -lock=false - 작업 중 상태 잠금을 유지하지 않아요. 다른 사람이 같은 워크스페이스에 대해 동시에 커맨드를 실행할 수 있다면 위험해요.

  • -lock-timeout=DURATION - -lock=false로 잠금을 비활성화하지 않았다면, 오류를 반환하기 전에 일정 시간 동안 잠금 획득을 재시도하도록 Terraform에 지시해요. 기간 문법은 숫자 뒤에 시간 단위 문자를 붙인 형태예요. 예: 3초는 "3s".

HCP Terraform CLI 통합 또는 remote 백엔드를 사용하는 설정에서만 terraform state mv-ignore-remote-version 옵션도 받아요. 레거시 옵션 -backup-backup-out은 로컬 상태 파일에서만 동작해요. remote 백엔드를 사용하는 설정은 -state 옵션으로 로컬 상태 파일을 지정해야 -backup-backup-out 옵션을 사용할 수 있어요. 로컬 상태를 사용하는 설정에서만 terraform state mv는 레거시 옵션 -state, -state-out, -backup, -backup-out도 받아요.

예제: 리소스 이름 바꾸기 (Example: Rename a Resource)

리소스 이름을 바꾸는 것은 다음과 같은 설정 변경을 의미해요:

-resource "packet_device" "worker" {
+resource "packet_device" "helper" {
   # ...
 }

Terraform이 새 "helper" 리소스를 기존 "worker" 리소스의 이름 변경으로 취급하도록, 위 설정 변경을 다음 커맨드와 함께 사용하세요:

terraform state mv packet_device.worker packet_device.helper

예제: 리소스를 모듈로 이동 (Example: Move a Resource Into a Module)

원래 루트 모듈에 리소스를 작성했지만 지금은 하위 모듈로 리팩터링하고 싶다면, resource 블록을 하위 모듈 설정으로 옮기고 루트 모듈의 원본을 제거한 뒤, 다음 커맨드를 실행해서 Terraform에 이동으로 취급하라고 알릴 수 있어요:

terraform state mv packet_device.worker module.worker.packet_device.worker

위 예제에서 새 리소스는 같은 이름이지만 다른 모듈 주소를 가져요. 새 모듈 구성이 다른 이름 체계를 제안한다면 리소스 이름도 동시에 바꿀 수 있어요:

terraform state mv packet_device.worker module.worker.packet_device.main

예제: 모듈을 모듈로 이동 (Example: Move a Module Into a Module)

전체 모듈을 하위 모듈로 리팩터링할 수도 있어요. 설정에서 모듈을 나타내는 module 블록을 다른 모듈로 옮긴 다음, 그 변경과 함께 다음 커맨드를 사용하세요:

terraform state mv module.app module.parent.module.app

예제: count를 사용해 특정 리소스 인스턴스 이동 (Example: Move a Particular Instance of a Resource using count)

count 메타-인자로 정의된 리소스는 각각 정수로 식별되는 여러 인스턴스를 가져요. 주소에 명시적 인덱스를 포함하면 특정 인스턴스를 선택할 수 있어요:

$ terraform state mv 'packet_device.worker[0]' 'packet_device.helper[0]'

countfor_each를 사용하지 않는 리소스는 주소가 리소스 자체와 같은 단일 리소스 인스턴스만 가지므로, 각 리소스가 어떻게 구성되어 있는지에 따라 주소 유형이 맞는 한 인덱스가 없는 주소에서 인덱스가 있는 주소로(또는 그 반대로) 이동할 수 있어요:

$ terraform state mv 'packet_device.main' 'packet_device.all[0]'

대괄호([, ])는 일부 셸에서 특별한 의미를 가지므로, 주소를 Terraform에 그대로 전달하려면 인용하거나 이스케이프해야 할 수 있어요. 위 예제는 Unix 스타일 셸의 일반적인 인용 문법을 보여줘요.

예제: for_each로 구성된 리소스 이동 (Example: Move a Resource configured with for_each)

for_each 메타-인자로 정의된 리소스는 각각 문자열로 식별되는 여러 인스턴스를 가져요. 주소에 명시적 키를 포함하면 특정 인스턴스를 선택할 수 있어요.

다만 문자열 문법에는 따옴표가 포함되고, 따옴표 기호는 종종 명령 셸에서 특별한 의미를 가지므로, 사용 중인 셸에 맞는 적절한 인용 및/또는 이스케이프 문법을 사용해야 해요. 예를 들어:

Linux나 macOS 같은 Unix 스타일 셸:

terraform state mv 'packet_device.worker["example123"]' 'packet_device.helper["example456"]'

Windows Command Prompt (cmd.exe):

terraform state mv packet_device.worker[\"example123\"] packet_device.helper[\"example456\"]

PowerShell:

terraform state mv 'packet_device.worker[\"example123\"]' 'packet_device.helper[\"example456\"]'

인스턴스 키에 정수 대신 문자열을 사용한다는 점만 빼면, for_each 리소스의 처리는 count 리소스와 유사해서 이전 섹션에서 설명한 인덱스 구성 요소가 있거나 없는 주소 조합이 동일하게 유효해요.

더 알아보기 (Learn more)