AWSTemplateFormatVersion: 2010-09-09 Resources: CognitoUserPool: Type: 'AWS::Cognito::UserPool' Properties: UserPoolName: CognitoPool CognitoUserPoolDomain: Type: 'AWS::Cognito::UserPoolDomain' Properties: # using client id will make the domain unique Domain: !Sub dns-name-${CognitoUserPoolClient} UserPoolId: !Ref CognitoUserPool DependsOn: - CognitoUserPoolClient CognitoUserPoolGroup: Type: 'AWS::Cognito::UserPoolGroup' Properties: GroupName: pet-veterinarian UserPoolId: !Ref CognitoUserPool DependsOn: - CognitoUserPool # >>> helper to create Cognito User without the need to confirm email HelperCognitoLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: helperCognitoLambdaRole PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - cognito-idp:Admin* Resource: !GetAtt CognitoUserPool.Arn - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${AWS::StackName}-HelperInitCognitoFunction-*:* HelperInitCognitoFunction: Type: AWS::Lambda::Function Properties: Code: ZipFile: > const AWS = require("aws-sdk"); const response = require("cfn-response"); const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'}); exports.handler = function (event, context, callback) { var userPoolId = event.ResourceProperties.UserPoolId; var username = event.ResourceProperties.CognitoUserName; var pass = event.ResourceProperties.CognitoUserPassword; console.log("username: " + username); var params = { UserPoolId: userPoolId, Username: username, TemporaryPassword: pass }; cognitoidentityserviceprovider.adminCreateUser(params, function (err, data) { if (err) { console.log(err, err.stack); } else { console.log(data); } const params = { UserPoolId: userPoolId, Username: username, Password: pass, Permanent: true }; cognitoidentityserviceprovider.adminSetUserPassword(params, function (err, data) { if (err) { response.send(event, context, "FAILED", {}); } else { response.send(event, context, "SUCCESS", {}); } }); }); }; Handler: index.handler Role: !GetAtt HelperCognitoLambdaRole.Arn Runtime: nodejs12.x Timeout: 30 HelperInitializeCognitoUser: Type: Custom::HelperInitCognitoFunction DependsOn: CognitoUserPool Properties: ServiceToken: !GetAtt HelperInitCognitoFunction.Arn UserPoolId: !Ref CognitoUserPool CognitoUserName: !Ref CognitoUserName CognitoUserPassword: !Ref CognitoUserPassword # <<< helper to create Cognito User without the need to confirm email CognitoUserPoolUserToGroupAttachment: Type: 'AWS::Cognito::UserPoolUserToGroupAttachment' Properties: GroupName: !Ref CognitoUserPoolGroup Username: !Ref CognitoUserName UserPoolId: !Ref CognitoUserPool DependsOn: - CognitoUserPoolGroup - HelperInitializeCognitoUser CognitoUserPoolClient: Type: 'AWS::Cognito::UserPoolClient' Properties: UserPoolId: !Ref CognitoUserPool AllowedOAuthFlows: - implicit AllowedOAuthFlowsUserPoolClient: true AllowedOAuthScopes: - email - openid CallbackURLs: - 'http://localhost' GenerateSecret: false ExplicitAuthFlows: - ALLOW_USER_PASSWORD_AUTH - ALLOW_USER_SRP_AUTH - ALLOW_REFRESH_TOKEN_AUTH SupportedIdentityProviders: - COGNITO DependsOn: - CognitoUserPool # <<< Amazon Cognito # >>> API Service ApiServiceIAMPolicy: Type: 'AWS::IAM::Policy' Properties: Roles: - !Ref ApiServiceIAMRole PolicyName: ApiServiceIAMPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - cognito-idp:Admin* Resource: !GetAtt CognitoUserPool.Arn - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/ApiServiceLambdaFunction:* ApiServiceIAMRole: Type: 'AWS::IAM::Role' Properties: RoleName: ApiServiceIAMRole AssumeRolePolicyDocument: |- { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "lambda.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] } ApiServiceLambdaFunction: Type: 'AWS::Lambda::Function' Properties: FunctionName: ApiServiceLambdaFunction Runtime: "python3.9" Handler: "lambda.handler" Role: !GetAtt ApiServiceIAMRole.Arn Code: S3Bucket: !Sub ${AWS::StackName}-${AWS::AccountId}-${AWS::Region}-lambdas S3Key: "pets-api.zip" ApiServiceLambdaFunctionPermission: Type: 'AWS::Lambda::Permission' Properties: Action: "lambda:InvokeFunction" FunctionName: !GetAtt ApiServiceLambdaFunction.Arn Principal: "apigateway.amazonaws.com" # <<< API Service # >>> Amazon API gateway ApiGatewayRestApi: Type: 'AWS::ApiGateway::RestApi' Properties: Name: "MyApiGateway" ApiGatewayResource: Type: 'AWS::ApiGateway::Resource' Properties: RestApiId: !Ref ApiGatewayRestApi ParentId: !GetAtt ApiGatewayRestApi.RootResourceId PathPart: "{api+}" ApiGatewayMethod: Type: 'AWS::ApiGateway::Method' Properties: HttpMethod: "ANY" ResourceId: !Ref ApiGatewayResource RestApiId: !Ref ApiGatewayRestApi AuthorizationType: NONE Integration: Type: AWS_PROXY IntegrationHttpMethod: "POST" Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ApiServiceLambdaFunction.Arn}/invocations ApiGatewayDeploymentUnProtected: Type: AWS::ApiGateway::Deployment Properties: RestApiId: !Ref ApiGatewayRestApi StageName: dev Description: unprotected api DependsOn: - ApiGatewayMethod # >>> Inputs Parameters: CognitoUserName: Type: String Default: cognitouser Description: Enter Cognito username. CognitoUserPassword: Type: String AllowedPattern: '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[\^$*.\[\]{}\(\)?\-“!@#%&/,><\’:;|_~`])\S{8,99}$' Description: |- Enter Cognito users password. Password must fulfill User Pool Password Requirements. See documentaton for more details https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-policies.html # >>> Outputs Outputs: CognitoUserPoolClientId: Value: !Ref CognitoUserPoolClient CognitoHostedUiUrl: Value: !Sub https://${CognitoUserPoolDomain}.auth.${AWS::Region}.amazoncognito.com/login?client_id=${CognitoUserPoolClient}&response_type=token&scope=email+openid&redirect_uri=http://localhost ApiGatewayDeploymentUrlApiEndpoint: Value: !Sub https://${ApiGatewayRestApi}.execute-api.${AWS::Region}.amazonaws.com/dev/petstore/v1/pets ApiGatewayDeploymentUrlApiEndpointV2: Value: !Sub https://${ApiGatewayRestApi}.execute-api.${AWS::Region}.amazonaws.com/dev/petstore/v2/pets