Creation of User Pool Client fails saying 'provider google does not exist'

I have a fairly annoying issue that shows up intermittently, which makes me think it’s some kind of race condition. I’m coming to suspect that this could be an AWS CloudFormation bug. I
CognitoUserPoolClient - The provider Google does not exist for User Pool us-west-2_xxxxxxxxx

My pertinent details of my configuration are here:

 CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      LambdaConfig:
        PreAuthentication:
          Fn::GetAtt: [MyLambdaFunction, Arn]
      MfaConfiguration: OFF
      UserPoolName: my-project-user-pool
      UsernameAttributes:
        - email
      AutoVerifiedAttributes:
        - email
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true

  CognitoUserPoolIdentityProvider:
    Type: AWS::Cognito::UserPoolIdentityProvider
    DependsOn: 
      - CognitoUserPool
      - CognitoUserPoolClient 
    Properties:
      ProviderName: Google
      AttributeMapping:
        email: email
      ProviderDetails:
        client_id: ${env:CLIENT_ID}
        client_secret: ${env:CLIENT_SECRET}
        authorize_scopes: email openid
      ProviderType: Google
      UserPoolId:
        Ref: CognitoUserPool

As you can see I’ve tried using “DependsOn”, to see if I can prevent this issue, but I can not. The only way around it that I’ve found is just running sls deploy repeatedly until it works. You can see how this solution is not satisfying.

If you have ideas, I’ll try them!
Thanks!

Thanks for the question/hint! I got this to work by reversing the DependsOn. Remove the DependsOn from the CognitoUserPoolIdentityProvider section, and instead add this DependsOn to the CognitoUserPool, like this:

 CognitoUserPool:
    Type: AWS::Cognito::UserPool
    DependsOn: 
      - CognitoUserPoolIdentityProvider
    Properties:
      LambdaConfig:
        PreAuthentication:
          Fn::GetAtt: [MyLambdaFunction, Arn]
      MfaConfiguration: OFF
      UserPoolName: my-project-user-pool
      UsernameAttributes:
        - email
      AutoVerifiedAttributes:
        - email
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true

  CognitoUserPoolIdentityProvider:
    Type: AWS::Cognito::UserPoolIdentityProvider
    Properties:
      ProviderName: Google
      AttributeMapping:
        email: email
      ProviderDetails:
        client_id: ${env:CLIENT_ID}
        client_secret: ${env:CLIENT_SECRET}
        authorize_scopes: email openid
      ProviderType: Google
      UserPoolId:
        Ref: CognitoUserPool

Note: I tried this in my own code, and it worked. I didn’t try it on your code.

Hello,

I hit the same problem on my side. Sometime it deploys, sometime I get the error “The provider Google does not exist for User Pool”.

I try to use the proposed fix with DependsOn, but it introduce a circular dependencies.

My serverless userpool part file:

CognitoUserPool:
  Type: AWS::Cognito::UserPool
  Properties:
    # Generate a name based on the stage
    UserPoolName: ${self:provider.stage}-userpool
    # Set email as an alias
    UsernameAttributes:
      - email
    AutoVerifiedAttributes:
      - email

CognitoUserPoolIdentityProvider:
  Type: AWS::Cognito::UserPoolIdentityProvider
  Properties:
    ProviderName: Google
    AttributeMapping:
      email: email
    ProviderDetails:
      client_id: ${self:custom.GOOGLE_APP_ID}
      client_secret: ${self:custom.GOOGLE_SECRET}
      authorize_scopes: profile email openid
    ProviderType: Google
    UserPoolId:
      Ref: CognitoUserPool

# Cognito User Pool Client (Server e.g. from web/lambda)
CognitoUserPoolServerClient:
  Type: AWS::Cognito::UserPoolClient
  Properties:
    # Generate an app client name based on the stage
    ClientName: ${self:provider.stage}-serverclient
    UserPoolId:
      Ref: CognitoUserPool
    ExplicitAuthFlows:
      - ADMIN_NO_SRP_AUTH
    GenerateSecret: false
    SupportedIdentityProviders: 
      - Google
    CallbackURLs: 
      - http://localhost:4200/home
    LogoutURLs:
      - http://localhost:4200/signin
    AllowedOAuthFlows:
      - code
      - implicit
    AllowedOAuthScopes: 
      - email
      - openid
      - profile
    AllowedOAuthFlowsUserPoolClient: true

serverless version:
Framework Core: 1.78.1
Plugin: 3.7.0
SDK: 2.3.1
Components: 2.34.3

Maybe I miss something ?

It seems that in my case adding the depends on in the UserPoolClient on the IdentityProvider make it working:

CognitoUserPool:
  Type: AWS::Cognito::UserPool
  Properties:
    # Generate a name based on the stage
    UserPoolName: ${self:provider.stage}-userpool
    # Set email as an alias
    UsernameAttributes:
      - email
    AutoVerifiedAttributes:
      - email

CognitoUserPoolIdentityProvider:
  Type: AWS::Cognito::UserPoolIdentityProvider
  Properties:
    ProviderName: Google
    AttributeMapping:
      email: email
    ProviderDetails:
      client_id: ${self:custom.GOOGLE_APP_ID}
      client_secret: ${self:custom.GOOGLE_SECRET}
      authorize_scopes: profile email openid
    ProviderType: Google
    UserPoolId:
      Ref: CognitoUserPool

# Cognito User Pool Client (Server e.g. from web/lambda)
CognitoUserPoolServerClient:
  Type: AWS::Cognito::UserPoolClient
  DependsOn:
    - CognitoUserPoolIdentityProvider
  Properties:
    # Generate an app client name based on the stage
    ClientName: ${self:provider.stage}-serverclient
    UserPoolId:
      Ref: CognitoUserPool
    ExplicitAuthFlows:
      - ADMIN_NO_SRP_AUTH
    GenerateSecret: false
    SupportedIdentityProviders: 
      - Google
    CallbackURLs: 
      - http://localhost:4200/home
    LogoutURLs:
      - http://localhost:4200/signin
    AllowedOAuthFlows:
      - code
      - implicit
    AllowedOAuthScopes: 
      - email
      - openid
      - profile
    AllowedOAuthFlowsUserPoolClient: true
2 Likes