I already have my cognito user pool cloudformation template working, and have it integrated to my api gateway. But somehow i still have to manually configure the app client settings, domain, and federated identities to have a working login portal for the users. I have been looking here and there for possible solutions in automating these, but i cannot seem to find anything close to it.
I would like to automate the configuration of the app client settings, domain, and federated identities via cloudformation sam template so i do not have to do these manually.
Any suggestions are much appreciated. Thank you.
(attachments posted for additional info)
Looks like there is no way to provide App integration -> Domain name and Federation -> Identity providers via CloudFormation.
I found only reference for User Pool Client (General settings -> App clients) but it will not configure App integration -> App client settings.
If you need to automate process of providing Domain name, Identity providers and App client settings for user pool, you can do that by creating custom script (AWS CLI) or Lambda (AWS SDK) which should be performed after stack deployment.
UPDATE
Check out excellent example (answer below) that shows usage of CloudFormation Custom Resources with Lambda.
I have created two CloudFormation custom resources to apply Cognito app client settings and domain name. With these resources, you can have a script like this:
UserPoolTestClient:
Type: 'AWS::Cognito::UserPoolClient'
Properties:
ClientName: UserPoolTestClient
GenerateSecret: true
UserPoolId: !Ref UserPoolTest
UserPoolTestClientSettings:
Type: 'Custom::CognitoUserPoolClientSettings'
Properties:
ServiceToken: !GetAtt CloudFormationCognitoUserPoolClientSettings.Arn
UserPoolId: !Ref UserPoolTest
UserPoolClientId: !Ref UserPoolTestClient
SupportedIdentityProviders:
- COGNITO
CallbackURL: 'https://www.amazon.com'
LogoutURL: 'https://www.google.com'
AllowedOAuthFlowsUserPoolClient: true
AllowedOAuthFlows:
- code
AllowedOAuthScopes:
- openid
UserPoolTestDomain:
Type: 'Custom::CognitoUserPoolDomain'
Properties:
ServiceToken: !GetAtt CloudFormationCognitoUserPoolDomain.Arn
UserPoolId: !Ref UserPoolTest
Domain: 'userpool-test-01'
The complete code is here.
Since yesterday, AWS CloudFormation added native support for configuring domain name, identities and other settings directly: https://aws.amazon.com/about-aws/whats-new/2019/10/amazon-cognito-increases-cloudformation-support/
This new support includes the ability to securely and automatically configure a hosted UI domain, configure customization for a hosted UI, configure an IdentityProvider, configure the behavior of advanced security features and configure resource servers, all directly within CloudFormation.
(thanks to my colleague Bernhard for this update)
CloudFormation has added the resource AWS::Cognito::UserPoolDomain to manage the User Pool Domain:
Type: AWS::Cognito::UserPoolDomain
Properties:
CustomDomainConfig:
CertificateArn: !Ref CertificateArn
Domain: "your.custom.domain.com"
UserPoolId: !Ref UserPool
In addition, there has been added configuration to the AWS::Cognito::UserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
AllowedOAuthFlows:
- String
AllowedOAuthFlowsUserPoolClient: Boolean
AllowedOAuthScopes:
- String
AnalyticsConfiguration:
AnalyticsConfiguration
CallbackURLs:
- String
ClientName: String
DefaultRedirectURI: String
ExplicitAuthFlows:
- String
GenerateSecret: Boolean
LogoutURLs:
- String
ReadAttributes:
- String
RefreshTokenValidity: Integer
SupportedIdentityProviders:
- String
UserPoolId: String
WriteAttributes:
- String
I want to add a different solution (suggested by Mickael) because CloudFormation is complex to set up ; this command line will create your domain after the CloudFormation stack is created :
aws cognito-idp create-user-pool-domain --domain test-domain --user-pool-id eu-west-1_xxxxxxxx
In your automated deployment you can add a script that sets your domain. Not as great as everything on CF but it works
I rolled a solution for these exact 3 resources for myself, and others that want to give it a shot. https://github.com/cyrfer/cloudformation-custom-resource-provider
Very much inspired by Rosberg Linhares example, but in python, and using the AWS cfn helper module:
If you write a lambda function with this code, basically using boto3 to do the client app settings
from crhelper import CfnResource
import boto3
from copy import copy
# setup the cfn helper
helper = CfnResource()
client = boto3.client('cognito-idp')
# these wrappers return the function unaltered, so we can chain them to apply
# the function in both create and update
@helper.create
@helper.update
def update_on_create(event, _):
params = copy(event['ResourceProperties'])
del params['ServiceToken']
client.update_user_pool_client(**params)
# don't do anything on delete. Deleting the client app is handled by the template
@helper.delete
def delete_user_pool_client(event, _):
pass
def handler(event, context):
helper(event, context)
Then your cloudformation would be similar, e.g.
UserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: 'TestClient'
GenerateSecret: true
UserPoolId: !Ref UserPool
UserPoolClientSettings:
Type: Custom::CognitoUserPoolClientSettings
DependsOn:
- LambdaForAppClientSettings
- UserPoolClient
Properties:
ServiceToken: !GetAtt LambdaForAppClientSettings.Arn
UserPoolId: !Ref UserPool
ClientId: !Ref UserPoolClient
CallbackURLs:
- https://www.amazon.com
SupportedIdentityProviders:
- COGNITO
With the possible benefit that you can specify either some or all of the arguments to update_user_pool_client(), due to the parameter expansion in client.update_user_pool_client(**params)
. You do have to make sure that the keys in the Properties
map of your cloudformation custom resource match exactly what is required by boto3. Check the boto3 documentation for the list of possible args.
来源:https://stackoverflow.com/questions/49524493/cloudformation-cognito-how-to-setup-app-client-settings-domain-and-federated