web-dev-qa-db-ja.com

Terraform:リモート状態ファイルの資格情報の選択

Terraformに既存のインフラストラクチャがあり、しばらくそれを使用しています。最近、ローカルラップトップのAWS認証情報(~/.aws/credentialsに保存されている認証情報)を交換しましたが、それらの認証情報を再設定するまで機能しなくなりました。

問題は、Terraformソース自体でクレデンシャルを宣言していることですが、それをまったく使用していないようです。

terraform {
  backend "s3" {
    bucket = "example_tf_states"
    key    = "global/vpc/us_east_1/example_state.tfstate"
    encrypt = true
    region     = "us-east-1"
  }
}

provider "aws" {
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
  region = "${var.region}"
}



variable "access_key" {
  default = "<hidden_for_stack_exchange_post>"
}

variable "secret_key" {
  default = "<hidden_for_stack_exchange_post>"
}

variable "region" {
  default = "us-east-1"
}

アクセスIDのアクセス許可は100%良好です。上記のTerraform変数宣言と同じように、aws configureに入る~/.aws/credentials設定に同じアカウントIDと秘密鍵を使用しています。

すべて正常に動作しますクレデンシャルが~/.aws/credentialsにある限り、ただしOSレベルのクレデンシャルがなくなるとすぐに(つまりrm ~/.aws/credentials)Terraform操作を実行しようとすると、次のメッセージが表示されます、terraform planなど:

Failed to load backend:
Error configuring the backend "s3": 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 Provider

Please update the configuration in your Terraform files to fix this error.
If you'd like to update the configuration interactively without storing
the values in your configuration, run "terraform init".

~/.aws/credentialsを実行してaws configureを再設定すると、再び正常に動作します。

理解していません-provider設定がTerraformソースコード内で使用する資格情報を明示的に宣言している場合、なぜOSレベルのAWS構成がまったく重要なのですか?

TerraformにTerraform構成で定義された資格情報のみを使用させ、OSユーザープロファイルの内容を無視するにはどうすればよいですか?

編集、それはTerraform v0.11.7です

編集:静的に宣言されたクレデンシャルがプロバイダー宣言で利用されていない理由に関する問題を解決しようとしていることに注意してください。代替方法や回避策を探していません。ありがとう。

10
emmdee

最初の質問

私のプロバイダー設定がTerraformソースコード内で使用する資格情報を明示的に宣言している場合、なぜOSレベルのAWS構成がまったく重要なのですか?

「バックエンドのロードに失敗しました:バックエンド "s3"の設定中にエラーが発生しました」というエラーメッセージは、バックエンドS3の設定を参照しています。

ファイル./.terraform/terraform.tfstateを見ると、S3バックエンド構成が表示されます。

Terraform S3バックエンドは、Terraform AWSプロバイダーとは異なります。エラーメッセージ「AWSプロバイダーの有効な認証情報ソースが見つかりません。」誤解を招くです。 AWSプロバイダー構成が使用されていることを意味しますが、これは誤りです。 S3バックエンドの認証情報は個別に設定され、terraform.tfstateファイルに保存されます。

ここに記載されているようにS3バックエンドの資格情報が指定されていない場合、OSレベルのAWS構成が重要になります https://www.terraform.io/docs/backends/types/s3.html の場合、Terraformはデフォルトで以下を順番に使用します。

  1. 環境変数AWS_ACCESS_KEY_IDおよびAWS_SECRET_ACCESS_KEY
  2. AWS共有認証情報ファイル。デフォルト値は「〜/ .aws/credentials」です。

S3バックエンド設定で認証情報を指定しなかったため、terraformはデフォルトでAWS共有認証情報ファイルになります。

S3バックエンド構成に認証情報が含まれていません。

terraform {
  backend "s3" {
    bucket = "example_tf_states"
    key    = "global/vpc/us_east_1/example_state.tfstate"
    encrypt = true
    region     = "us-east-1"
  }
}

2番目の質問、

TerraformにTerraform構成で定義された資格情報のみを使用させ、OSユーザープロファイルの内容を無視するにはどうすればよいですか?

まず、バックエンドに補間を含めることはできません。 https://www.terraform.io/docs/backends/config.html を参照してください。そのため、バックエンド構成では変数を使用できません。例えばこの構成は無効です

terraform {
  backend "s3" {
    bucket = "example_tf_states"
    key    = "global/vpc/us_east_1/example_state.tfstate"
    encrypt = true
    region     = "us-east-1"
    access_key = ${var.access_key}
    secret_key = ${var.secret_key}
  }
}

terraform initの実行時にAWS認証情報を指定する場合は、バックエンド構成をオプションとして指定します。

terraform init --backend-config="access_key=your_access_key" --backend-config="secret_key=your_secret_key"

これにより、次のようなS3バックエンド構成が生成され、./.terraform/terraform.tfstateファイルに保存されます。

{
    "version": 3,
    "serial": 1,
    "lineage": "bd737d2d-1181-ed64-db57-467d14d2155a",
    "backend": {
        "type": "s3",
        "config": {
            "access_key": "your_access_key",
            "secret_key": "your_secret_key"
        },
        "hash": 9345827190033900985
    },

ここでも、S3バックエンドの認証情報は、AWSプロバイダーの認証情報とは別に設定されています。

terraform initを再実行し、コマンドラインで--backend-configオプションとして認証情報を指定して、エラーを修正します。

10
Mike Marseglia

発生しているエラーは、特にS3バックエンドの構成に関するものであり、AFAIKはAWSプロバイダー構成から設定を継承しません。それもaccess_keysecret_key構成オプション。使用しない場合は~/.aws/credentials明示的に設定する必要があります。

3
bodgit

次のような~/.aws/credentialsファイルにプロファイルを設定することをお勧めします

[profile1]
aws_access_key_id = xxxx
aws_secret_access_key = xxxxx
region = us-east-1

[profile2]
aws_access_key_id = xxxx
aws_secret_access_key = xxxx
region = us-west-2

次に、プロバイダーで、使用するプロファイルを指定できます

provider "aws" {
  profile = "profile2"
  region = "${var.region}"
}

キーをterraformファイルから除外します。これは、キーをソース管理に入れたい場合に適しています。

1
Mike