terraform sensitive

도은호·2025년 9월 17일

terraform

목록 보기
6/32

sensitive값을 콘솔 출력과 로그에서 마스킹(가리기)하는 플래그.
암호화 기능이 아니라는 점! 상태/플랜 파일에는 값이 들어갈 수 있으니 백엔드 보안은 따로 챙겨야 함.

  • 변수/출력/리소스 인자에 sensitive = true 또는 sensitive() 함수로 노출 최소화
  • 마스킹일 뿐 저장 자체를 막지 않음 → 원격 상태 암호화 + 접근제어 필수
  • 민감값으로 계산된 결과는 자동으로 민감성 전파(derived values도 숨김)
  • 자동화가 필요하면 terraform output -json/-raw로 기계가 읽고, 사람 화면엔 숨기기

1) 어디에 쓰나?

(1) 변수에 표시

variable "db_password" {
  type      = string
  sensitive = true
}
  • plan/apply 출력에서 값이 Sensitive로 가려집니다.
  • 하지만 state/plan 파일에는 실제 값이 들어갈 수 있어요 → 백엔드 보안 필수.

(2) 출력(Outputs) 숨기기

output "db_password" {
  value     = var.db_password
  sensitive = true
}
  • 콘솔엔 안 보임.
  • 자동화 필요 시: terraform output -json 또는 -raw로 프로그램이 읽게만 사용.

(3) 리소스 인자(파일·템플릿 등) 마스킹

resource "local_file" "secret" {
  filename          = "secret.txt"
  sensitive_content = var.db_password   # content 대신 sensitive_content
}
  • 계획/적용 로그에 내용이 찍히지 않습니다.
  • 유사 리소스: local_sensitive_file(민감 콘텐츠 전용)

2) 관련 함수 두 가지

locals {
  masked_token   = sensitive(var.api_token)   # 민감성 부여
  last4          = nonsensitive(regex("\\d{4}$", var.card_number))  # 안전한 파생값만 평문 처리
}
  • sensitive(): 해당 값에 민감 표시 추가
  • nonsensitive(): 민감 표시 제거(주의! 콘솔에 평문이 찍힐 수 있으니 안전한 파생값에만)

3) 민감성 전파(Propagation)

  • sensitive 값으로 만든 모든 파생값은 기본적으로 민감 표시가 따라갑니다.
  • 필요할 때만 nonsensitive()로 안전한 부분만 꺼내 쓰세요(예: 카드번호 마지막 4자리).

4) 진짜 보안은 “백엔드”에서

sensitive출력 가리기일 뿐, 저장 차단/암호화가 아님. 그래서:

  • 원격 상태(S3 등) + 암호화

    • S3: SSE-KMS, 버킷 Public Access Block, 버전관리(선택)
    • DynamoDB 테이블로 state 락(경합·동시수정 방지)
  • IAM 최소권한: 상태 버킷/락 테이블에 읽기·쓰기 최소만 부여

  • 로컬 상태 금지: 팀 환경에선 절대 local 백엔드 쓰지 않기

백엔드 예시:

terraform {
  backend "s3" {
    bucket         = "my-tf-state-bucket"
    key            = "projectA/terraform.tfstate"
    region         = "ap-northeast-2"
    dynamodb_table = "tf-lock"
    encrypt        = true        # S3 서버측 암호화
  }
}

5) 실전

(A) 변수/출력/리소스 한 번에

variable "db_password" {
  type        = string
  sensitive   = true
  description = "DB password (환경변수 TF_VAR_db_password 권장)"
}

# 사용 예: 파일로 쓰되 로그에 노출 안 함
resource "local_file" "db_secret" {
  filename          = "db.pass"
  sensitive_content = var.db_password
}

output "db_password" {
  value     = var.db_password
  sensitive = true
}

(B) 안전한 파생값만 노출

variable "card_number" { type = string; sensitive = true }

output "card_last4" {
  value = nonsensitive(regex("\\d{4}$", var.card_number))
}

(C) 민감값을 환경변수로 주입

# 터미널/CI에서
export TF_VAR_db_password='SuperSecret#1234'
terraform apply -auto-approve

6) 자주 하는 실수 & 예방책

  • “sensitive면 저장도 안 되겠지?” → 아니요. state/plan에는 들어감.
    ✅ 백엔드 암호화 + 접근제어를 반드시 구성.

  • output에 비밀을 그대로 노출
    sensitive = true 또는 안전한 파생값만 nonsensitive()로 가공해서 노출.

  • UserData/로그 파일에 비밀 평문 기록
    ✅ 가능하면 시크릿 매니저(예: AWS Secrets Manager/Vault)와 통합하고, 로그에 찍히지 않도록 설계.

  • tfvars에 비밀 커밋
    ✅ 비밀은 환경변수/시크릿 스토어로 주입, terraform.tfvars엔 기본값만.
    .gitignore: *.tfstate, .terraform/, *.tfvars(민감용) 등 포함.


7) 체크리스트(현업용)

  • 민감한 입력값에 sensitive = true 지정
  • 로그/출력에 비밀이 찍히지 않도록 sensitive_content/sensitive() 사용
  • 원격 상태 백엔드 + 암호화 + + IAM 최소권한
  • 자동화 시 terraform output -json/-raw로만 기계에 전달(사람 화면엔 숨김)
  • 비밀은 환경변수/시크릿 매니저로 주입, tfvars 평문 커밋 금지
  • 비밀이 포함된 템플릿/유저데이터/로그 경로 재점검

8) 마무리

sensitive는 “안 보이게” 만드는 마스킹 플래그일 뿐, 보관 보안은 백엔드에서 책임진다.
콘솔엔 숨기고, 저장소는 암호화/권한으로 지키자.

profile
`•.¸¸.•´´¯`••._.• 🎀 𝒸𝓇𝒶𝓏𝓎 𝓅𝓈𝓎𝒸𝒽💞𝓅𝒶𝓉𝒽 🎀 •._.••`¯´´•.¸¸.•`

0개의 댓글