🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Terraform 변수와 출력값 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 30. · 0 Views

Terraform 변수와 출력값 완벽 가이드

Terraform의 입력 변수와 출력값을 활용하여 재사용 가능하고 유연한 인프라 코드를 작성하는 방법을 배웁니다. 변수 타입, 검증, 파일 분리부터 민감한 출력값 처리까지 실무에 필요한 모든 내용을 다룹니다.


목차

  1. 입력 변수 정의
  2. 변수 타입과 검증
  3. 변수 파일 분리
  4. 환경 변수 활용
  5. 출력값 정의
  6. 민감한 출력값 처리

1. 입력 변수 정의

어느 날 이태라 씨는 개발 환경과 운영 환경을 위한 인프라 코드를 작성하고 있었습니다. 그런데 두 환경의 차이는 인스턴스 타입과 리전뿐인데, 코드를 두 번 작성해야 한다는 사실이 불편했습니다.

"분명히 더 좋은 방법이 있을 텐데..." 선배 개발자 최인프라 씨가 다가와 말했습니다. "변수를 사용해 보는 게 어때요?"

입력 변수는 Terraform 코드를 재사용 가능하게 만드는 핵심 요소입니다. 마치 함수의 매개변수처럼, 코드 실행 시점에 값을 전달받아 다양한 환경에 대응할 수 있습니다.

변수를 사용하면 하나의 코드로 여러 환경을 관리할 수 있어 코드 중복을 크게 줄일 수 있습니다.

다음 코드를 살펴봅시다.

# variables.tf
variable "instance_type" {
  description = "EC2 인스턴스 타입"
  type        = string
  default     = "t3.micro"
}

variable "environment" {
  description = "배포 환경 (dev, staging, prod)"
  type        = string
}

# main.tf
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = var.instance_type

  tags = {
    Name        = "web-server-${var.environment}"
    Environment = var.environment
  }
}

이태라 씨는 입사 6개월 차 DevOps 엔지니어입니다. 회사에서 AWS 인프라를 관리하는데, 개발 환경과 운영 환경의 설정이 조금씩 다른 것이 고민이었습니다.

같은 코드를 복사해서 조금씩 수정하다 보니, 나중에 한쪽만 업데이트하는 실수도 종종 발생했습니다. 최인프라 씨가 이태라 씨의 화면을 보며 말했습니다.

"변수를 사용하면 이런 문제를 깔끔하게 해결할 수 있어요." 입력 변수란 정확히 무엇일까요? 프로그래밍 언어의 함수를 생각해 봅시다.

함수는 매개변수를 받아서 다양한 값으로 동작할 수 있습니다. Terraform의 변수도 마찬가지입니다.

마치 빵 굽는 틀처럼, 같은 틀로 초코빵도 만들고 크림빵도 만들 수 있는 것입니다. 변수는 코드라는 틀에 다양한 값을 채워 넣을 수 있게 해줍니다.

변수가 없던 시절에는 어땠을까요? 개발 환경용 코드와 운영 환경용 코드를 각각 작성해야 했습니다.

인스턴스 타입을 바꾸려면 모든 파일을 일일이 수정해야 했습니다. 더 큰 문제는 환경이 늘어날 때마다 코드를 복사해야 한다는 점이었습니다.

10개의 환경이 있다면 같은 코드를 10번 작성해야 했고, 버그를 수정하려면 10개 파일을 모두 고쳐야 했습니다. 바로 이런 문제를 해결하기 위해 입력 변수가 등장했습니다.

변수를 사용하면 코드의 재사용성이 극적으로 높아집니다. 하나의 코드로 개발, 스테이징, 운영 환경을 모두 관리할 수 있습니다.

또한 설정 값을 중앙에서 관리할 수 있어 유지보수가 쉬워집니다. 무엇보다 코드의 의도를 명확하게 표현할 수 있다는 큰 이점이 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 variable 블록으로 변수를 선언합니다.

description은 변수의 용도를 설명하는 필드로, 문서화와 협업에 매우 중요합니다. type은 변수가 받을 수 있는 데이터 타입을 지정합니다.

default는 값이 전달되지 않았을 때 사용할 기본값입니다. 실제 리소스에서는 var.변수명 형식으로 변수 값을 참조합니다.

실제 현업에서는 어떻게 활용할까요? 대형 쇼핑몰 서비스를 운영한다고 가정해봅시다.

평소에는 작은 인스턴스로 운영하다가, 블랙프라이데이 같은 대규모 이벤트 때는 큰 인스턴스가 필요합니다. 변수를 활용하면 instance_type만 바꿔서 손쉽게 스케일업할 수 있습니다.

많은 기업에서 환경별 설정을 변수로 관리하는 패턴을 적극적으로 사용하고 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 모든 값을 변수로 만드는 것입니다. 변경될 가능성이 없는 값까지 변수로 만들면 오히려 코드가 복잡해집니다.

따라서 환경마다 달라지거나 자주 변경되는 값만 변수로 만드는 것이 좋습니다. 다시 이태라 씨의 이야기로 돌아가 봅시다.

최인프라 씨의 설명을 들은 이태라 씨는 감탄했습니다. "와, 이렇게 하면 코드를 한 번만 작성해도 되겠네요!" 입력 변수를 제대로 이해하면 더 유연하고 관리하기 쉬운 인프라 코드를 작성할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - description은 필수는 아니지만, 팀 협업을 위해 반드시 작성하세요

  • default 값이 없는 변수는 실행 시 반드시 값을 제공해야 합니다
  • 변수명은 snake_case를 사용하는 것이 Terraform 커뮤니티의 관례입니다

2. 변수 타입과 검증

이태라 씨가 변수를 사용해 코드를 작성하고 실행했는데, 이상한 에러가 발생했습니다. 환경 이름에 "production" 대신 "prod"를 입력했더니, 나중에 태그가 엉망이 되어 버렸습니다.

최인프라 씨가 코드를 보며 말했습니다. "변수에 타입과 검증 규칙을 추가해야 이런 실수를 막을 수 있어요."

변수 타입은 변수가 받을 수 있는 데이터의 종류를 지정하고, 검증 규칙은 입력된 값이 올바른지 확인합니다. 마치 공항 보안 검색대처럼, 잘못된 값이 시스템에 들어오기 전에 걸러내는 역할을 합니다.

이를 통해 런타임 에러를 사전에 방지하고 코드의 안정성을 높일 수 있습니다.

다음 코드를 살펴봅시다.

# variables.tf
variable "instance_count" {
  description = "생성할 인스턴스 개수"
  type        = number
  default     = 1

  validation {
    condition     = var.instance_count > 0 && var.instance_count <= 10
    error_message = "인스턴스 개수는 1개 이상 10개 이하여야 합니다."
  }
}

variable "environment" {
  description = "배포 환경"
  type        = string

  validation {
    condition     = contains(["dev", "staging", "production"], var.environment)
    error_message = "환경은 dev, staging, production 중 하나여야 합니다."
  }
}

variable "tags" {
  description = "리소스 태그"
  type        = map(string)
  default     = {}
}

이태라 씨는 변수를 사용하면서 새로운 문제에 부딪혔습니다. 팀원 중 한 명이 환경 이름을 "prd"라고 입력했고, 다른 팀원은 "prod"라고 입력했습니다.

같은 운영 환경을 의미하는데 이름이 달라서 리소스 태그가 일관성 없이 만들어졌습니다. 인스턴스 개수에 "-1"을 입력하는 실수도 발생했습니다.

최인프라 씨가 모니터를 보며 고개를 끄덕였습니다. "예상했던 문제네요.

변수에 타입과 검증 규칙을 추가해 봅시다." 변수 타입이란 무엇일까요? 마치 택배 상자처럼, 담을 수 있는 물건의 종류가 정해져 있다고 생각하면 쉽습니다.

냉동 택배 상자에는 냉동 식품만, 서류 봉투에는 종이만 담는 것처럼, 변수도 받을 수 있는 데이터의 종류가 있습니다. Terraform은 string(문자열), number(숫자), bool(참/거짓), list(리스트), map(맵), object(객체) 등 다양한 타입을 지원합니다.

타입 검증이 없던 시절에는 어땠을까요? 개발자가 숫자를 입력해야 하는 곳에 문자를 넣어도 실행 단계까지 가서야 에러가 발생했습니다.

더 심각한 경우, 에러 없이 실행되지만 의도하지 않은 결과가 나오기도 했습니다. 디버깅하는 데 몇 시간씩 걸리는 일이 비일비재했습니다.

바로 이런 문제를 해결하기 위해 타입 시스템검증 규칙이 도입되었습니다. 타입을 명시하면 계획 단계에서 잘못된 입력을 즉시 발견할 수 있습니다.

또한 IDE가 자동 완성과 타입 힌트를 제공할 수 있어 개발 경험이 향상됩니다. 무엇보다 코드를 읽는 사람이 변수의 용도를 명확하게 이해할 수 있다는 큰 이점이 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. type = number는 이 변수가 숫자만 받는다는 것을 명시합니다.

validation 블록은 더 세밀한 검증을 수행합니다. condition에는 참/거짓을 반환하는 표현식을 작성합니다.

조건을 만족하지 않으면 error_message에 지정한 메시지가 출력됩니다. contains 함수는 리스트에 특정 값이 있는지 확인하는 내장 함수입니다.

실제 현업에서는 어떻게 활용할까요? 금융권 시스템을 구축한다고 가정해봅시다.

보안 등급은 "high", "medium", "low" 세 가지만 허용되어야 합니다. 검증 규칙을 사용하면 잘못된 등급이 입력되는 것을 원천적으로 차단할 수 있습니다.

또한 인스턴스 개수가 예산 범위를 초과하지 않도록 상한선을 설정할 수 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 너무 엄격한 검증 규칙을 만드는 것입니다. 예를 들어 인스턴스 타입을 "t3.micro"만 허용하도록 하면, 나중에 다른 타입이 필요할 때 코드를 수정해야 합니다.

따라서 꼭 필요한 제약만 검증하는 것이 좋습니다. 다시 이태라 씨의 이야기로 돌아가 봅시다.

검증 규칙을 추가한 후, 팀원들이 잘못된 값을 입력하면 즉시 명확한 에러 메시지를 받게 되었습니다. "이제 실수할 걱정이 없네요!" 변수 타입과 검증을 제대로 활용하면 더 안전하고 예측 가능한 인프라 코드를 작성할 수 있습니다.

여러분도 중요한 변수에는 반드시 검증 규칙을 추가해 보세요.

실전 팁

💡 - validation 블록은 여러 개 추가할 수 있습니다

  • 복잡한 타입은 object나 tuple을 사용하여 구조를 명확히 하세요
  • 에러 메시지는 해결 방법을 포함하도록 작성하면 좋습니다

3. 변수 파일 분리

이태라 씨의 프로젝트가 커지면서 변수 선언과 값 할당이 뒤섞여 코드가 복잡해졌습니다. 개발 환경과 운영 환경의 설정을 찾기도 어려워졌습니다.

최인프라 씨가 조언했습니다. "변수 선언과 값을 파일로 분리해서 관리하면 훨씬 깔끔해질 거예요."

변수 파일 분리는 변수 선언과 실제 값을 별도 파일로 관리하는 패턴입니다. 마치 옷장에서 여름옷과 겨울옷을 서랍으로 나누어 정리하는 것처럼, 환경별 설정을 파일로 분리하면 관리가 훨씬 쉬워집니다.

이를 통해 코드의 가독성과 유지보수성을 크게 향상시킬 수 있습니다.

다음 코드를 살펴봅시다.

# variables.tf - 변수 선언만
variable "region" {
  description = "AWS 리전"
  type        = string
}

variable "instance_type" {
  description = "EC2 인스턴스 타입"
  type        = string
}

variable "db_password" {
  description = "데이터베이스 비밀번호"
  type        = string
  sensitive   = true
}

# dev.tfvars - 개발 환경 값
region        = "ap-northeast-2"
instance_type = "t3.micro"
db_password   = "dev-password-123"

# prod.tfvars - 운영 환경 값
region        = "us-east-1"
instance_type = "t3.large"
db_password   = "prod-secure-password-456"

# 실행 방법
# terraform plan -var-file="dev.tfvars"
# terraform apply -var-file="prod.tfvars"

이태라 씨의 인프라 프로젝트가 점점 커지면서 관리해야 할 환경도 늘어났습니다. 개발, 스테이징, 운영 환경이 각각 다른 설정을 가지고 있었습니다.

처음에는 커맨드 라인에서 -var 옵션으로 값을 전달했는데, 변수가 10개, 20개로 늘어나니 명령어가 한 줄에 다 들어가지 않았습니다. 최인프라 씨가 이태라 씨의 긴 명령어를 보고 웃으며 말했습니다.

"변수 파일을 사용해 보세요. 훨씬 편해질 거예요." 변수 파일 분리는 왜 필요할까요?

책상을 생각해 봅시다. 모든 서류를 책상 위에 쌓아두면 필요한 문서를 찾기 어렵습니다.

하지만 서류를 파일 박스에 주제별로 분류해 두면 금방 찾을 수 있습니다. 변수 파일도 마찬가지입니다.

환경별로 파일을 나누면 각 환경의 설정을 한눈에 파악할 수 있습니다. 파일 분리 없이 관리하던 시절에는 어땠을까요?

커맨드 라인에 수십 개의 -var 옵션을 나열해야 했습니다. 실수로 하나라도 빠뜨리면 에러가 발생했습니다.

더 큰 문제는 설정 값의 히스토리를 추적하기 어렵다는 점이었습니다. 누가 언제 무슨 값을 바꿨는지 알 수 없었습니다.

바로 이런 문제를 해결하기 위해 .tfvars 파일이 등장했습니다. 변수 파일을 사용하면 환경별 설정을 명확하게 분리할 수 있습니다.

Git으로 버전 관리도 가능해져 변경 이력을 추적할 수 있습니다. 또한 코드 리뷰 시 설정 변경을 쉽게 확인할 수 있습니다.

무엇보다 새로운 환경을 추가할 때 파일만 복사하면 된다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.

variables.tf에는 변수 선언만 들어갑니다. 타입과 설명, 검증 규칙 같은 메타데이터만 정의합니다.

dev.tfvarsprod.tfvars는 각각 개발 환경과 운영 환경의 실제 값을 담습니다. 파일 형식은 간단한 key = value 형식입니다.

실행할 때는 -var-file 옵션으로 사용할 파일을 지정합니다. 실제 현업에서는 어떻게 활용할까요?

글로벌 서비스를 운영하는 회사를 생각해 봅시다. 서울, 도쿄, 버지니아 리전에 각각 인프라를 구축해야 합니다.

seoul.tfvars, tokyo.tfvars, virginia.tfvars로 파일을 나누면 각 리전의 설정을 독립적으로 관리할 수 있습니다. CI/CD 파이프라인에서도 환경 변수로 파일 경로만 바꿔주면 자동 배포가 가능합니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 비밀번호 같은 민감한 정보가 담긴 .tfvars 파일을 Git에 커밋하는 것입니다.

이렇게 하면 보안 사고로 이어질 수 있습니다. 따라서 .gitignore.tfvars를 추가하고, 민감한 정보는 환경 변수나 비밀 관리 시스템을 사용해야 합니다.

다시 이태라 씨의 이야기로 돌아가 봅시다. 변수 파일을 분리한 후, 이태라 씨는 환경을 전환할 때 파일 하나만 바꾸면 되었습니다.

"이제 실수할 일이 없겠어요!" 변수 파일 분리를 제대로 활용하면 더 체계적이고 안전한 인프라 관리가 가능합니다. 여러분도 프로젝트 초기부터 파일 구조를 잘 설계해 보세요.

실전 팁

💡 - .gitignore에 *.tfvars를 추가하여 민감한 정보 유출을 방지하세요

  • terraform.tfvars 파일은 자동으로 로드되므로 공통 설정에 사용하세요
  • 환경별 파일명은 일관된 규칙을 따르도록 하세요 (예: {env}.tfvars)

4. 환경 변수 활용

이태라 씨가 CI/CD 파이프라인을 구축하던 중 문제가 생겼습니다. 데이터베이스 비밀번호를 .tfvars 파일에 저장했는데, 보안팀에서 경고를 받았습니다.

"파일로 관리하면 유출 위험이 있습니다." 최인프라 씨가 해결책을 제시했습니다. "환경 변수를 사용하면 안전하게 관리할 수 있어요."

환경 변수는 운영체제 수준에서 관리되는 변수로, 민감한 정보를 안전하게 전달하는 방법입니다. 마치 비밀 편지를 봉투에 넣어 전달하는 것처럼, 파일에 기록하지 않고 메모리상으로만 값을 전달할 수 있습니다.

Terraform은 TF_VAR_ 접두사가 붙은 환경 변수를 자동으로 인식합니다.

다음 코드를 살펴봅시다.

# variables.tf
variable "db_password" {
  description = "데이터베이스 비밀번호"
  type        = string
  sensitive   = true
}

variable "api_key" {
  description = "외부 API 키"
  type        = string
  sensitive   = true
}

# main.tf
resource "aws_db_instance" "main" {
  identifier     = "main-db"
  engine         = "postgres"
  instance_class = "db.t3.micro"
  password       = var.db_password

  # 비밀번호는 로그에 출력되지 않습니다
}

# 환경 변수 설정 (Linux/Mac)
# export TF_VAR_db_password="super-secret-password"
# export TF_VAR_api_key="api-key-12345"

# 환경 변수 설정 (Windows)
# set TF_VAR_db_password=super-secret-password
# set TF_VAR_api_key=api-key-12345

이태라 씨는 회사의 CI/CD 파이프라인에 Terraform을 통합하는 작업을 맡았습니다. 처음에는 데이터베이스 비밀번호를 .tfvars 파일에 저장했습니다.

하지만 보안팀의 정기 감사에서 문제가 지적되었습니다. "비밀번호가 Git 히스토리에 남아있네요.

즉시 조치해 주세요." 최인프라 씨가 이태라 씨의 당황한 표정을 보고 조언했습니다. "환경 변수를 사용하면 이런 문제를 원천적으로 막을 수 있어요." 환경 변수란 무엇일까요?

비밀 다이얼 자물쇠를 생각해 봅시다. 자물쇠에 번호를 적어 붙이면 누구나 열 수 있습니다.

하지만 번호를 머릿속에만 기억하면 본인만 열 수 있습니다. 환경 변수도 마찬가지입니다.

값을 파일에 적지 않고 시스템 메모리에만 저장하여, 프로세스 실행 시점에만 접근 가능하게 합니다. 환경 변수 없이 관리하던 시절에는 어땠을까요?

민감한 정보가 텍스트 파일에 평문으로 저장되었습니다. 실수로 Git에 커밋하거나, 로그 파일에 출력되는 사고가 빈번했습니다.

더 큰 문제는 한번 Git에 올라간 정보는 히스토리에서 완전히 지우기 어렵다는 점이었습니다. 보안 사고가 발생하면 모든 비밀번호를 재발급해야 했습니다.

바로 이런 문제를 해결하기 위해 환경 변수 패턴이 널리 사용되기 시작했습니다. 환경 변수를 사용하면 민감한 정보가 파일 시스템에 기록되지 않습니다.

Git 히스토리에 남을 걱정도 없습니다. 또한 CI/CD 시스템의 시크릿 관리 기능과 자연스럽게 통합됩니다.

무엇보다 환경마다 다른 값을 주입하기 쉽다는 큰 이점이 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.

sensitive = true는 이 변수가 민감한 정보임을 Terraform에게 알립니다. Terraform은 이 값을 로그나 출력에서 자동으로 마스킹합니다.

환경 변수명은 TF_VAR_ 접두사 뒤에 변수명을 붙이는 규칙을 따릅니다. 예를 들어 db_password 변수는 TF_VAR_db_password 환경 변수로 전달됩니다.

실제 현업에서는 어떻게 활용할까요? GitHub Actions나 GitLab CI 같은 CI/CD 플랫폼을 사용한다고 가정해봅시다.

이런 플랫폼들은 시크릿 관리 기능을 제공합니다. 시크릿을 등록하면 파이프라인 실행 시 자동으로 환경 변수로 주입됩니다.

Terraform은 이 환경 변수를 읽어서 안전하게 인프라를 구축합니다. 개발자는 민감한 정보를 직접 다룰 필요가 없어집니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 환경 변수를 쉘 히스토리에 남기는 것입니다.

export 명령어를 터미널에서 실행하면 히스토리 파일에 기록됩니다. 따라서 export HISTCONTROL=ignoreboth를 설정하거나, 명령어 앞에 공백을 넣어 히스토리에서 제외해야 합니다.

다시 이태라 씨의 이야기로 돌아가 봅시다. 환경 변수로 전환한 후, 보안팀의 재감사를 무사히 통과했습니다.

"이제 안심하고 배포할 수 있겠어요!" 환경 변수를 제대로 활용하면 더 안전하고 신뢰할 수 있는 인프라 운영이 가능합니다. 여러분도 민감한 정보는 반드시 환경 변수로 관리해 보세요.

실전 팁

💡 - CI/CD 플랫폼의 시크릿 관리 기능을 적극 활용하세요

  • sensitive = true를 설정하면 Terraform이 자동으로 값을 마스킹합니다
  • AWS Secrets Manager나 HashiCorp Vault 같은 전문 도구도 고려해 보세요

5. 출력값 정의

이태라 씨가 인프라를 구축한 후, 생성된 리소스의 정보를 다른 팀에 전달해야 했습니다. 로드 밸런서의 DNS 이름을 일일이 AWS 콘솔에서 찾아 복사하는 것이 번거로웠습니다.

최인프라 씨가 말했습니다. "출력값을 정의해 두면 필요한 정보를 자동으로 확인할 수 있어요."

출력값은 Terraform이 생성한 리소스의 정보를 외부로 노출하는 방법입니다. 마치 공장에서 제품을 만들고 품질 검사 결과를 출하 증명서에 적는 것처럼, 인프라 구축 후 중요한 정보를 정리하여 제공합니다.

이를 통해 다른 모듈이나 시스템에서 생성된 리소스 정보를 쉽게 활용할 수 있습니다.

다음 코드를 살펴봅시다.

# main.tf
resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"

  tags = {
    Name = "web-server"
  }
}

resource "aws_lb" "main" {
  name               = "main-lb"
  load_balancer_type = "application"
  subnets            = ["subnet-12345", "subnet-67890"]
}

# outputs.tf
output "instance_id" {
  description = "EC2 인스턴스 ID"
  value       = aws_instance.web.id
}

output "instance_public_ip" {
  description = "EC2 퍼블릭 IP 주소"
  value       = aws_instance.web.public_ip
}

output "lb_dns_name" {
  description = "로드 밸런서 DNS 이름"
  value       = aws_lb.main.dns_name
}

# 실행 후 출력 확인
# terraform output
# terraform output -json
# terraform output instance_public_ip

이태라 씨는 Terraform으로 웹 서버와 로드 밸런서를 구축했습니다. 프론트엔드 팀에서 API 서버의 주소를 알려달라고 요청했습니다.

이태라 씨는 AWS 콘솔에 접속해서 로드 밸런서 목록을 찾고, 해당 로드 밸런서를 클릭해서 DNS 이름을 복사했습니다. "매번 이렇게 찾아야 하나?" 최인프라 씨가 이태라 씨의 화면을 보며 웃었습니다.

"출력값을 정의해 두면 명령어 하나로 바로 확인할 수 있어요." 출력값이란 정확히 무엇일까요? 요리를 생각해 봅시다.

요리사가 음식을 만들고 나면 서빙 직원에게 "3번 테이블, 스테이크 미디엄"이라고 알려줍니다. 출력값도 마찬가지입니다.

Terraform이 인프라를 구축하고 나면, 중요한 정보를 정리하여 사용자나 다른 시스템에 전달합니다. 이 정보는 나중에 참조하거나 자동화에 활용할 수 있습니다.

출력값이 없던 시절에는 어땠을까요? 인프라를 구축한 후, 필요한 정보를 수동으로 찾아야 했습니다.

AWS 콘솔을 뒤지거나 CLI 명령어를 여러 번 실행해야 했습니다. 더 큰 문제는 자동화가 어렵다는 점이었습니다.

다른 Terraform 모듈에서 정보를 참조하려면 하드코딩해야 했고, 값이 바뀌면 모든 곳을 수정해야 했습니다. 바로 이런 문제를 해결하기 위해 output 블록이 도입되었습니다.

출력값을 사용하면 리소스 정보를 체계적으로 관리할 수 있습니다. terraform output 명령어로 언제든 확인 가능합니다.

또한 다른 Terraform 모듈에서 terraform_remote_state를 통해 이 값을 참조할 수 있습니다. 무엇보다 CI/CD 파이프라인에서 출력값을 읽어 다음 단계에 전달할 수 있다는 큰 이점이 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. output 블록으로 출력값을 정의합니다.

description은 이 출력값의 용도를 설명합니다. value에는 출력할 값을 지정합니다.

리소스의 속성은 리소스타입.리소스명.속성명 형식으로 참조합니다. terraform output 명령어로 모든 출력값을 확인하거나, 특정 출력값만 조회할 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 마이크로서비스 아키텍처를 구축한다고 가정해봅시다.

네트워크 모듈에서 VPC와 서브넷을 생성하고, 그 정보를 출력값으로 정의합니다. 애플리케이션 모듈에서는 이 출력값을 읽어서 EC2 인스턴스를 적절한 서브넷에 배치합니다.

각 모듈이 독립적으로 관리되면서도 필요한 정보를 주고받을 수 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 모든 리소스 속성을 출력값으로 만드는 것입니다. 너무 많은 출력값은 오히려 혼란을 줍니다.

따라서 실제로 외부에서 참조할 필요가 있는 정보만 출력값으로 정의하는 것이 좋습니다. 다시 이태라 씨의 이야기로 돌아가 봅시다.

출력값을 정의한 후, 프론트엔드 팀의 요청에 즉시 대응할 수 있게 되었습니다. "terraform output lb_dns_name 명령어 하나면 끝이에요!" 출력값을 제대로 활용하면 더 효율적이고 자동화된 인프라 운영이 가능합니다.

여러분도 중요한 리소스 정보는 반드시 출력값으로 정의해 보세요.

실전 팁

💡 - description을 명확하게 작성하면 다른 팀원이 출력값의 용도를 쉽게 이해합니다

  • terraform output -json으로 JSON 형식으로 출력하여 스크립트에서 활용하세요
  • 모듈을 만들 때는 재사용을 고려하여 충분한 출력값을 제공하세요

6. 민감한 출력값 처리

이태라 씨가 데이터베이스 엔드포인트를 출력값으로 정의했는데, 로그에 그대로 노출되는 것을 발견했습니다. 보안팀에서 또 다시 경고가 왔습니다.

"민감한 정보가 CI/CD 로그에 평문으로 나타나고 있습니다." 최인프라 씨가 해결책을 알려주었습니다. "sensitive 속성을 사용하면 자동으로 마스킹됩니다."

민감한 출력값 처리는 비밀번호나 API 키 같은 중요 정보가 로그에 노출되지 않도록 보호하는 기능입니다. 마치 개인정보가 적힌 서류에 검은 마커로 가리는 것처럼, Terraform이 자동으로 민감한 값을 숨겨줍니다.

sensitive = true 속성을 사용하면 출력값을 안전하게 관리할 수 있습니다.

다음 코드를 살펴봅시다.

# main.tf
resource "aws_db_instance" "main" {
  identifier     = "main-db"
  engine         = "postgres"
  instance_class = "db.t3.micro"
  username       = "admin"
  password       = var.db_password
}

resource "random_password" "api_key" {
  length  = 32
  special = true
}

# outputs.tf
output "db_endpoint" {
  description = "데이터베이스 엔드포인트"
  value       = aws_db_instance.main.endpoint
  sensitive   = true  # 민감한 정보로 표시
}

output "db_password" {
  description = "데이터베이스 비밀번호"
  value       = var.db_password
  sensitive   = true  # 로그에 노출되지 않음
}

output "api_key" {
  description = "생성된 API 키"
  value       = random_password.api_key.result
  sensitive   = true  # 마스킹 처리
}

# 출력값 확인 시
# terraform output  -> (sensitive value) 표시
# terraform output db_password  -> 실제 값 출력 (의도적 조회)

이태라 씨는 데이터베이스를 Terraform으로 관리하면서 엔드포인트 정보를 출력값으로 정의했습니다. 개발팀에서 데이터베이스 접속 정보를 쉽게 확인할 수 있어 편리했습니다.

하지만 CI/CD 파이프라인 로그를 확인하던 중, 데이터베이스 비밀번호가 그대로 노출되어 있는 것을 발견했습니다. 보안팀의 자동 스캔 시스템이 이를 감지하고 경고 메일을 보냈습니다.

"즉시 조치하지 않으면 접근 권한이 제한될 수 있습니다." 최인프라 씨가 급히 달려와 말했습니다. "sensitive 속성을 추가하면 바로 해결돼요." 민감한 출력값 처리는 왜 중요할까요?

은행 ATM 화면을 생각해 봅시다. 비밀번호를 입력할 때 숫자 대신 별표가 표시됩니다.

뒤에 서 있는 사람이 비밀번호를 볼 수 없도록 보호하는 것입니다. Terraform의 sensitive 속성도 마찬가지입니다.

중요한 정보가 터미널 출력이나 CI/CD 로그에 평문으로 나타나지 않도록 자동으로 마스킹합니다. 민감한 정보 보호 기능이 없던 시절에는 어땠을까요?

데이터베이스 비밀번호, API 키, 접근 토큰 같은 정보가 로그 파일에 그대로 기록되었습니다. 누구든 로그에 접근할 수 있으면 이런 정보를 볼 수 있었습니다.

더 큰 문제는 로그가 외부 모니터링 시스템으로 전송되거나 장기 보관되면서, 민감한 정보가 여러 곳에 퍼지는 것이었습니다. 바로 이런 문제를 해결하기 위해 sensitive 속성이 도입되었습니다.

sensitive = true를 설정하면 Terraform이 여러 단계에서 값을 보호합니다. terraform output 명령어 실행 시 **(sensitive value)**로 표시됩니다.

terraform plan이나 apply의 로그에서도 마스킹됩니다. 또한 Terraform Cloud나 Terraform Enterprise의 웹 UI에서도 자동으로 숨겨집니다.

값이 필요할 때는 terraform output 출력값이름으로 명시적으로 조회할 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.

출력값 블록에 sensitive = true를 추가하는 것이 핵심입니다. 이 한 줄이면 Terraform이 자동으로 모든 출력에서 값을 마스킹합니다.

변수에 sensitive를 설정했다면, 그 변수를 사용하는 출력값도 자동으로 민감한 것으로 간주됩니다. 하지만 명시적으로 표시하는 것이 가독성에 좋습니다.

실제 현업에서는 어떻게 활용할까요? 대규모 플랫폼 서비스를 운영한다고 가정해봅시다.

Terraform으로 수십 개의 데이터베이스와 캐시 서버를 관리합니다. 각 서비스의 접속 정보를 출력값으로 제공하되, 모두 sensitive로 표시합니다.

개발팀은 필요할 때만 명시적으로 값을 조회하고, 일반적인 로그에는 노출되지 않아 보안이 강화됩니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 sensitive 출력값을 다른 리소스에서 참조하는 것입니다. 민감한 값을 일반 리소스의 태그나 이름에 사용하면, 해당 리소스의 속성이 민감하지 않은 것으로 표시되어 노출될 수 있습니다.

따라서 민감한 정보는 꼭 필요한 곳에만 제한적으로 사용해야 합니다. 다시 이태라 씨의 이야기로 돌아가 봅시다.

sensitive 속성을 추가한 후, CI/CD 로그를 다시 확인했습니다. 비밀번호 대신 **(sensitive value)**가 표시되었습니다.

"이제 안전하네요!" 민감한 출력값 처리를 제대로 활용하면 더 안전하고 컴플라이언스를 준수하는 인프라 운영이 가능합니다. 여러분도 중요한 정보는 반드시 sensitive로 표시해 보세요.

실전 팁

💡 - 비밀번호, API 키, 토큰, 인증서는 항상 sensitive로 표시하세요

  • terraform output -json도 sensitive 값을 마스킹하지만, 파이프로 jq에 전달하면 노출될 수 있으니 주의하세요
  • 민감한 출력값을 스크립트에서 사용할 때는 환경 변수로 전달하고 즉시 삭제하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Terraform#Variables#Outputs#Validation#Sensitive#Terraform,IaC,DevOps

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

Terraform 프로바이더와 리소스 완벽 가이드

Terraform의 핵심인 프로바이더와 리소스 개념을 실무 중심으로 설명합니다. AWS 프로바이더 설정부터 리소스 정의, 의존성 관리, 멀티 프로바이더 구성까지 초급 개발자도 쉽게 이해할 수 있도록 스토리텔링 방식으로 풀어냈습니다.

HCL 문법과 기본 구조 완벽 가이드

Terraform의 핵심 언어인 HCL을 처음 배우는 초급 개발자를 위한 가이드입니다. 기본 문법부터 블록 구조, 데이터 타입, 주석, 포맷팅까지 실무에 필요한 모든 것을 다룹니다. 점프 투 자바 스타일로 쉽고 재미있게 배워보세요.

Terraform 소개 및 설치 완벽 가이드

인프라를 코드로 관리하는 IaC의 개념부터 Terraform의 특징, 설치 방법, 그리고 첫 번째 리소스 생성까지 초급 개발자를 위한 친절한 입문 가이드입니다. 실무에서 바로 활용할 수 있는 예제와 팁을 담았습니다.

실전 프로젝트 글로벌 엔터프라이즈급 AWS 아키텍처

글로벌 서비스를 위한 엔터프라이즈급 AWS 아키텍처 설계부터 구축까지 실전 프로젝트로 배우는 완벽 가이드입니다. 멀티 리전 고가용성, 보안, 모니터링, CI/CD까지 실무에서 바로 적용할 수 있는 노하우를 담았습니다.

Python 기본 문법 복습 완벽 가이드

Python 프로그래밍의 핵심 기초 문법을 체계적으로 정리합니다. 변수, 조건문, 함수부터 리스트 컴프리헨션과 예외 처리까지 실무에서 바로 활용할 수 있는 필수 지식을 담았습니다.