amazon-web-servicesaws-cloudformationamazon-cognitoaws-opsworks

Cannot set a property of cognito userpool client via cloudformation


I am trying to run congnito via cloudformation and everything works but there is section in cognito as follows:

enter image description here

As you see there is section "Enable identity providers" and I can not find where I can set it to my cognito user pool in cloudformation!

I tried this attributes but it says not supported.

SupportedIdentityProviders

Here is my code for user pool client:

  UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
  ClientName: !Sub ${project}-client
  ExplicitAuthFlows:
   - ADMIN_NO_SRP_AUTH
   - USER_PASSWORD_AUTH
  GenerateSecret: false
  UserPoolId: !Ref UserPool
  RefreshTokenValidity: 30

and here is my user pool:

  UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
  UserPoolName: !Sub ${project}-user-pool-test
  AutoVerifiedAttributes:
    - email
  UsernameAttributes:
    - email
  MfaConfiguration: "OFF"
  LambdaConfig:
    CustomMessage:
      Fn::ImportValue: !Sub ${project}-${EnvironmentApp}-lambda-cognito-custom-message-post
  Policies:
    PasswordPolicy:
      MinimumLength: !Ref MinimumLength
      RequireLowercase: !Ref RequireLowercase
      RequireNumbers: !Ref RequireNumbers
      RequireSymbols: !Ref RequireSymbols
      RequireUppercase: !Ref RequireUppercase
  Schema:
    -
        AttributeDataType: String
        DeveloperOnlyAttribute: false
        Mutable: true
        Name: !Sub ${project}-stg
        Required: false
    -
        AttributeDataType: String
        DeveloperOnlyAttribute: false
        Mutable: true
        Name: !Sub zuora-stg
        Required: false
    -
        AttributeDataType: String
        DeveloperOnlyAttribute: false
        Mutable: true
        Name: !Sub salesforce-stg
        Required: false

Is it supported in cloud formation? I appreciate any help?


Solution

  • As other answer suggest, this can't be done in CloudFormation natively as of yet. However, as ASR answer advises it is possible to do so through CloudFormation custom resource.

    My employer has open sourced its collection of custom resources, including CognitoUserPool and CognitoDomainName (which is also not supported in CloudFormation). Custom resources source code can be found on github

    Below are manual directions on setting this up - you can always automate things further by placing Custom Resource backing Lambda in CloudFormation as well.

    All commands below are for Mac. You may need to modify base64 flags for other platforms

    1. Create IAM Role For Lambda

    aws iam create-role --role-name LambdaRoleCognito --assume-role-policy-document '{
          "Version": "2012-10-17",
          "Statement": [
          {
              "Effect": "Allow",
              "Principal": {
                  "Service": "lambda.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
          }
      ]
      }'
    aws iam attach-role-policy --role-name LambdaRoleCognito \
      --policy-arn  arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
    
    aws iam attach-role-policy --role-name LambdaRoleCognito \
      --policy-arn  arn:aws:iam::aws:policy/AmazonCognitoPowerUser
    

    2. Download lambda source code, upload to your local bucket, and create lambda

    wget https://github.com/base2Services/cloudformation-custom-resources-nodejs/releases/download/1.0.0/ccr-nodejs-1.0.0.zip
    account_id=$(aws sts get-caller-identity --query Account --output text)
    aws s3 mb s3://${account_id}.cfncustomres.source
    aws s3 cp ccr-nodejs-1.0.0.zip s3://${account_id}.cfncustomres.source/ccr-nodejs-1.0.0.zip
    
    aws lambda create-function --function-name CfnCrCognitUPC --runtime nodejs6.10 \
        --role arn:aws:iam::${account_id}:role/LambdaRoleCognito  \
        --timeout 30 \
        --memory-size 512 \
        --code S3Bucket=${account_id}.cfncustomres.source,S3Key=ccr-nodejs-1.0.0.zip \
        --handler cognito-user-pool-client/index.handler
    

    3. Optional Test lambda by invoking with test payload

    aws lambda invoke --function-name CfnCrCognitUPC --payload '{
      "StackId": "arn:aws:cloudformation:us-west-2:EXAMPLE/stack-name/guid",
      "ResponseURL": "http://pre-signed-S3-url-for-response",
      "ResourceProperties": {
        "ClientName": "MyCCRCreatedUP",
        "SupportedIdentityProviders": [
          "COGNITO"
        ],
        "UserPoolId":"!! REPLACE WITH YOUR USER POOL ID !!"
      },
      "RequestType": "Create",
      "ResourceType": "Custom::TestResource",
      "RequestId": "unique id for this create request",
      "LogicalResourceId": "MyTestResource"
    }' --log-type Tail --invocation-type RequestResponse output.txt --query LogResult --output text | base64 -D
    

    4. Create custom resource in CloudFormation template

    For list of all supported properties checkout custom resource JSON schema

    Resources:
      MyPoolApplication:
        Type: Custom::CognitoUserPool
        Properties:
          ServiceToken: arn:aws:lambda:<<REPLACE_WITH_YOUR_REGION>>:<<REPLACE_WITH_YOUR_ACCOUNT_ID>>:function:CfnCrCognitUPC
          ClientName: ApplicationClientNameHere
          UserPoolId: 
            Ref: UserPool
          SupportedIdentityProviders:
            - COGNITO
          .... other support properties ....