APIが先か? CloudWatch Logsのロールが先か?

2023-07-14

thumbnail

CloudWatch LogsのロールがないためにAPI Gatewayのデプロイに失敗したことはありませんか? このブログ投稿ではその解決方法を紹介します。

背景

AWS CloudFormation (CloudFormation)のスタックをデプロイする際に、次のようなエラーに遭遇したことはないですか?

Resource handler returned message: "CloudWatch Logs role ARN must be set in acc
ount settings to enable logging (Service: ApiGateway, Status Code: 400, Request
ID: 00000000-0000-0000-0000-000000000000)" (RequestToken: 00000000-0000-0000-00
00-000000000000, HandlerErrorCode: InvalidRequest)

このエラーの原因は単純(なはず)で、Amazon API Gateway (API Gateway)用のAmazon CloudWatch Logs (CloudWatch Logs)ロールを設定していないからです。 ということで解決方法も単純で、CloudWatch LogsロールをAPI Gatewayに設定するだけです。以上!

ところが、アカウントにAPI GatewayのAPIをまだ一度もデプロイしたことがない場合は単純には解決しません。 API Gatewayのコンソールは、少なくともひとつ以上のAPIをデプロイしない限りCloudWatch Logsのロールを設定するページを表示してくれないのです。

解決方法

考えられる解決方法は:

  1. API Gatewayのコンソールを介する方法: ログを無効にしてAPIをデプロイした後、API GatewayのコンソールでCloudWatch Logsのロールを設定。 それからログを有効にしてAPIを再デプロイする。
  2. AWS CLIを介する方法: CloudWatch LogsのロールをAWS CLIを介して設定。 それからログを有効にしてAPIをデプロイする。
  3. CDK*を介する方法: CDKでRestApiを設定する際にcloudWatchRoleプロパティを有効にする。 お勧めしません

次の節で、2番目の方法を紹介します。 節「なぜcloudWatchRoleを有効化すべきでないか?」では、なぜcloudWatchRoleを有効化すべきでないかについても解説します。

* CDK: AWS Cloud Development Kit

AWS CLIを介してCloudWatch Logsロールを設定する

API Gateway用のCloudWatch Logsロールを設定するのに使うAWS CLIのコマンドはどれでしょうか? 残念なことに、AWSのドキュメント [1]はAWS CLIを介して設定する方法をなぜか紹介していません。 実は apigateway update-accountがそのコマンド [2]なのですが、 分かりにくくないですか? それはさておき、コマンドのサンプルではまさにCloudWatch Logsのロールを設定する方法を紹介しています。

aws apigateway update-account --patch-operations op='replace',path='/cloudwatchRoleArn',value='arn:aws:iam::123412341234:role/APIGatewayToCloudWatchLogs'

IAMロールを作成する方法はこの投稿の範囲外ですが、補足で紹介します。

なぜcloudWatchRoleを有効化すべきでないか?

cloudWatchRoleオプションを使うとお手軽な気がしますが、将来的に分かりにくいエラーが起きる可能性があります。

問題が起こる可能性があるのはCDK (CloudFormation)スタックを削除したときです。 スタックを削除すると、そのスタックが確保したCloudWatch Logsのロールも同時に削除されます。 CloudWatch Logsロールはアカウントレベルの設定なので、アカウント内の他のすべてのAPIが存在しないロールのせいでクラッシュし始めます

まとめ

この投稿では、以下を紹介しました。

補足

API Gatewayのログ用のIAMロールを作成する

以下のステップで、AWS CLIを使ってAPI Gatewayのログ用のIAMロールを作成・設定できます。

  1. apigateway.amazonaws.comが引き受ける(assume)ことのできるIAMロールを作成

    aws iam create-role \
        --role-name APIGatewayToCloudWatchLogs \
        --description 'API Gateway logging role' \
        --assume-role-policy-document '{
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "",
              "Effect": "Allow",
              "Principal": {
                "Service": "apigateway.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        }'
    
  2. ステップ1で作成したIAMロールにAWSのマネージドポリシーAmazonAPIGatewayPushToCloudWatchLogsを追加

    aws iam attach-role-policy --role-name APIGatewayToCloudWatchLogs --policy-arn arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
    

参考

  1. Setting up CloudWatch logging for a REST API in API Gateway - Amazon API Gateway Developer Guide
  2. apigateway update-account - AWS CLI Command Reference