구성 생성하기

구성 생성하기 (Generating configuration)

이 주제는 import 블록에 정의된 단일 리소스 또는 소량의 리소스에 대한 코드를 생성하는 방법을 설명해요. 기존 인프라에서 리소스를 쿼리하고 검색 결과를 바탕으로 import 구성을 생성하는 방법은 기존 리소스 일괄 가져오기를 참고하세요.

출처: 문서

본문

실험적(Experimental): 구성 생성은 Terraform v1.5에서 실험적 기능으로 제공돼요. 이후의 마이너 버전에는 생성된 구성의 형식과 -generate-config-out 플래그를 사용하는 terraform plan 명령의 동작에 변경이 있을 수 있어요.

Terraform은 구매에 아직 존재하지 않는 import 블록에 정의한 리소스에 대한 코드를 생성할 수 있어요. Terraform은 각 리소스 인자의 적절한 값에 대한 최선의 추측을 담은 템플릿 역할을 하는 HCL을 생성해요. Terraform이 생성한 HCL에서 시작해서 일부 속성을 제거하고, 다른 속성의 값을 조정하며, 필요한 곳에 resource 블록을 파일과 모듈로 재배치하는 식으로 반복해서 이상적인 구성을 찾는 것을 권장해요.

구성을 생성하려면 -generate-config-out 플래그와 함께 terraform plan을 실행하고 새 파일 경로를 제공하세요. 기존 파일의 경로를 제공하면 Terraform이 오류를 던져요.

$ terraform plan -generate-config-out="generated_resources.tf"

import 블록이 대상으로 하는 리소스 중 구성에 존재하지 않는 것이 있다면, Terraform은 해당 리소스의 구성을 생성해 generated_resources.tf에 기록해요.

워크플로 (Workflow)

구성 생성 워크플로는 import 블록 워크플로와 비슷하지만, 플래닝 단계에서 구성을 생성하는 단계가 하나 더 있어요. 적용하기 전에 생성된 구성을 검토하고 수정할 수 있어요.

1. import 블록 추가하기

구성에 import 블록을 추가하세요. 이 import 블록은 별도의 파일(예: import.tf)에 있거나 기존 구성 파일에 있을 수 있어요.

import {
  to = aws_iot_thing.bar
  id = "foo"
}

import 블록의 to 인자는 resource가 스테이트 파일에서 가질 주소를 가리켜요. 스테이트의 리소스 주소가 import 블록의 to 인자와 일치하면 Terraform은 그 리소스로 가져오기를 시도해요. 이후 플래닝에서 Terraform은 스테이트에 이미 존재하는 리소스에 대해 구성을 생성할 필요가 없다는 것을 알아요.

import 블록의 id 인자는 그 리소스의 import ID를 사용해요.

선택한 제공사에 대한 다른 리소스가 구성에 없다면, Terraform이 구성 생성에 사용할 제공사를 알 수 있도록 provider 블록을 추가해야 해요. 그렇지 않으면 Terraform이 어떤 제공사를 사용할지 결정할 수 없을 때 오류를 표시해요. 구성에 새 provider 블록을 추가했다면 terraform init를 다시 실행해야 해요.

2. 플랜하고 구성 생성하기

정의한 import 블록에 대한 구성을 생성하도록 Terraform에 지시하려면 -generate-config-out= 플래그와 새 파일 경로를 사용해 terraform plan을 실행하세요. Terraform은 리소스를 가져오기 위한 플랜과, 이 플랜을 바탕으로 구성이 생성된 파일을 표시해요.

$ terraform plan -generate-config-out=generated.tf

aws_iot_thing.bar: Preparing import... [id=foo]
aws_iot_thing.bar: Refreshing state... [id=foo]

Terraform will perform the following actions:

  # aws_iot_thing.bar will be imported
  # (config will be generated)
    resource "aws_iot_thing" "bar" {
        arn               = "arn:aws:iot:eu-west-1:1234567890:thing/foo"
        attributes        = {}
        default_client_id = "foo"
        id                = "foo"
        name              = "foo"
        version           = 1
    }

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

╷
│ Warning: Config generation is experimental
│
│ Generating configuration during import is currently experimental, and the generated configuration format may change in future versions.
╵

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Terraform has generated configuration and written it to generated.tf. Please review the configuration and edit it as necessary before adding it to version control.

3. 생성된 구성 검토하기

위 예시는 Terraform이 generated.tf라는 파일에 구성을 생성하도록 지시해요. 아래 코드는 generated.tf 파일의 예시예요.

resource "aws_iot_thing" "bar" {
  name = "foo"
}

생성된 구성을 검토하고 필요에 따라 업데이트하세요. 생성된 구성을 다른 파일로 옮기거나, 리소스 인자를 추가/제거하거나, 구성의 입력 변수나 다른 리소스를 참조하도록 업데이트할 수 있어요.

4. 적용하기

terraform apply를 실행해 인프라를 가져오세요.

$ terraform apply

aws_iot_thing.bar: Preparing import... [id=foo]
aws_iot_thing.bar: Refreshing state... [id=foo]

Terraform will perform the following actions:

  # aws_iot_thing.bar will be imported
    resource "aws_iot_thing" "bar" {
        arn               = "arn:aws:iot:eu-west-1:1234567890:thing/foo"
        attributes        = {}
        default_client_id = "foo"
        id                = "foo"
        name              = "foo"
        version           = 1
    }

Plan: 1 to import, 0 to add, 0 to change, 0 to destroy.
aws_iot_thing.bar: Importing... [id=foo]
aws_iot_thing.bar: Import complete [id=foo]

Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed.

새 리소스 구성을 버전 제어 시스템에 커밋하세요.

제한 사항 (Limitations)

충돌하는 리소스 인자 (Conflicting resource arguments)

Terraform은 플랜 중 제공사에 리소스 속성 값을 요청해서 가져올 수 있는 리소스에 대한 구성을 생성해요. 복잡한 스키마를 가진 일부 리소스의 경우 Terraform이 이 값들로 유효한 구성을 만들지 못할 수 있어요.

구성 생성 중 리소스 속성에 대한 값을 받지 못하면 Terraform은 아래와 같은 오류를 표시해요.

$ terraform plan -generate-config-out="generated.tf"
╷
│ Error: Conflicting configuration arguments
│
│   with aws_instance.ubuntu,
│   on g.tf line 20, in resource "aws_instance" "ubuntu":
│   20:   ipv6_address_count                   = 0
│
│ "ipv6_address_count": conflicts with ipv6_addresses
╵

위 예시에서 Terraform은 여전히 구성을 생성해 generated.tf에 기록해요. 이 오류는 ipv6_address_countipv6_addresses 인자 간의 충돌에서 비롯돼요. 리소스가 두 인자를 모두 지원하지만, 리소스를 구성할 때 둘 중 하나만 선택해야 해요. 두 인자 중 하나를 제거한 뒤 terraform plan을 다시 실행해서 더 이상 문제가 없는지 확인하면 오류를 고칠 수 있어요.

더 알아보기 (Learn more)