변수와 출력값

LinuxBeginner
지금 연습하기

소개

커피를 주문한다고 생각해 보겠습니다. 메뉴에 "Coffee"라고만 적혀 있다면 매번 블랙커피를 받게 될 수 있습니다. 하지만 메뉴에 "Size"나 "Milk Type" 같은 옵션이 있다면, 바리스타가 모든 조합에 맞는 새로운 레시피를 배울 필요 없이 주문을 원하는 대로 바꿀 수 있습니다.

Terraform 에서 변수는 전체 파일을 다시 작성하지 않고도 입력값을 변경할 수 있게 하여 구성을 재사용 가능하게 만듭니다.

출력값을 사용하면 Terraform 이 ID, 이름, 주소와 같은 중요한 결과값을 알려 줍니다. 변수와 출력값을 함께 사용하면 Terraform 구성을 더 모듈화되고 실용적으로 만들 수 있습니다.

이 실습을 마치면 요청에 따라 서로 다른 이름으로 컨테이너를 생성할 수 있는 유연한 Terraform 구성을 완성하게 됩니다.

변수는 구성 로직과 환경별 데이터를 분리합니다. 출력값은 반대로 유용한 결과값을 사용자나 이후 자동화 과정에 다시 제공합니다.

변수 파일 만들기

요리를 시작하기 전에 재료를 정리하는 것이 좋은 요리사의 습관입니다. Terraform 에서도 사용자 지정 옵션 (변수) 을 기본 레시피와 별도의 파일에 보관하는 것이 좋습니다.

이 파일의 표준 이름은 variables.tf입니다. 이 파일을 만든다고 Terraform 의 작동 방식이 바뀌지는 않습니다. Terraform 은 폴더 안의 모든 .tf 파일을 하나의 큰 책처럼 읽습니다. 하지만 파일을 분리하면 구성을 체계적으로 관리할 수 있습니다.

IaC 에서는 실제 구성이 빠르게 커지므로 이러한 정리 원칙이 중요합니다. 변수, 리소스, 출력값을 명확히 분리하면 이후 유지 관리가 훨씬 쉬워집니다.

프로젝트 폴더로 이동하여 이 파일을 만듭니다.

cd ~/project
touch variables.tf

이제 변수 정의를 입력할 빈 파일이 준비되었습니다. 다음 단계에서 파일에 내용을 추가합니다.

변수 정의하기

이제 사용할 수 있는 옵션을 선언해야 합니다. 주문서에 "Name" 입력란을 추가하는 것과 같습니다.

nano를 사용하여 variables.tf를 엽니다.

nano variables.tf

다음 블록을 추가합니다. 이 블록은 Terraform 에 다음과 같이 알려 줍니다. "container_name이라는 옵션이 있고, 텍스트 (string) 를 입력받으며, 사용자가 값을 지정하지 않으면 이름을 'ExampleNginxContainer'로 지정합니다."

variable "container_name" {
  description = "Value of the name for the Docker container"
  type        = string
  default     = "ExampleNginxContainer"
}

nano에서 저장하고 종료합니다 (Ctrl+O, Enter, Ctrl+X).

이제 주문서의 입력란이 만들어졌으므로 레시피에서 이 입력란을 사용해야 합니다. 이 변수를 사용하는 main.tf 파일을 만듭니다.

main.tf를 만듭니다.

nano main.tf

다음 코드를 붙여 넣습니다. name = var.container_name에 주의합니다. 이 구문으로 구성에 변수를 연결합니다.

terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

provider "docker" {}

resource "docker_image" "nginx" {
  name         = "nginx:latest"
  keep_locally = false
}

resource "docker_container" "nginx" {
  image = docker_image.nginx.image_id
  name  = var.container_name
  ports {
    internal = 80
    external = 8000
  }
}

파일을 저장하고 nano를 종료합니다.

var.container_name을 사용하면 이름을 코드에 직접 지정하지 않고, container_name 변수에 들어 있는 값을 찾아 그 값을 사용한다는 의미가 됩니다.

출력값 정의하기

무언가를 구매하면 영수증을 받습니다. Terraform 에서 출력값은 영수증과 같은 역할을 하며, 방금 생성한 항목의 중요한 세부 정보를 보여 줍니다.

출력값은 리소스가 생성되기 전에는 알 수 없는 정보를 확인할 때 특히 유용합니다. 예를 들어 시스템이 할당한 임의의 ID 나 공용 IP 주소를 확인할 수 있습니다.

인프라의 한 부분이 사람인 운영자, 다른 Terraform 모듈 또는 이후 자동화 단계에 정보를 전달해야 할 때도 출력값이 유용합니다.

이러한 반환값을 정리하기 위해 outputs.tf라는 파일을 만듭니다. nano로 파일을 엽니다.

nano outputs.tf

다음 블록을 추가합니다. 이 블록은 Terraform 에 작업이 끝난 뒤 nginx 컨테이너의 ID 를 출력하라고 지시합니다.

output "container_id" {
  description = "ID of the Docker container"
  value       = docker_container.nginx.id
}

파일을 저장하고 nano를 종료합니다.

이제 코드를 실행합니다.

먼저 프로젝트를 초기화하여 Docker provider 를 다운로드합니다.

terraform init

다음으로 구성을 적용합니다. 컨테이너 이름을 지정하지 않으므로 기본값인 ExampleNginxContainer를 사용합니다. -auto-approve를 사용하면 시간을 절약하기 위해 "yes" 확인 프롬프트를 건너뜁니다.

terraform apply -auto-approve

출력의 맨 아래를 확인합니다. Outputs:가 표시되고 그 아래에 container_id가 출력되어야 합니다.

변수 재정의하기

변수의 진정한 장점은 코드를 다시 작성하지 않고도 값을 바꿀 수 있다는 것입니다. 다른 이름으로 두 번째 컨테이너를 실행하려고 해도 main.tf를 수정할 필요가 없습니다.

-var 플래그를 사용하여 기본값을 재정의한다고 Terraform 에 알려 주면 됩니다. 바리스타에게 "잠시만요, Large 로 만들어 주세요"라고 말하는 것과 같습니다.

다음 명령을 실행합니다.

terraform apply -var="container_name=MyDynamicContainer" -auto-approve

출력을 주의 깊게 확인합니다. Terraform 에 docker_container.nginx must be replaced가 표시됩니다.

그 이유는 Docker 에서 실행 중인 컨테이너의 이름을 쉽게 변경할 수 없기 때문입니다. 이름을 바꾸기 위해 Terraform 은 기존 컨테이너를 Destroy(-) 하고 새 이름으로 새 컨테이너를 Create(+) 해야 한다고 판단합니다. 이는 변경 불가능한 인프라 (Immutable Infrastructure) 의 핵심 원칙입니다. 기존 항목을 수정하는 대신 교체합니다.

새 컨테이너가 실행 중인지 확인합니다.

docker ps --format "{{.Names}}"

MyDynamicContainer가 표시되어야 합니다.

요약

축하합니다! Terraform 코드를 동적으로 만드는 작업을 성공적으로 완료했습니다.

이 실습에서는 다음 내용을 배웠습니다.

  • 변수: variables.tf를 사용하여 코드에 유연한 "입력란"을 만드는 방법
  • 참조: var.variable_name을 사용하여 기본 구성에 값을 삽입하는 방법
  • 출력값: 실행이 끝난 후 중요한 데이터 ("영수증") 를 표시하도록 outputs.tf를 사용하는 방법
  • 재정의: -var를 사용하여 명령줄에서 새 값을 입력하고, 동일한 코드를 다양한 상황에 재사용하는 방법