Terraform/OpenTofu 기초 · 변수의 형 · 이론
형은 문서가 아니라 검문소다
한 줄 요약
변수의 형은 잘못된 값을 경계에서 막고, 맞출 수 있는 값은 조용히 바꾸고, 선언에 없는 것은 말없이 버린다. 이 셋을 구분해야 한다.
왜 형을 적어야 하나
형을 적지 않아도 설정은 돈다. 그래서 급할 때 빼먹기 쉽고, 빼먹어도 그날은 아무 일이 없다. 문제는 잘못된 값이 들어오는 날이다.
형이 없으면 그 값은 변수 경계를 그냥 통과한다. 통과한 값은 locals 를 지나고 함수를 지나 리소스 인자까지 흘러가고, 결국 어딘가에서 터진다. 그때 메시지는 "당신이 준 값이 틀렸다" 가 아니라 "이 함수 호출이 실패했다" 다. 설정 파일을 위에서부터 거슬러 올라가며 값을 추적해야 원인에 닿는다.
형을 적어 두면 같은 실수가 이렇게 막힌다.
Error: Invalid value for input variable on v.tfvars line 1: 1: tight = 7number required.줄 번호가 나오고, 무엇을 기대했는지가 나온다. 고치는 데 드는 시간이 완전히 다르다.
어떻게 동작하나
형은 세 갈래로 나뉜다. 기본형(string·number·bool), 컬렉션형(list·set·map), 구조형(object·tuple), 그리고 아무거나 받는 any 다.
막는다. 바꿀 수 없는 값이 오면 그 자리에서 거절한다. 숫자 자리에 목록을 주거나, 튜플의 개수가 다르거나, 오브젝트의 필수 속성이 없으면 계획조차 세워지지 않는다.
바꾼다. 바꿀 수 있으면 바꾼다. tfvars 에 replicas = "3" 이라고 적어도 number 변수에는 3 이 들어가고, debug = "true" 도 참이 된다. 더 조용한 것은 컬렉션 안쪽이다.
variable "tags" { type = map(string) }# tags = { team = "core", rev = 3, tls = true }# 결과 { "team" = "core", "rev" = "3", "tls" = "true" }숫자 3 이 문자열 "3" 이 되었는데 아무도 알려 주지 않는다. 그 값으로 나중에 산술이나 같다 비교를 하려 했다면 그때 이상해진다.
버린다. 구조형에는 또 다른 성질이 있다. 오브젝트는 선언한 속성만 받고, 선언에 없는 속성은 오류가 아니라 버림이다. 속성 이름에 오타를 내면 그 값은 사라지고, 기본값이 적용된 것처럼 보인다. 이것이 형 검사가 잡아 주지 않는 대표적인 구멍이다.
목록과 집합의 차이도 기억할 만하다. 같은 ["b", "a", "b"] 를 주어도 목록은 세 개를 순서대로 담고, 집합은 중복을 버리고 자기 규칙대로 정렬해 두 개만 담는다. 길이가 달라지므로 개수를 세는 코드가 영향을 받는다.
선택 속성은 짧은 입력을 받게 해 준다.
variable "service" { type = object({ name = string port = optional(number, 8080) tls = optional(bool, false) })}이렇게 두면 쓰는 쪽은 name 만 주면 되고, 나머지는 기본값이 채워진다. 기본값을 주지 않으면 그 속성은 null 이 되어 하류에서 다시 확인해야 하므로 되도록 함께 적는다.
null 을 받지 않겠다는 선언은 두 갈래로 동작한다. 기본값이 있으면 들어온 null 이 기본값으로 대체되고, 기본값이 없으면 오류가 된다. "값이 없을 때 무엇이 되는가" 를 한 곳에 못 박는 장치다.
마지막으로 형과 값 검사는 다른 일이다. 형은 모양을 보고, 값의 범위는 validation 블록이 본다. 포트가 숫자인지는 형이 보지만, 그 숫자가 1024 이상인지는 형이 모른다.
현장에서 만나는 모습
가장 흔한 것은 모듈 입력을 any 로 열어 둔 경우다. 쓰는 쪽이 편하라고 열어 두었는데, 정작 잘못 쓴 사람은 모듈 안쪽의 오류를 보게 된다. 모듈 경계의 형은 문서이자 계약이므로 좁게 적는 편이 모두에게 낫다.
두 번째는 맵 안에서 일어난 변환을 모르고 쓴 경우다. 태그 맵에 숫자를 담았다가 나중에 그 값으로 비교를 하면 영원히 거짓이 된다. 숫자로 쓸 값이라면 맵의 원소 형을 숫자로 선언하거나, 쓰는 자리에서 변환 함수를 거친다.
세 번째는 오브젝트의 오타다. 속성 이름 하나를 잘못 적었는데 적용은 성공하고, 그 값만 기본값으로 동작한다. 리뷰에서도 잘 안 보인다. 이런 종류를 줄이려면 출력으로 실제 들어간 값을 한 번 내보내 확인하는 습관이 도움이 된다.
다음 실습에서 할 것
여덟 단계를 돕니다. 기본형에서 무엇이 막히고 무엇이 바뀌는지 확인하고, 컬렉션 안쪽의 조용한 변환을 출력으로 들여다보고, 같은 입력을 목록·집합·튜플로 받았을 때의 차이를 봅니다. 이어서 오브젝트의 누락과 여분을 각각 확인하고, 선택 속성과 기본값으로 짧은 입력을 받고, null 을 받지 않겠다는 선언의 두 갈래를 봅니다. 마지막 두 단계에서는 형을 적지 않았을 때와 좁게 적었을 때 오류가 어디서 나는지를 나란히 비교하고, 중첩 형으로 입력 규격을 못 박아 채점기가 넣는 잘못된 입력이 거절되는지 확인합니다.