Ssoon

[6주차] 06 Terraform으로 Secret 관리 - Terraform과 함께 Secret 관리 도구 사용 본문

Terraform 101 Study

[6주차] 06 Terraform으로 Secret 관리 - Terraform과 함께 Secret 관리 도구 사용

구구달스 2022. 11. 22. 23:30
CloudNet@ 팀의 가시다님이 진행하는 Terraform 101 Study 06주차 정리입니다.
 

GitHub - kschoi728/T101: Terraform 101 Study

Terraform 101 Study. Contribute to kschoi728/T101 development by creating an account on GitHub.

github.com

 Providers

 AWS 공급자를 사용하는 코드에 적용하려면 먼저 AWS에 인증해야 하며 이는 일반적으로 secret 인 액세스 키를 사용함을 의미합니다. 이러한 비밀을 어떻게 저장해야 할까요 ?

Human users

💠 환경 변수 (environment variables)를 사용

$ export AWS_ACCESS_KEY_ID=(YOUR_ACCESS_KEY_ID)
$ export AWS_SECRET_ACCESS_KEY=(YOUR_SECRET_ACCESS_KEY)

 처음에 액세스 키 ID와 보안 액세스 키를 어디에 저장

access keys (및 기타 secrets)를 personal secrets 으로 설계된 secret manager 에 저장

특정 제공업체의 경우 이를 더욱 쉽게 해주는 전용 CLI 도구가 있습니다

예를 들어 AWS에 인증하기 위해 오픈 소스를 사용할 수 있습니다

aws-vault

다음과 같이 dev라는 프로필에서 aws-vault add 명령을 사용하여 액세스 키를 저장할 수 있습니다.

$ aws-vault add dev
Enter Access Key Id: (YOUR_ACCESS_KEY_ID)
Enter Secret Key: (YOUR_SECRET_ACCESS_KEY)

내부적으로 aws-vault는 이러한 자격 증명을 운영 체제의 기본 암호 관리자(예:macOS의 키체인, Windows의 자격 증명 관리자)에 안전하게 저장합니다.

자격 증명을 저장하면 이제 다음과 같이 모든 CLI 명령에 대해 AWS에 인증할 수 있습니다

$ aws-vault exec <PROFILE> -- <COMMAND>
  • PROFILE : 이전에 add 명령 (예: dev) 을 통해 만든 프로필 의 이름
  • COMMAND : 실행할 명령

이전에 저장한 dev 자격 증명을 사용하여 terraform apply 를 실행하는 방법입니다.

$ aws-vault exec dev -- terraform apply

exec 명령은 자동으로 AWS STS를 사용하여 임시 자격 증명을 가져오고 실행 중 인 명령 (terraform apply)에 대한 환경 변수로 노출합니다

영구 자격 증명이 안전한 방식으로(운영 체제의 기본 암호 관리자에) 저장될 뿐만 아니라 이제 실행 중인 모든 프로세스에 임시 자격 증명만 노출됩니다. 따라서 자격 증명 유출 위험이 최소화됩니다

 

 

Machine users

 Terraform 코드를 자동으로 실행하기 위해 CI/CD 파이프라인을 설정하는 경우 해당 파이프라인을 어떻게 안전하게 인증 할까요? secret 을 일반 텍스트로 저장하지 않고 어떻게 하나의 시스템(예: CI 서버)이 다른 시스템(예:AWS API 서버)에 자신을 인증하게 할까요?

💠 Jenkins를 IAM 역할과 함께 CI 서버로 실행하는 EC2 인스턴스

C2 인스턴스를 사용하여 Terraform 코드를 실행하는 경우(예: CI 서버로 EC2 인스턴스에서 Jenkins를 실행하는 경우) 사용자 인증에 권장하는 것은 해당 EC2 인스턴스에 IAM role 을 부여하는 것입니다.

IAM role  IAM permissions 을 부여받을 수 있는 IAM user 와 유사합니다.

그러나 IAM user 와 달리 IAM role 은 한 사람과 연결되지 않으며 영구 자격 증명(암호 또는 액세스 키)이 없습니다. 대신 다른 IAM 엔터티가 역할을 맡을 수 있습니다.

예를 들어 IAM 사용자는 일반적으로 가지고 있는 권한 다른 권한에 일시적으로 액세스할 수 있는 역할을 맡을 수 있습니다.

 

 EC2 인스턴스의 Security Group 입니다.

ec2-iam-role/main.tf

resource "aws_security_group" "stg_mysg" {
  name        = "T101 SG"
  description = "T101 Study SG"
}

resource "aws_security_group_rule" "stg_mysginbound" {
  type              = "ingress"
  from_port         = 0
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.stg_mysg.id
}

resource "aws_security_group_rule" "stg_mysgoutbound" {
  type              = "egress"
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.stg_mysg.id
}

 EC2 인스턴스를 배포하기 위한 코드입니다.

 ec2-iam-role/sg.tf

resource "aws_instance" "example" {
  ami                    = "ami-0fb653ca2d3203ac1"
  instance_type          = "t2.micro"
  key_name               = "new-key"
  vpc_security_group_ids = ["${aws_security_group.stg_mysg.id}"]

 

aws_iam_policy_document 를 사용하여 EC2 서비스가 IAM role 을 맡도록 허용하는 assume role policy 을 정의합니다.

  ✔ IAM role 을 생성하려면 먼저 IAM role 을 맡을 수 있는 사람을 정의하는 IAM 정책인 assume role policy 을 정의해야 합니다

  ✔ Terraform에는 편리한 JSON을 생성할 수 있는 aws_iam_policy_document data source 가 있습니다.

 ec2-iam-role/main.tf

#! EC2 인스턴스가 IAM 역할을 맡도록 허용
data "aws_iam_policy_document" "assume_role" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

 

aws_iam_role 리소스를 사용하여 IAM role 을 생성합니다.

  ✔ assume role policy 로 사용할 aws_iam_policy_document 의 JSON입니다.

 ec2-iam-role/main.tf

#! IAM role 생성
resource "aws_iam_role" "instance" {
  name_prefix        = var.name
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

IAM role 이 있지만 기본적으로 IAM role 은 권한을 부여하지 않습니다. 따라서 다음 단계는 일단 수임한 역할로 실제로 수행할 수 있는 작업을 지정하는 하나 이상의 IAM policy IAM role 에 연결하는 것입니다.

 

 aws_iam_policy_document data source 을 사용하여 EC2 인스턴스에 대한 관리자 권한을 부여하는 IAM policy 을 정의합니다.

 ec2-iam-role/main.tf

#! EC2 관리자 권한을 부여하는 IAM policy 생성
data "aws_iam_policy_document" "ec2_admin_permissions" {
  statement {
    effect    = "Allow"
    actions   = ["ec2:*"]
    resources = ["*"]
  }
}

 

 aws_iam_policy_document 리소스를 사용하여 이 IAM policy IAM role 에 연결합니다.

 ec2-iam-role/main.tf

#! EC2 관리자 권한을 IAM role 에 연결
resource "aws_iam_role_policy" "example" {
  role   = aws_iam_role.instance.id
  policy = data.aws_iam_policy_document.ec2_admin_permissions.json
}

 

 인스턴스 프로파일을 생성하여 EC2 인스턴스가 해당 IAM role을 자동으로 맡도록(assume) 허용합니다.

 ec2-iam-role/main.tf

#! IAM role 이 연결된 인스턴스 프로파일 생성
resource "aws_iam_instance_profile" "instance" {
  role = aws_iam_role.instance.name
}

 

 iam_instance_profile 매개변수를 통해 해당 인스턴스 프로필을 사용하도록 EC2 인스턴스에 지시합니다.

 ec2-iam-role/main.tf

resource "aws_instance" "example" {
  ami           = "ami-0fb653ca2d3203ac1"
  instance_type = "t2.micro"

  #! 인스턴스 프로필 연결
  iam_instance_profile = aws_iam_instance_profile.instance.name
}

 

📌 인스턴스에 연결된 IAM role 이 있는 경우(인스턴스 프로필을 통해) 해당 메타데이터에는 AWS에 인증하고 해당 IAM role 을 수임(assume)하는 데 사용할 수 있는 AWS 자격 증명이 포함됩니다 👉 이 IAM role 로 EC2 인스턴스에서 terraform apply를 실행하는 즉시 Terraform 코드가 이 IAM role 로 인증되어 실행하는 데 필요한 EC2 관리자 권한이 코드에 부여됩니다

📌 CI 서버와 같이 AWS에서 실행되는 자동화된 프로세스의 경우 IAM role 은 (1) 자격 증명을 수동으로 관리할 필요 없이 인증할 수 있는 방법을 제공합니다 (2) AWS가 인스턴스 메타데이터 엔드포인트를 통해 제공하는 자격 증명은 항상 일시적이며 교체됩니다. 👉 이는 AWS 계정 외부에서 실행되는 CircleCI와 같은 도구를 사용하여 수동으로 관리되는 영구 자격 증명에 비해 두 가지 큰 이점입니다.

📢 CLI 확인

🚩 Console 확인

Comments