본문 바로가기

IaC/terraform

[terraform] variables and outputs

테라폼에도 변수라는 개념이 존재한다. 일반적으로 variables이란 입력 변수를 일컫고 그 외에 local values와 output values가 있다.

Input variables : 테라폼 모듈에 인자로서 정의되는 값. 변수를 이용하여 테라폼 구성파일을 작성함으로써 소스코드 변경 없이 변수만 변경하여 테라폼 코드를 변경할 수 있다. 

Local values : 입력변수(Input variables)는 테라폼 실행시 값을 전달할 수 있지만 local values는 그렇지 못하다. 구성 내부에서 이미 계산된 값으로 모듈에서 여러번 사용될 수 있다. 

Output values : 테라폼 모듈에서 리턴값과 같은 역할을 한다.

 

Input variables syntax

variable "name_labe" {
	# type 인수는 변수와 관련된 데이터유형을 정의하고 오류 검사를 제공해준다.
	type = value
	# 에러가 발생했을때 또는 모듈 작성할때 도움이 된다.
	description = "value"
	# default를 사용하면 변수의 기본값을 지정할 수 있다.
	default = "value"
	# true일 경우 로그나 터미널 출력에 변수값을 출력하지 않는다.(암호, API 키와 같은 민감한 정보를 숨기기에 좋다.)
	sensative = true | false
 	# 값이 null이 될 수 있는지 아닌지를 정할 수 있다.
	nullable = true | false
 	# 조건에 맞지않는 값을 받았는지 체크할 수 있다.
	validation {
    	condition = 조건문
        error_message = "value"
    }
}

 

 

예시)

aws_region 이라는 변수를 생성하는데, string type을 값으로 받고, 이 변수에 대한 설명이 있다. 테라폼 실행 시 별도의 값을 지정하지 않으면 “us-east-1”의 값을 가지고 민감한 정보는 아니므로 출력시 변수의 값을 보여준다.

해당 변수를 참조하기 위해서는 var.aws_region 으로 사용할 수 있다.

 

여기서 type이란 테라폼의 데이터 타입을 말하는데, 테라폼에서 사용할 수 있는 데이터 타입들은 다음과 같다.

string, number, boolean 은 다른 데이터 유형들과 크게 다르지 않으니 설명은 필요 없을 것 같다.

collection에서 List 는 순서가 지정된 그룹, Set 은 순서가 지정되지 않고 고유의 값을 가지는 그룹, map 은 키-쌍 그룹이다.

각 collection에 저장된 데이터들은 동일한 유형을 가져야 한다.

structural은 collection과 비슷할 수 있는데 structural에 저장된 데이터들은 동일한 유형을 가지지 않아도 된다.

Tuple 은 List와 비슷하고, Object 는 Set과 비슷하다.

 

List 예시)

[1,2,3,4]

["us-east-1","us-east-2","us-west-1","us-west-2"]

다음은 List로는 부적절하지만 Tuple형식은 될 수 있다. (그룹에 있는 데이터들이 다른 유형을 가짐)

[1, "us-east-1", true]

Map 예시)

{
	small = "t2.micro"
	medium = "t2.small"
	large = "t2.large"
}

Object 예시)

{
  name = "John"
  age  = 52
}

 

그럼 변수들은 어떻게 정의하고 참조할 수 있을까?

만약 string으로 이루어진 list의 변수를 만들고 싶다면 type = list(string) 으로 쓸 수 있고, 값으로 default = ["us-east-1","us-east-2","us-west-1","us-west-2"] 로 쓸 수 있다.

variable "aws_regions" {
	type = list(string)
	default = ["us-east-1","us-east-2","us-west-1","us-west-2"]
}

참조하기 위해서는 var.<name_label>[<element_number>]var.aws_regions[0] 이런식으로 사용할 수 있고 이경우 us-east-1 의 값을 가져온다.

만약 뒤의 대괄호 없이 name_label 까지만 쓰면 리스트 전체 목록을 가져올 수 있다. 

string으로 이루어진 map의 변수 type은 map(string) 이 될것이고 참조하는 방법은 다음과 같다.

var.<name_label>.<key_name> 또는 var.<name_label>["key_name"]

variable "ec2_types" {
	type = map(string)
	default = {
	small = "t2.micro"
	medium = "t2.small"
	large = "t2.large"
	}
}

 

Local values syntax

locals {
	key = value
}

참조 하기 위해서는 다음과 같이 사용한다. local.<name_label>

 

Out values syntax

output "name_label" {
	value = output_value
	description = "Description of output"
	# 한 모듈에서 다른 모듈로 값을 전달하고 로그 또는 터미널에 인쇄되지 않도록 할때 유용함
	sensative = true | false
}

 

테라폼 코드를 작성한 후에 문법 오류가 있는지 확인해 보기 위해서 terraform validate 명령어를 사용할 수 있다. 

terraform init 후에 논리적인 문법 오류를 확인하기 위해 사용할 수 있다. 단지 구문 검사만 진행하기 때문에 상태파일을 확인하지는 않는다. 

 

테라폼을 실행할 때 input variables에 값을 제공하는 방법은 여러가지가 있다. 

  1. variables block에 default 지정
  2. 테라폼 실행시 -var 옵션 사용
  3. 파일에 모든 변수값을 작성하고 테라폼 실행시 -var-file 옵션으로 파일 전달
  4. 디렉토리에 .auto.trvars 또는 .auto.tfvars.json 이라는 이름으로 끝나는 파일이 존재할 경우에 테라폼은 실행시 해당 파일에서 찾은 값을 사용한다.
  5. 디렉토리에 terraform.tfvars 또는 terraform.tfvars.json 이라는 이름의 파일이 존재할 경우 테라폼은 실행시 해당 파일에서 찾은 값을 사용한다.
  6. 테라폼은 TF_VAR_ 로 시작하는 환경변수를 이용한다. 해당 prefix뒤에 있는 변수이름을 찾는다.

만약 CLI로 하나의 변수에 대해 여러개의 값을 받았을때의 우선순위는 어떻게 될까?

아래 사진에서 오른쪽의 우선순위가 가장 높다.