AWSアカウント間のIAMロールを使用したアクセスの委任をしているときのクレデンシャル設定

AWS CLI上のお話

本番環境と開発環境でAWSアカウントを分けることがある。

で、以下のような感じでsts:AssumeRoleを使って開発環境のIAMユーザのまま本番環境のIAMロールで振る舞えるようにすることがある(あまりサクサク切り替えられるとAWSアカウントを分けた意味がないので実際には色々と調整)。

チュートリアル: AWS アカウント間の IAM ロールを使用したアクセスの委任
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html

このときに手元のPCからAWS CLIのコマンドを開発環境用と本番環境用で呼び分けたいと思ったのでそのときのメモ(defaultはまた別のアカウント用なので気にしない)。
まあ実際にはAWS CLIコマンドではなくterraformの適用先の切り替えをしたくてやっているのですが(resourceのproviderが変数を受け付けてくれないのでmoduleと併用だといろいろ厳しい)。

~/.aws/credentials

[default]
aws_access_key_id=xxx
aws_secret_access_key=xxx

[development]
aws_access_key_id=yyy
aws_secret_access_key=yyy

~/.aws/config

[default]
region=ap-northeast-1

[profile development]
region=ap-northeast-1

[profile production]
source_profile=development
role_arn=arn:aws:iam::xxx:role/role-xxx
region=ap-northeast-1

これで以下のように切り替えて使うことができる。めでたし。

aws ec2 describe-instances --profile development
aws ec2 describe-instances --profile production

terraform上のお話

なお、現時点のterraform(0.6.16)ではproviderを複数指定できるものの、resourceのproviderには変数が使えないため、provider汎用のmoduleを作って呼び元で指定しわけるということができない。
同じようなresourceでproviderをハードコードしたのを複数作らないとダメかなぁ。tjたんも「しかたないのでコピペしてる」って言ってるし。
https://github.com/hashicorp/terraform/issues/1819

追記01:

結局、ハードコードしてもproviderのaliasがmoduleに伝わらないことが分かったのでダミーのproviderをトップに置きつつ(「No valid credential sources found for AWS Provider.」って怒られるので)、実際にはaws_workaround.tfなるものを各moduleの中に入れた。うーん。

aws_workaround.tf

# TODO:
# 本当はprovider汎用のmoduleにproviderのaliasを渡してハンドリングしたいが
# terraform 0.6.16ではresourceのproviderに変数が使えず動的に変えられない。
# https://github.com/hashicorp/terraform/issues/1819
# かつ、そもそもmoduleにaliasしたproviderが伝達されない。
# https://github.com/hashicorp/terraform/issues/4789
# 仕方ないのでproviderを個々のmoduleで定義しているがいつ使えなくなるのか分からないので注意。

variable "profile" { }
variable "region" { }

provider "aws" {
  profile = "${var.profile}"
  region = "${var.region}"
}
追記02:

トップのが効いてダメそうだ。うーん。
とりあえず横断的にやるのは諦めて、
env/development/main.tf
env/production/main.tf
module/xxx/main.tf
module/yyy/main.tf
的にやって各envの中(provider定義こみ)でコマンド発行する方向にした。

ただ、今度はterraform remote configでS3にアクセスする際にassume roleが効かないというのが……。
https://github.com/hashicorp/terraform/issues/7014

以下の感じだとそもそもaws-sdk-go自体が対応していないのかな。
https://github.com/aws/aws-sdk-go/issues/472