AWS CDK で同一リージョンに複数 API Gateway を定義した場合にIAMロールが上書きされる問題と対処法

AWS CDK で同一リージョンに複数 API Gateway を定義した場合にIAMロールが上書きされる問題と対処法

Clock Icon2025.07.07

こんにちは。リテールアプリ共創部のきんじょーです。

担当している案件で AWS CDK の書き方によって 意図せぬ CloudFormation のドリフトが発生してしまう問題に遭遇したため、原因と解消法をご紹介します。

AWS::ApiGateway::Account リソースとは

CloudFormation のAWS::ApiGateway::Accountは Amazon API Gateway が API のログを CloudWatch Logs へのログ出力で使用する IAM ロールを作成するリソースです。

この設定は Amazon API Gateway 全体で 1 つとなっており、リージョン単位での設定です。
CloudFormation で同一リージョンに複数のAWS::ApiGateway::Accountを定義した場合、最後にデプロイされるスタックの設定が反映され、それ以前の定義は上書きされます。

公式ドキュメントでも以下の記載がされています。

この AWS::ApiGateway::Account リソースは、Amazon API Gateway が API ログを Amazon CloudWatch Logs に書き込むために使用する IAM ロールを指定します。他のロールを上書きしないようにするため、AWS::ApiGateway::Account アカウントごとにリージョンごとにリソースを 1 つだけ指定してください。

https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-account.html

AWS コンソール上では以下で確認できます。

api-gateway-account-role.png

AWS CDK で Amazon API Gateway を定義する際の注意点

AWS CDK でapigateway.RestApiコンストラクトを利用する際にAWS::ApiGateway::Accountが作成されるコードは以下です。

https://github.com/aws/aws-cdk/blob/8a77828ab14f635953af27a1b00174d988e85303/packages/aws-cdk-lib/aws-apigateway/lib/restapi.ts#L633-L664

IAMロールの作成はapigateway.RestApiコンストラクトのcloudWatchRoleオプションで制御可能です。
この時、API Gateway のロール作成に関するフィーチャーフラグを設定していない場合、デフォルトで API Gateway 毎にIAM ロールとAWS::ApiGateway::Accountリソースが作成されます。

1 つのリージョンで複数の API Gateway を定義する場合、前述の通りデプロイされるスタック順によってAWS::ApiGateway::Accountリソースが上書きされてしまい、意図せぬドリフトが発生してしまいます。
また、最後にデプロイされた API Gateway のリソースが何らかの理由で削除された場合、API Gateway 全体に設定されたロールがなくなってしまうため、その他の API についても CloudWatch Logs にログが出力できなくなる点にも注意が必要です。

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_apigateway.RestApi.html#cloudwatchrole

API Gateway に設定される IAM ロールの上書きを防ぐ方法

apigateway.RestApicloudWatchRoleオプションを false で設定して、各 API Gateway で IAM ロールとAWS::ApiGateway::Accountリソースが作成されないようにします。

new apigateway.RestApi(this, "ApiGateway", {
  cloudWatchRole: false,
});

IAM ロールとAWS::ApiGateway::Accountリソースを手動で作成しましょう。

// IAMロールはリージョンにつき1つだけ定義します
const apiGatewayAccountRole = new aws_iam.Role(scope, "logs-role", {
  assumedBy: new aws_iam.ServicePrincipal("apigateway.amazonaws.com"),
  managedPolicies: [
    aws_iam.ManagedPolicy.fromAwsManagedPolicyName(
      "service-role/AmazonAPIGatewayPushToCloudWatchLogs"
    ),
  ],
});

const apiGatewayAccount = new cfn.CfnAccount(this, "ApiGatewayAccount", {
  roleArn: apiGatewayAccountRole.roleArn,
});

フィーチャーフラグによるロール上書きの制御

この問題を解消するためにAWS::ApiGateway::Accountリソースを作成する機能を無効化するフィーチャーフラグが追加されています。

https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md#aws-cdkaws-apigatewaydisablecloudwatchrole

このフラグを有効にすると、手動で CloudWatch Logs 書き込み用の IAM Role とAWS::ApiGateway::Accountリソースを作成する必要がありますが、意図しないドリフトや API Gateway リソース削除時の IAM ロールの消失を防ぐことができます。

AWS CDK v2.38.0 から推奨設定となっているため、これより古いバージョンのAWS CDKを利用している場合は、この問題が発生していないか確認してみてはいかがでしょうか?

最後に

本日はクラスメソッド創立記念日なので案件でハマった小ネタをご紹介しました。

この記事が誰かの役に立つと幸いです。
以上。リテールアプリ共創部のきんじょーでした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.