やりたいこと
ECS TaskからLambdaを呼び出したい。
ECSとそれに付与するIAMロールはCloudFormationで定義しているが、IAMロールが正しいところに対して設定できていないとエラーが発生する。
エラーの例
message:Unable to locate credentials
環境
- 起動タイプ
- Fargate
- OS
- linux(alpine)
書き方
詳細については後述
AWSTemplateFormatVersion: 2010-09-09
Resources:
TaskRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ecs-tasks.amazonaws.com
Action:
- sts:AssumeRole
RoleName: TaskRoleNameHoge
RolePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: TaskRolePolicyNameHoge
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: Hoge
Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- <実行したいLambdaのArn>
Roles:
- TaskRoleNameHoge
TaskDefinition:
ExecutionRoleArn: ecsTaskExecutionRole
TaskRoleArn : !Ref TaskRole
<その他TaskDefinition省略>
ExecutionRoleとTaskRoleとTargetRoleの違い
TaskDefinitionの中でRoleを指定するところは
- ExecutionRoleArn
- TaskRoleArn
がある。
さらにECSタスクにスケジュール設定する場合は
- Targets: RoleArn
もある。
このどこにLambda実行ポリシーをつければいいかわかっていなかったためにかなり迷走したので本記事を書いた。
(まず前提として このあたり が混乱していたのも迷走の一因)
結論としては上記のsampleに書いた通り、TaskRoleArnに指定すれば良い。
それはそれとしてExecutionRoleとTaskRoleとTargetsRoleはどう違うのか。
ExecutionRole
Amazon ECSコンテナエージェント、あるいはFargateエージェントにAWS APIの呼び出しを代行する権限を付与するタスク実行ロール。
目的やサービスごとに複数のタスク実行ロールを持つことができる。
Fargateを利用しているのであれば、主にコンテナイメージをプルし、コンテナログを Amazon CloudWatch に出力する権限が付与されていれば良い。
ECSコンソール初回実行に ecsTaskExecutionRole
というRoleが自動生成されるので、基本のpolicyとなる AmazonECSTaskExecutionRolePolicy
などを必要に応じてアタッチして使うと良い。
また このようにECSへSSMから機密情報を受け渡す 場合には、ここにssmへの権限もアタッチしておく必要がある。
コンテナインスタンス上で実行されているコンテナは、コンテナインスタンスプロファイルに供給された資格情報にアクセスすることはできないため、ここは最小限の権限にとどめたほうが良い。
参考:開発者ガイド Amazon ECS タスク実行 IAM ロール
TaskRole
ECSタスクの実体となるコンテナに AWS API を呼び出す許可を与えるIAMロールのARN。
AWSのクレデンシャルを作成してコンテナに配布したり、EC2インスタンスのロールを使用する代わりに、ECSのタスク定義やRunTask APIの操作にIAMロールを関連付けることができる。
このロールを使ってタスクのコンテナ内のアプリケーションは、AWS SDKやCLIを使用して、認可されたAWSサービスへのAPIリクエストを行うことができる。
だから今回の「ECS TaskからLambdaを呼び出したい」のためには、ここにLambda実行権限を付与すれば良い。
AWS::Events::Rule Targets配下のRole
ルールがトリガーされたときに、そのターゲットに使用されるIAMロールのARN。
1つのルールが複数のターゲットをトリガーする場合、ターゲットごとに異なるIAMロールを使用することができる。
別のアカウントのイベントバスをターゲットとして設定していて、そのアカウントがアカウントIDによって直接ではなく組織を介してアカウントに権限を付与している場合は、このパラメータで適切な権限を持つRoleArnをここに指定する必要がある。
参考:ユーザーガイド AWS::Events::Rule Target