LabHub
学习 学习路径 课程

Terraform 实战

加了第二个区域后,模块拿不到 provider 了

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

같은 프로바이더를 두 벌 설정해 리소스마다 고르고, 모듈에 그 설정을 넘기고, 하나를 빠뜨렸을 때 무엇이 막는지 본 뒤, 버전 제약을 좁혀 가며 init 이 언제 통과하고 언제 거절하는지 직접 확인합니다.

왜 중요한가

인프라 코드가 한 리전·한 계정 안에 머무는 기간은 생각보다 짧습니다. 재해 복구용 두 번째 리전, 감사 로그를 따로 모으는 계정, 공용 레지스트리와 사설 레지스트리 — 어느 쪽이든 같은 프로바이더를 서로 다른 설정으로 두 벌 갖게 됩니다. 이때 리소스가 어느 설정으로 만들어졌는지는 코드가 아니라 상태에 남고, 그 기록이 틀리면 나중에 엉뚱한 곳을 지웁니다. 모듈은 한 걸음 더 나갑니다 — 모듈이 자기 프로바이더 설정을 스스로 만들면 그 모듈은 두 번 쓸 수 없게 되므로, 자리만 선언하고 부르는 쪽이 채우게 설계합니다. 버전 제약은 이 모든 것의 바닥입니다. 제약을 어떻게 적느냐가 '내일 아침 CI 가 새 판을 받아 와도 되는가' 를 결정하고, 잠금 파일이 그 결정의 근거를 남깁니다.

단계

  1. /root/tfa-alias/main.tfrequired_version = ">= 1.6.0"required_providers 의 random(source = "hashicorp/random", version = "3.9.0")을 두고, 기본 프로바이더 설정 블록 하나와 random_pet.root(length 2)를 선언한 뒤 init·apply 하세요.
  2. /root/tfa-alias/aliased.tf 를 새로 만들어 alias = "seeded" 인 두 번째 random 프로바이더 설정과, 그 설정으로 만들어지는 random_pet.aliased(length 4)를 선언하세요. main.tfrandom_pet.root 는 기본 설정 그대로 둡니다. apply 한 뒤 상태 파일에서 두 리소스의 프로바이더 주소가 어떻게 다른지 확인하세요.
  3. /root/tfa-alias/modules/site/main.tfconfiguration_aliases = [random.east, random.west] 를 선언하고 각각으로 만드는 random_pet.east·random_pet.west(둘 다 length 2)와 같은 이름의 출력 두 개를 두세요. /root/tfa-alias/site.tf 에서 그 모듈을 부르며 providers 맵을 random.east = randomrandom.west = random.seeded 로 채우고, 모듈의 두 출력을 루트 출력 site_east·site_west 로 올린 뒤 init·apply 하세요.
  4. /root/tfa-alias/site.tfproviders 맵에서 random.west 줄만 지우고 tofu init 을 돌려 오류를 /root/tfa-alias/missing-provider.txt 에 저장하세요(성공하면 안 됩니다). 그다음 지운 줄을 되돌리고 다시 init·apply 해서 계획이 깨끗한 상태로 마치세요.
  5. /root/tfa-alias/probe/too-new/main.tf 에 random 을 version = ">= 4.0.0" 으로 제약한 required_providers 만 두고 그 디렉터리에서 init 하세요. 출력은 /root/tfa-alias/probe/too-new/init.txt 에 저장합니다. 이 디렉터리에는 잠금 파일이 생기지 않아야 합니다.
  6. 두 디렉터리에서 같은 프로바이더를 서로 다르게 제약해 결과를 견주세요. /root/tfa-alias/probe/minor/main.tf 에는 random 제약을 ~> 3.8 로 둡니다. /root/tfa-alias/probe/patch/main.tf 에는 random 제약을 ~> 3.8.0 으로 둡니다. 둘 다 init 한 뒤 /root/tfa-alias/probe/verdict.tsvminor·patch 두 줄을 탭 세 칸(<이름>, ok 또는 fail, 설치된 버전 또는 none)으로 적습니다.
  7. /root/tfa-alias/probe/core/main.tfrequired_version = ">= 999.0.0" 만 둔 뒤 init 해 오류를 /root/tfa-alias/probe/core/init.txt 에 저장하고, 지금 파드의 실제 코어 버전(tofu version 첫 줄의 숫자만, 예: 1.2.3 꼴)을 /root/tfa-alias/probe/core/version.txt 에 한 줄로 적으세요.
  8. /root/tfa-alias/report.tsv 에 네 줄을 탭 두 칸으로 적으세요. lock_version = 루트 잠금 파일에 적힌 random 의 버전, lock_constraints = 그 잠금 파일에 적힌 제약 문자열, provider_configs = 루트 설정의 random 프로바이더 설정 블록 수, aliased_resources = 상태에서 별칭 설정으로 만들어진 리소스 수(모듈 안까지 셉니다).

참고

코어와 프로바이더의 버전을 못 박는다

/root/tfa-alias/main.tfrequired_version = ">= 1.6.0"required_providers 의 random(source = "hashicorp/random", version = "3.9.0")을 두고, 기본 프로바이더 설정 블록 하나와 random_pet.root(length 2)를 선언한 뒤 init·apply 하세요.

required_version 은 코어(OpenTofu 자체)의 버전을, required_providers 의 version 은 플러그인의 버전을 제약합니다. 둘은 서로 다른 것이라 한쪽만 적어도 init 은 됩니다. 잠금 파일이 무엇을 적어 두는지 apply 뒤에 열어 보세요.

같은 프로바이더를 두 벌 설정한다

/root/tfa-alias/aliased.tf 를 새로 만들어 alias = "seeded" 인 두 번째 random 프로바이더 설정과, 그 설정으로 만들어지는 random_pet.aliased(length 4)를 선언하세요. main.tfrandom_pet.root 는 기본 설정 그대로 둡니다. apply 한 뒤 상태 파일에서 두 리소스의 프로바이더 주소가 어떻게 다른지 확인하세요.

리소스에서 별칭 설정을 고르는 메타 인자는 provider 입니다(providers 가 아닙니다 — 그건 모듈용입니다). 상태 파일의 각 리소스에는 어떤 프로바이더 설정으로 만들어졌는지가 문자열로 적혀 있고, 별칭이 붙은 쪽만 끝이 다릅니다.

모듈에 프로바이더 설정을 넘긴다

/root/tfa-alias/modules/site/main.tfconfiguration_aliases = [random.east, random.west] 를 선언하고 각각으로 만드는 random_pet.east·random_pet.west(둘 다 length 2)와 같은 이름의 출력 두 개를 두세요. /root/tfa-alias/site.tf 에서 그 모듈을 부르며 providers 맵을 random.east = randomrandom.west = random.seeded 로 채우고, 모듈의 두 출력을 루트 출력 site_east·site_west 로 올린 뒤 init·apply 하세요.

configuration_aliases 는 '이 모듈은 이런 이름의 설정을 부르는 쪽에서 받는다' 는 선언입니다. 모듈 안에서 provider 블록을 만들지 않는 이유는, 모듈이 자기 자격증명을 스스로 정하면 재사용이 불가능해지기 때문입니다. providers 맵의 왼쪽은 모듈 안의 이름, 오른쪽은 루트의 설정입니다.

넘기는 것을 하나 빠뜨리면 무엇이 막나

/root/tfa-alias/site.tfproviders 맵에서 random.west 줄만 지우고 tofu init 을 돌려 오류를 /root/tfa-alias/missing-provider.txt 에 저장하세요(성공하면 안 됩니다). 그다음 지운 줄을 되돌리고 다시 init·apply 해서 계획이 깨끗한 상태로 마치세요.

모듈이 요구한 설정 자리를 부르는 쪽이 채우지 않으면 도구가 어떤 이름을 못 받았는지 콕 집어 말해 줍니다. 오류 메시지에 그 이름이 그대로 나오는지 보세요. 출력은 표준 오류로 나가니 2>&1 로 함께 받아야 합니다.

미러에 없는 버전을 요구해 본다

/root/tfa-alias/probe/too-new/main.tf 에 random 을 version = ">= 4.0.0" 으로 제약한 required_providers 만 두고 그 디렉터리에서 init 하세요. 출력은 /root/tfa-alias/probe/too-new/init.txt 에 저장합니다. 이 디렉터리에는 잠금 파일이 생기지 않아야 합니다.

이 파드의 프로바이더 미러에는 random 이 한 판만 들어 있습니다. 제약을 만족하는 판이 없을 때 도구가 '무엇을 찾다가 못 찾았는지' 를 그대로 말해 주는지 확인하세요. 실패한 init 은 잠금 파일을 남기지 않습니다.

물결표 제약 두 가지가 서로 다른 것을 허용한다

두 디렉터리에서 같은 프로바이더를 서로 다르게 제약해 결과를 견주세요. /root/tfa-alias/probe/minor/main.tf 에는 random 제약을 ~> 3.8 로 둡니다. /root/tfa-alias/probe/patch/main.tf 에는 random 제약을 ~> 3.8.0 으로 둡니다. 둘 다 init 한 뒤 /root/tfa-alias/probe/verdict.tsvminor·patch 두 줄을 탭 세 칸(<이름>, ok 또는 fail, 설치된 버전 또는 none)으로 적습니다.

물결표 제약은 맨 오른쪽 자리만 올릴 수 있게 허용합니다. 자리를 몇 개 적었는지가 곧 '어디까지 올라가도 되는가' 입니다. 설치된 버전은 그 디렉터리의 잠금 파일에서 읽습니다.

코어 버전 제약은 플러그인보다 먼저 막는다

/root/tfa-alias/probe/core/main.tfrequired_version = ">= 999.0.0" 만 둔 뒤 init 해 오류를 /root/tfa-alias/probe/core/init.txt 에 저장하고, 지금 파드의 실제 코어 버전(tofu version 첫 줄의 숫자만, 예: 1.2.3 꼴)을 /root/tfa-alias/probe/core/version.txt 에 한 줄로 적으세요.

코어 버전 제약은 프로바이더를 받기도 전에 검사합니다 — 그래서 required_providers 가 아예 없어도 막힙니다. 오류 메시지가 '지금 쓰는 버전' 을 그대로 말해 주니 version.txt 와 같은 숫자인지 견줘 보세요.

무엇이 어떤 설정으로 만들어졌는지 표로 낸다

/root/tfa-alias/report.tsv 에 네 줄을 탭 두 칸으로 적으세요. lock_version = 루트 잠금 파일에 적힌 random 의 버전, lock_constraints = 그 잠금 파일에 적힌 제약 문자열, provider_configs = 루트 설정의 random 프로바이더 설정 블록 수, aliased_resources = 상태에서 별칭 설정으로 만들어진 리소스 수(모듈 안까지 셉니다).

잠금 파일에는 고른 버전과 그때의 제약이 함께 적혀 있어서, 나중에 '왜 이 판이 골라졌나' 를 되짚을 수 있습니다. 별칭으로 만들어진 리소스는 상태의 provider 문자열 끝이 다릅니다 — jq 로 세어 보세요.