Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 8051

AWS CDK で Amazon API Gateway の「CloudWatch ログのロール ARN」を設定する - kakakakakku blog

$
0
0

Amazon API Gateway でアクセスログを有効化してデプロイしようとすると CloudWatch Logs role ARN must be set in account settings to enable loggingというエラーが出る場合がある😇もしかしたら Amazon API Gateway の設定「CloudWatch ログのロール ARN (CloudWatch log role ARN)」が不足している可能性がある.

「CloudWatch ログのロール ARN」は Amazon API Gateway の API 単位の設定ではなく「アカウント/リージョン」単位の設定で,少し珍しいと思う.もしマルチアカウント戦略を採用できてなく,複数のプロダクトで同じアカウントを共有していたりすると,管理が面倒になることもあると思う😇

AWS CDK でエラーに対処する

選択肢 1: aws_apigateway.RestApi

まず aws_apigateway.RestApiには cloudWatchRoleという設定があって(デフォルトは false),trueにすると自動的に IAM Role を追加して Amazon API Gateway に設定してくれる👌以下にサンプルコードを載せておく.

docs.aws.amazon.com

しかし後述する理由で使わない方が良いと思う💨

import{
    Stack,
    StackProps,
    aws_apigateway,
    aws_logs,
}from'aws-cdk-lib'import{ Construct }from'constructs'exportclass ApiGatewayCloudWatchRoleStack extends Stack {constructor(scope:Construct, id:string, props?:StackProps) {super(scope, id, props)

        const apiAccessLogGroup = new aws_logs.LogGroup(this, 'ApiGatewayAccessLogGroup', {logGroupName: 'sandbox-api-gateway-access-logs',
            retention: aws_logs.RetentionDays.ONE_MONTH,
        })

        const api = new aws_apigateway.RestApi(this, 'ApiGateway', {restApiName: 'sandbox-api-gateway-cloudwatch-role',
            deployOptions: {accessLogDestination: new aws_apigateway.LogGroupLogDestination(apiAccessLogGroup),
                accessLogFormat: aws_apigateway.AccessLogFormat.jsonWithStandardFields(),
            },
            cloudWatchRole: true,
        })
        api.root.addMethod('GET', new aws_apigateway.HttpIntegration('https://dog.ceo/api/breeds/image/random'))
    }}

実際にデプロイすると arn:aws:iam::000000000000:role/ApiGatewayCloudWatchRoleS-ApiGatewayCloudWatchRoleA-nA8OCNOvnkCSという IAM Role が設定されていた💡

もし cloudWatchRoleを設定した Amazon API Gateway を2つ以上デプロイする場合に IAM Role が上書きされてしまうという課題がある.

import{
    Stack,
    StackProps,
    aws_apigateway,
    aws_logs,
}from'aws-cdk-lib'import{ Construct }from'constructs'exportclass ApiGatewayCloudWatchRoleStack extends Stack {constructor(scope:Construct, id:string, props?:StackProps) {super(scope, id, props)

        const apiAccessLogGroup = new aws_logs.LogGroup(this, 'ApiGatewayAccessLogGroup', {logGroupName: 'sandbox-api-gateway-access-logs',
            retention: aws_logs.RetentionDays.ONE_MONTH,
        })

        const api = new aws_apigateway.RestApi(this, 'ApiGateway', {restApiName: 'sandbox-api-gateway-cloudwatch-role',
            deployOptions: {accessLogDestination: new aws_apigateway.LogGroupLogDestination(apiAccessLogGroup),
                accessLogFormat: aws_apigateway.AccessLogFormat.jsonWithStandardFields(),
            },
            cloudWatchRole: true,
        })
        api.root.addMethod('GET', new aws_apigateway.HttpIntegration('https://dog.ceo/api/breeds/image/random'))

        const api2 = new aws_apigateway.RestApi(this, 'ApiGateway2', {restApiName: 'sandbox-api-gateway-cloudwatch-role2',
            deployOptions: {accessLogDestination: new aws_apigateway.LogGroupLogDestination(apiAccessLogGroup),
                accessLogFormat: aws_apigateway.AccessLogFormat.jsonWithStandardFields(),
            },
            cloudWatchRole: true,
        })
        api2.root.addMethod('GET', new aws_apigateway.HttpIntegration('https://dog.ceo/api/breeds/image/random'))
    }}

実際にデプロイすると arn:aws:iam::000000000000:role/ApiGatewayCloudWatchRoleS-ApiGateway2CloudWatchRole-gT1C2Om2Nr4Yという IAM Role に上書きされていた😇 AWS CDK でリソースを管理しているのにデプロイするリソースの順番によって「CloudWatch ログのロール ARN」の値が変わってしまうのは微妙だと思う.

選択肢 2: aws_apigateway.CfnAccount

そこで aws_apigateway.CfnAccountを使うと「CloudWatch ログのロール ARN」を独立したリソースとして管理できる❗️ドキュメントには以下のように書いてあった.できれば AWS CDK Stack も別にしておくと良いと思う👌

To avoid overwriting other roles, you should only have one AWS::ApiGateway::Account resource per region per account.

docs.aws.amazon.com

以下のように aws_iam.Roleaws_apigateway.CfnAccountを組み合わせて実装できる.

import{
    Duration,
    Stack,
    StackProps,
    aws_apigateway,
    aws_iam,
}from'aws-cdk-lib'import{ Construct }from'constructs'exportclass ApiGatewayAccountStack extends Stack {constructor(scope:Construct, id:string, props?:StackProps) {super(scope, id, props)

        const role = new aws_iam.Role(this, 'ApiGatewayLogsRole', {roleName: 'api-gateway-logs-role',
            assumedBy: new aws_iam.ServicePrincipal('apigateway.amazonaws.com'),
            managedPolicies: [
                aws_iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonAPIGatewayPushToCloudWatchLogs'),
            ],
            maxSessionDuration: Duration.hours(1),
        })

        new aws_apigateway.CfnAccount(this, 'ApiGatewayAccount', {cloudWatchRoleArn: role.roleArn,
        })
    }}

実際にデプロイすると arn:aws:iam::000000000000:role/api-gateway-logs-roleという指定した IAM Role を設定できていた👏

関連ドキュメント

docs.aws.amazon.com


Viewing all articles
Browse latest Browse all 8051

Trending Articles