Terraform cloud から OIDC 経由で AWS の Credentials を取得する
Terraform cloud の文脈でいうと、2023年の1月に「Dynamic Provider Credentials」という機能がリリースされ、特定の Provider に対して動的に Credentials の情報が取得できるようになりました
2023/11現在でサポートされてる Provider は以下になります
- Vault
- AWS
- GCP
- Azure
AWS からの動的な Credentials の取得は、 OIDC (OpenID Connect) 経由での取得になります。
ここでは、設定に必要な手順について簡易的に記載をします。
公式ドキュメント
公式ドキュメントに、一通りの設定手順について記載されています。
ただ、この記事では後述の learn-terraform-dynamic-credentials
をベースに説明していきます。
learn-terraform-dynamic-credentials
Dynamic Provider Credentials の設定については Hashicorp 公式のリポジトリにサンプルの設定集がおいてあります。こちらを倣って設定していくのがおそらく一番楽な手順になると思います。
AWS への設定
OIDC フェデレーション用の IAM の設定を行います。
以下がおおまかな手順になります。
Policy の作成
まず、OIDC 経由で接続してきたユーザーに対して、どのような権限を付与するかを定義します
learn-terraform-dynamic-credentials のサンプルでは、EC2 に対する全般的な権限を付与する、という設定になっています。こちらはその現場で必要な権限を適切に設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": "*"
}
]
}
Role の作成
Role 側では信頼ポリシーの定義を行います。
Terraform cloud 側の provider URL は基本的に https://app.terraform.io
になると思います。
信頼条件については、環境によって設定が変わってくると思います。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "${aws_iam_openid_connect_provider.tfc_provider.arn}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${var.tfc_hostname}:aud": "${one(aws_iam_openid_connect_provider.tfc_provider.client_id_list)}"
},
"StringLike": {
"${var.tfc_hostname}:sub": "organization:${var.tfc_organization_name}:project:${var.tfc_project_name}:workspace:${var.tfc_workspace_name}:run_phase:*"
}
}
}
]
}
learn-terraform-dynamic-credentials でのサンプルは上記の様になっています。
Principal.Federated
には arn:aws:iam::(AccountId):oidc-provider/app.terraform.io
のような値が入ります。
Condition
には、以下の2つの条件が記載されています
"app.terraform.io:aud": "aws.workload.identity"
"app.terraform.io:sub": "organization:(TFC ORG_NAME):project:(TFC PROJECT_NAME):workspace:(TFC WORKSPACE_NAME):run_phase:(TFC RUN_PHASE)"
Audience claim の値は上記の値で固定となると思います。
Subject claim の値は、現場の環境により適切な値を設定していく形になります。
item | value |
---|---|
TFC ORG_NAME | Terraform cloud の organization の名前 |
TFC PROJECT_NAME | Terraform cloud の project の名前 |
TFC WORKSPACE_NAME | Terraform cloud の workspace の名前 |
TFC RUN_PHASE | 権限付与を許可する run phase (plan or apply) の値。terraform plan だけ許可する、という指定が可 |
それぞれの値は、それぞれ固定の値を入れて完全一致で指定することもできますし、 *
を指定してワイルドカード指定をすることもできます。
organization だけ指定し、それ以外についてはすべて許可する、という条件を書く場合は以下のような書き方になります。
"app.terraform.io:sub": "organization:some_org:project:*:workspace:*:run_phase:*"
learn-terraform-dynamic-credentials を用いて設定する場合は、variables.tf に必要な設定をしていけば自動的に各種設定に反映されるようになります。
上記の IAM Role の設定を AWS 側で行えば、AWS 側の準備は完了です。
作成した IAM Role の ARN を Terraform cloud 側の設定で使用するので、控えておきます。
Terraform cloud への設定
AWS 側に作成した IAM Role の情報を、 Terraform cloud の variables に設定をします。
item | value |
---|---|
TFC_AWS_PROVIDER_AUTH | true |
TFC_AWS_RUN_ROLE_ARN | IAM Role の ARN |
上記の値を Variables に設定すれば基本的には OK、です。
見落としがちな大事なハマりポイントとして、 「Dynamic Provider Credentials の設定には Variable Set は使えない(ように見える)」 という点があります。
公式ドキュメントでは variable set も使えると書いてあるのですが、私の環境では何度試してもダメでした。Workspace variables に同じ値を設定すると、問題なく動作しました。
You can set these as workspace variables, or if you’d like to share one AWS role across multiple workspaces, you can use a variable set.
OIDC 関連の設定は複数のプロジェクト/ワークスペースで共有したいので Variable set に指定したくなりますが、このような制約があるため、Variable set に正しい値を設定しても、おそらく正しく動作してくれません。ご注意ください。
逆に、この点だけハマらなければ、AWS の Dynamic Provider Credentials の設定は比較的かんたんに実施できると思います。
※ 2024/03/14 追記
Variable set に設定した値を読んでくれない、と上記では書いていましたが、今日現在、再度試してみると、問題なく参照されるようになっていました。
いつ Fix されたかは調べてません。
ということで、今は、Variable set に設定しても問題なく動作するようになっていると思います。
Discussion