question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

(cognito): Race condition when creating an user pool and its identity provider in the same stack

See original GitHub issue

When creating a Cognito User Pool and a User Pool Client which uses another Cognito user pool as its identity provider, the deployment fails. It seems like this is due to the race condition between the creation of the user pool identity provider and the user pool client.

Reproduction Steps

Deploy the following stack in a freshly setup cdk project (aws-cdk libs on v. 1.114.0):

import * as cognito from '@aws-cdk/aws-cognito';
import { OAuthScope } from '@aws-cdk/aws-cognito';
import * as cdk from '@aws-cdk/core';

export class UserPool extends cdk.Construct {
    constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) {
        super(scope, id);

        const userPool = new cognito.UserPool(this, id, {
            userPoolName: 'Test-UserPool',
            signInAliases: { email: true },
            removalPolicy: cdk.RemovalPolicy.DESTROY
        })

        const userPoolDomain = new cognito.CfnUserPoolDomain(this, 'TestUserPoolDomain', {
            domain: 'user-pool-chaining-test',
            userPoolId: userPool.userPoolId
        })

        const cognitoProviderName = 'RootCognito';
        let provider = new cognito.CfnUserPoolIdentityProvider(this, 'IDPProvider', {
            userPoolId: userPool.userPoolId,
            providerName: cognitoProviderName,
            providerType: 'OIDC',
            providerDetails: {
                client_id: '<client-id>',
                client_secret: '<client-secret>',
                attributes_request_method: 'POST',
                oidc_issuer: '<cognito-url>',
                authorize_scopes: 'openid email profile', // 'openid-connect'
            }
        });

        const UserPoolClient = new cognito.UserPoolClient(this, 'Test-AppClient', {
            userPool: userPool,
            supportedIdentityProviders: [
                cognito.UserPoolClientIdentityProvider.custom(provider.providerName)
            ],
            oAuth: {
                callbackUrls: ['https://my-test-callback-url.example.com'],
                flows: {
                    authorizationCodeGrant: true,
                    clientCredentials: false,
                    implicitCodeGrant: false
                },
                scopes: [
                    OAuthScope.OPENID,
                    OAuthScope.EMAIL,
                    OAuthScope.PHONE,
                    OAuthScope.PROFILE
                ],
            }
        });
    }
}

What did you expect to happen?

I expect the user pool client to wait for the successful creation of the user pool identity provider before starting its own creation.

What actually happened?

The creation of the stack failed with the following error:

cdk deploy
TestCognitoChainingStack: deploying...
TestCognitoChainingStack: creating CloudFormation changeset...
13:36:01 | CREATE_FAILED        | AWS::Cognito::UserPoolClient           | YourServiceUserpoolTestAppClientB7160A99
The provider RootCognito does not exist for User Pool eu-central-1_MXSHIJTeZ. (Service: AWSCognitoIdentityProviderService;
Status Code: 400; Error Code: InvalidParameterException; Request ID: 74c94dc4-c955-49ce-acea-d19e16435de4; Proxy: null)

        new UserPoolClient (/Users/jasper/dev/test-cognito-chaining/node_modules/@aws-cdk/aws-cognito/li2 | ROLLBACK_IN_PROGRESS | AWS::CloudFormation::Stack             | TestCognitoChainingStack
b/user-pool-client.ts:206:22)
        \_ new UserPool (/Users/jasper/dev/test-cognito-chaining/lib/user-pool-stack.ts:36:32)
        \_ new TestCognitoChainingStack (/Users/jasper/dev/test-cognito-chaining/lib/test-cognito-chaini
ng-stack.ts:8:22)
        \_ Object.<anonymous> (/Users/jasper/dev/test-cognito-chaining/bin/test-cognito-chaining.ts:7:1)
        \_ Module._compile (internal/modules/cjs/loader.js:1085:14)
        \_ Module.m._compile (/Users/jasper/dev/test-cognito-chaining/node_modules/ts-node/src/index.ts:
1056:23)
        \_ Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        \_ Object.require.extensions.<computed> [as .ts] (/Users/jasper/dev/test-cognito-chaining/node_m
odules/ts-node/src/index.ts:1059:12)
        \_ Module.load (internal/modules/cjs/loader.js:950:32)
        \_ Function.Module._load (internal/modules/cjs/loader.js:790:14)
        \_ Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
        \_ main (/Users/jasper/dev/test-cognito-chaining/node_modules/ts-node/src/bin.ts:198:14)
        \_ Object.<anonymous> (/Users/jasper/dev/test-cognito-chaining/node_modules/ts-node/src/bin.ts:2
88:3)
        \_ Module._compile (internal/modules/cjs/loader.js:1085:14)
        \_ Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
        \_ Module.load (internal/modules/cjs/loader.js:950:32)
        \_ Function.Module._load (internal/modules/cjs/loader.js:790:14)
        \_ Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
        \_ /usr/local/Cellar/node@14/14.17.3/lib/node_modules/npm/node_modules/libnpx/index.js:268:14


 ❌  TestCognitoChainingStack failed: Error: The stack named TestCognitoChainingStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE
    at Object.waitForStackDeploy (/usr/local/lib/node_modules/aws-cdk/lib/api/util/cloudformation.ts:305:11)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at Object.deployStack (/usr/local/lib/node_modules/aws-cdk/lib/api/deploy-stack.ts:294:26)
    at CdkToolkit.deploy (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:184:24)
    at initCommandLine (/usr/local/lib/node_modules/aws-cdk/bin/cdk.ts:213:9)
The stack named TestCognitoChainingStack failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE

Environment

  • CDK CLI Version : 1.114.0 (build 7e41b6b)
  • Framework Version: 1.114.0
  • Node.js Version: 14.17.3
  • OS : Mac OS 11.4
  • Language (Version): TypeScript 3.9.7

This is 🐛 Bug Report

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

11reactions
jumiccommented, Jul 21, 2021

You can solve this by adding the dependency between UserPoolClient and provider manually:

UserPoolClient.node.addDependency(provider);

CDK can’t handle this automatically because the UserPoolClient only receives the name of the provider (provider.providerName) as a string. This name is not sufficient to generate the dependency between both constructs.

Two solution approaches (as long there is no L2 construct for UserPoolIdentityProvider):

  • Explain this behavior in CDK Cognito documentation with addDependency workaround.
  • Implement new initializer like cognito.UserPoolClientIdentityProvider.fromCfnUserPoolIdentityProvider(provider). In this case, the UserPoolClient could generate the dependency automatically because it has a reference to the identity provider.
0reactions
github-actions[bot]commented, Aug 12, 2021

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Configuring identity providers for your user pool
The identity provider creates an app ID and an app secret for your app, and you configure those values in your Amazon Cognito...
Read more >
AWS Cognito & Amplify Auth - Bad, Bugged, Baffling
The new, not verified email is already taken in the user pool, which blocks any users who might have that email from using...
Read more >
User Pool allows two users with same email despite ...
I think Cognito will let two users sign up with the same email, but only one will ever be able to verify/confirm the...
Read more >
AWS Cognito & Amplify Auth - Bad, Bugged, Baffling - Reddit
Now you don't have 2 accounts for the same email and can use user attributes across the different authentication providers - it's a...
Read more >
@aws-cdk/aws-cognito | Yarn - Package Manager
User pools can either be configured so that user name is primary sign in form, but also allows for the other three to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found