구성에서 민감한 데이터 관리하기

구성에서 민감한 데이터 관리하기

Terraform은 인프라를 프로비저닝하기 위해 클라우드 프로바이더 자격 증명, API 토큰, 기타 비밀 값 같은 민감한 데이터에 접근해야 할 수 있어요. 비밀 값을 구성에 직접 추가하면 Terraform이 그 비밀을 상태와 계획 파일에 저장해요. 구성에서 민감한 데이터를 보호하기 위한 다양한 옵션과 각 접근 방식의 장단점을 알아보세요.

출처: 문서

본문

배경

Terraform 상태와 계획 파일에는 리소스 속성과 초기 데이터베이스 비밀번호나 API 토큰 같은 민감한 값을 포함할 수 있는 메타데이터를 포함해 인프라에 대한 자세한 정보가 들어 있어요. 로컬에서 Terraform으로 개발한다면 Terraform은 상태를 일반 텍스트 파일(구성에 정의한 비밀 값을 포함한 파일)에 저장해요. 상태 파일을 Git 워크플로에서 제외하고 상태 파일 보안 유지에 대한 권장 사항을 따르는 등 상태 파일을 민감한 데이터로 취급하세요.

또한 Terraform이 상태와 계획 파일을 원격 위치에 저장하도록 구성할 수도 있어요. Terraform을 원격 상태 저장소를 사용하도록 구성하면, 적극적으로 사용할 때만 상태를 메모리에 보관해요. 저장 시점(at rest)에 상태를 암호화할 수 있지만, 암호화 방법은 특정 백엔드에 따라 달라요. 예를 들어 HCP Terraform은 저장 시 상태를 자동 암호화하고 전송 중(in transit)에는 TLS로 보호해요.

요구 사항

다음 요구 사항은 Terraform 구성에서 민감한 값을 처리하는 데 사용할 수 있는 특정 블록과 인자에 연결돼 있어요:

  • variableoutput 블록에 sensitive 인자를 추가하려면 Terraform 0.15 이상을 사용하세요.
  • 변수와 하위 모듈 출력에 ephemeral 인자를 추가하거나 ephemeral 블록을 추가하려면 Terraform 1.10 이상을 사용하세요.
  • 관리 리소스에서 쓰기 전용(write-only) 인자를 사용하려면 Terraform 1.11 이상을 사용하세요.

각 프로바이더는 관리 리소스에 사용 가능한 ephemeral 블록과 쓰기 전용 인자를 정의해요. 여러분의 프로바이더가 무엇을 지원하는지 알아보려면 Terraform 레지스트리를 참고하세요.

민감한 데이터 처리 방법 결정하기

구성에서 민감한 값을 어떻게 처리할지 결정하려면, 먼저 Terraform CLI와 HCP Terraform UI에서 값을 숨기고 싶은지, 아니면 Terraform이 그 값을 전혀 저장하지 않도록 하고 싶은지 결정하세요.

variable 또는 output 블록에 sensitive 인자를 추가하면 Terraform이 CLI 출력과 HCP Terraform UI에서 해당 값을 자동으로 삭제(redact)해요. Terraform은 또한 민감한 변수나 출력을 참조하는 모든 표현식을 본질적으로 민감한 것으로 취급해요. 변수와 출력에서 민감한 데이터를 숨기는 방법은 민감한 변수와 출력 숨기기를 참고하세요.

임시(ephemeral) 값은 런타임에 사용할 수 있지만 Terraform은 그 값을 상태와 계획 파일에서 완전히 생략해요. Terraform은 구성에서 임시 값을 정의하는 네 가지 방법을 제공해요:

  • 변수와 하위 모듈 출력의 ephemeral 인자
  • ephemeral 블록
  • 관리 리소스의 쓰기 전용 인자

임시 값과 그 제한 사항에 대한 자세한 내용은 상태와 계획 파일에서 값 생략하기를 참고하세요. 또한 variable과 하위 모듈 output 블록에 ephemeralsensitive 인자를 모두 추가해 Terraform이 그 값을 저장하지 않도록 할 수도 있어요. 이렇게 하면 Terraform CLI와 HCP Terraform UI에서 그 값이 삭제돼요. 저장하지 않고 CLI에서 값 숨기기에 대해 자세히 알아보세요.

민감한 변수와 출력 숨기기

실습: Protect Sensitive Input Variables 튜토리얼을 해보세요.

Terraform CLI 로그 출력과 HCP Terraform UI에서 값을 삭제하려면 variableoutput 블록에서 sensitive 인자를 사용하세요. Terraform은 또한 민감한 변수나 출력을 참조하는 모든 표현식을 본질적으로 민감한 것으로 취급해요.

민감한 데이터를 포함한 variable 블록에 sensitive 인자를 추가하세요:

variable "database_password" {
  description = "Password for the database instance"
  type        = string
  sensitive   = true
}

민감한 데이터를 포함한 output 블록에도 sensitive를 추가할 수 있어요:

output "connection_string" {
  description = "Database connection string"
  value       = "postgresql://${var.db_username}:***@${aws_db_instance.main.endpoint}/mydb"
  sensitive   = true
}

그러면 Terraform은 Terraform CLI의 운영 로그에서 민감한 변수와 출력을 삭제해요. 예를 들어 다음 적용(apply) 요약에서 connection_string 출력이 삭제돼요:

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

connection_string = (sensitive value)

Terraform은 또한 민감한 변수나 출력을 참조하는 어떤 표현식도 자동으로 민감한 것으로 취급해요. 다음 예시에서 password 인자는 다른 리소스에서 민감한 var.database_password를 참조해요:

resource "aws_db_instance" "main" {
  identifier = "my-database"
  engine     = "postgres"
  username   = var.db_username
  password   = var.database_password
}

Terraform은 계획(plan)과 적용(apply) 작업에서 main 리소스의 password 인자를 삭제해요:

# aws_db_instance.main will be created
+ resource "aws_db_instance" "main" {
    + password = (sensitive value)
    + username = "admin"
  }

Terraform은 sensitive 인자를 가진 값을 상태와 계획 파일 둘 다에 저장하며, 그 파일에 접근할 수 있는 사람은 누구나 민감한 값에 접근할 수 있어요. 또한 terraform output CLI 명령-json이나 -raw 플래그와 함께 사용하면 Terraform이 민감한 변수와 출력을 일반 텍스트로 표시해요.

민감한 변수와 출력의 값을 저장하고 싶지 않다면 상태와 계획 파일에서 값 생략하기를 참고하세요. 상태와 계획 파일에 민감한 값이 있다면 상태 보안 유지를 권장해요.

저장하지 않고 값 숨기기

ephemeral 인자가 있는 변수와 하위 모듈 출력에 sensitive 인자를 추가해 두 가지 이점을 결합할 수 있어요. 다음 database_password 변수는 상태와 계획 파일에서 생략되고, 그 값은 Terraform CLI와 HCP Terraform UI에서 삭제돼요:

variable "database_password" {
  description = "Password for the database instance"
  type        = string
  sensitive   = true
  ephemeral   = true
}

ephemeral 인자에 대해 더 알아보려면 상태와 계획 파일에서 값 생략하기를 참고하세요.

상태와 계획 파일에서 값 생략하기

임시 값은 작업의 런타임에 사용할 수 있지만 Terraform은 그 값을 상태와 계획 파일에서 생략해요. Terraform은 임시 값을 저장하지 않기 때문에, 보존하려는 생성 값을 구성의 다른 리소스나 출력에 캡처해야 해요.

구성에서 임시 값을 정의하려면 다음 방법을 사용할 수 있어요:

Terraform은 구성에서 임시 값을 참조할 수 있는 위치를 제한해요. 다음 문맥에서만 임시 값을 참조할 수 있어요:

변수나 출력에 ephemeral 인자 추가하기

일시적인 민감한 데이터를 포함한 variable 블록에 ephemeral 인자를 true로 설정해 그 값을 상태와 계획 파일에서 생략하세요:

variable "api_token" {
  description = "Short-lived API token for provider authentication"
  type        = string
  sensitive   = true
  ephemeral   = true
}

ephemeral 인자가 있는 variable 블록을 다른 임시 문맥에서 참조할 수 있어요. 예를 들어 provider 블록에서 api_token 변수를 사용해 프로바이더를 구성할 수 있어요:

provider "example" {
  api_token = var.api_token
}

또한 하위 모듈의 output 블록에 ephemeral 인자를 추가해 상태나 계획 파일에 영속화하지 않고 모듈 간 데이터를 전달할 수 있어요. 루트 모듈의 출력에는 ephemeral 인자를 추가할 수 없어요.

output "session_token" {
  value     = ephemeral.auth_provider.main.token
  ephemeral = true
  sensitive = true
}

하위 모듈과 루트 모듈 사이에 출력 값을 전달하는 것은 상태에 저장하고 싶지 않은 자격 증명, 토큰, 기타 임시 값을 관리할 때 유용해요.

또한 variableoutput 블록에 sensitive 인자를 추가해 CLI와 HCP Terraform UI에서 그 값을 숨길 수 있어요. sensitive 인자와 함께 ephemeral 인자 사용에 대해 자세히 알아보세요.

ephemeral 블록 사용하기

ephemeral 블록은 현재 Terraform 작업 동안에만 존재하는 일시적인 임시 리소스를 선언해요. Terraform은 임시 리소스를 상태나 계획 파일에 저장하지 않으므로, 영속화하고 싶지 않은 민감한 데이터나 일시적인 데이터(임시 비밀번호나 다른 시스템에 대한 연결 등)를 관리하는 데 이상적이에요. 각 프로바이더는 사용 가능한 임시 리소스를 정의해요. 여러분의 프로바이더가 무엇을 지원하는지 알아보려면 Terraform 레지스트리를 참고하세요.

예를 들어 random_password 임시 리소스를 사용해 임시 비밀번호를 생성할 수 있어요:

ephemeral "random_password" "db_password" {
  length           = 16
  override_special = "!#$%&*()-_=+[]{}<>:?"
}

ephemeral 블록은 다른 임시 문맥, 예를 들어 관리 리소스의 쓰기 전용 인자에서만 참조할 수 있어요. 쓰기 전용 인자를 사용하면 작업 중에 임시 값을 관리 리소스에 안전하게 전달하면서 값을 영속화하지 않을 수 있어요. 예를 들어 password_wo 쓰기 전용 인자에서 db_password를 참조할 수 있어요:

#...

ephemeral "random_password" "db_password" {
  length           = 16
  override_special = "!#$%&*()-_=+[]{}<>:?"
}

resource "aws_db_instance" "example" {
  instance_class       = "db.t3.micro"
  allocated_storage    = "5"
  engine               = "postgres"
  username             = "example"
  skip_final_snapshot  = true
  publicly_accessible  = true
  db_subnet_group_name = aws_db_subnet_group.example.name
  password_wo          = ephemeral.random_password.db_password.result
  password_wo_version  = 1
}

쓰기 전용 인자와 ephemeral 블록은 둘 다 현재 Terraform 실행 밖으로 영속화되지 않아요. 이렇게 하면 ephemeral.random_password.db_password.result 값이 상태와 계획 파일에서 완전히 생략되도록 보장해요.

Terraform은 ephemeral.random_password.db_password.result의 생성 값을 저장하지 않지만, 다른 리소스에 캡처해 값이 손실되지 않게 할 수 있어요. 임시 비밀번호의 생성, 저장, 검색, 사용 예시는 쓰기 전용 인자를 참고하세요. 임시 리소스에 대해 알아보려면 ephemeral 블록 참조를 참고하세요.

쓰기 전용 인자 사용하기

쓰기 전용 인자를 사용하면 작업 중에 임시 값을 Terraform의 관리 리소스에 안전하게 전달하면서 그 값을 상태나 계획 파일에 영속화하지 않을 수 있어요. 각 프로바이더는 관리 리소스에서 사용 가능한 쓰기 전용 인자를 정의해요. 여러분의 프로바이더가 무엇을 지원하는지 알아보려면 Terraform 레지스트리를 참고하세요.

쓰기 전용 인자는 일반적으로 _wo로 끝나고 그에 대응하는 _wo_version 인자가 있어요. 예를 들어 aws_db_instance에는 password_wo 쓰기 전용 인자가 있어요:

resource "aws_db_instance" "main" {
  instance_class      = "db.t3.micro"
  allocated_storage   = "20"
  engine              = "postgres"
  username            = "admin"
  skip_final_snapshot = true

  password_wo         = ephemeral.random_password.db_password.result
  password_wo_version = 1
}

Terraform 작업 중에 aws 프로바이더는 password_wo 값을 사용해 데이터베이스 인스턴스를 만들고, 그 후 Terraform은 그 값을 계획이나 상태 파일에 저장하지 않고 버려요. 버전으로 업데이트하고 값을 저장하는 방법을 포함한 쓰기 전용 인자에 대해 더 알아보려면 쓰기 전용 인자를 참고하세요.

상태 보안 모범 사례

상태 파일에 민감한 값을 저장한다면 상태를 안전하게 유지하기 위해 추가 보안 조치를 구현하는 것을 권장해요:

  • 상태를 원격으로 저장하세요.
  • 저장 시 상태를 암호화하세요.
  • 상태에 접근할 수 있는 사람을 제한하는 접근 제어를 사용하세요.
  • 시간 경과에 따른 상태 접근을 추적하는 감사 로그를 사용하세요.

상태를 원격으로 저장하면 저장 시 상태를 암호화할 수 있어 더 나은 보안을 제공할 수 있어요. 예를 들어 다음 백엔드는 상태 암호화를 지원해요:

더 알아보기 (Learn more)