没写类型,报错落在了不相干的行上
한국어 원문으로 표시합니다.
목표
기본형·컬렉션형·구조형을 하나씩 선언해 무엇이 변수 경계에서 막히고 무엇이 조용히 변환되는지 확인합니다. 선택 속성과 기본값, null 을 받지 않겠다는 선언, 그리고 형을 적지 않았을 때 오류가 어디서 나는지까지 봅니다.
왜 중요한가
형은 문서가 아니라 검문소입니다. 형을 적어 두면 잘못된 값이 변수 경계에서 tfvars 줄 번호와 함께 막히고, 적지 않으면 그 값이 저 안쪽까지 흘러 들어가 엉뚱한 메시지로 터집니다. 같은 실수인데 고치는 데 드는 시간이 열 배 차이 납니다. 그런데 형 검사는 막기만 하는 것이 아니라 바꾸기도 합니다. 문자열로 적은 숫자는 숫자가 되고, 원소 형을 지정한 맵에 숫자를 넣으면 문자열이 됩니다. 이 변환은 오류 없이 일어나므로, 나중에 비교나 산술을 하려는 값이라면 미리 알고 있어야 합니다. 반대로 구조형은 선언에 없는 속성을 아무 말 없이 버립니다 — 속성 이름에 오타를 내면 기본값이 적용된 것처럼 보입니다. 무엇이 막히고 무엇이 바뀌고 무엇이 사라지는지, 이 셋을 구분하는 것이 이 모듈의 전부입니다.
단계
/root/tfb-types/prim/main.tf에string변수name,number변수replicas,bool변수debug와 세 개의 출력을 두세요.ok.tfvars에는name = "api",replicas = "3",debug = "true"를 적어 apply 하고tofu output -json을/root/tfb-types/prim.json에 저장하세요.bad.tfvars에는replicas에 목록을 넣어 plan 을 돌리고 오류 출력을/root/tfb-types/prim-bad.txt에 저장하세요./root/tfb-types/quiet/main.tf에map(string)변수tags와list(string)변수ids, 두 개의 출력을 두세요.v.tfvars에서tags에는team = "core",rev = 3,tls = true를,ids에는[1, 2, 10]을 주고 apply 한 뒤tofu output -json을/root/tfb-types/quiet.json에 저장하세요./root/tfb-types/coll/main.tf에list(string)변수as_list,set(string)변수as_set,tuple([string, number, bool])변수as_tuple과 다섯 개의 출력(세 값과 목록·집합의 길이)을 두세요.v.tfvars에서 앞의 두 변수에 똑같이["b", "a", "b"]를, 튜플에["web", 3, true]를 주고 apply 한 뒤tofu output -json을/root/tfb-types/coll.json에 저장하세요. 이어서 튜플 원소를 두 개만 준bad.tfvars로 plan 을 돌려 오류를/root/tfb-types/tuple-bad.txt에 저장하세요./root/tfb-types/obj/main.tf에object({ name = string, port = number })변수svc와 출력 하나를 두세요.ok.tfvars에는name·port에 더해 선언에 없는owner = "team-a"까지 적어 apply 하고tofu output -json을/root/tfb-types/obj.json에 저장하세요.bad.tfvars에는name을 빼고 plan 을 돌려 오류를/root/tfb-types/obj-bad.txt에 저장하세요./root/tfb-types/opt/main.tf에svc변수를 오브젝트로 두되name만 필수로 하고port(기본 8080),tls(기본 false),tags(기본 빈 맵),aliases(기본 빈 목록)는 선택으로 선언하세요.v.tfvars에는name만 주고 apply 한 뒤tofu output -json을/root/tfb-types/opt.json에 저장하세요./root/tfb-types/nul/main.tf에nullable = false인 변수 두 개를 두세요 — 기본값"a"가 있는zone과 기본값이 없는must. 출력도 둘 두세요.ok.tfvars에zone = null,must = "x"를 주고 apply 한 뒤tofu output -json을/root/tfb-types/nul.json에 저장하세요.bad.tfvars에는must = null만 주고 plan 을 돌려 오류를/root/tfb-types/nul-bad.txt에 저장하세요./root/tfb-types/late/에any형 변수loose와 그 길이를 내보내는 출력을 두고,/root/tfb-types/tight/에는 같은 모양이되list(string)형 변수tight를 두세요. 두 곳 모두v.tfvars에 값7을 주고 plan 을 돌려 출력을 각각/root/tfb-types/late.txt와/root/tfb-types/tight.txt에 저장하세요. 그다음 두 오류의 첫 줄만 뽑아/root/tfb-types/blame.txt에late=<첫 오류 줄>과tight=<첫 오류 줄>두 줄로 적으세요(Error:뒤의 문구만)./root/tfb-types/schema/main.tf에service변수를 5단계와 같은 모양(필수name, 선택port·tls·tags·aliases)으로 두고, 그 값으로service.conf를 만드세요. 다섯 줄은name=,port=,tls=,tags=(JSON 으로 인코딩),aliases=(콤마로 이어 붙임) 입니다.v.tfvars에는name = "api",port = "9090",tags = { team = "core", rev = 3 },aliases = ["api-1", "api-2"]를 주고 apply 하세요. 채점기가 이 설정의 사본에 잘못된 입력 두 가지를 넣어 거절되는지 확인합니다.
참고
- 형은 '모양' 을 보고 validation 블록은 '값의 범위' 를 봅니다. 두 가지는 서로를 대신하지 못합니다.
- 출력 JSON 에는 값과 함께 형도 들어 있어, 무엇으로 들어갔는지 눈으로 확인하기 좋습니다.
- 명령줄로 값을 줄 때 기본형 변수는 따옴표까지 값의 일부로 받습니다. 이 실습에서는 헷갈리지 않게 tfvars 파일만 씁니다.
- 흔한 실수: 3단계의 bad.tfvars 를 고쳐 통과시키는 것. 그 파일은 틀린 채로 두어야 오류가 확인됩니다.
- 입력 변수 · 형 제약 · 타입과 값 · Type Constraints (HashiCorp)
기본형은 변수 경계에서 걸린다
/root/tfb-types/prim/main.tf 에 string 변수 name, number 변수 replicas, bool 변수 debug 와 세 개의 출력을 두세요. ok.tfvars 에는 name = "api", replicas = "3", debug = "true" 를 적어 apply 하고 tofu output -json 을 /root/tfb-types/prim.json 에 저장하세요. bad.tfvars 에는 replicas 에 목록을 넣어 plan 을 돌리고 오류 출력을 /root/tfb-types/prim-bad.txt 에 저장하세요.
따옴표가 붙은 값이라도 형에 맞게 바꿀 수 있으면 도구가 바꿔 줍니다. 출력 JSON 에는 값뿐 아니라 형도 함께 나오니 무엇으로 들어갔는지 눈으로 확인하세요.
컬렉션 안에서는 변환이 조용히 일어난다
/root/tfb-types/quiet/main.tf 에 map(string) 변수 tags 와 list(string) 변수 ids, 두 개의 출력을 두세요. v.tfvars 에서 tags 에는 team = "core", rev = 3, tls = true 를, ids 에는 [1, 2, 10] 을 주고 apply 한 뒤 tofu output -json 을 /root/tfb-types/quiet.json 에 저장하세요.
원소의 형을 지정한 컬렉션은 넣는 값을 그 형으로 바꿔서 담습니다. 숫자와 참거짓이 문자열이 되어도 오류가 나지 않으니, 나중에 비교나 산술을 하려는 값이라면 이 변환을 알고 있어야 합니다.
같은 입력을 목록·집합·튜플로 받으면 다르게 남는다
/root/tfb-types/coll/main.tf 에 list(string) 변수 as_list, set(string) 변수 as_set, tuple([string, number, bool]) 변수 as_tuple 과 다섯 개의 출력(세 값과 목록·집합의 길이)을 두세요. v.tfvars 에서 앞의 두 변수에 똑같이 ["b", "a", "b"] 를, 튜플에 ["web", 3, true] 를 주고 apply 한 뒤 tofu output -json 을 /root/tfb-types/coll.json 에 저장하세요. 이어서 튜플 원소를 두 개만 준 bad.tfvars 로 plan 을 돌려 오류를 /root/tfb-types/tuple-bad.txt 에 저장하세요.
목록은 적은 순서와 중복을 그대로 지키고, 집합은 중복을 버리고 자기 규칙대로 정렬합니다. 튜플은 자리마다 형이 정해진 고정 길이라 개수가 다르면 그 자리에서 막힙니다.
오브젝트는 빠지면 막고 남으면 조용히 버린다
/root/tfb-types/obj/main.tf 에 object({ name = string, port = number }) 변수 svc 와 출력 하나를 두세요. ok.tfvars 에는 name·port 에 더해 선언에 없는 owner = "team-a" 까지 적어 apply 하고 tofu output -json 을 /root/tfb-types/obj.json 에 저장하세요. bad.tfvars 에는 name 을 빼고 plan 을 돌려 오류를 /root/tfb-types/obj-bad.txt 에 저장하세요.
오브젝트 형은 선언한 속성만 받아들이고, 선언에 없는 속성은 오류가 아니라 버림입니다. 그래서 오타 난 속성 이름은 아무 말 없이 사라지고, 기본값이 적용된 것처럼 보이게 됩니다.
선택 속성과 기본값으로 짧은 입력을 받는다
/root/tfb-types/opt/main.tf 에 svc 변수를 오브젝트로 두되 name 만 필수로 하고 port(기본 8080), tls(기본 false), tags(기본 빈 맵), aliases(기본 빈 목록)는 선택으로 선언하세요. v.tfvars 에는 name 만 주고 apply 한 뒤 tofu output -json 을 /root/tfb-types/opt.json 에 저장하세요.
선택 속성은 두 번째 인자로 기본값을 받습니다. 기본값을 주지 않으면 그 속성은 null 이 되어 하류에서 다시 확인해야 하므로, 기본값을 함께 적는 편이 쓰는 쪽을 편하게 합니다.
null 을 받지 않겠다는 선언은 두 갈래로 동작한다
/root/tfb-types/nul/main.tf 에 nullable = false 인 변수 두 개를 두세요 — 기본값 "a" 가 있는 zone 과 기본값이 없는 must. 출력도 둘 두세요. ok.tfvars 에 zone = null, must = "x" 를 주고 apply 한 뒤 tofu output -json 을 /root/tfb-types/nul.json 에 저장하세요. bad.tfvars 에는 must = null 만 주고 plan 을 돌려 오류를 /root/tfb-types/nul-bad.txt 에 저장하세요.
null 을 받지 않겠다고 선언했을 때, 기본값이 있으면 null 은 기본값으로 대체되고 기본값이 없으면 오류가 됩니다. 값이 없을 때 무엇이 되는지를 한 곳에서 못 박아 두는 장치입니다.
any 로 받으면 오류가 저 안쪽에서 난다
/root/tfb-types/late/ 에 any 형 변수 loose 와 그 길이를 내보내는 출력을 두고, /root/tfb-types/tight/ 에는 같은 모양이되 list(string) 형 변수 tight 를 두세요. 두 곳 모두 v.tfvars 에 값 7 을 주고 plan 을 돌려 출력을 각각 /root/tfb-types/late.txt 와 /root/tfb-types/tight.txt 에 저장하세요. 그다음 두 오류의 첫 줄만 뽑아 /root/tfb-types/blame.txt 에 late=<첫 오류 줄> 과 tight=<첫 오류 줄> 두 줄로 적으세요(Error: 뒤의 문구만).
형을 적어 두지 않으면 잘못된 값이 변수 경계를 그대로 통과합니다. 그러면 오류는 그 값을 쓰는 자리에서 나고, 메시지는 변수가 아니라 함수 이야기를 합니다. 형을 좁히면 같은 실수가 tfvars 줄 번호와 함께 앞에서 막힙니다.
중첩 형으로 입력 규격을 못 박는다
/root/tfb-types/schema/main.tf 에 service 변수를 5단계와 같은 모양(필수 name, 선택 port·tls·tags·aliases)으로 두고, 그 값으로 service.conf 를 만드세요. 다섯 줄은 name=, port=, tls=, tags=(JSON 으로 인코딩), aliases=(콤마로 이어 붙임) 입니다. v.tfvars 에는 name = "api", port = "9090", tags = { team = "core", rev = 3 }, aliases = ["api-1", "api-2"] 를 주고 apply 하세요. 채점기가 이 설정의 사본에 잘못된 입력 두 가지를 넣어 거절되는지 확인합니다.
형을 제대로 적어 두면 잘못된 입력이 tfvars 줄 번호와 함께 그 자리에서 막힙니다. 문자열로 적은 포트가 숫자로 들어가는 것과 맵 안의 숫자가 문자열이 되는 것, 두 변환이 한 입력에서 함께 일어나니 결과를 눈으로 확인하세요.