프로바이더 요구 사항

프로바이더 요구 사항 (Provider Requirements)

Terraform은 "프로바이더"라고 부르는 플러그인에 의존해서 원격 시스템과 상호작용해요. Terraform 구성은 어떤 프로바이더를 필요로 하는지 선언해야 Terraform이 그 프로바이더를 설치하고 사용할 수 있어요. 이 페이지는 프로바이더를 선언해 Terraform이 설치할 수 있게 하는 방법을 다뤄요.

출처: 문서

본문

또한 일부 프로바이더는 사용 전에 구성(예: 엔드포인트 URL이나 클라우드 리전)이 필요해요. provider 블록 참조가 프로바이더 설정을 구성하는 방법을 다뤄요.

참고: 이 페이지는 Terraform 0.13 이상의 기능에 관한 내용이며, Terraform 0.12에서 사용할 수 있었던 그 기능의 더 제한된 버전을 사용하는 방법도 설명해요.

개요

각 Terraform 루트 모듈은 어떤 프로바이더를 필요로 하는지 선언해야 Terraform이 그 프로바이더를 설치하고 사용할 수 있어요. 모듈에서 프로바이더를 선언하려면 다음 세 단계를 수행하세요.

  • 최상위 terraform 블록 안의 required_providers 블록에서 프로바이더의 소스(source), 로컬 이름, 버전을 정의하세요.
  • 구성에 최상위 provider 블록을 추가해 인증, 리전, 기타 프로바이더별 인자로 프로바이더를 구성하세요.
  • 프로바이더를 설치하세요. 로컬에서 terraform init을 실행하면 프로바이더를 설치하고, required_providers 블록에서 구성한 버전 문자열과 일치하는 최신 버전으로 의존성 잠금 파일을 업데이트해요. HCP Terraform과 Terraform Enterprise는 잠금 파일이 있으면 그 잠금 파일에 제공된 버전을 사용해 매번 실행마다 프로바이더를 설치해요.

로컬에서 Terraform을 실행한다면 계획(plan)과 적용(apply) 작업은 의존성 잠금 파일에 지정된 프로바이더 버전을 사용해요. required_providers 블록에서 버전을 변경하고 terraform init을 다시 실행하면 잠금 파일의 프로바이더 버전을 업그레이드할 수 있어요.

프로바이더 요구하기

각 Terraform 모듈은 어떤 프로바이더를 필요로 하는지 선언해야 Terraform이 그 프로바이더를 설치하고 사용할 수 있어요. 프로바이더 요구 사항은 required_providers 블록에 선언돼요. 프로바이더 요구 사항은 로컬 이름, 소스 위치, 버전 제약으로 구성돼요:

terraform {
  required_providers {
    mycloud = {
      source  = "mycorp/mycloud"
      version = "~> 1.0"
    }
  }
}

required_providers 블록은 최상위 terraform 블록 안에 중첩되어야 해요 (그 블록은 다른 설정도 포함할 수 있어요). required_providers 블록의 각 인자는 하나의 프로바이더를 활성화해요. 키는 프로바이더의 로컬 이름(이 모듈 안에서의 고유 식별자)을 결정하고, 값은 다음 요소를 가진 객체예요:

  • source - 사용하려는 프로바이더의 전역 소스 주소 (예: hashicorp/aws).
  • version - 모듈이 호환되는 사용 가능한 프로바이더 버전의 부분집합을 지정하는 버전 제약.

참고: required_providers에 대한 name = { source, version } 문법은 Terraform v0.13에 추가됐어요. 이전 Terraform 버전은 객체 대신 버전 제약 문자열(mycloud = "~> 1.0"처럼)을 사용했고, 프로바이더 소스 주소를 지정할 방법이 없었어요. Terraform v0.12와 v0.13 둘 다에서 작동하는 모듈을 작성하려면 아래의 v0.12 호환 프로바이더 요구 사항을 참고하세요.

이름과 주소

각 프로바이더에는 두 개의 식별자가 있어요:

  • 소스 주소(source address): 요구할 때만 사용하는 고유한 주소.
  • 로컬 이름(local name): Terraform 모듈의 다른 모든 곳에서 사용되는 이름.

참고: Terraform 0.13 이전에는 Terraform이 HashiCorp가 배포하는 프로바이더만 자동으로 다운로드할 수 있었기 때문에 프로바이더에 로컬 이름만 있었어요.

로컬 이름 (Local Names)

로컬 이름은 모듈별로 지정되며 프로바이더를 요구할 때 할당돼요. 로컬 이름은 모듈별로 고유해야 해요. required_providers 블록 밖에서는 Terraform 구성이 항상 로컬 이름으로 프로바이더를 참조해요. 예를 들어 다음 구성은 mycloudmycorp/mycloud의 로컬 이름으로 선언한 다음, 프로바이더 구성 시에 그 로컬 이름을 사용해요:

terraform {
  required_providers {
    mycloud = {
      source  = "mycorp/mycloud"
      version = "~> 1.0"
    }
  }
}

provider "mycloud" {
  # ...
}

프로바이더 사용자는 그 프로바이더에 원하는 로컬 이름을 선택할 수 있어요. 그러나 거의 모든 프로바이더는 선호하는 로컬 이름을 가지며, 그것을 모든 리소스 타입의 접두사로 사용해요. (예를 들어 hashicorp/aws의 리소스는 aws_instanceaws_security_group처럼 모두 aws로 시작해요.)

가능하면 프로바이더의 선호 로컬 이름을 사용하세요. 그러면 구성을 이해하기 쉬워지고, 대부분의 리소스에서 provider 메타 인자를 생략할 수 있어요. (리소스가 사용할 프로바이더 구성을 지정하지 않으면 Terraform은 리소스 타입의 첫 단어를 로컬 프로바이더 이름으로 해석해요.)

소스 주소 (Source Addresses)

프로바이더의 소스 주소는 전역 식별자예요. 또한 Terraform이 다운로드할 수 있는 주요 위치를 지정해요. 소스 주소는 슬래시(/)로 구분된 세 부분으로 구성돼요:

[HOSTNAME/]NAMESPACE/TYPE

유효한 프로바이더 소스 주소 형식의 예시는 다음과 같아요:

  • NAMESPACE/TYPE

  • HOSTNAME/NAMESPACE/TYPE

  • 호스트명(선택): 프로바이더를 배포하는 Terraform 레지스트리의 호스트명. 생략하면 공개 Terraform 레지스트리의 호스트명인 registry.terraform.io가 기본값이에요.

  • Namespace: 지정된 레지스트리 안의 조직적 네임스페이스. 공개 Terraform 레지스트리와 HCP Terraform의 프라이빗 레지스트리의 경우 프로바이더를 게시하는 조직을 나타내요. 다른 레지스트리 호스트에서는 이 필드가 다른 의미를 가질 수 있어요.

  • Type: 프로바이더가 관리하는 플랫폼이나 시스템의 짧은 이름. 특정 레지스트리 호스트의 특정 네임스페이스 안에서 고유해야 해요. type은 보통 프로바이더의 선호 로컬 이름이에요. (예외가 있는데, 예를 들어 hashicorp/google-betahashicorp/google의 대체 릴리스 채널이라 선호 로컬 이름이 google이에요. 의심스러우면 프로바이더 문서를 확인하세요.)

예를 들어 공식 HTTP 프로바이더registry.terraform.iohashicorp 네임스페이스에 속하므로, 그 소스 주소는 registry.terraform.io/hashicorp/http 또는 더 흔하게는 그냥 hashicorp/http예요.

세 구성 요소를 모두 명시한 소스 주소를 프로바이더의 정규화된 주소(fully-qualified address)라고 불러요. 정규화된 주소는 오류 메시지 같은 다양한 출력에서 볼 수 있지만, 대부분의 경우 단순화된 표시 버전이 사용돼요. 이 표시 버전은 소스 호스트가 공개 레지스트리일 때 소스 호스트를 생략하므로, "registry.terraform.io/hashicorp/random" 대신 짧은 버전 "hashicorp/random"을 볼 수 있어요.

참고: 프로바이더를 요구할 때 source 인자를 생략하면 Terraform은 registry.terraform.io/hashicorp/라는 암시적 소스 주소를 사용해요. 이것은 Terraform 0.13로의 전환을 지원하기 위한 하위 호환성 기능이에요. 0.13 이상을 요구하는 모듈에서는 모든 프로바이더에 명시적 소스 주소를 사용하는 것을 권장해요.

로컬 이름 충돌 처리

가능하면 프로바이더의 선호 로컬 이름을 사용하는 것을 권장해요. 보통 그것은 소스 주소의 "type" 부분과 같아요. 하지만 같은 모듈에서 선호 로컬 이름이 같은 두 프로바이더를 사용해야 하는 경우가 가끔 있는데, 보통 프로바이더가 일반적인 인프라 타입의 이름을 따랐을 때 그래요. Terraform은 모듈의 각 프로바이더에 고유한 로컬 이름을 요구하므로, 최소 하나에는 비선호 이름을 사용해야 해요.

이런 경우 각 프로바이더의 네임스페이스와 타입 이름을 결합해 대시를 붙인 복합 로컬 이름을 사용하는 것을 권장해요:

terraform {
  required_providers {
    # In the rare situation of using two providers that
    # have the same type name -- "http" in this example --
    # use a compound local name to distinguish them.
    hashicorp-http = {
      source  = "hashicorp/http"
      version = "~> 2.0"
    }
    mycorp-http = {
      source  = "mycorp/http"
      version = "~> 1.0"
    }
  }
}

# References to these providers elsewhere in the
# module will use these compound local names.
provider "mycorp-http" {
  # ...
}

data "http" "example" {
  provider = hashicorp-http
  #...
}

Terraform은 리소스 타입만으로 두 프로바이더의 이름을 추측할 수 없으므로, 영향을 받는 모든 리소스에 provider 메타 인자를 지정해야 해요. 하지만 모듈의 독자와 유지 관리자는 무슨 일이 일어나는지 쉽게 이해할 수 있고, 혼동을 피하는 것이 입력을 피하는 것보다 훨씬 중요해요.

버전 제약 (Version Constraints)

각 프로바이더 플러그인은 자신만의 사용 가능한 버전 집합을 가지고 있어 프로바이더의 기능이 시간이 지남에 따라 진화할 수 있어요. 선언하는 각 프로바이더 의존성은 version 인자에 버전 제약이 주어져야 Terraform이 모든 모듈이 호환되는 프로바이더별 단일 버전을 선택할 수 있어요.

version 인자는 선택 사항이에요. 생략하면 Terraform은 프로바이더의 어떤 버전이든 호환되는 것으로 받아들여요. 그러나 모듈이 의존하는 모든 프로바이더에 버전 제약을 지정하는 것을 강력히 권장해요.

주어진 구성에 대해 Terraform이 항상 같은 프로바이더 버전을 설치하도록 보장하려면 Terraform CLI를 사용해 의존성 잠금 파일을 만들고 구성과 함께 버전 관리에 커밋하세요. 잠금 파일이 있으면 HCP Terraform, CLI, Enterprise는 모두 프로바이더를 설치할 때 그것을 따를 거예요.

실습: Lock and Upgrade Provider Versions 튜토리얼을 해보세요.

프로바이더 버전 모범 사례

각 모듈은 >= 버전 제약 문법을 사용해 최소한 그 모듈이 작동한다고 알려진 최소 프로바이더 버전을 선언해야 해요:

terraform {
  required_providers {
    mycloud = {
      source  = "hashicorp/aws"
      version = ">= 1.0"
    }
  }
}

구성의 루트, 즉 terraform apply를 실행하는 디렉터리로 사용하려는 모듈은 호환되지 않는 새 버전으로의 우발적 업그레이드를 피하기 위해 최대 프로바이더 버전도 지정해야 해요. ~> 연산자는 버전의 가장 오른쪽 구성 요소가 증가하는 것을 허용하는 편리한 약식 표기법이에요. 다음 예시는 그 연산자를 사용해 특정 마이너 릴리스 내에서 패치 릴리스만 허용해요:

terraform {
  required_providers {
    mycloud = {
      source  = "hashicorp/aws"
      version = "~> 1.0.4"
    }
  }
}

여러 구성에서 재사용하려는 모듈에는 ~>(또는 다른 최대 버전 제약)를 사용하지 마세요. 모듈이 특정 새 버전과 호환되지 않는다는 것을 알아도 마찬가지예요. 이렇게 하면 때로 오류를 방지할 수도 있지만, 더 자주 루틴 업그레이드를 수행할 때 모듈 사용자가 많은 모듈을 동시에 업데이트해야 하는 상황을 만듭니다. 최소 버전을 지정하고, 알려진 비호환성을 문서화하고, 최대 버전은 루트 모듈이 관리하게 두세요.

기본 제공 프로바이더 (Built-in Providers)

대부분의 Terraform 프로바이더는 플러그인으로 별도 배포되지만, Terraform 자체에 내장된 프로바이더가 하나 있어요. 이 프로바이더는 terraform_remote_state 데이터 소스를 가능하게 해요. 이 프로바이더는 Terraform에 내장돼 있으므로 그 기능을 사용하기 위해 required_providers 블록에 선언할 필요가 없어요. 하지만 일관성을 위해 특별한 프로바이더 소스 주소인 terraform.io/builtin/terraform을 가져요. 이 주소는 가상의 terraform 타입 이름을 가진 제3자 프로바이더와 구별하기 위해 Terraform의 오류 메시지와 기타 출력에 가끔 나타날 수 있어요.

또한 hashicorp/terraform라는 소스 주소를 가진 기존 프로바이더가 있는데, 이것은 더 오래된 Terraform 버전이 사용하던 현재 내장 프로바이더의 이전 버전이에요. hashicorp/terraform은 Terraform v0.11 이상과 호환되지 않으며 required_providers 블록에 절대 선언해서는 안 돼요.

사내(In-house) 프로바이더

누구나 자신만의 Terraform 프로바이더를 개발하고 배포할 수 있어요. 프로바이더 개발에 대한 자세한 내용은 Terraform 프로바이더로 API 호출하기 튜토리얼을 참고하세요. 일부 조직은 독점 시스템을 구성하기 위해 자체 프로바이더를 개발하고, 공개 Terraform 레지스트리에 게시하지 않고 Terraform에서 사용하고 싶어해요.

이런 프로바이더를 배포하는 한 가지 방법은 프로바이더 레지스트리 프로토콜을 구현해 사내 프라이빗 레지스트리를 운영하는 거예요. 단일 프로바이더를 내부 배포하기 위해 추가 서비스를 운영하는 것이 바람직하지 않을 수 있으므로, Terraform은 파일시스템 미러를 통해 로컬 파일시스템의 특정 디렉터리에 프로바이더 플러그인을 직접 배치하는 것(기타 프로바이더 설치 방법)도 지원해요.

모든 프로바이더는 레지스트리의 호스트명을 포함(또는 암시)하는 소스 주소를 가져야 하지만, 그 호스트명이 실제 레지스트리 서비스를 제공할 필요는 없어요. 로컬 파일시스템 디렉터리에서 배포하려는 사내 프로바이더의 경우 조직이 제어하는 도메인의 임의 호스트명을 사용할 수 있어요.

예를 들어 회사 도메인이 example.com이라면 그 호스트명이 실제로 DNS에서 해석되지 않더라도 자리 표시자 호스트명으로 terraform.example.com을 선택할 수 있어요. 그런 다음 그 호스트명 아래에서 사내 프로바이더를 나타낼 네임스페이스와 타입을 선택해 terraform.example.com/examplecorp/ourcloud 같은 소스 주소를 만들 수 있어요:

terraform {
  required_providers {
    mycloud = {
      source  = "terraform.example.com/examplecorp/ourcloud"
      version = ">= 1.0"
    }
  }
}

이 프로바이더의 버전 1.0.0을 로컬 파일시스템에서 설치할 수 있게 하려면 암시적 로컬 미러 디렉터리 중 하나를 선택하고 그 아래에 다음과 같은 디렉터리 구조를 만드세요:

terraform.example.com/examplecorp/ourcloud/1.0.0

1.0.0 디렉터리 아래에 Terraform을 실행하는 플랫폼을 나타내는 추가 디렉터리(예: AMD64/x64 프로세서의 Linux를 위한 linux_amd64)를 만들고, 그 디렉터리에 프로바이더 플러그인 실행 파일과 필요한 기타 파일을 배치하세요. 따라서 Windows 시스템에서는 프로바이더 플러그인 실행 파일이 다음 경로에 있을 수 있어요:

terraform.example.com/examplecorp/ourcloud/1.0.0/windows_amd64/terraform-provider-ourcloud.exe

나중에 실제 프라이빗 프로바이더 레지스트리로 전환하기로 결정하면 대역 외로 바이너리를 배포하는 대신 terraform.example.com에 레지스트리 서버를 배포하고 같은 네임스페이스와 타입 이름을 유지할 수 있어요. 그 경우 기존 모듈은 레지스트리 서버로 같은 프로바이더를 찾는 데 변경이 필요하지 않아요.

v0.12 호환 프로바이더 요구 사항

명시적 프로바이더 소스 주소는 Terraform v0.13과 함께 도입됐으므로, 전체 프로바이더 요구 사항 문법은 Terraform v0.12에서 지원되지 않아요. 하지만 Terraform v0.12와 v0.13 둘 다와 호환되는 모듈을 작성할 수 있도록, v0.12.26과 v0.13 사이의 Terraform 버전은 required_providers 블록의 source 인자를 받아들이되 무시해요.

Terraform v0.13용으로 작성된 다음 예시를 살펴보세요:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 1.0"
    }
  }
}

Terraform v0.12.26은 위와 같은 문법을 받아들이지만, 다음 v0.12 스타일 문법과 같은 방식으로 이해해요:

terraform {
  required_providers {
    aws = "~> 1.0"
  }
}

즉, Terraform v0.12.26은 source 인자를 무시하고 version 인자만 고려하며, 주어진 로컬 이름을 네임스페이스가 없는 프로바이더 타입으로 사용해 설치해요.

Terraform v0.12.26과 v0.13.0 이상 둘 다와 호환되는 모듈을 작성할 때는 두 버전이 같은 프로바이더를 설치하도록 선택하도록 다음 추가 규칙을 따라야 해요:

  • Terraform v0.12가 자동으로 설치할 수 있는 프로바이더만 사용하세요. Terraform 레지스트리의 커뮤니티 프로바이더 같은 타사 프로바이더는 계층적 소스 주소 네임스페이스를 지원하지 않으므로 Terraform v0.12가 선택할 수 없어요.
  • 선택한 로컬 이름이 source 인자에 주어진 소스 주소의 "type" 부분과 정확히 일치하는지 확인하세요. (예: 위 예시처럼 둘 다 "aws"여야 해요.) Terraform v0.12는 로컬 이름을 사용해 다운로드하고 설치할 프로바이더 플러그인을 결정하기 때문이에요.
  • 프로바이더가 위에 표시된 hashicorp/aws처럼 hashicorp 네임스페이스에 속한다면 source 인자를 생략하고 Terraform v0.13이 기본적으로 hashicorp 네임스페이스를 선택하도록 하세요.
  • 프로바이더 타입 이름은 항상 소문자로 작성해야 해요. Terraform v0.13은 프로바이더 소스 주소를 대소문자를 구분하지 않는 것으로 취급하지만, Terraform v0.12는 레거시 스타일 프로바이더 이름을 대소문자를 구분하는 것으로 간주해요. 소문자를 사용하면 이름이 두 Terraform 메이저 버전 모두에서 선택 가능하게 보장돼요.

이 호환성 메커니즘은 임시 전환 보조 수단으로만 제공돼요. Terraform v0.12가 이해하지 못하는 새 source 인자의 사용을 감지하면, 그 인자에 주어진 소스 주소를 무시하고 있다는 것을 사용자에게 알리는 경고를 발생시켜요.

더 알아보기 (Learn more)