DevOps/Terraform

[Terraform] AWS Provider credential Authentication

background

Terraform을 사용하면서 AWS Provider에서 제공하는 resource, data, modules를 사용하는 중이다. 매번 provider.tf 를 만들어서 다음코드를 통해 provider를 정의한다.

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

초기에는 access_keysecret_key 를 직접할당(Static Credential)한 방법으로 선언해 주었지만, Hard-coded credential은 risk leakage도 있고해서 다른 방법으로 구성했어야 했다.

Authentication Methods

Authentication 방법은 다양하게 있다.

  • static credentials
  • Environment variables
  • Shared credentials / configuration files
  • CodeBuild, ECS, and EKS Roles
  • EC2 Instance Metadata Service (IMDS and IMDSv2)

현재 내가 사용할 수 있는 서비스 관련해서만 설명

Static Credential(직접할당)

access_keysecret_key 를 in-line으로 AWS Provider Block에 직접 hard-coded 한 방법으로 할당하는 것이다.

provider "aws" {
    region = "ap-northeast-2"
    access_key = "my-access-key"
    secret_key = "my-secret-key"
}

Environment Variables(환경변수)

credential 값을 환경변수로 선언하고 불러오는 형식으로 사용할 수 있다. 반복적으로 사용이 가능하고

환경변수로 credential을 할당하는 것은 AWS_SHARED_CREDENTIALS_FILEAWS_PROFILE 을 재정의 하는 것이다.

provider "aws" {}
$ export AWS_ACCESS_KEY_ID="anaccesskey"
$ export AWS_SECRET_ACCESS_KEY="asecretkey"
$ export AWS_DEFAULT_REGION="ap-northeast-2"
$ terraform plan

Shared Credential File

AWS CLI에서 사용하는 구성파일(~/.aws/credentials 혹은 ~/.aws/config) 파일을 특정하여 사용하는 것이다. shared_credentials_file argument를 한다.

  • [Linux, MacOS] : $HOME/.aws/credentials
  • [Windows] : %USERPROFILE%\.aws\credentials
provider "aws" {
    region = "ap-northeast-2"
    shared_credentials_file = "/Users/tf_user/.aws/creds"
    profile = "customprofile"
}

EC2 Instance Metadata Service

Terraform가 EC2 Instance에서 IAM Role을 사용하여 작동중이라면, the metadata API endpoint를 통해 credential를 질의할 수 있다.

 

이는 동작중인 EC2에 credential을 hard coding한 방식으로 증명을 피할 수 있어서 다른 접근 방식보다 선호된다. 대신, 대출 가능성이 있기때문에 Terraform이 즉석에서 임대한다.

 

custom Metadata API endpoint를 AWS_METADATA_URL 변수를 통해 제공한다.

Assume Role

Role ARN을 제공하면 Terraform이 Role을 통해 자격증명을 할 수 있다.

provider "aws" {
    assume_role {
        role_arn = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
        session_name = "SESSION_NAME"
        external_id = "EXTERNAL_ID"
    }
}

Ref