アプリケーションからの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リソースにアクセスできた。