Terraform 상태 관리

LinuxBeginner
지금 연습하기

소개

Terraform 은 관리하는 인프라에 대한 정보를 저장하기 위해 상태 파일 (state file) 을 사용합니다. 이 상태 파일은 구성 파일 (configuration files) 에 정의된 리소스를 실제 리소스에 매핑하므로 매우 중요합니다. 이 상태를 유지함으로써 Terraform 은 어떤 리소스를 생성, 업데이트 또는 파괴할지 결정할 수 있습니다.

본 랩 (lab) 에서는 Terraform 상태 관리에 대한 실습 경험을 쌓게 됩니다. 다양한 terraform state 하위 명령어를 사용하여 현재 상태를 검사하고, 관리되는 리소스를 나열하며, 상태 내에서 리소스 이름을 변경하고, 실제 인프라와 일치하도록 상태를 새로 고치는 방법을 배웁니다. 이는 모든 Terraform 사용자에게 필수적인 기술입니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 89%입니다.학습자들로부터 91%의 긍정적인 리뷰율을 받았습니다.

terraform show 로 현재 상태 보기

이 단계에서는 terraform show 명령어를 사용하여 현재 상태를 보는 방법을 배웁니다. 이 명령어는 Terraform 이 상태 파일에 기록된 대로 현재 관리하고 있는 리소스에 대한 사람이 읽을 수 있는 출력을 제공합니다. 이는 인프라 상태를 검사하는 안전하고 읽기 전용 (read-only) 방식입니다.

이 랩의 설정 스크립트는 이미 Terraform 을 초기화하고 리소스를 생성하여 terraform.tfstate 파일을 생성했습니다. 이를 검사해 봅시다.

터미널에서 다음 명령어를 실행합니다.

terraform show

Terraform 이 관리하고 있는 local_file 리소스를 설명하는 자세한 출력을 보게 될 것입니다.

## local_file.example:
resource "local_file" "example" {
    content              = "This is an example file managed by Terraform."
    content_base64sha256 = "F5EYZhFNzSXdE4CUftwQoDVqvdiufZpVyiLMqyZVOcQ="
    content_base64sha512 = "m1hvaxMuc/EhaKintyI54NSTTJ5yXpqHPCBNoHubF0rvF3JAj36lMj20aPcv21+3/OK+SqkiTlnT/LdvLCwqDA=="
    content_md5          = "a43bdd236c2f0f4d87452ba2ef0867e4"
    content_sha1         = "ec3adcab998872def2df6200fb03992ac6f237a4"
    content_sha256       = "17911866114dcd25dd1380947edc10a0356abdd8ae7d9a55ca22ccab265539c4"
    content_sha512       = "9b586f6b132e73f12168a8a7b72239e0d4934c9e725e9a873c204da07b9b174aef1772408f7ea5323db468f72fdb5fb7fce2be4aa9224e59d3fcb76f2c2c2a0c"
    directory_permission = "0777"
    file_permission      = "0777"
    filename             = "./example.txt"
    id                   = "ec3adcab998872def2df6200fb03992ac6f237a4"
}

이 출력은 Terraform 이 local_file.example이라는 하나의 리소스를 인지하고 있으며, 해당 리소스의 모든 속성 (attribute) 을 나열하고 있음을 확인시켜 줍니다.

terraform.tfstate 상태 파일 검사

이 단계에서는 원시 상태 파일인 terraform.tfstate를 검사합니다. terraform show는 사용자 친화적인 보기를 제공하지만, 원시 JSON 파일을 살펴보면 Terraform 이 데이터를 저장하는 방식을 이해하는 데 도움이 됩니다.

경고: terraform.tfstate 파일을 수동으로 편집해서는 거의 안 됩니다. 잘못된 수정은 상태를 손상시키고 심각한 문제로 이어질 수 있습니다. 우리는 교육 목적으로만 이 파일을 보고 있습니다.

cat 명령어를 사용하여 상태 파일의 내용을 표시합니다.

cat terraform.tfstate

출력은 JSON 객체입니다. 여기에는 Terraform 버전과 같은 메타데이터와 가장 중요하게는 resources 배열이 포함되어 있습니다.

{
  "version": 4,
  "terraform_version": "1.13.3",
  "serial": 1,
  "lineage": "2a568739-a81d-ced7-dee1-7a92a1666022",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "local_file",
      "name": "example",
      "provider": "provider[\"registry.terraform.io/hashicorp/local\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "content": "This is an example file managed by Terraform.",
            "content_base64sha256": "...",
            "content_base64sha512": "...",
            "content_md5": "...",
            "content_sha1": "...",
            "content_sha256": "...",
            "content_sha512": "...",
            "directory_permission": "0777",
            "file_permission": "0777",
            "filename": "./example.txt",
            "id": "ec3adcab998872def2df6200fb03992ac6f237a4",
            "sensitive_content": null,
            "source": null
          },
          "sensitive_attributes": [
            [
              {
                "type": "get_attr",
                "value": "sensitive_content"
              }
            ]
          ],
          "identity_schema_version": 0
        }
      ]
    }
  ],
  "check_results": null
}

이 원시 데이터는 Terraform 이 실행 계획 (execution plans) 을 생성하는 데 사용하는 데이터입니다.

리소스 목록을 위해 terraform state list 실행

이 단계에서는 terraform state list를 사용하여 상태에 있는 모든 리소스의 간결한 목록을 얻는 방법을 배웁니다. 인프라가 커지고 수십 또는 수백 개의 리소스가 있을 때 terraform show는 너무 장황할 수 있습니다. state list 명령어는 리소스 주소 (resource address) 를 줄 바꿈으로 구분하여 간단하게 제공합니다.

터미널에서 명령어를 실행합니다.

terraform state list

출력은 매우 간단하며, 우리가 생성한 리소스의 주소만 표시됩니다.

local_file.example

이 명령어는 스크립팅을 하거나 다른 명령어로 대상을 지정해야 할 때 특정 리소스의 주소를 빠르게 식별하는 데 매우 유용합니다.

리소스 이름을 바꾸기 위해 terraform state mv 사용

이 단계에서는 terraform state mv를 사용하여 상태 파일 내의 리소스 이름을 바꾸는 방법을 배웁니다. 이는 Terraform 코드를 리팩토링할 때 흔히 발생하는 작업입니다. .tf 파일에서 리소스 블록의 이름을 바꾸면, Terraform 은 기존 리소스를 파괴하고 새 리소스를 생성하려 한다고 인식합니다. state mv 명령어를 사용하면 상태 파일을 코드 변경 사항에 맞게 업데이트하여 불필요한 파괴 및 생성을 방지할 수 있습니다.

먼저, 구성 파일에서 리소스 이름을 변경해 보겠습니다. nano 편집기로 main.tf를 엽니다.

nano main.tf

리소스 이름을 example에서 example_renamed로 변경합니다. 파일은 다음과 같이 보여야 합니다.

resource "local_file" "example_renamed" {
  content  = "This is an example file managed by Terraform."
  filename = "${path.module}/example.txt"
}

Ctrl+X를 누른 다음 Y를 누르고 Enter를 눌러 저장하고 종료합니다.

이제 terraform plan을 실행하여 Terraform 이 무엇을 할 것인지 확인합니다.

terraform plan

계획 (plan) 은 Terraform 이 local_file.example을 파괴하고 local_file.example_renamed를 생성하려고 함을 보여줄 것입니다. 이는 우리가 원하는 동작이 아닙니다.

local_file.example: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  ## local_file.example will be destroyed
  ## (because local_file.example is not in configuration)
  - resource "local_file" "example" {
      - content              = "This is an example file managed by Terraform." -> null
      - content_base64sha256 = "F5EYZhFNzSXdE4CUftwQoDVqvdiufZpVyiLMqyZVOcQ=" -> null
      - content_base64sha512 = "m1hvaxMuc/EhaKintyI54NSTTJ5yXpqHPCBNoHubF0rvF3JAj36lMj20aPcv21+3/OK+SqkiTlnT/LdvLCwqDA==" -> null
      - content_md5          = "a43bdd236c2f0f4d87452ba2ef0867e4" -> null
      - content_sha1         = "ec3adcab998872def2df6200fb03992ac6f237a4" -> null
      - content_sha256       = "17911866114dcd25dd1380947edc10a0356abdd8ae7d9a55ca22ccab265539c4" -> null
      - content_sha512       = "9b586f6b132e73f12168a8a7b72239e0d4934c9e725e9a873c204da07b9b174aef1772408f7ea5323db468f72fdb5fb7fce2be4aa9224e59d3fcb76f2c2c2a0c" -> null
      - directory_permission = "0777" -> null
      - file_permission      = "0777" -> null
      - filename             = "./example.txt" -> null
      - id                   = "ec3adcab998872def2df6200fb03992ac6f237a4" -> null
    }

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

이를 해결하기 위해, 우리는 리소스를 단순히 이동했음을 Terraform 에 알려줄 것입니다. 이전 주소와 새 주소를 사용하여 terraform state mv 명령어를 실행합니다.

terraform state mv local_file.example local_file.example_renamed

확인 메시지가 표시됩니다.

Move "local_file.example" to "local_file.example_renamed"
Successfully moved 1 object(s).

이제 terraform plan을 다시 실행합니다.

terraform plan

이번에는 상태가 구성과 일치하므로 Terraform 이 변경 사항이 없음을 보고합니다.

local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

상태 업데이트를 위해 terraform refresh 실행

이 단계에서는 terraform refresh를 사용하여 상태 파일과 실제 인프라를 일치시키는 방법을 배웁니다. 때로는 Terraform 의 제어 범위를 벗어나 인프라에 변경 사항이 발생할 수 있습니다. 이를 "드리프트 (drift)"라고 합니다. refresh 명령어는 이러한 변경 사항을 반영하도록 상태 파일을 업데이트합니다.

Terraform 이 생성한 파일을 수동으로 삭제하여 드리프트를 시뮬레이션해 보겠습니다.

rm example.txt

이제 plan 을 실행하면 Terraform 은 파일이 누락되었으며 다시 생성해야 함을 감지합니다.

terraform plan
local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

하지만 terraform refresh 명령어는 상태를 명시적으로 새로 고치는 데에도 사용될 수 있습니다. 이 명령어는 실제 리소스를 확인하고 그에 따라 상태 파일을 업데이트합니다.

terraform refresh
local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

이제 상태가 최신인지 확인하기 위해 terraform plan을 다시 실행합니다.

terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

terraform refresh를 성공적으로 사용하여 상태 드리프트를 수정했습니다.

요약

Terraform 상태 관리 (State Management) 에 대한 실습을 완료하신 것을 축하드립니다!

본 실습에서 여러분은 필수적인 terraform state 하위 명령어들에 대한 실질적인 경험을 쌓았습니다. 다음 사항들을 배웠습니다.

  • terraform show를 사용하여 인프라 상태의 사람이 읽기 쉬운 표현을 보는 방법.
  • 구조를 이해하기 위해 원시 terraform.tfstate JSON 파일을 검사하는 방법.
  • terraform state list를 사용하여 관리되는 모든 리소스의 깔끔한 목록을 얻는 방법.
  • 구성에서 리소스 이름을 안전하게 바꾸고 terraform state mv를 사용하여 상태를 그에 맞게 업데이트하는 방법.
  • terraform refresh를 사용하여 상태 파일을 실제 인프라와 일치시키고 드리프트 (drift) 를 수정하는 방법.

이 명령어들을 숙달하는 것은 Terraform 을 사용하여 인프라를 효과적이고 자신 있게 관리하는 데 기본이 됩니다.