AWS API Gateway with Cloudwatch
Overview
The following document is a step-by-step guide on integrating AWS API Gateway with Cloudwatch through the CDK
Stack
The following stack creates AWS API Gateway with authentication provided by Cognito and logging provided by Cloudwatch.
Steps
The following are the steps required to add Auth & Cloudwatch to the API Gateway. This document goes in more depth about adding Authentication
Request to log diagram
API Gateway + Auth
- Create Cognito User Pool
- Create an app client
- Create a domain
- Create a REST API Gateway
- Create a resource
/ditto
- Create a
GET
HTTP Integration for the resource - Create Cognito authorizer for the API Gateway
- Uses the created Cognito User Pool instance to create the authorizer
- Set the authorization handler for the resource's
GET
method as the created Cognito's authorizer
- Create a resource
API Gateway + Cloudwatch
- Create a deployment instance of the REST API Gateway
- Create a log group
- Use the same Rest API Gateway from API Gateway + Auth
- Create a dev stage with custom access logging & cloudwatch error/info logs enabled
CDK Code
View code
import * as cdk from 'aws-cdk-lib'import * as apiGateway from 'aws-cdk-lib/aws-apigateway'import * as cognito from 'aws-cdk-lib/aws-cognito'import * as logs from 'aws-cdk-lib/aws-logs'export class CdkStack extends cdk.Stack {constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {super(scope, id, props)// SECTION: API Gateway + Auth// Create Cognito user poolconst USER_POOL_ID = 'APIgatewayUserPool'const userPool = new cognito.UserPool(this, USER_POOL_ID, {// Allow users to sign-upselfSignUpEnabled: true,autoVerify: {email: true,},standardAttributes: {// By default, Cognito verify sign-ups. When the email isn't required-// Cognito hosted UI won't display it when singing upemail: {required: true,},},})// Add an App Client. Necessary for the hosted API and-// for other apps to interact with Cognito API programmaticallyuserPool.addClient('APIgatewayUserPoolClient')// Create a domain for the Hosted UIuserPool.addDomain('Domain', {cognitoDomain: {// "onetwo" are meant to make the prefix uniquedomainPrefix: 'apigatewayauthonetwo',},// You could provide a custom domain instead// customDomain: 'myClient.website.com'})// Create REST API Gatewayconst api = new apiGateway.RestApi(this, 'ditto-api', {// Automatically create a Cloudwatch role for this APIcloudWatchRole: true,})// Declare HTTP Integration type with target as pokeAPI to be used laterconst httpIntegration = new apiGateway.HttpIntegration('https://pokeapi.co/api/v2/pokemon/ditto')// Add `/ditto` resource to the API Gatewayconst dittoResource = api.root.addResource('ditto')// Create Cognito authorizer for the API Gatewayconst cognitoAuth = new apiGateway.CognitoUserPoolsAuthorizer(this,'ApiGatewayAuth',{cognitoUserPools: [userPool],})// Create a protected GET method with Cognito authorizer for `/ditto` resourcedittoResource.addMethod('GET', httpIntegration, {authorizer: cognitoAuth,authorizationType: apiGateway.AuthorizationType.COGNITO,})// API Gateway + Auth end// SECTION: API Gateway + Cloudwatch startconst deployment = new apiGateway.Deployment(this, 'Deployment', { api })// Create a log group for Cloudwatchconst devLogGroup = new logs.LogGroup(this, 'DevLogs')// Create a dev stage for the API Gatewaynew apiGateway.Stage(this, 'dev', {stageName: 'dev',deployment,// Enables Custom Access LoggingaccessLogDestination: new apiGateway.LogGroupLogDestination(devLogGroup),accessLogFormat: apiGateway.AccessLogFormat.jsonWithStandardFields(),// Enabled Cloudwatch info & error loggingsloggingLevel: apiGateway.MethodLoggingLevel.INFO,})// API Gateway + Cloudwatch end}}