티스토리 뷰
안녕하세요. CloudNet@ Terraform Study를 진행하며 해당 내용을 이해하고 공유하기 위해 작성한 글입니다. 도서 ‘Terraform: Up & Running(By Yevgeniy Brikman)’ 의 내용 및 스터디 시간 동안 언급된 주요 내용 위주로 간단히 정리했습니다.
배포 과정에서 민감 정보 (DB암호, API 키, TLS인증서, SSH키, GPG 키 등)를 안전하게 관리가 필요합니다.
민감 정보 관리 방식
2가지 암호 저장 방식이 있습니다.
- 파일 기반 암호 저장 : 민감 정보를 암호화 후 저장 → 암호화 관련 키 관리가 중요 ⇒ 해결책 : AWS KMS, GCP KMS 혹은 PGP Key
- 중앙 집중식 암호 저장 : 데이터베이스(MySQL, Psql, DynamoDB 등)에 비밀번호를 암호화하여 저장, 암호화 키는 서비스 자체 혹은 클라우드 KMS를 사용
민감 정보 관리 방법(with Terraform)
IAM 자격 증명 정보를 코드의 Provider 에 직접 입력하는 방법은 안전하지 않습니다.
- 사용자(Human users) : 환경 변수 사용, 여전히 컴퓨터 파일에 평문으로 저장 시 문제 될 수 있어 1Password / LastPass (유료)저장 후 사용 or aws-vault(오픈소스)
# mac 설치
brew install --cask aws-vault
# 윈도우 설치
choco install aws-vault # 윈도우 Chocolatey
scoop install aws-vault # 윈도우 Scoop
# 버전 확인
aws-vault --version
v6.6.0
# 설정
#aws-vault add <PROFILE_NAME>
aws-vault add t101
Enter Access Key Id: (YOUR_ACCESS_KEY_ID)
Enter Secret Key: (YOUR_SECRET_ACCESS_KEY)
- aws-vault 설정 후 ~/.aws/credentials 파일은 삭제를 권장합니다.
- 좀 더 보안 강화 : MFA 사용, IAM 사용자 기반 → IAM 역할 기반
2. 시스템 사용자(Machine users) : 시스템에 따라 인증 방식이 조금 다름, 예) CI서버
- [Providers]CircleCI as a CI server, with stored secrets : CI/CD 플랫폼인 CircleCI 를 통해 테라폼 코드를 실행한다고 가정
- [Providers]GitHub Actions as a CI server, with OIDC : Github Actions 은 직접 자격 증명과 OIDC(Open ID Connect) 지원
- [Providers]EC2 Instance running Jenkins as a CI server, with IAM roles : EC2에 Jenkins 설치 후 CI서버로 테라폼 코드를 실행한다고 가정 시 IAM roles 활용
- [Resources and data sources] Encrypted files : 암호를 파일에 저장 후 버전 관리 → 암호화 키를 클라우드 공급자 KMS를 통해 안전하게 저장 혹은 PGP 키 사용
실습(EC2 Instance running Jenkins as a CI server, with IAM roles)
- EC2 Instance running Jenkins as a CI server, with IAM roles
- IAM role 는 특정 사용자에 연결되지 않으며, 영구적인 자격증명이 아닙니다.
- Role(EC2FullAccess) Switch 를 통해, EC2를 사용할 수 있습니다.
- 실습 코드 : Github -repo
- [issue] Error: with the retirement of EC2-Classic no new Security Groups can be created without referencing a VPC (terraform v4.30.0 이상에서 fix)
# SSH 키페어 이름 지정
SSHKP=<각자 자신의 SSH 키페어 이름>
SSHKP=kp-hayley
# init & plan & apply
$ terraform init && terraform plan && terraform apply -auto-approve
- 각자 자신의 SSH 키페어로 EC2 접속 후 IAM role 동작 확인합니다.
#ssh -i <자신의 SSH 키파일 지정> ec2-user@$(terraform output -raw instance_ip)
ssh -i ~/.ssh/kp-hayley.pem ec2-user@$(terraform output -raw instance_ip)
curl -s http://169.254.169.254/latest/meta-data/
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials ; echo
IAMROLE=$(curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials)
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAMROLE
# EC2 관련 명령 실행 확인
export AWS_DEFAULT_REGION=ap-northeast-2
aws ec2 describe-vpcs --output table
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text
# 실습 자원 삭제
$ terraform destroy -auto-approve
실습(Encrypted files)
- AWS KMS : AWS 키 관리 서비스 KMS는 공유 하드웨어 보안 모듈HSM 을 사용하면서 암호화키를 생성하고 관리할 수 있게 도와줍니다.
- CloudHSM : AWS 내에서 암호화키를 관리할 수 있지만 보안 강화를 위해 전용 HSM을 사용할 수 있는 서비스입니다.
# 키 생성(기본값)
# 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=hayley
aws kms create-alias --alias-name alias/$ALIAS_SUFFIX --target-key-id $KEY_ID
# 생성한 별칭 확인
aws kms list-aliases
# CMK로 평문을 암호화해보기
echo "Hello 123123" > secrect.txt
aws kms encrypt --key-id alias/$ALIAS_SUFFIX --cli-binary-format raw-in-base64-out --plaintext file://secrect.txt --output text --query CiphertextBlob | base64 --decode > secrect.txt.encrypted
# 암호문 확인
cat secrect.txt.encrypted
# 복호화해보기
aws kms decrypt --ciphertext-blob fileb://secrect.txt.encrypted --output text --query Plaintext | base64 --decode
Hello 123123
AWS CMK(KMS Key) 생성을 위해 Key policy 생성 : 현재 사용자가 CMK 권한을 가질 수 있게 코드 설정합니다.
# 테라폼에서 aws_caller_identity 데이터소스로 사용자 정보 확인
provider "aws" {
region = "us-east-2"
}
# Look up the details of the current user
data "aws_caller_identity" "self" {}
- 아래 처럼 현재 사용자에 KMS 권한 부여 정책 생성 할 수 있습니다.
data "aws_iam_policy_document" "cmk_admin_policy" {
statement {
effect = "Allow"
resources = ["*"]
actions = ["kms:*"]
principals {
type = "AWS"
identifiers = [data.aws_caller_identity.self.arn]
}
}
}
- 먼저, DB계정 정보가 포함된 db-creds.yml 파일을 생성합니다.
cat <<EOT > db-creds.yml
username: admin
password: password
EOT
- AWS KMS CMK로 파일 암호화 하기 : 암호화파일 생성 후 db-creds.yml 삭제합니다.
# CMK로 평문을 암호화해보기
#aws kms encrypt --key-id alias/$ALIAS_SUFFIX --cli-binary-format raw-in-base64-out --plaintext file://db-creds.yml --output text --query CiphertextBlob | base64 --decode | tee db-creds.yml.encrypted2
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.encrypted2
# 암호문 확인
cat db-creds.yml.encrypted2
# 복호화해보기
aws kms decrypt --ciphertext-blob fileb://db-creds.yml.encrypted2 --output text --query Plaintext | base64 --decode
- 테라폼 코드에서 암호화(파일) 활용 할 수 있게 설정합니다.
# 먼저 aws_kms_secrets data source 설정
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"])
}
# DB 계정과 암호를 aws_kms_secrets 의 복호화된 로컬 변수를 전달
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
}
$ terraform init & terraform plan & terraform apply -auto-approve
# 리소스 생성 및 AWS RDS 정보 확인(username 등)
$ aws rds describe-db-instances --query "*[].[DBInstanceIdentifier,MasterUsername,Endpoint.Address,Endpoint.Port]" --output text
# 실습 완료 후 삭제
$ 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
blog migration project
written in 2022.11.20
https://medium.com/techblog-hayleyshim/iac-managing-secrets-with-terraform-b1f25ab6fc74
'Programming > IaC' 카테고리의 다른 글
[IaC] GKE configuration deep dive (0) | 2023.10.28 |
---|---|
[IaC] Production-grade Terraform code (0) | 2023.10.28 |
[IaC] Terraform tips & tricks — Loops & Conditions (0) | 2023.10.28 |
[IaC] Terraform modules (0) | 2023.10.28 |
[IaC] Terraform state -상태파일격리 (0) | 2023.10.28 |
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- GCP
- GKE
- 파이썬
- k8s calico
- terraform
- k8s
- handson
- OS
- S3
- 혼공파
- AI
- EKS
- 도서
- cni
- 혼공챌린지
- AWS
- controltower
- security
- NFT
- gcp serverless
- NW
- IaC
- cloud
- SDWAN
- VPN
- 혼공단
- operator
- 국제 개발 협력
- k8s cni
- PYTHON
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함