새소식

IaC/Terraform

6주차(1)_Terraform 민감정보 관리 (Provider)

  • -
CloudNet@ 팀의 가시다님께서 Leading 하시는 Terraform T101 Study 내용 요약

 

해당 Terraform Study 는 Terraform Up and Running 책을 기반으로 진행 중입니다.

 

테라폼을 사용하다보면 민감정보(비밀번호 등) 를 다루게 되는 상황이 오게 됩니다.
이번 포스팅에서는 테라폼 민감정보를 관리하는 방법에 대해서 알아보겠습니다.

 

 

테라폼을 사용하면서 민감정보가 노출될 수 있는 부분은 다음 3가지 입니다.
  1. Provider
    인증 관련 민감정보 노출
  2. Resource & Data Info
    DB 암호 등 리소스 접근 민감정보 노출
  3. Terraform State & Plan file
    상태 파일, 플랜 파일에 테라폼 리소스 관련 정보 노출

 

  • 때문에, 해당 정보들은 공개된 백엔드나 Git 등에 코드를 업로드 하기 전에 한 번 더 확인해볼 필요가 있습니다.
    그렇다면 각 부분에서 사용되는 민감정보를 관리하는 방법에 대해서 알아봅시다.



1. Provider 민감정보


Provider 에서 다루는 민감정보는 AWS Access Key & Secret Key 등의 인증 정보

 

테라폼을 사용할 때 가장 먼저 설정하는 Provider 에 대해 다음과 같이 인증정보를 설정하는 경우가 있습니다.

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

  access_key = "AWS_Access_Key"
  secret_key = "AWS_Secret_Key"
}

  • 하지만 코드가 유출된다면 굉장히 치명적인 보안사고가 발생할 수 있기 때문에
    절대 인증정보를 Provider 안에 직접 입력해서는 안됩니다.

인증정보를 Provider에 직접 입력하지 않고 관리할 수 있는 방법 4가지를 알아봅시다.

 

1.1. 환경변수 활용

첫 번째 방법은 직접 환경변수로 인증정보를 설정해주는 것입니다.

다음과 같이 터미널에 환경변수를 입력하고 테라폼을 실행해봅시다.

export AWS_ACCESS_KEY_ID="AWS_Access_Key"
export AWS_SECRET_ACCESS_KEY="AWS_Secret_Key"

 

  • 단점
    컴퓨터 재부팅 시, 매번 재입력해줘야하는 번거로움 발생

 

1.2. 설정파일 활용

두 번째 방법은 설정파일 안에 인증정보를 생성하는 것입니다.

다음과 같은 명령어를 사용하면 AWS 설정파일을 생성할 수 있습니다.

aws configure

 

aws 설정파일을 생성하게 되면, 사용자 디렉토리 안에 .aws 라는 디렉토리가 생성이 되고 그 속에 config & credentials 파일이 각각 생성되는 것을 확인할 수 있습니다.
테라폼에서는 해당 설정파일을 사용하여 AWS 에 접근하고 리소스를 배포할 수 있게됩니다.

 

  • 단점
    결국 민감정보를 평문으로 파일에 저장하는 것이기 때문에, 해당 파일이 노출되면 보안사고가 발생할 가능성이 존재

 

1.3. 인증관리도구 활용 (aws-vault)

세 번째 방법은 인증관리도구를 활용하여 임시 인증정보를 발급받아 Provider 에 인증하는 것입니다.

이 방법을 활용하면 aws credentials 파일 조차 생성할 필요가 없습니다.
오픈소스인 aws-vault 를 활용하여 인증관리도구를 알아보겠습니다.

 

aws-vault 는 AWS STS 서비스를 활용하여 AWS API 에 접근할 수 있는 임시 토큰을 발급해주는 도구입니다.

 

GitHub - 99designs/aws-vault: A vault for securely storing and accessing AWS credentials in development environments

A vault for securely storing and accessing AWS credentials in development environments - GitHub - 99designs/aws-vault: A vault for securely storing and accessing AWS credentials in development envi...

github.com

 

aws-vault 를 설치해봅시다.

# Mac User
brew install aws-vault

# Windows User
choco install aws-vault

# version check
aws-vault --version

aws-vault 를 설치했다면 다음과 같이 Profile 을 추가해줍니다.
Profile 추가 시 Acees Key 와 Secret Key 가 필요합니다.

 

해당 Profile Name 은 .aws/config 의 Profile 과 연동됩니다.

aws-vault add kimalarm

 

이후 명령어를 통해 aws 리소스에 접근할 수 있습니다.

# 실행
aws-vault exec [profile] -- [command]

# 예시
aws-vault exec kimalarm -- aws s3 ls

아래와 같이 명령어가 잘 실행된다면 인증에 성공한 것입니다.

 

명령어 실행 중 다음과 같은 오류가 발생 시 ~/.aws/config 파일 안에 default region을 입력해줍니다.
aws-vault: error: exec: Failed to get credentials for [profile]: operation error STS: GetSessionToken, failed to resolve service endpoint, an AWS region is required, but was not found

 

 

aws-vault 는 OS 의 암호 관리 시스템을 활용하여 인증정보를 관리하며, 짧은 시간 동안 사용할 수 있는 인증정보를 제공합니다.

  • aws-vault 정보는 OS 가 Mac 이라면 macOS Keychain 에 저장 되고, Windows 라면 Windows Credential Manager 에 저장된다.
  • aws-vault 가 인증해주는 임시 토큰의 Access Key & Secret Key 는 사용자의 것과 전혀 다른 것임을 확인할 수 있습니다.

 

테라폼 명령어 또한 aws-vault 와 함께 사용 가능합니다.

 

1.4. IAM Role 을 부여한 CI 서버 활용

네 번째 방법은 서버에 IAM Role 을 부여한 후, 해당 서버로 테라폼 리소스를 배포하는 것입니다.

이 방법의 장점은 다음과 같습니다.

  1. 특정 사용자의 Access Key , Secret Key 를 발급하지 않아도 됨
  2. 영구적인 자격증명이 아닌 임시적인 자격증명

 

만약 로컬 환경에서 직접 테라폼 코드를 배포하지 않고,
Jenkins 등의 도구를 활용한 CI/CD 파이프라인을 사용하여 테라폼 코드를 관리한다면 이 방법이 가장 적합할 수 있습니다.

이번에는 IAM Role 이 부여된 EC2 서버가 어떤 식으로 자격증명을 가져오는 지 확인해보겠습니다.

 

먼저 IAM Role 을 만들어서 EC2 에 부여해줍니다.
이번에는 테스트를 위해 S3FullAccess 권한을 부여한 후 서버에 접속합니다.

 

AWS 의 Metadata 접속 IP 는 169.254.169.254 입니다.
서버 내부에서 다음과 같은 명령어를 입력하여 IAM Role 이 어떻게 권한을 인증하는 지 확인해봅시다.

curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/{IAM-Role-Name}

 

앞서 aws-vault 의 인증방식과 동일하게 만료기간이 있는 임시토큰을 발급해서 권한을 인증해주는 방식인 것을 확인할 수 있습니다.
IAM Role 을 활용하면 aws 설정파일을 생성할 필요가 없으며, 서버에서 컨테이너 사용시 컨테이너에게도 그대로 상속되게 됩니다.

 

이번 포스팅에서는 테라폼을 이용할 때 사용되는 민감정보 중 Provider 인증 관리에 대해서 알아보았습니다.
다음 포스팅에서는 DB 암호 관리에 대해서 알아보겠습니다.

Contents

포스팅 주소를 복사했습니다