ECS FargateからIAMロールでAWSリソースにアクセスする


アプリケーションからのAWSの操作はアクセスキーを発行するのではなくIAMロールを使うことが推奨されています。

FargateのアプリケーションからAWSアクセスキーではなくIAMロールでS3等のAWS上のリソースを操作するのにハマりポイントがあったのでメモ。
EC2からのアクセスと同じだと思いこんでいたら違った。

環境

  • ECS Fargate 1.14
  • aws-sdk-php version3

方法

SDK

SDKの使い方はECSでIAMロールを使う場合と同じ。アクセスキーではなくIAMロールを使う場合は'credentials'は記述しない。

$config = [
    'version' => '2017-10-17',
    'region' => 'ap-northeast-1',
];

return new S3Client($config);

タスクロールに必要なポリシーをアタッチ

タスクからS3などのリソースにアクセスするため、タスクロール(タスク実行ロールではない)にポリシーをアタッチ。
今回はS3、Lambda、Route53等権限が必要なリソースが多くあったため個別サービスに対しての権限ではなく"PowerUserAccess"をアタッチ。ここは要件に応じてもっと細かく制御もできる。
ここまではEC2からのIAMロールの利用と同じ。

ハマりどころ

この状態でタスクを実行すると以下のエラーがでた。

2021-06-18 01:52:12 Error: [Aws\Exception\CredentialsException] Error retrieving credentials from the instance profile metadata service. (Client error: `GET http://169.254.169.254/latest/meta-data/iam/security-credentials/` resulted in a `404 Not Found` response:

後から分かったのですが、EC2とFargateのタスクロールでは、AWSの認証情報を取得するエンドポイントが異なるそう。

  • EC2の場合
http://169.254.169.254/latest/meta-data/iam/security-credentials/
  • Fargateの場合
http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI

Fargateの場合は後者に接続しなければならないのが、$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI この環境変数がセットされていなかったためにエラーが出た模様。
こちらのブログを参考に、環境変数追加のためDockerfileに以下の一行を追加。(Bashの場合)

RUN echo 'export $(strings /proc/1/environ | grep AWS_CONTAINER_CREDENTIALS_RELATIVE_URI)' >> /etc/bashrc​

これでタスクを実行するとIAMロールでAWSリソースにアクセスできた。

参考