본 포스트는, Terraform Up & Running 테라폼 - OREILLY를 참고했습니다.
이전 포스트에서 생성한 EC2를 변수와 출력을 이용해서 조금 더 프로그래밍적으로 만들고자 합니다.
변수
많은 프로그래밍에서 DRY원칙 ( Don’t Repeat Yourself )가 있습니다.
즉 똑같은 일을 두번하지 말라는 말입니다.
테라폼에서도 이를 위해 변수를 생성하고 이를 이용할 수 있습니다.
이전 포스트에서 생성한 EC2에서 변수를 사용하는 방법을 설명하고자 합니다.
기본 사용법
variable "var_name" {
description = "var's description"
type = number
default = 42
}
기본적으로 변수는, description, type, default이렇게 3개로 이루어져 있습니다.
default의 경우 선택적으로 설정하는데, 만약 default값이 설정되어 있지 않는다면 terraform apply시 입력받습니다.
variable "number_example" {
description = "An example of a number variable in Terraform"
type = number
}
예시로 살펴보면 위와 같이 작성하고 terraform apply
를 입력했다면,
$ terraform apply
var.number_example
An example of a number variable in Terraform
Enter a value:
위와 같이, description과 value를 입력하라는 내용이 나옵니다.
만약 default를 선언하고 값을 입력 때, 변경하고 싶다면,
$ terraform apply -var="number_example"=2
위와 같이 입력할 수 있습니다.
number
variable "number_example" {
description = "An example of a number variable in Terraform"
type = number
default = 42
}
먼저 위에서 살펴본 number type입니다.
숫자를 변수로 사용할 때 사용합니다.
string
variable "string_example" {
description = "An example of a string variable in Terraform"
type = string
default = "example"
}
다음으론 문자열 타입입니다.
문자열을 입력받을 때 사용합니다.
list - string
variable "list_example" {
description = "An example of list in Terraform"
type = list
default = ["a", "b", "c"]
}
리스트를 변수로 사용할 수 있는데, 여기서 list는 string의 List임을 참고하세요
list(number)
variable "list_numeric_example" {
type = list(number)
default = [1,2,3]
}
만약 Number list를 사용하고 싶다면, 괄호를 통해 number라고 입력합니다.
map
variable "map_example" {
type = map(string)
default = {
key1 = "value1"
key2 = "value2"
key3 = "value3"
}
}
맵을 이용해서 키 밸류를 변수로 사용할 수도 있는데, 위와 같이 사용합니다.
object
variable "object_example" {
type = object({
name = string
age = number
tags = list(string)
enabled = bool
})
default = {
name = "value1"
age = 42
tags = ["a", "b", "c"]
enabled = true
}
}
마지막으로 object 타입입니다. C언어의 구조체랑 비슷한 구조를 가져서 익숙합니다.
map이나 object를 사용한다면, cli를 통해서 입력받기는 어려울 것 같고, default를 사용할 것 같습니다.
포트번호를 변수로 받기
이전 포스트에서 만들었던 EC2는 8080 포트를 고정으로 받고 8080로 접속했다면, 이번에는 이를 변수로 받고 사용할 예정입니다.
# var.tf
variable "server_port" {
description = "The port hte server will use for HTTP requests"
type = number
}
먼저 server_port라는 변수를 선언했습니다.
default값은 따로 설정하지 않아서, 직접 입력받도록 유도했습니다.
# main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "ec2" {
ami = "ami-0ea5eb4b05645aa8a"
instance_type = "t3.nano"
tags = {
Name = "terraform-example"
}
user_data = <<-EOF
#!/bin/bash
echo "Hello, world" > index.html
nohup busybox httpd -f -p ${var.server_port} &
EOF
vpc_security_group_ids = [aws_security_group.instance.id]
}
resource "aws_security_group" "instance" {
name = "terraform-example-instance"
ingress {
from_port = var.server_port
to_port = var.server_port
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
이전에 사용했던 코드에서 변수로 변경했습니다.
주목해야할 부분은 변수를 사용하는 부분입니다.
from_port = var.server_port
변수를 사용할 때는 var이후 .변수이름을 통해서 사용합니다.
User_data에 보면 ${var.server_port}가 있는데, 여기서 var.sever_port만 작성하면 문자열로 인식해서 오류를 일으킵니다. 이를 변수라고 인지시키기 위해서 ${var.server_port} 를 사용합니다.
이렇게 구성하고 terraform apply를 입력합니다.
$ terraform apply
var.server_port
The port hte server will use for HTTP requests
Enter a value: 8000
저는 8000번 포트를 입력하고 yes를 입력했습니다.
$ curl http://[public ip]:8000
Hello, world
이제 정상적으로 생성되었는지 테스트합니다.
Output
처음 terraform을 접했을 때, var이랑 output이 뭔 차이를 가지는 지 궁금했습니다.
var의 경우 변수고, output의 경우 출력문이라고 생각하면 편합니다.
생성한 EC2의 접속주소를 출력하도록 output을 만들어보겠습니다.
# output.tf
output "test_ip" {
description = "This is test_ip"
value = "${aws_instance.ec2.public_ip}:${var.server_port}"
}
value의 경우 생성될 instance의 public ip와 입력받을 port를 출력하도록 구성했습니다.
이제 다시 terraform apply이후 8000를 입력해줍니다.
정상적으로 생성이 된 후, 설정한 Output이 출력됨을 알 수 있습니다.
Outputs:
test_ip = "3.35.167.31:8000"
간단한 var와 ouput사용법을 알아봤습니다.
둘다 유용하게 사용될 듯합니다.
이전과 동일하게 더 이상 안쓸 리소스는 과금을 피하기 위해서 주석처리 후 apply해줍니다.
terraform destroy
destroy명령어를 통해서 지울 수도 있습니다. (단 undo가 불가능 하니 신중하게 동작하세요.)