13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

IAM Roles for Service Accountsの認証情報をAWS SDKで利用する方法

Last updated at Posted at 2019-11-04

はじめに

最近EKSでは「IAM Roles for Service Accounts」が正式にサポートされ、EKSクラスターでこの設定をONにしてPodベースでのIAM roleの割り当てが可能になりました。
kube2iamなどを使ったノード(EC2)ベースのロール割り当ての場合は、AWS SDKが良しなに認証情報を読み込んでくれますが、2019/11/01現在のAWS SDK for Java(ver2)ではPodに割り当てられた認証情報をそのままのコードで読み取ることができませんでした。
その時の対応を含めて、AWS SDKでの認証情報の使用方法をまとめます。

IAM Roles for Service Accountsとは

その名の通り、KubernetesリソースであるService AccountにIAM Roleを割り当てる仕組みです。
Kubernetes 1.3以降を実行するEKSクラスターで有効にすることができます。

AWSのブログ記事がとても分かりやすいので、そちらを参照していただければと思います。

この機能を有効化したEKSクラスターはOpenID Connectの認可サーバーのエンドポイントが発行され、Pod及びAWS SDKはこの認可サーバーにトークンを検証してもらいIAM Roleの割り当てを受けます。

image.png

Podに割り当てられる情報

(具体的な記述方法については省略しますが、)アノテーションを利用してIAM Roles for Service Accountsを使用したPodには、以下の情報が割り当てられます。
kubectl describe pods 等で確認できると思います。

  • 環境変数 AWS_ROLE_ARN
    • arn:aws:iam::000000000000:role/xxxxxxxxx-role
  • 環境変数 AWS_WEB_IDENTITY_TOKEN_FILE
    • /var/run/secrets/eks.amazonaws.com/serviceaccount/token
  • OIDC用のサービスアカウントファイルのボリュームマウント
    • /var/run/secrets/eks.amazonaws.com/serviceaccount

これらの情報を使いEKSクラスターのOIDCエンドポイントからroleの認証情報の引き受けをAWS SDKは行う必要があります。

AWS SDK for Java(ver2)

上述したOIDCエンドポイントから認証情報を取得する実装は、古いAWS SDKではサポートされておらず、対応しているバージョンまで引き上げる必要があります。
公式のドキュメントを参照するとAWS SDK for Java(ver2)は2.7.36以上が必要であるようなのでバージョンを上げます。

build.gradle.kts
- val awsSdkVersion = "2.7.23"
+ val awsSdkVersion = "2.10.4"

dependencies {
    implementation(platform("software.amazon.awssdk:bom:$awsSdkVersion"))
    implementation("software.amazon.awssdk:s3")
}

WebIdentityTokenFileCredentialsProviderというクラスがIAM Roles for Service Accountでの認証方式のProviderのようです。
環境変数 AWS_ROLE_ARNAWS_WEB_IDENTITY_TOKEN_FILE 、またそれに対応するJavaのシステムプロパティを読んで処理をしているみたいです。

ドキュメントを参照する限り対応はこれだけで良いのかと思ったのですが、以下の二点の対応をしないと動作しませんでした。

Security Token Serviceモジュールの追加

AWS SDKがIAM Roleを引き受けるときに、Security Token Serviceの実装が必要になります。

build.gradle.kts
val awsSdkVersion = "2.10.4"

dependencies {
    implementation(platform("software.amazon.awssdk:bom:$awsSdkVersion"))
    implementation("software.amazon.awssdk:s3")
+   implementation("software.amazon.awssdk:sts")
}

実装を見てみるとわかりますが、 Class.forName() しているので、モジュールが不足していてもコンパイルエラーにはならず実行時エラーになる点に注意が必要です。
https://github.com/aws/aws-sdk-java-v2/blob/f3265c681e68dbbadca9d8794617a067dda9959d/core/auth/src/main/java/software/amazon/awssdk/auth/credentials/internal/WebIdentityCredentialsUtils.java#L43-L55

credentialsProviderの明示的な指定

Issueにも挙がっていますが、2019/11/01現在の最新バージョン( 2.10.4 )でも、デフォルトの認証情報プロバイダチェーンに上述のWebIdentityTokenFileCredentialsProviderは含まれておらず、Service AccountのIAM roleを引き受けるには明示的にcredentialsProviderを指定する必要があります。
(Issueをぱっと見た感じAWS SDK for Java(ver2)以外でもこの問題はあるようです)

modules.kt
single {
    S3AsyncClient.builder()
+       .credentialsProvider(WebIdentityTokenFileCredentialsProvider.create())
        .endpointOverride(URI(s3Config.endpoint))
        .region(Region.of(s3Config.region))
        .build()
}

ローカル環境

credentialsProviderを明示的に指定した場合デフォルトの認証情報取得の処理は行われないため、ローカル環境での処理が動かなくなってしまいました。
仕方がないのでとりあえず以下の形で対応しました。
時間があればこの辺りを読んでPRでも出せたら良いな、と思っています。

modules.kt
single {
    if (!System.getenv("AWS_ROLE_ARN").isNullOrEmpty()) {
        S3AsyncClient.builder()
            .credentialsProvider(WebIdentityTokenFileCredentialsProvider.create())
            .endpointOverride(URI(s3Config.endpoint))
            .region(Region.of(s3Config.region))
            .build()
    } else {
        S3AsyncClient.builder()
            .endpointOverride(URI(s3Config.endpoint))
            .region(Region.of(s3Config.region))
            .build()
    }
}

まとめ

  • AWS SDK for Java(ver2)では2019/11/01現在最新バージョンに上げるだけではIAM Roles for Service Accountsの認証情報を引き受けることができない
    • stsの依存の追加と、credentialsProviderの明示的な指定が必要
    • 他のSDKでも同様の実装になっているかもしれない(未確認)
  • デフォルトの認証情報プロバイダチェーンへの追加は、Issueにもあるので今後対応されると思われる

参考

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?