AWSTemplateFormatVersion: 2010-09-09 Parameters: env: Type: String authRoleArn: Type: String unauthRoleArn: Type: String identityPoolName: Type: String allowUnauthenticatedIdentities: Type: String resourceNameTruncated: Type: String userPoolName: Type: String autoVerifiedAttributes: Type: CommaDelimitedList mfaConfiguration: Type: String mfaTypes: Type: CommaDelimitedList smsAuthenticationMessage: Type: String smsVerificationMessage: Type: String emailVerificationSubject: Type: String emailVerificationMessage: Type: String defaultPasswordPolicy: Type: String passwordPolicyMinLength: Type: Number passwordPolicyCharacters: Type: CommaDelimitedList requiredAttributes: Type: CommaDelimitedList aliasAttributes: Type: CommaDelimitedList userpoolClientGenerateSecret: Type: String userpoolClientRefreshTokenValidity: Type: Number userpoolClientWriteAttributes: Type: CommaDelimitedList userpoolClientReadAttributes: Type: CommaDelimitedList userpoolClientLambdaRole: Type: String userpoolClientSetAttributes: Type: String sharedId: Type: String resourceName: Type: String authSelections: Type: String useDefault: Type: String userPoolGroupList: Type: CommaDelimitedList serviceName: Type: String usernameCaseSensitive: Type: String dependsOn: Type: CommaDelimitedList Conditions: ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ] ShouldOutputAppClientSecrets: !Equals [!Ref userpoolClientGenerateSecret, true ] Resources: # BEGIN SNS ROLE RESOURCE SNSRole: # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process Type: AWS::IAM::Role Properties: RoleName: !If [ShouldNotCreateEnvResources, 'amazon6570cbea_sns-role', !Join ['',[ 'sns', '6570cbea', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Sid: "" Effect: "Allow" Principal: Service: "cognito-idp.amazonaws.com" Action: - "sts:AssumeRole" Condition: StringEquals: sts:ExternalId: amazon6570cbea_role_external_id Policies: - PolicyName: amazon6570cbea-sns-policy PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "sns:Publish" Resource: "*" # BEGIN USER POOL RESOURCES UserPool: # Created upon user selection # Depends on SNS Role for Arn if MFA is enabled Type: AWS::Cognito::UserPool UpdateReplacePolicy: Retain Properties: UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]] UsernameConfiguration: CaseSensitive: false Schema: - Name: email Required: true Mutable: true AutoVerifiedAttributes: - email EmailVerificationMessage: !Ref emailVerificationMessage EmailVerificationSubject: !Ref emailVerificationSubject Policies: PasswordPolicy: MinimumLength: !Ref passwordPolicyMinLength RequireLowercase: false RequireNumbers: false RequireSymbols: false RequireUppercase: false AliasAttributes: !Ref aliasAttributes MfaConfiguration: !Ref mfaConfiguration SmsVerificationMessage: !Ref smsVerificationMessage SmsAuthenticationMessage: !Ref smsAuthenticationMessage SmsConfiguration: SnsCallerArn: !GetAtt SNSRole.Arn ExternalId: amazon6570cbea_role_external_id UserPoolClientWeb: # Created provide application access to user pool # Depends on UserPool for ID reference Type: "AWS::Cognito::UserPoolClient" Properties: ClientName: amazon6570cbea_app_clientWeb RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity UserPoolId: !Ref UserPool DependsOn: UserPool UserPoolClient: # Created provide application access to user pool # Depends on UserPool for ID reference Type: "AWS::Cognito::UserPoolClient" Properties: ClientName: amazon6570cbea_app_client GenerateSecret: !Ref userpoolClientGenerateSecret RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity UserPoolId: !Ref UserPool DependsOn: UserPool # BEGIN USER POOL LAMBDA RESOURCES UserPoolClientRole: # Created to execute Lambda which gets userpool app client config values Type: 'AWS::IAM::Role' Properties: RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', '6570cbea', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]] AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' DependsOn: UserPoolClient UserPoolClientLambda: # Lambda which gets userpool app client config values # Depends on UserPool for id # Depends on UserPoolClientRole for role ARN Type: 'AWS::Lambda::Function' Properties: Code: ZipFile: !Join - |+ - - 'const response = require(''cfn-response'');' - 'const aws = require(''aws-sdk'');' - 'const identity = new aws.CognitoIdentityServiceProvider();' - 'exports.handler = (event, context, callback) => {' - ' if (event.RequestType == ''Delete'') { ' - ' response.send(event, context, response.SUCCESS, {})' - ' }' - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' - ' const params = {' - ' ClientId: event.ResourceProperties.clientId,' - ' UserPoolId: event.ResourceProperties.userpoolId' - ' };' - ' identity.describeUserPoolClient(params).promise()' - ' .then((res) => {' - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});' - ' })' - ' .catch((err) => {' - ' response.send(event, context, response.FAILED, {err});' - ' });' - ' }' - '};' Handler: index.handler Runtime: nodejs12.x Timeout: 300 Role: !GetAtt - UserPoolClientRole - Arn DependsOn: UserPoolClientRole UserPoolClientLambdaPolicy: # Sets userpool policy for the role that executes the Userpool Client Lambda # Depends on UserPool for Arn # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing Type: 'AWS::IAM::Policy' Properties: PolicyName: amazon6570cbea_userpoolclient_lambda_iam_policy Roles: - !Ref UserPoolClientRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'cognito-idp:DescribeUserPoolClient' Resource: !GetAtt UserPool.Arn DependsOn: UserPoolClientLambda UserPoolClientLogPolicy: # Sets log policy for the role that executes the Userpool Client Lambda # Depends on UserPool for Arn # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing Type: 'AWS::IAM::Policy' Properties: PolicyName: amazon6570cbea_userpoolclient_lambda_log_policy Roles: - !Ref UserPoolClientRole PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: !Sub - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda} DependsOn: UserPoolClientLambdaPolicy UserPoolClientInputs: # Values passed to Userpool client Lambda # Depends on UserPool for Id # Depends on UserPoolClient for Id # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing Type: 'Custom::LambdaCallout' Properties: ServiceToken: !GetAtt UserPoolClientLambda.Arn clientId: !Ref UserPoolClient userpoolId: !Ref UserPool DependsOn: UserPoolClientLogPolicy # BEGIN IDENTITY POOL RESOURCES IdentityPool: # Always created Type: AWS::Cognito::IdentityPool Properties: IdentityPoolName: !If [ShouldNotCreateEnvResources, 'amazonrekognitionidv6570cbea_identitypool_6570cbea', !Join ['',['amazonrekognitionidv6570cbea_identitypool_6570cbea', '__', !Ref env]]] CognitoIdentityProviders: - ClientId: !Ref UserPoolClient ProviderName: !Sub - cognito-idp.${region}.amazonaws.com/${client} - { region: !Ref "AWS::Region", client: !Ref UserPool} - ClientId: !Ref UserPoolClientWeb ProviderName: !Sub - cognito-idp.${region}.amazonaws.com/${client} - { region: !Ref "AWS::Region", client: !Ref UserPool} AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities DependsOn: UserPoolClientInputs IdentityPoolRoleMap: # Created to map Auth and Unauth roles to the identity pool # Depends on Identity Pool for ID ref Type: AWS::Cognito::IdentityPoolRoleAttachment Properties: IdentityPoolId: !Ref IdentityPool Roles: unauthenticated: !Ref unauthRoleArn authenticated: !Ref authRoleArn DependsOn: IdentityPool Outputs : IdentityPoolId: Value: !Ref 'IdentityPool' Description: Id for the identity pool IdentityPoolName: Value: !GetAtt IdentityPool.Name UserPoolId: Value: !Ref 'UserPool' Description: Id for the user pool UserPoolArn: Value: !GetAtt UserPool.Arn Description: Arn for the user pool UserPoolName: Value: !Ref userPoolName AppClientIDWeb: Value: !Ref 'UserPoolClientWeb' Description: The user pool app client id for web AppClientID: Value: !Ref 'UserPoolClient' Description: The user pool app client id AppClientSecret: Value: !GetAtt UserPoolClientInputs.appSecret Condition: ShouldOutputAppClientSecrets