概要
AWS CDKでAPI Gatewayのcloud_watch_role
のIAMロールを明示的に指定して作成しようとすると以下のエラーになりました。
The role ARN does not have required permissions configured. Please grant trust permission for API Gateway and add the required role policy
こちらのエラーの原因と解決方法を紹介します。
前提と原因
前提として、以下のようにAWS CDKでcloud_watch_role=True
にしてdeployすると、
api = apigateway.RestApi(self, "Sample-ApiGateway",
rest_api_name="Sample-ApiGateway",
description="API Gateway for Sample API",
cloud_watch_role=True
)
IAMロールが自動で生成されます。ロールはAWS管理のservice-role/AmazonAPIGatewayPushToCloudWatchLogs
がアタッチされていました。
また、cloud_watch_role=True
としたことで、CloudWatchログには/aws/apigateway/welcome
というロググループの中に「Cloudwatch logs enabled for API Gateway」と書かれたログが確認できました。
ちなみにこれは、cloud_watch_role
を書かずに実行しても生成されたので、デフォルトではTrue
の動きのようでした。
False
にすると、IAMロールの自動生成がなく、また、ログも出ないことを確認しました。
API Gateway のステージでログ記録を有効化し、リクエストやレスポンスの詳細なログを CloudWatch Logs に記録するように設定できるので、IAMロール自体は作成したいのですが、自動生成されるものは名前にスタック名が入っていたりやたら長かったりとわかりづらかったので、明示的に指定したいと思いました。
ということで、以下の状態で実行。
IAMポリシーに、自動生成されたロールと同じ内容のポリシーを付与しています。
api_gateway_role = iam.Role(self, "Sample-ApiGatewayRole",
assumed_by=iam.ServicePrincipal("apigateway.amazonaws.com"),
role_name="Sample-ApiGatewayRole"
)
api_gateway_role.add_to_policy(iam.PolicyStatement(
actions=[
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
resources=["*"]
))
api = apigateway.RestApi(self, "Sample-ApiGateway",
rest_api_name="Sample-ApiGateway",
description="sample-api-gateway",
cloud_watch_role=False, # 自動生成をオフ
deploy=False
)
apigateway.CfnAccount(self, "Sample-ApiGatewayAccount",
cloud_watch_role_arn=api_gateway_role.role_arn
)
これで行けるはず...!
しかしこれで実行すると、上記の「Please grant trust permission...」というエラーになりました。
なぜだ...
解決方法
しばらく試行錯誤したのですが、解決方法がわからず...
作成されるリソースの依存関係の問題かな?と思い、IAMロール作成とアタッチを分けてデプロイしてみましたが、やはり同じエラーになりました。
しかし、以下で実行するとエラーが出ずに無事に生成されました。
api_gateway_role = iam.Role(self, "Sample-ApiGatewayRole",
assumed_by=iam.ServicePrincipal("apigateway.amazonaws.com"),
role_name="Sample-ApiGatewayRole"
)
api_gateway_role.add_managed_policy(
iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AmazonAPIGatewayPushToCloudWatchLogs")
)
api = apigateway.RestApi(self, "Sample-ApiGateway",
rest_api_name="Sample-ApiGateway",
description="sample-api-gateway",
cloud_watch_role=False, # 自動生成をオフ
deploy=False
)
apigateway.CfnAccount(self, "Sample-ApiGatewayAccount",
cloud_watch_role_arn=api_gateway_role.role_arn
)
上記の方法は、add_managed_policy
でservice-role/AmazonAPIGatewayPushToCloudWatchLogs
を指定しています。
違いはそこだけでした。
どうしてAWS管理のservice-role
なら成功したのかはよくわかりませんでしたが、エラーは出なくなりましたのでよかった。
理由がわかる方いらっしゃったらぜひ教えてください。