Terraform 실전 · 프로바이더 별칭과 버전 제약 · 이론
별칭과 버전 제약 — 어느 설정으로 만들 것인가
한 줄 요약
alias 는 같은 프로바이더의 두 번째 설정에 이름표를 붙이는 것이고, 버전 제약은 내일 아침 CI 가 어디까지 새 판을 받아도 되는지 정하는 것이다. 둘 다 "선택" 을 코드에 남기는 장치다.
왜 이게 필요했나
프로바이더 설정은 자격증명·엔드포인트·리전 같은 연결 정보를 담는다. 리소스는 그중 하나를 골라 만들어진다. 설정이 하나뿐일 때는 고를 것이 없어서 이 선택이 보이지 않는다. 두 번째가 생기는 순간 모든 리소스가 답해야 한다 — 너는 어느 쪽에서 만들어지는가.
이 질문에 답하지 않으면 도구는 기본 설정을 쓴다. 조용히 쓴다. 그래서 "DR 리전에 만들려고 했는데 주 리전에 또 만들었다" 는 사고는 오류 없이 지나간다. 더 나쁜 것은 그다음이다. 상태 파일에는 그 리소스가 어느 설정으로 만들어졌는지가 적혀서, 나중에 지울 때도 같은 설정으로 지운다. 잘못된 짝이 그대로 굳는다.
버전 제약은 다른 방향의 같은 문제다. 제약을 안 적으면 오늘은 잘 되고 내일 CI 에서 처음 보는 오류가 난다. 새 판이 나왔기 때문이다. 반대로 한 판에 못 박으면 보안 수정이 나와도 손으로 올려야 한다. 제약은 이 둘 사이 어디에 설 것인지를 적는 문장이다.
어떻게 동작하나
세 가지를 구분해야 한다.
provider "random" {} # 기본 설정 — 이름표 없음provider "random" { alias = "seeded" # 두 번째 설정 — 이름표 seeded}resource "random_pet" "a" { provider = random.seeded # 리소스는 provider (단수)}module "site" { providers = { # 모듈은 providers (복수, 맵) random.east = random random.west = random.seeded }}- 리소스는
provider, 모듈은providers. 이름이 비슷해 자주 틀리는데, 하나는 "나는 이 설정을 쓴다", 다른 하나는 "모듈 안의 이 이름은 바깥의 이 설정이다" 로 뜻이 전혀 다르다. - 모듈은 자기 설정을 만들지 않는다. 모듈 안에서
provider블록을 선언하면 그 모듈은 자격증명을 스스로 정해 버려 두 번 쓸 수 없게 된다. 대신configuration_aliases로 "이런 이름의 설정을 받겠다" 고 자리만 선언한다. 부르는 쪽이 그 자리를 채우지 않으면init이 어떤 이름을 못 받았는지 콕 집어 막는다. - 상태가 기억한다. 상태 파일의 리소스마다
provider문자열이 있고, 별칭으로 만들어진 것만 끝이 다르다. 코드를 아무리 고쳐도 이미 만들어진 것의 짝은 상태에 적힌 대로다.
버전 제약은 자리 수가 의미를 만든다. 물결표 제약은 맨 오른쪽 자리만 올라갈 수 있게 허용한다. 자리를 두 개 적으면 가운데 자리가 올라가는 것까지 받아들이고, 세 개 적으면 맨 끝 자리만 받아들인다. 실습에서 같은 미러를 두고 이 둘이 서로 다른 결과를 내는 것을 직접 본다.
코어 버전 제약(required_version)은 또 다른 층이다. 이것은 플러그인을 받기도 전에 검사하므로, required_providers 가 아예 없어도 막힌다. 막힐 때 도구는 지금 쓰는 버전을 그대로 알려 준다.
현장에서 만나는 모습
가장 흔한 사고는 모듈을 두 번 부르면서 프로바이더 맵을 복사해 놓고 한 줄만 안 고친 것이다. 문법은 맞고 init 도 통과한다. 두 번째 호출이 첫 번째와 같은 설정을 쓰게 되어, 두 리전에 나뉘어야 할 것이 한쪽에 몰린다. 리뷰에서 잡으려면 모듈 호출마다 맵 전체를 보게 만드는 수밖에 없다.
두 번째는 제약 없이 쓰다가 어느 날 CI 만 깨지는 것이다. 사람 손의 작업 디렉터리에는 잠금 파일이 이미 있어서 예전 판이 계속 쓰이고, 깨끗한 CI 작업 공간만 새 판을 받는다. "내 컴퓨터에서는 되는데" 의 전형이다. 잠금 파일을 커밋하는 이유가 여기에 있다.
세 번째는 제약을 너무 좁혀 놓고 잊는 것이다. 한 판에 못 박은 설정이 수십 개 저장소에 흩어지면, 보안 수정이 나왔을 때 올려야 할 곳을 찾는 일이 먼저 일이 된다. 실무에서는 dev 쪽 저장소만 제약을 느슨하게 두고 먼저 올려 보는 식으로 순서를 만든다.
네 번째는 별칭 이름을 환경 이름으로 쓰는 것이다. provider "aws" { alias = "prod" } 처럼 적어 두면 읽기는 좋지만, 그 설정이 어느 리전·어느 계정인지는 여전히 안 보인다. 나중에 계정을 옮기면 이름과 실제가 어긋나고, 어긋난 이름은 아무도 고치지 않는다. 별칭은 연결 대상을 가리키는 이름으로 짓는 편이 오래간다.
정리하면 이 모듈이 다루는 두 가지는 모두 "선택을 코드에 남기는" 일이다. 어느 설정으로 만들 것인가를 리소스마다 적어 두면 상태가 그 선택을 기억하고, 어디까지 새 판을 받아도 되는가를 제약으로 적어 두면 잠금 파일이 그 결정의 근거를 남긴다. 둘 다 적지 않으면 도구가 말없이 대신 정하고, 그 결정은 사고가 난 뒤에야 보인다.
다음 실습에서 할 것
/root/tfa-alias 에서 random 프로바이더를 두 벌 설정해 리소스마다 고르고, 모듈에 그 설정을 넘겨 봅니다. 그다음 맵에서 한 줄을 빼 init 이 무엇을 말하는지 오류로 받아 보고, 미러에 없는 버전을 요구해 거절당하고, 물결표 제약 두 가지가 서로 다른 것을 허용하는 것을 확인한 뒤, 잠금 파일과 상태에서 값을 읽어 표로 정리합니다.