Importing Cognito User Pool For Cross Stack Deployments

Hi,

I’m in the process of reorganizing our API project that relies on Cognito for authentication to take advantage of base path mapping to better organize our endpoints. We’re planning on 3 different deployments/stacks:

/auth for authentication endpoints. This stack will also hold the actual Cognito user pool.
/v1 for our first version of the API
/v2 for our second version of the API

Both /v1 and /v2 will need access to the user pool in the /auth stack. I believe I’m exporting things correctly from /auth because when I look in CloudFormation for that stack, I can see the exported names (See CognitoExports.jpg attachment).

This is how I’m trying to import the Cognito pool in the Resources section:

CognitoUserPool:
Fn::ImportValue:
CognitoUserPool-${self:provider.stage}

CognitoUserPoolClient:
Fn::ImportValue:
CognitoUserPoolClient-${self:provider.stage}

When I go to deploy this setup, I get the following error.

The CloudFormation template is invalid: Invalid template resource property ‘Fn::ImportValue’

I’m having trouble finding an example on-line of just what I’m trying to do. Is there something simple I’m doing wrong? What should I be adding as the “resource property” for the user pool and the user pool client for the imports to work? Should I be creating an identity pool to point to the main user pool instead??

Let me know if you need more information.

Thanks!!
-Larry

I got some guidance from AWS support, but it’s still not quite right yet. As you can see from the attachment, it looks like the export is created successfully. Here’s where I try to us Fn::ImportValue to import the CognitoUserPool:

  CognitoUserPool:
    Fn::ImportValue:
      Fn::Sub "${cf:CAS-API-AUTHLarry-${self:provider.stage}.CognitoUserPool}"

When I go to deploy, this is the error I get:

$ sls deploy -s dev --service-suffix Larry

Serverless Error ---------------------------------------

Trying to request a non exported variable from CloudFormation. Stack name: “CAS-API-AUTHLarry-dev” Requested variable: “CognitoUserPool”.

It looks like the import is using the correct stack name and variable name, but it says it can’t find it. That’s what’s confusing.

Thanks,
-Larry

Can you provide your serverless.yml files? I need to see where and how are you using the Fn::ImportValue.

Hi, Sorry for the delay. Was distracted with other tasks. Here’s the main serverless.yml file:

service:
  name: CAS-API-V1${opt:service-suffix,''}

frameworkVersion: ">=1.2.0 <2.0.0"

custom: ${file(../common/custom.yml)}

provider:
  name: aws
  runtime: java8
  timeout: 29
  stage: ${opt:stage, 'dev'}
  environment: ${self:custom.${self:provider.stage}.environment}
  vpc: ${self:custom.${self:provider.stage}.vpc}
  deploymentBucket:
    name: cas-api-serverless
  logRetentionInDays: 14
  apiGateway:
    restApiId:
      Ref: CasApiGateway
    restApiRootResourceId:
      Fn::GetAtt:
        - CasApiGateway
        - RootResourceId
package:
  artifact: ../lambdas/target/unicasws-vpcproxy-1.0.1.jar

iamRoleStatements:
  - Effect: 'Allow'
    Action:
      - 'lambda:InvokeFunction'
    Resource: "*"
          
functions:
  UnicasAPIInstanceProxy: ${file(./sls/functions/UnicasAPIInstanceProxy.yml)}

  UnicasAPIOrganizationProxy: ${file(./sls/functions/UnicasAPIOrganizationProxy.yml)}

  UnicasAPIApplicationStatusProxy: ${file(./sls/functions/UnicasAPIApplicationStatusProxy.yml)}
  
  UnicasAPIConfigInfoProxy: ${file(./sls/functions/UnicasAPIConfigInfoProxy.yml)}

  FileAPIProxy: ${file(./sls/functions/FileAPIProxy.yml)}

resources: ${file(../common/resources/resources.yml)}

plugins:
  - serverless-plugin-bind-deployment-id
  - serverless-apigw-binary
  - serverless-plugin-lambda-warmup

And here is the resources.yml that tries to import Cognito:

Resources:
  __deployment__:
    Properties:
      StageName: unused_temp_stage
      Description: Deploying ${self:service}-${self:provider.stage}

  CasApiGateway: ${file(../common/resources/api-gateway-restapi.yml)}

  ApiGatewayStage: ${file(../common/resources/api-gateway-stage-${self:provider.stage}.yml)}

  CognitoUserPool:
    Fn::ImportValue:
      ${cf:CAS-API-AUTH${opt:service-suffix,''}-${self:provider.stage}.CognitoUserPool}

This shows you the two main files and how I’m trying to do the import. Let me know if you’d like to see anything more. Thanks!!

1 Like

this really helps me. thank you Larry a lot! i really appreciate it. i was just wondering if you can help me with something when i would have questions? (as i can feel that i will have some)