almeynman
almeynman

Reputation: 7428

reference cognito user pool created by sst (serverless-stack) in serverless.yml

I have quite a big app built with serverless and now we are trying out serverless-stack. I am trying to reference a user pool created by sst in serverless.yml function. Is it possible? Below are the steps I've tried:

I have created a user pool

import * as cdk from '@aws-cdk/core'
import * as cognito from '@aws-cdk/aws-cognito'
import * as sst from '@serverless-stack/resources'

export default class UserServiceStack extends sst.Stack {
  constructor(scope: cdk.Construct, id: string, props: sst.StackProps = {}) {
    super(scope, id, props)

    const userPool = new cognito.UserPool(this, 'userPool', {
      signInAliases: {
        email: true,
        phone: true,
      },
      autoVerify: {
        email: true,
        phone: true,
      },
      passwordPolicy: {
        minLength: 8,
        requireDigits: false,
        requireLowercase: false,
        requireSymbols: false,
        requireUppercase: false,
      },
      signInCaseSensitive: false,
      selfSignUpEnabled: true,
    })

    new cdk.CfnOutput(this, 'UserPoolId', {
      value: userPool.userPoolId,
    })

    const userPoolClient = new cognito.UserPoolClient(this, 'userPoolClient', {
      userPool,
      authFlows: {
        adminUserPassword: true,
        userPassword: true,
      },
    })
    
    new cdk.CfnOutput(this, 'UserPoolClientId', {
      value: userPoolClient.userPoolClientId,
    })
  }
}

and want to update my post confirmation trigger defined in serverless.yml

  ...
  createUser:
    handler: createUser.default
    events:
      - cognitoUserPool:
          pool: !ImportValue '${self:custom.sstApp}...' # what to put here?
          trigger: PostConfirmation
          existing: true

Upvotes: 1

Views: 949

Answers (1)

almeynman
almeynman

Reputation: 7428

Figured it out. First How to use cdk output variables in serverless.yml.

Export them into a file

AWS_PROFILE=<profile-name> npx sst deploy --outputs-file ./exports.json

and in serverless.yml you can reference it like so

  ...
  createUser:
    handler: createUser.default
    events:
      - cognitoUserPool:
          pool: ${file(../../infrastructure/exports.json):${self:custom.sstApp}-UserServiceStack.userPoolName}
          trigger: PostConfirmation
          existing: true

Second. serverless is setup such that you have to pass userPoolName, not userPoolId. So I had to generate userpool name and output it

import * as uuid from 'uuid'

...

    const userPoolName = uuid.v4()
    const userPool = new cognito.UserPool(this, 'userPool', {
      userPoolName,
      ...
    })
    ...
    // eslint-disable-next-line no-new
    new cdk.CfnOutput(this, 'userPoolName', {
      value: userPoolName,
    })

Third to avoid AccessDeniedException when calling lambda as a trigger you need to add the following to your resources

  - Resources:
      OnCognitoSignupPermission:
        Type: 'AWS::Lambda::Permission'
        Properties:
          Action: "lambda:InvokeFunction"
          FunctionName:
            Fn::GetAtt: [ "CreateUserLambdaFunction", "Arn"] # the name must be uppercased name of your lambda + LambdaFunction at the end
          Principal: "cognito-idp.amazonaws.com"
          SourceArn: ${file(../../infrastructure/exports.json):${self:custom.sstApp}-UserServiceStack.userPoolArn}

Upvotes: 0

Related Questions