AWSTemplateFormatVersion: "2010-09-09" Description: Amazon Rekognition Custom Labels Demo (uksb-1q6fl3pi5) Transform: AWS::Serverless-2016-10-31 Globals: Function: Runtime: nodejs18.x MemorySize: 1024 Timeout: 300 Environment: Variables: COGNITO_IDENTITY_POOL: !Ref CognitoIdentityPool COGNITO_USER_POOL_ID: !Ref CognitoUserPool COGNITO_USER_POOL_CLIENT_ID: !Ref CognitoUserPoolClient FROM_BUCKET: !Sub solution-builders-${AWS::Region} CREATE_CLOUDFRONT_DISTRIBUTION: !Ref CreateCloudFrontDistribution REGION: !Ref AWS::Region TO_BUCKET: !Ref WebUIBucket VERSION: "1.8" Parameters: AdminEmail: Description: Creates a username to be used for Authentication. It needs to be an e-mail address. Type: String AllowedPattern: ^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$ ResourcePrefix: Description: AWS Resources are named based on the value of this parameter. You must customise this if you are launching more than one instance of the stack within the same account. Type: String Default: RekogCustomLabelsDemo AllowedPattern: ^[a-zA-Z0-9_]*$ CreateCloudFrontDistribution: Description: Creates a CloudFront distribution for accessing the web interface of the demo. This must be enabled if S3 Block Public Access is enabled at an account level. Type: String Default: "true" AllowedValues: - "true" - "false" Conditions: WithCloudFront: !Equals [!Ref CreateCloudFrontDistribution, "true"] Outputs: url: Value: !If - WithCloudFront - !Sub "https://${CloudFrontDistribution.DomainName}" - !Sub "https://${WebUIBucket.RegionalDomainName}/index.html" Description: Amazon Rekognition Custom Labels Demo Url Resources: SetupWebUI: Type: Custom::Setup Properties: ServiceToken: !GetAtt LambdaSetup.Arn Region: !Ref AWS::Region WebUIBucket: Type: AWS::S3::Bucket Properties: CorsConfiguration: CorsRules: - AllowedHeaders: ["*"] AllowedMethods: [GET] AllowedOrigins: ["*"] Id: !Sub ${ResourcePrefix}RekogCorsRule MaxAge: 3600 BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 WebUIBucketReadPolicy: Type: AWS::S3::BucketPolicy Condition: WithCloudFront Properties: Bucket: !Ref WebUIBucket PolicyDocument: Statement: - Action: s3:GetObject Effect: Allow Resource: !Sub arn:aws:s3:::${WebUIBucket}/* Principal: CanonicalUser: !GetAtt CloudFrontOriginAccessIdentity.S3CanonicalUserId CognitoIdentityPool: Type: AWS::Cognito::IdentityPool Properties: IdentityPoolName: !Sub ${ResourcePrefix}RekogIdentityPool CognitoIdentityProviders: - ClientId: !Ref CognitoUserPoolClient ProviderName: !GetAtt CognitoUserPool.ProviderName AllowUnauthenticatedIdentities: false CognitoIdentityPoolRole: Type: AWS::Cognito::IdentityPoolRoleAttachment Properties: IdentityPoolId: !Ref CognitoIdentityPool Roles: authenticated: !GetAtt RekognitionInvokeRole.Arn CognitoUserPool: Type: AWS::Cognito::UserPool Properties: UserPoolName: !Sub ${ResourcePrefix}RekogUsersPool AdminCreateUserConfig: AllowAdminCreateUserOnly: true InviteMessageTemplate: EmailMessage: 'Your Amazon Rekognition Custom Labels Demo username is {username} and the temporary password is {####}' EmailSubject: 'Your temporary password for Amazon Rekognition Custom Labels Demo' SMSMessage: 'Your Amazon Rekognition Custom Labels Demo username is {username} and the temporary password is {####}' AutoVerifiedAttributes: - email Policies: PasswordPolicy: MinimumLength: 6 RequireLowercase: false RequireNumbers: false RequireSymbols: false RequireUppercase: false CognitoUserPoolClient: Type: AWS::Cognito::UserPoolClient Properties: UserPoolId: !Ref CognitoUserPool ClientName: !Sub ${ResourcePrefix}RekogUsersPoolClient GenerateSecret: false RefreshTokenValidity: 30 CognitoUserPoolUser: Type: AWS::Cognito::UserPoolUser Properties: Username: !Ref AdminEmail UserPoolId: !Ref CognitoUserPool DesiredDeliveryMediums: - EMAIL UserAttributes: - Name: email Value: !Ref AdminEmail - Name: email_verified Value: "true" RekognitionInvokeRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Federated: - cognito-identity.amazonaws.com Action: - sts:AssumeRole - sts:AssumeRoleWithWebIdentity Condition: StringEquals: "cognito-identity.amazonaws.com:aud": !Ref CognitoIdentityPool Policies: - PolicyName: RekogCustomLabelsDemo-RekogInvoke PolicyDocument: Statement: - Effect: Allow Action: - rekognition:DetectCustomLabels - rekognition:DescribeProjectVersions - rekognition:StopProjectVersion - rekognition:StartProjectVersion - rekognition:DescribeProjects Resource: "*" CustomResourceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: RekogCustomLabelsDemo-setup-S3-fc PolicyDocument: Statement: - Effect: Allow Action: - s3:DeleteObject - s3:ListBucket - s3:PutObject - s3:PutObjectAcl Resource: - !GetAtt WebUIBucket.Arn - !Sub ${WebUIBucket.Arn}/* - Effect: Allow Action: s3:GetObject Resource: !Sub "arn:aws:s3:::solution-builders-${AWS::Region}/*" - PolicyName: RekogCustomLabelsDemo-cloudwatch-logs PolicyDocument: Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:* - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:*:log-stream:* LambdaSetup: Type: AWS::Serverless::Function Properties: FunctionName: !Sub ${ResourcePrefix}RekogCustomLabelsDemoSetup Handler: index.handler CodeUri: ../backend/functions/setup/ Description: Custom Lambda resource for the Amazon Rekognition Custom Labels Demo Cloudformation Stack Role: !GetAtt CustomResourceRole.Arn CloudFrontOriginAccessIdentity: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Condition: WithCloudFront Properties: CloudFrontOriginAccessIdentityConfig: Comment: !Ref WebUIBucket CloudFrontDistribution: Type: AWS::CloudFront::Distribution Condition: WithCloudFront Properties: DistributionConfig: Origins: - DomainName: !GetAtt WebUIBucket.RegionalDomainName Id: !Sub ${ResourcePrefix}-myS3Origin S3OriginConfig: OriginAccessIdentity: !Sub origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity} Enabled: true HttpVersion: http2 Comment: The Distribution for the Rekognition Custom Label Demo DefaultRootObject: index.html DefaultCacheBehavior: AllowedMethods: - HEAD - GET - OPTIONS TargetOriginId: !Sub ${ResourcePrefix}-myS3Origin ForwardedValues: QueryString: false Cookies: Forward: none ViewerProtocolPolicy: redirect-to-https PriceClass: PriceClass_All ViewerCertificate: CloudFrontDefaultCertificate: true