So far we’ve configured our DynamoDB table and S3 bucket in CDK. We are now ready to setup our Cognito User Pool. The User Pool stores our user credentials and allows our users to sign up and login to our app.

Create a Stack

Add the following to infrastructure/lib/CognitoStack.js.

import { CfnOutput } from "@aws-cdk/core";
import * as cognito from "@aws-cdk/aws-cognito";
import * as sst from "@serverless-stack/resources";

export default class CognitoStack extends sst.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    const userPool = new cognito.UserPool(this, "UserPool", {
      selfSignUpEnabled: true, // Allow users to sign up
      autoVerify: { email: true }, // Verify email addresses by sending a verification code
      signInAliases: { email: true }, // Set email as an alias

    const userPoolClient = new cognito.UserPoolClient(this, "UserPoolClient", {
      generateSecret: false, // Don't need to generate secret for web app running on browsers

    // Export values
    new CfnOutput(this, "UserPoolId", {
      value: userPool.userPoolId,
    new CfnOutput(this, "UserPoolClientId", {
      value: userPoolClient.userPoolClientId,

Let’s quickly go over what we are doing here:

  • We are creating a new stack for our Cognito related resources. We don’t have to create a separate stack here. We could’ve used one of our existing stacks. But this setup allows us to illustrate how you would use multiple stacks together.

  • We are creating a new instance of the cognito.UserPool class. And setting up the options to match what we did back in the Create a Cognito user pool chapter.

  • We then create a new instance of the cognito.UserPoolClient class and link it to the User Pool we defined above.

  • Finally, we output the UserPoolId and UserPoolClientId. We’ll be using this later in our React app.

You can refer to the CDK docs to learn more about the cognito.UserPool and the cognito.UserPoolClient constructs.

Let’s add the Cognito CDK package. Run the following in your infrastructure/ directory.

$ npx sst add-cdk @aws-cdk/aws-cognito

This will do an npm install using the right CDK version.

Add the Stack

Let’s add this stack to our CDK app. Replace your infrastructure/lib/index.js with this.

import S3Stack from "./S3Stack";
import CognitoStack from "./CognitoStack";
import DynamoDBStack from "./DynamoDBStack";

// Add stacks
export default function main(app) {
  new DynamoDBStack(app, "dynamodb");

  new S3Stack(app, "s3");

  new CognitoStack(app, "cognito");

Deploy the Stack

Now let’s deploy our new Cognito User Pool by running the following from the infrastructure/ directory.

$ npx sst deploy

You should see something like this at the end of your deploy output.

Stack dev-notes-infra-cognito
  Status: deployed
    UserPoolClientId: 68clr7ilru7rheikb3g8gvgvfq
    UserPoolId: us-east-1_LqVQhcQDe

We’ll be copying over these values in one of our later chapters.

Next, let’s look at configuring our Cognito Identity Pool.