terraformでAWS Providerを使用されている方は多いのではないでしょうか?
こちらの記事では、AWS Providerを使用する際に、認証情報の設定方法の選択肢について概要をまとめています。
認証情報の取り扱いは一歩間違えると、重大なインシデントに繋がりかねないため、重要な設計観点となるかと思います。
本記事がみなさんの安全なterraform×AWSの利用に貢献できれば幸いです。
基本的には公式ドキュメントの情報をかいつまんで説明しつつ、また追記もしつつ、書いたものになります。
説明に誤っている部分などあれば編集リクエストなどいただけると嬉しいです。
設定方法
1. 認証情報のハードコーディング
AWS providerのブロックに直接記載する方法です。
下記の要領で設定を行います。
provider "aws" {
region = "us-west-2"
access_key = "my-access-key"
secret_key = "my-secret-key"
}
ただし、上記のような認証情報自体のハードコーディングは非推奨です。
公開されたバージョン管理システムにコミットしてしまうと、認証情報の流出に繋がり、ひいてはAWSリソースの不正利用を招いてしまいます。
2. 環境変数での設定
AWS CLIを普段から使用している方からすると馴染みがあるかと思いますが、環境変数のAWS_ACCESS_KEY_ID
とAWS_SECRET_ACCESS_KEY
を使用して認証情報を設定することも可能です。
3. 共有認証情報ファイルの使用
共有認証情報ファイルというのは、AWSのクレデンシャル情報を記載したファイルのことです。aws cliにてaws configure
を実施した際に作成されるファイルですね。
Linux、macOS、またはUnixの場合、デフォルトでは~/.aws/credentials
に作成されます。
共有認証情報ファイルは下記のような構成になっています。
複数の認証情報がプロファイルとして管理されています。
[default]
aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
[another]
aws_access_key_id = YOUR_ANOTHER_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_ANOTHER_AWS_SECRET_ACCESS_KEY
この方法で設定する場合は、共有認証情報ファイルのパスと、使用するプロファイル名をterraformに設定する必要があります。その方法は更に2つに分かれます。
1つは環境変数で指定する方法です。それぞれ、AWS_SHARED_CREDENTIALS_FILEとAWS_PROFILEで設定します。
もう1つはAWS Providerブロックにコーディングする方法です。下記のような形で設定することができます。
provider "aws" {
region = "us-west-2"
shared_credentials_file = "/Users/tf_user/.aws/creds"
profile = "customprofile"
}
なお、profileを指定しなかった場合は、defaultプロファイルの認証情報が使用されます。
4. IAMロールの使用(CodeBuild, ECS, EKS)
CodeBuild, ECSでterraformを実行する場合、それらのサービス側で実行環境であるコンテナにアタッチするIAM Task Roleを使用した認証を行うことが可能です。
EKSのPodでterraformを実行する場合は、IAM Roles for Service Accounts (IRSA)を設定し、Podに設定したIAMロールを使用して認証することが可能です。
5. EC2 Instance Metadata Service (IMDS and IMDSv2)
EC2インスタンスでterraformを実行する場合、IAMロールをアタッチしていると、EC2インスタンスメタデータから該当ロールの認証情報が取得できます。
注意点
上記方法で設定されるクレデンシャルのうち、1.及び3.のように、AWS Providerブロックで直接コードで設定を施すタイプのものについては1点注意が必要です。それは、設定した認証情報が、terraformのstateファイルを管理するバックエンドのs3にアクセスする際には自動で使用されないという点です。それらの設定は別物の扱いとなります。
よって、別途backend側のブロックでもコーディングが必要となります(ただ、こちらについても認証情報自体のハードコーディングは非推奨です)。
- 認証情報のハードコーディングの場合
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
access_key = "my-access-key"
secret_key = "my-secret-key"
}
}
- 共有認証情報ファイルの使用
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
shared_credentials_file = "/Users/tf_user/.aws/creds"
profile = "customprofile"
}
}
参考