# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: > Template to deploy lambda functions as part of bootstrap Parameters: CognitoOperationUsersUserPoolId: Type: String CognitoOperationUsersUserPoolClientId: Type: String CognitoUserPoolId: Type: String CognitoUserPoolClientId: Type: String TenantDetailsTableArn: Type: String TenantUserMappingTableArn: Type: String Globals: Function: Timeout: 29 Layers: - !Sub "arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:14" Environment: Variables: LOG_LEVEL: DEBUG POWERTOOLS_METRICS_NAMESPACE: "ServerlessSaaS" Resources: ServerlessSaaSLayers: Type: AWS::Serverless::LayerVersion Properties: LayerName: serverless-saas-dependencies Description: Utilities for project ContentUri: ../layers/ CompatibleRuntimes: - python3.9 LicenseInfo: "MIT" RetentionPolicy: Retain Metadata: BuildMethod: python3.9 AuthorizerExecutionRole: Type: AWS::IAM::Role Properties: RoleName: authorizer-execution-role Path: '/' AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess Policies: - PolicyName: authorizer-execution-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - cognito-idp:List* Resource: - !Sub arn:aws:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/* - Effect: Allow Action: - dynamodb:GetItem Resource: - !Ref TenantDetailsTableArn AuthorizerAccessRole: Type: AWS::IAM::Role DependsOn: AuthorizerExecutionRole Properties: RoleName: authorizer-access-role Path: '/' AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: AWS: - !GetAtt 'AuthorizerExecutionRole.Arn' Action: - sts:AssumeRole Policies: - PolicyName: authorizer-access-role-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - dynamodb:BatchGetItem - dynamodb:GetItem - dynamodb:PutItem - dynamodb:DeleteItem - dynamodb:UpdateItem - dynamodb:Query - dynamodb:Scan Resource: - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/* SharedServicesAuthorizerFunction: Type: AWS::Serverless::Function DependsOn: AuthorizerAccessRole Properties: CodeUri: ../Resources/ Handler: shared_service_authorizer.lambda_handler Runtime: python3.9 Role: !GetAtt AuthorizerExecutionRole.Arn MemorySize: 256 Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: OPERATION_USERS_USER_POOL: !Ref CognitoOperationUsersUserPoolId OPERATION_USERS_APP_CLIENT: !Ref CognitoOperationUsersUserPoolClientId TENANT_USER_POOL: !Ref CognitoUserPoolId TENANT_APP_CLIENT: !Ref CognitoUserPoolClientId #Create user pool for the tenant TenantUserPoolLambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub tenant-userpool-lambda-execution-role-${AWS::Region} Path: "/" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess Policies: - PolicyName: !Sub tenant-userpool-lambda-execution-policy-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - cognito-idp:* Resource: "*" - Effect: Allow Action: - dynamodb:GetItem Resource: - !Ref TenantDetailsTableArn - Effect: Allow Action: - dynamodb:GetItem - dynamodb:Query Resource: - !Ref TenantUserMappingTableArn CreateUserLambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub create-user-lambda-execution-role-${AWS::Region} Path: "/" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess Policies: - PolicyName: !Sub create-user-lambda-execution-policy-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - cognito-idp:* Resource: "*" - Effect: Allow Action: - dynamodb:PutItem Resource: - !Ref TenantUserMappingTableArn - Effect: Allow Action: - dynamodb:GetItem Resource: - !Ref TenantDetailsTableArn CreateTenantAdminUserFunction: Type: AWS::Serverless::Function DependsOn: CreateUserLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.create_tenant_admin_user Runtime: python3.9 Role: !GetAtt CreateUserLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId TENANT_APP_CLIENT_ID: !Ref CognitoUserPoolClientId POWERTOOLS_SERVICE_NAME: "UserManagement.CreateTenantAdmin" #User management CreateUserFunction: Type: AWS::Serverless::Function DependsOn: CreateUserLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.create_user Runtime: python3.9 Role: !GetAtt CreateUserLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId POWERTOOLS_SERVICE_NAME: "UserManagement.CreateUser" UpdateUserFunction: Type: AWS::Serverless::Function DependsOn: TenantUserPoolLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.update_user Runtime: python3.9 Role: !GetAtt TenantUserPoolLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId POWERTOOLS_SERVICE_NAME: "UserManagement.UpdateUser" DisableUserFunction: Type: AWS::Serverless::Function DependsOn: TenantUserPoolLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.disable_user Runtime: python3.9 Role: !GetAtt TenantUserPoolLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId POWERTOOLS_SERVICE_NAME: "UserManagement.DisableUser" DisableUsersByTenantFunction: Type: AWS::Serverless::Function DependsOn: TenantUserPoolLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.disable_users_by_tenant Runtime: python3.9 Role: !GetAtt TenantUserPoolLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId POWERTOOLS_SERVICE_NAME: "UserManagement.DisableUsersByTenant" EnableUsersByTenantFunction: Type: AWS::Serverless::Function DependsOn: TenantUserPoolLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.enable_users_by_tenant Runtime: python3.9 Role: !GetAtt TenantUserPoolLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId POWERTOOLS_SERVICE_NAME: "UserManagement.EnableUsersByTenant" GetUserFunction: Type: AWS::Serverless::Function DependsOn: TenantUserPoolLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.get_user Runtime: python3.9 Role: !GetAtt TenantUserPoolLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId POWERTOOLS_SERVICE_NAME: "UserManagement.GetUser" GetUsersFunction: Type: AWS::Serverless::Function DependsOn: TenantUserPoolLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: user-management.get_users Runtime: python3.9 Role: !GetAtt TenantUserPoolLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: TENANT_USER_POOL_ID: !Ref CognitoUserPoolId POWERTOOLS_SERVICE_NAME: "UserManagement.GetUsers" #Tenant Management TenantManagementLambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub tenant-management-lambda-execution-role-${AWS::Region} Path: "/" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess Policies: - PolicyName: !Sub create-tenant-execution-policy-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - dynamodb:PutItem - dynamodb:GetItem - dynamodb:UpdateItem - dynamodb:Scan - dynamodb:Query Resource: - !Ref TenantDetailsTableArn - !Join ["", [!Ref TenantDetailsTableArn, '/index/*']] CreateTenantFunction: Type: AWS::Serverless::Function DependsOn: TenantManagementLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: tenant-management.create_tenant Runtime: python3.9 Role: !GetAtt TenantManagementLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: POWERTOOLS_SERVICE_NAME: "TenantManagement.CreateTenant" ActivateTenantFunction: Type: AWS::Serverless::Function DependsOn: TenantManagementLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: tenant-management.activate_tenant Runtime: python3.9 Role: !GetAtt TenantManagementLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: POWERTOOLS_SERVICE_NAME: "TenantManagement.ActivateTenant" ENABLE_USERS_BY_TENANT: "/users/enable" PROVISION_TENANT: "/provisioning/" GetTenantFunction: Type: AWS::Serverless::Function DependsOn: TenantManagementLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: tenant-management.get_tenant Runtime: python3.9 Role: !GetAtt TenantManagementLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: POWERTOOLS_SERVICE_NAME: "TenantManagement.GetTenant" DeactivateTenantFunction: Type: AWS::Serverless::Function DependsOn: TenantManagementLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: tenant-management.deactivate_tenant Runtime: python3.9 Role: !GetAtt TenantManagementLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: POWERTOOLS_SERVICE_NAME: "TenantManagement.DeactivateTenant" DEPROVISION_TENANT: "/provisioning/" DISABLE_USERS_BY_TENANT: "/users/disable" UpdateTenantFunction: Type: AWS::Serverless::Function DependsOn: TenantManagementLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: tenant-management.update_tenant Runtime: python3.9 Role: !GetAtt TenantManagementLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: POWERTOOLS_SERVICE_NAME: "TenantManagement.UpdateTenant" GetTenantsFunction: Type: AWS::Serverless::Function DependsOn: TenantManagementLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: tenant-management.get_tenants Runtime: python3.9 Role: !GetAtt TenantManagementLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers #Tenant Registration RegisterTenantLambdaExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub tenant-registration-lambda-execution-role-${AWS::Region} Path: "/" AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess RegisterTenantFunction: Type: AWS::Serverless::Function DependsOn: RegisterTenantLambdaExecutionRole Properties: CodeUri: ../TenantManagementService/ Handler: tenant-registration.register_tenant Runtime: python3.9 Role: !GetAtt RegisterTenantLambdaExecutionRole.Arn Tracing: Active Layers: - !Ref ServerlessSaaSLayers Environment: Variables: # Need to find a better way than hard coding resource paths CREATE_TENANT_ADMIN_USER_RESOURCE_PATH: "/user/tenant-admin" CREATE_TENANT_RESOURCE_PATH: "/tenant" PROVISION_TENANT_RESOURCE_PATH: "/provisioning" POWERTOOLS_SERVICE_NAME: "TenantRegistration.RegisterTenant" Outputs: RegisterTenantLambdaExecutionRoleArn: Value: !GetAtt RegisterTenantLambdaExecutionRole.Arn TenantManagementLambdaExecutionRoleArn: Value: !GetAtt TenantManagementLambdaExecutionRole.Arn RegisterTenantFunctionArn: Value: !GetAtt RegisterTenantFunction.Arn ActivateTenantFunctionArn: Value: !GetAtt ActivateTenantFunction.Arn GetTenantsFunctionArn: Value: !GetAtt GetTenantsFunction.Arn CreateTenantFunctionArn: Value: !GetAtt CreateTenantFunction.Arn GetTenantFunctionArn: Value: !GetAtt GetTenantFunction.Arn DeactivateTenantFunctionArn: Value: !GetAtt DeactivateTenantFunction.Arn UpdateTenantFunctionArn: Value: !GetAtt UpdateTenantFunction.Arn GetUsersFunctionArn: Value: !GetAtt GetUsersFunction.Arn GetUserFunctionArn: Value: !GetAtt GetUserFunction.Arn UpdateUserFunctionArn: Value: !GetAtt UpdateUserFunction.Arn DisableUserFunctionArn: Value: !GetAtt DisableUserFunction.Arn CreateTenantAdminUserFunctionArn: Value: !GetAtt CreateTenantAdminUserFunction.Arn CreateUserFunctionArn: Value: !GetAtt CreateUserFunction.Arn DisableUsersByTenantFunctionArn: Value: !GetAtt DisableUsersByTenantFunction.Arn EnableUsersByTenantFunctionArn: Value: !GetAtt EnableUsersByTenantFunction.Arn SharedServicesAuthorizerFunctionArn: Value: !GetAtt SharedServicesAuthorizerFunction.Arn AuthorizerExecutionRoleArn: Value: !GetAtt AuthorizerExecutionRole.Arn