All Articles

Setting up API Gateway CloudWatch Logging for your AWS Account

API Gateway offers support for logging endpoint access to CloudWatch Logs, but setting it up is a bit of pain.

You need to manually create a role, attach a policy, and then configure the role for API Gateway in each region. Thankfully, once you have configured it in a region, it doesn’t need to be applied again.

You will know it isn’t set up if you have ever enabled the DataTraceEnabled flag on your API Gateway Stage, then got an error like this:

CloudWatch Logs role ARN must be set in account settings to enable logging (Service: AmazonApiGatewayV2; Status Code: 400; Error Code: BadRequestException; Request ID: 8aa70bda-0a41-4ce1-9fcd-897277171149; Proxy: null)

AWS provides instructions for setting it up using the AWS Console, but we can automate the process using the CLI.

Instructions

This script has been tested to work on Linux. It should work on MacOS X or Windows (with WSL) as it is fairly generic, but this hasn’t been verified.

  1. Make sure you have the latest AWS CLI installed and configured for your AWS Account
  2. Create a new file called 'setup-apigateway-cloudwatch-role.sh' and copy and paste the following:

    #!/bin/sh
    export AWS_PAGER=
    ACCOUNT_ID=$(aws sts get-caller-identity --output text --query "Account")
    echo "Creating role in account: ${ACCOUNT_ID}"
    
    aws iam create-role --role-name APIGatewayCloudWatchLogsRole \
      --assume-role-policy-document '{"Statement": {"Effect": "Allow", "Principal": {"Service": "apigateway.amazonaws.com"}, "Action": "sts:AssumeRole"}}' --output text
    ROLE_NAME="arn:aws:iam::${ACCOUNT_ID}:role/APIGatewayCloudWatchLogsRole"
    echo "Attaching policy to role ${ROLE_NAME}"
    aws iam attach-role-policy \
      --role-name APIGatewayCloudWatchLogsRole \
      --policy-arn arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs \
      --no-paginate
    
    REGIONS=$(aws ec2 describe-regions --output text --query "Regions[*].RegionName")
    for region in $REGIONS
    do
      echo Setting CloudWatchRoleARN in region ${region}
      aws apigateway update-account --region ${region} \
        --patch-operations op='replace',path='/cloudwatchRoleArn',value="arn:aws:iam::${ACCOUNT_ID}:role/APIGatewayCloudWatchLogsRole" \
        --output text --no-paginate
    done
  3. Run chmod u+x setup-apigateway-cloudwatch-role.sh to set execute permissions on the script
  4. Execute it with ./setup-apigateway-cloudwatch-role.sh

The script will:

  1. Create a role called APIGatewayCloudWatchLogsRole
  2. Attach the managed policy AmazonAPIGatewayPushToCloudWatchLogs, which allows API Gateway to write CloudWatch Logs
  3. Get a list of enabled regions in your account, and configure the role for API Gateway in each region