Terraform plan にてError: No valid credential となる
概要
- AWS 環境のクレデンシャルを設定したにも関わらず、terraform plan実行時に、Error: No valid credential となりました。
- 以下、エラーメッセージとなります。
- Error: No valid credential sources found for AWS Provider.
Please see https://terraform.io/docs/providers/aws/index.html for more information on
providing credentials for the AWS Provideron setting.tf line 5, in provider “aws":
5: provider “aws" {
- Error: No valid credential sources found for AWS Provider.
- 今回、MFAが導入され、かつ複数アカウントをスイッチロールでアクセスする環境だったため、これまでのクレデンシャルを設定する方法では対応できませんでした。今回の対処方法は、本記事の最後の項目に記載しております。
Terraform でクレデンシャルを設定する (おさらい)
- AWS 環境でTerraform で使用する場合に、クレデンシャルを設定する方法がいくつかあります。
- 私の場合、これまで以下の3パターンが多かったです。
シェル環境変数 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
- すべての環境において、シェルの環境変数に、AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY を渡す方法はシンプルです。
export AWS_ACCESS_KEY_ID=AAAAAAAAAAAAAAAAAAAA
export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export AWS_DEFAULT_REGION=ap-northeast-1
- 上記の場合、tf ファイルに記載するprovider もシンプルになります。
provider "aws" {
region = "ap-northeast-1"
}
- クレデンシャルを設定後は、aws sts get-caller-identity にてアカウント番号を確認しています。
- こちらの方法は、AWS CLI を利用するパターンでも ok ですね。
シェル環境変数 (AWS_PROFILE)
- AWS CLI がインストールされ、クレデンシャルファイル(~/.aws/credentials)に profile を登録しているケースは、シェルの環境変数に、AWS_PROFILE を渡す方法が簡単です。
- なお、AWS_PROFILE より、AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY が優先されるため、ご注意ください。
export AWS_PROFILE=profile-name
- 上記の場合、tf ファイルに記載するprovider もシンプルになります。
provider "aws" {
region = "ap-northeast-1"
}
- クレデンシャルを設定後は、aws sts get-caller-identity にてアカウント番号を確認しています。
- こちらの方法は、AWS CLI を利用するパターンでも ok ですね。
Terraform のtfvars に記載する
- tf ファイルに、access_key, secret_key 変数を定義して、tfvars ファイルに値を記載して渡す方法です。また、var-fileオプション、stateオプションを使用することで環境毎に変数を指定したり、tfstate ファイルを管理できます。
- こちらの方法は、tfvars ファイルにアクセスキー、シークレットアクセスキーを記載するため、git 管理から除外する必要があります。ご注意ください。
- 例:provider.tf
variable "access_key" {}
variable "secret_key" {}
provider "aws" {
region = "ap-northeast-1"
access_key = var.access_key
secret_key = var.secret_key
}
- 例: env1.tfvars
access_key = "AAAAAAAAAAAAAAAAAAAA"
secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- terraform実行時にtfvars ファイルを指定します。
terraform plan --var-file=env1/env1.tfvars
terraform apply --var-file=env1/env1.tfvars
- あるいは、terraform実行時にtfvars ファイル、tfstate ファイルを指定します。
terraform plan --var-file=env1/env1.tfvars --state=env1/env1.tfstate
terraform apply --var-file=env1/env1.tfvars --state=env1/env1.tfstate
MFA + 複数アカウントをスイッチロールする環境にterraform を実行する場合
- 冒頭に記載した通り、今回は、MFAが導入され、かつ複数アカウントをスイッチロールでアクセスする環境だったため、これまでのクレデンシャルを設定する方法では対応できませんでした。
- MFAが導入され、かつ複数アカウントをスイッチロールでアクセスする環境の場合、私は普段こちらにご紹介した aws-mfa を利用してクレデンシャルを設定しています。aws-mfa の場合、profile を利用するため、シェルの環境変数にAWS_PROFILE を渡す方法で対応できると思いましたが、今回は以下エラーとなりました。
- Error: No valid credential sources found for AWS Provider.
Please see https://terraform.io/docs/providers/aws/index.html for more information on
providing credentials for the AWS Provideron setting.tf line 5, in provider “aws":
5: provider “aws" {
- Error: No valid credential sources found for AWS Provider.
- tf ファイルに、aws_shared_credentials_file, aws_profile 変数を定義して、tfvars ファイルに値を記載して渡します。aws_shared_credentials_file にはデフォルトの"~/.aws/credentials"を指定し、aws_profile には設定するprofile名を指定します。
- 例: provider.tf
variable "aws_shared_credentials_file" {
type = string
}
variable "aws_profile" {
type = string
}
variable "aws_region" {
type = string
}
provider "aws" {
shared_credentials_file = var.aws_shared_credentials_file
profile = var.aws_profile
region = var.aws_region
}
- 例: env2.tfvars
aws_shared_credentials_file = "~/.aws/credentials"
aws_profile = "profile-name"
aws_region = "ap-northeast-1"
- terraform実行時にtfvars ファイルを指定します。
terraform plan --var-file=env2/env2.tfvars
terraform apply --var-file=env2/env2.tfvars
- あるいは、terraform実行時にtfvars ファイル、tfstate ファイルを指定します。
terraform plan --var-file=env2/env2.tfvars --state=env2/env2.tfstate
terraform apply --var-file=env2/env2.tfvars --state=env2/env2.tfstate