Managing Secret with Terraform

kimchigood·2022년 12월 11일
0

Terraform Study

목록 보기
6/6
post-thumbnail

이번 포스팅에서는 terraform에서의 key 암호화에 대해 알아보겠다.
terraform을 통해 AWS RDB를 만든다고 가정했을 때, terraform 코드에 계정과 패스워드가 평문으로 들어갈 수 있다.
rdb.tf

resource "aws_db_instance" "example" {
  identifier_prefix   = "terraform-up-and-running"
  engine              = "mysql"
  allocated_storage   = 10
  instance_class      = "db.t2.micro"
  skip_final_snapshot = true
  db_name             = var.db_name

  # How to set these parameters securely?
  username = "???"
  password = "???"
}

이런 민감정보들이 소스코드 관리 툴이나 버전관리 시스템에 노출되었을 때 끼치는 영향은 치명적일 것이다. 이러한 보안위협을 방지하기 위해서 terraform에서는 AWS KMS, GCP KMS 등과 연계하여 보안기능을 제공한다.

바로 실습을 통해 알아보자.

1. AWS KMS?

AWS Key Management Service(AWS KMS)를 통해 민감데이터를 암호화 하여 AWS의 각종 서비스들과 연계할 수 있다.

1-1. AWS KMS Key 생성

# 키 생성(기본값)
# aws kms create-key --description "my text encrypt descript demo"
CREATE_KEY_JSON=$(aws kms create-key --description "my text encrypt descript demo")
echo $CREATE_KEY_JSON | jq

# 키 ID확인
KEY_ID=$(echo $CREATE_KEY_JSON | jq -r ".KeyMetadata.KeyId")
echo $KEY_ID

# 키 alias 생성
export ALIAS_SUFFIX=kimchigood
aws kms create-alias --alias-name alias/$ALIAS_SUFFIX --target-key-id $KEY_ID

# 생성한 별칭 확인
aws kms list-aliases

kms 키를 생성하고, 생성된 KEY_ID값으로 Key alias를 생성해준다.

2. terraform secret

이제 terraform 코드에서 관리되는 평문의 민감데이터를 AWS KMS와 연동해보자. 실습순서는 민감데이터를 AWS KMS를 통해 암호화하고, terraform 코드를 통해 암호화된 데이터에 접근하여 리소스를 생성하는 순서로 한다.

2-1. AWS KMS 암호화

db-creds.yaml

cat <<EOT > db-creds.yml
username: admin
password: password
EOT

AWS KMS 암호화

aws kms encrypt --key-id alias/$ALIAS_SUFFIX  --cli-binary-format raw-in-base64-out --plaintext file://db-creds.yml --output text --query CiphertextBlob | tee db-creds.yml.encrypted

# 암호문 확인
cat db-creds.yml.encrypted

$ AQICAHg8IvteQXbfnvbAi0mI9EZbzfkFa7fyZdPjYrOmNfVFPwEONo1NMIe6nekkVfoJpOyIAAAAgTB/BgkqhkiG9w0BBwagcjBwAgEAMGsGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMwnhGRVbCvjdpRb+vAgEQgD7dCm1uBTHdzVnZ2d7vxA65OMMeyeqK7j7/PlF+yG5j3x9jvTP3bBGhpm3STAEzriYFXbvg7mXs93woRS1WHw==

terraform 코드 연동

rds.tf

provider "aws" {
  region = "ap-northeast-2"
}

data "aws_kms_secrets" "creds" {
  secret {
    name    = "db"
    payload = file("${path.module}/db-creds.yml.encrypted")
  }
}

locals {
  db_creds = yamldecode(data.aws_kms_secrets.creds.plaintext["db"])
}

resource "aws_db_instance" "example" {
  identifier_prefix   = "terraform-up-and-running"
  engine              = "mysql"
  allocated_storage   = 10
  instance_class      = "db.t2.micro"
  skip_final_snapshot = true
  db_name             = var.db_name

  # Pass the secrets to the resource
  username = local.db_creds.username
  password = local.db_creds.password
}

variables.tf

variable "db_name" {
  description = "The name to use for the database"
  type        = string
  default     = "example"
}

outputs.tf

output "address" {
  value       = aws_db_instance.example.address
  description = "Connect to the database at this endpoint"
}

output "port" {
  value       = aws_db_instance.example.port
  description = "The port the database is listening on"
}

terraform 실행

terraform init & terraform plan

rds.tf 코드를 보면 db-creds.yml.encrypted의 값을 읽어와서 RDS를 생성하게 되는데, 현재 세팅되어있는 AWS KMS를 통해 암호화된 db-creds.yml.encrypted 를 복호화 하고, 그 변수를 가져와서 ID/PASSWORD를 적용하여 리소스를 생성하게 된다.

마무리

AWS KMS 키는 아래와 같은 방법으로 삭제하도록 하자.

terraform destroy -auto-approve

# 생성한 키 ID 변수 지정
KEY_ID=$(echo $CREATE_KEY_JSON | jq -r ".KeyMetadata.KeyId")

# 키 비활성화
aws kms disable-key --key-id $KEY_ID

# 키 삭제 예약 : 대기 기간(7일) 
aws kms schedule-key-deletion --key-id $KEY_ID --pending-window-in-days 7
profile
Shout out to Kubernetes⎈

0개의 댓글