AWSTemplateFormatVersion: 2010-09-09 Description: > This template deploys a CI/CD pipeline used to build the Lex Web UI. It deploys a CodePipeline pipeline, a CodeBuild project and and S3 buckets to hold build artifacts and to host the application. It optionally deploys a Lambda function to delete the S3 bucket. Additionally, it deploys the related IAM roles needed for the stack. Parameters: CodePipelineName: Type: String Description: Name of CodePipeline to be created. Default: lex-web-ui MinLength: 1 MaxLength: 100 AllowedPattern: '^[A-Za-z0-9.@\-_]+$' ConstraintDescription: Alphanumeric, dot and dash. CodeCommitRepoName: Type: String Description: > CodeCommit repository name to be used as the source of the pipeline. Default: lex-web-ui MinLength: 1 MaxLength: 100 AllowedPattern: '^[\w\.-]+$' ConstraintDescription: Alphanumeric, dot and dash. RepoBranchName: Type: String Description: > CodeCommit repository branch name to be used as the source of the pipeline. Default: master MinLength: 1 MaxLength: 100 AllowedPattern: '^[\w\.-]+$' ConstraintDescription: Alphanumeric, dot and dash. CodeBuildName: Type: String Description: > CodeBuild project to be created. Used for building the web app with the pipeline. Default: lex-web-ui MinLength: 2 MaxLength: 255 AllowedPattern: '^[A-Za-z0-9][A-Za-z0-9\-_]{1,254}$' ConstraintDescription: > Should start with Alphanumeric. May contain alphanumeric, underscore and dash. CognitoIdentityPoolId: Type: String Description: > Cognito Identity Pool Id to used in the web app configuration. MinLength: 1 MaxLength: 55 AllowedPattern: '^[\w-]+:[0-9a-f-]+$' ConstraintDescription: > Alphanumeric followed by a column and ending with a hex uuid type. CognitoAppUserPoolClientId: Type: String Description: > Cognito App User Pool Client Id to used in the web app configuration. CognitoUserPoolId: Type: String Description: > Cognito App User Pool Id LexV2BotId: Description: > Bot ID (not bot name) of an existing Lex V2 Bot to be used by the web ui. NOTE: You must also enter your Bot alias ID in the LexV2BotAliasId field below. Type: String Default: '' MinLength: 0 MaxLength: 50 AllowedPattern: '(^$|^[a-zA-Z0-9]+((_[a-zA-Z0-9]+)*|([a-zA-Z0-9]+_)*|_))' ConstraintDescription: > Must conform with the permitted Lex V2 Bot name pattern. LexV2BotAliasId: Description: > Use your Lex V2 bot's alias id (not alias name) here. Type: String Default: '' MinLength: 0 MaxLength: 50 AllowedPattern: '(^$|^[$a-zA-Z0-9]+((_[$a-zA-Z0-9]+)*|([$a-zA-Z0-9]+_)*|_))' ConstraintDescription: > Must conform with the permitted Lex V2 Alias name pattern. LexV2BotLocaleId: Description: > Use your bot's locale id here. By default this is en_US. Lex V2 supported values are en_AU, en_GB, es_419, es_ES, es_US, fr_CA, fr_FR, it_IT. See "https://docs.aws.amazon.com/lexv2/latest/dg/lex2.0.pdf" for details on supported languages and locales. Type: String Default: 'en_US' MinLength: 2 MaxLength: 50 BotName: Description: > Name of an existing Lex Bot to be used by the web ui. NOTE: You must also enter your published bot alias in the BotAlias field below. DO NOT MODIFY this value if configuring a V2 Bot. Type: String Default: '' MinLength: 0 MaxLength: 50 AllowedPattern: '(^$|^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_))' ConstraintDescription: > Must conform with the permitted Lex Bot name pattern. BotAlias: Description: > WARNING: For production deployments, use your bot's published alias here. The $LATEST alias should only be used for manual testing. Amazon Lex limits the number of runtime requests that you can make to the $LATEST version of the bot. DO NOT MODIFY this value if configuring a V2 Bot. Type: String Default: '$LATEST' MinLength: 2 MaxLength: 50 AllowedPattern: '(^$|^[$a-zA-Z]+((_[$a-zA-Z]+)*|([$a-zA-Z]+_)*|_))' ConstraintDescription: > Must conform with the permitted Lex Alias name pattern. ParentOrigin: Type: String Description: > Browser origin (e.g. http://mysite.example.com:8080) of an existing site that is allowed to send/receive data and events from the web ui in an iframe setup. This is an optional parameter. If left empty, an S3 bucket will be created to host a sample parent site embedding the webapp as an iframe. AllowedPattern: '(^$|^https?://[\w\.-]+(:\d+)?$)' ConstraintDescription: Empty or valid browser origin CleanupBuckets: Type: String Default: true AllowedValues: - true - false Description: > If set to True, buckets and their associated data will be deleted on CloudFormation stack delete. If set to False, S3 buckets will be retained. CustomResourceCodeBucket: Type: String Description: S3 bucket name for custom resource Lambda bundle Default: tom-bootstrap-bucket # Default: aws-bigdata-blog CustomResourceCodePrefix: Type: String Description: Prefix that identifies root of custom resources Default: artifacts CustomResourceCodeObject: Type: String Description: > S3 object zip file containing Lambda custom resource functions Default: artifacts/aws-lex-web-ui/artifacts/custom-resources.zip InitiateChatLambdaCodeObject: Type: String Description: > S3 object zip file containing Lambda custom resource functions Default: artifacts/aws-lex-web-ui/artifacts/initiate-chat-lambda.zip WebAppConfNegativeFeedback: Type: String Default: Thumbs down Description: > This optional parameter defines the message to be sent by the user upon pressing a feedback button signaling a negative feedback. If left empty feedback buttons will be disabled on the UI. WebAppConfPositiveFeedback: Type: String Default: Thumbs up Description: > This optional parameter defines the message to be sent by the user upon pressing a feedback button signaling a positive feedback. If left empty feedback buttons will be disabled on the UI. WebAppConfHelp: Type: String Default: Help Description: > This is an optional parameter, when defined with a value, a help button will display on the chat bot toolbar. When pressed the button will send the entered string to the bot as a help message. If left empty the help button will be disabled. WebAppConfCname: Type: String Default: "" Description: This optional parameter allows a single CNAME to be defined and used as an alias to the cloudfront distribution that is created by this template. If a CNAME is provided, a WebAppAcmCertificateArn must also be provided. WebAppAcmCertificateArn: Type: String Default: "" Description: This optional parameter allows a AcmCertificateArn to be provided for use in the Cloudfront distribution created by this template. if a AcmCertificateArn is provided, a WebAppConfCname must also be provided. WebAppWafAclArn: Type: String Default: "" Description: This optional parameter allows a AWS WAF web ACL to be specified in ARN formation. This supports AWS WAF V2. ShouldEnableLiveChat: Type: String Default: false AllowedValues: - true - false Description: > This is an optional parameter, if set to True, the AWS Connect live Chat functionality will be available. A item to start a live chat will appear at the menu. ConnectContactFlowId: Type: String Description: > Connect Contract Flow Id ConnectInstanceId: Type: String Description: > Connect Instance Id Default: "" ConnectPromptForNameMessage: Type: String Description: > Message to display prompting the user for a name Default: Before starting a live chat, please tell me your name? ConnectWaitForAgentMessage: Type: String Description: > Message to display every message interval while waiting for an agent to connect Default: Thanks for waiting. An agent will be with you when available. ConnectWaitForAgentMessageIntervalInSeconds: Type: Number Description: > Interval in seconds between successive ConnectWaitForAgentMessage. 0 to disable interval. Default: 60 ConnectAgentJoinedMessage: Type: String Description: > Message to play when an agent joins the chat. {Agent} will be replaced with the Agent's name. Default: "{Agent} has joined." ConnectAgentLeftMessage: Type: String Description: > Message to play when an agent leaves the chat. {Agent} will be replaced with the Agent's name. Default: "{Agent} has left." ConnectChatEndedMessage: Type: String Description: > Message to play when a chat session has ended. Default: "Chat ended." ConnectAttachChatTranscript: Type: String Default: true AllowedValues: - true - false Description: > Attach chat transcript as file. This only works if you enable ConnectLiveChatTerms: Type: String Description: > Command separated list of terms that can be used to start Live Chat mode Default: "live chat" ConnectStartLiveChatLabel: Type: String Description: > Label used in Menu to start connect live chat Default: "Start Live Chat" ConnectStartLiveChatIcon: Type: String Description: > Icon to use in menu to start connect live chat Default: "people_alt" ConnectEndLiveChatLabel: Type: String Description: > Label to use in menu and toolbar to end connect live chat Default: "End Live Chat" ConnectEndLiveChatIcon: Type: String Description: > Icon to use in menu and toolbar to end connect live chat Default: "call_end" ConnectTranscriptMessageDelayInMsec: Type: Number Description: > Delay to insert between each transcript message send to Connect in msec. Default: 150 ResourcePrefix: Type: String Description: > This will be a prefix for resources that must have unique names. Conditions: NeedsParentOrigin: !Equals [!Ref ParentOrigin, ''] ShouldCleanupBuckets: !Equals [!Ref CleanupBuckets, true] EnableLiveChat: !Equals [!Ref ShouldEnableLiveChat, true] UseDefaultCloudfrontUrl: !Or [ !Equals [!Ref WebAppConfCname, ''], !Equals [!Ref WebAppAcmCertificateArn, ''] ] ShouldNotSpecifyWafAcl: !Equals [!Ref WebAppWafAclArn, ''] Resources: # Bucket where S3 access logs are stored S3ServerAccessLogs: Type: AWS::S3::Bucket UpdateReplacePolicy: Retain DeletionPolicy: Retain Properties: VersioningConfiguration: Status: Enabled AccessControl: "LogDeliveryWrite" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 # Artifact Bucket used by CodePipeline and CodBuild ArtifactStore: Type: AWS::S3::Bucket UpdateReplacePolicy: Retain DeletionPolicy: Retain Properties: VersioningConfiguration: Status: Enabled LoggingConfiguration: DestinationBucketName: !Ref S3ServerAccessLogs LogFilePrefix: "artifactstore/" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 # Bucket where the web app is deployed WebAppBucket: Type: AWS::S3::Bucket UpdateReplacePolicy: Retain DeletionPolicy: Retain Properties: WebsiteConfiguration: IndexDocument: index.html VersioningConfiguration: Status: Enabled LoggingConfiguration: DestinationBucketName: !Ref S3ServerAccessLogs LogFilePrefix: "webappbucket/" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 WebAppBucketOriginAccessIdentity: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Properties: CloudFrontOriginAccessIdentityConfig: Comment: !Sub "access-identity-${WebAppBucket}" WebAppBucketBucketPolicy: Type: "AWS::S3::BucketPolicy" Properties: Bucket: Ref: "WebAppBucket" PolicyDocument: Statement: - Effect: "Allow" Action: - "s3:GetObject" Resource: - !Sub "arn:aws:s3:::${WebAppBucket}/*" Principal: CanonicalUser: !GetAtt WebAppBucketOriginAccessIdentity.S3CanonicalUserId # Bucket for CloudFrontDistributionLogs LexWebUiCloudFrontDistributionLogsBucket: Type: AWS::S3::Bucket UpdateReplacePolicy: Retain DeletionPolicy: Retain Properties: VersioningConfiguration: Status: Enabled BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 LexWebUIResponseHeaderPolicy: Type : "AWS::CloudFront::ResponseHeadersPolicy" Properties: ResponseHeadersPolicyConfig: Comment: "Response header policy for LexWebUI" Name: !Join ["-", [!Ref ResourcePrefix, "LexWebUIResponseHeaderPolicy"]] CorsConfig: AccessControlAllowOrigins: Items: - !If - NeedsParentOrigin - "*" - !Ref ParentOrigin AccessControlAllowHeaders: Items: - "*" AccessControlAllowMethods: Items: - "GET" AccessControlAllowCredentials: False AccessControlMaxAgeSec: 600 OriginOverride: true SecurityHeadersConfig: XSSProtection: Override: False Protection: True ModeBlock: True ReferrerPolicy: Override: False ReferrerPolicy: "strict-origin-when-cross-origin" ContentTypeOptions: Override: false StrictTransportSecurity: Override: False IncludeSubdomains: True Preload: False AccessControlMaxAgeSec: 47304000 #cloudfront distribution LexWebUiDistribution: Type: AWS::CloudFront::Distribution DependsOn: - WebAppBucket Properties: DistributionConfig: Origins: - DomainName: !Sub "${WebAppBucket}.s3.${AWS::Region}.amazonaws.com" S3OriginConfig: OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${WebAppBucketOriginAccessIdentity}" Id: webuiorigin Enabled: 'true' Comment: cloudfront distribution for lex-web-ui DefaultRootObject: index.html Logging: Bucket: !GetAtt LexWebUiCloudFrontDistributionLogsBucket.DomainName IncludeCookies: true Prefix: "lexwebui/" CustomErrorResponses: # Send errors to index file # TODO move TTL to mapping or parameter - ErrorCachingMinTTL: 300 ErrorCode: 403 ResponseCode: 200 ResponsePagePath: /index.html - ErrorCachingMinTTL: 300 ErrorCode: 404 ResponseCode: 200 ResponsePagePath: /index.html DefaultCacheBehavior: AllowedMethods: - GET - HEAD - OPTIONS CachedMethods: - GET - HEAD - OPTIONS Compress: true TargetOriginId: webuiorigin CachePolicyId: "658327ea-f89d-4fab-a63d-7e88639e58f6" OriginRequestPolicyId: "88a5eaf4-2fd4-4709-b370-b4c650ea3fcf" ViewerProtocolPolicy: redirect-to-https ResponseHeadersPolicyId: !GetAtt LexWebUIResponseHeaderPolicy.Id Aliases: !If - UseDefaultCloudfrontUrl - !Ref AWS::NoValue - [ !Ref WebAppConfCname ] ViewerCertificate: !If - UseDefaultCloudfrontUrl - CloudFrontDefaultCertificate: true - AcmCertificateArn: !Ref WebAppAcmCertificateArn CloudFrontDefaultCertificate: false MinimumProtocolVersion: TLSv1.2_2018 SslSupportMethod: sni-only WebACLId: !If - ShouldNotSpecifyWafAcl - !Ref AWS::NoValue - !Ref WebAppWafAclArn HttpVersion: http2 IPV6Enabled: true # Bucket where the test parent page is hosted ParentPageBucket: Type: AWS::S3::Bucket Condition: NeedsParentOrigin UpdateReplacePolicy: Retain DeletionPolicy: Retain Properties: WebsiteConfiguration: IndexDocument: index.html VersioningConfiguration: Status: Enabled LoggingConfiguration: DestinationBucketName: !Ref S3ServerAccessLogs LogFilePrefix: "parentpagebucket/" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 RestApi: Type: AWS::CloudFormation::Stack Condition: EnableLiveChat Properties: TimeoutInMinutes: 15 TemplateURL: !Sub "https://${CustomResourceCodeBucket}.s3.${AWS::Region}.amazonaws.com/${CustomResourceCodePrefix}/templates/restapi.yaml" Parameters: ParentStackName: !Ref "AWS::StackName" SourceBucket: !Ref CustomResourceCodeBucket InitiateChatLambdaCodeObject: !Ref InitiateChatLambdaCodeObject ConnectContactFlowId: !Ref ConnectContactFlowId ConnectInstanceId: !Ref ConnectInstanceId ParentOrigin: !Sub "https://${LexWebUiDistribution.DomainName}" CodeBuild: Type: AWS::CodeBuild::Project Properties: Name: !Ref CodeBuildName Description: Used to build the Lex Web UI ServiceRole: !GetAtt CodeBuildRole.Arn TimeoutInMinutes: 30 Artifacts: Type: CODEPIPELINE Environment: Type: LINUX_CONTAINER Image: aws/codebuild/amazonlinux2-x86_64-standard:2.0 ComputeType: BUILD_GENERAL1_SMALL EnvironmentVariables: - Name: BUILD_TYPE Value: full - Name: POOL_ID Value: !Ref CognitoIdentityPoolId - Name: ENABLE_LIVE_CHAT Value: !Ref ShouldEnableLiveChat - Name: CONNECT_CONTACT_FLOW_ID Value: !Ref ConnectContactFlowId - Name: CONNECT_INSTANCE_ID Value: !Ref ConnectInstanceId - Name: CONNECT_API_GATEWAY_ENDPOINT Value: !If [EnableLiveChat, !Sub "https://${RestApi.Outputs.RestApiId}.execute-api.${AWS::Region}.amazonaws.com/Prod/livechat", ""] - Name: CONNECT_PROMPT_FOR_NAME_MESSAGE Value: !Ref ConnectPromptForNameMessage - Name: CONNECT_WAIT_FOR_AGENT_MESSAGE Value: !Ref ConnectWaitForAgentMessage - Name: CONNECT_WAIT_FOR_AGENT_MESSAGE_INTERVAL_IN_SECONDS Value: !Ref ConnectWaitForAgentMessageIntervalInSeconds - Name: CONNECT_LIVE_CHAT_TERMS Value: !Ref ConnectLiveChatTerms - Name: CONNECT_AGENT_JOINED_MESSAGE Value: !Ref ConnectAgentJoinedMessage - Name: CONNECT_AGENT_LEFT_MESSAGE Value: !Ref ConnectAgentLeftMessage - Name: CONNECT_CHAT_ENDED_MESSAGE Value: !Ref ConnectChatEndedMessage - Name: CONNECT_ATTACH_CHAT_TRANSCRIPT Value: !Ref ConnectAttachChatTranscript - Name: CONNECT_START_LIVE_CHAT_LABEL Value: !Ref ConnectStartLiveChatLabel - Name: CONNECT_START_LIVE_CHAT_ICON Value: !Ref ConnectStartLiveChatIcon - Name: CONNECT_END_LIVE_CHAT_LABEL Value: !Ref ConnectEndLiveChatLabel - Name: CONNECT_END_LIVE_CHAT_ICON Value: !Ref ConnectEndLiveChatIcon - Name: CONNECT_TRANSCRIPT_MESSAGE_DELAY_IN_MSEC Value: !Ref ConnectTranscriptMessageDelayInMsec - Name: APP_USER_POOL_CLIENT_ID Value: !Ref CognitoAppUserPoolClientId - Name: APP_USER_POOL_NAME Value: !Ref CognitoUserPoolId - Name: WEBAPP_BUCKET Value: !Ref WebAppBucket - Name: AWS_DEFAULT_REGION Value: !Sub "${AWS::Region}" - Name: V2_BOT_ID Value: !Ref LexV2BotId - Name: V2_BOT_ALIAS_ID Value: !Ref LexV2BotAliasId - Name: V2_BOT_LOCALE_ID Value: !Ref LexV2BotLocaleId - Name: BOT_NAME Value: !Ref BotName - Name: BOT_ALIAS Value: !Ref BotAlias - Name: PARENT_ORIGIN Value: !If - NeedsParentOrigin - !Sub "https://${LexWebUiDistribution.DomainName}" - !Ref ParentOrigin - Name: IFRAME_ORIGIN Value: !Sub "https://${LexWebUiDistribution.DomainName}" - Name: NEGATIVE_INTENT Value: !Ref WebAppConfNegativeFeedback - Name: POSITIVE_INTENT Value: !Ref WebAppConfPositiveFeedback - Name: HELP_INTENT Value: !Ref WebAppConfHelp Source: Type: CODEPIPELINE BuildSpec: !Sub | version: 0.1 phases: install: commands: - make install-deps pre_build: commands: - aws configure set region "$AWS_DEFAULT_REGION" - cp src/config/default-lex-web-ui-loader-config.json src/config/lex-web-ui-loader-config.json - make config build: commands: - make build post_build: commands: - make sync-website - aws cloudfront create-invalidation --distribution-id "${LexWebUiDistribution}" --paths '/*' CodeBuildRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Principal: Service: - codebuild.amazonaws.com Effect: Allow Action: - sts:AssumeRole Policies: - PolicyName: CloudFrontInvalidateDistribution PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - cloudfront:CreateInvalidation Resource: "*" - PolicyName: CloudWatchLogsCodeBuild PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}" - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${CodeBuildName}:*" - PolicyName: S3ReadWrite PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:Get* - s3:Head* - s3:List* - s3:CreateMultipartUpload - s3:CompleteMultipartUpload - s3:AbortMultipartUpload - s3:CopyObject - s3:PutObject* - s3:DeleteObject* - s3:Upload* Resource: - !Sub "arn:aws:s3:::${ArtifactStore}" - !Sub "arn:aws:s3:::${ArtifactStore}/*" - !Sub "arn:aws:s3:::${WebAppBucket}" - !Sub "arn:aws:s3:::${WebAppBucket}/*" - !If - NeedsParentOrigin - !Sub "arn:aws:s3:::${ParentPageBucket}" - !Ref AWS::NoValue - !If - NeedsParentOrigin - !Sub "arn:aws:s3:::${ParentPageBucket}/*" - !Ref AWS::NoValue - PolicyName: PollySynthesizeSpeech PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - polly:SynthesizeSpeech Resource: "*" - PolicyName: TranslateText PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - translate:TranslateText - comprehend:DetectDominantLanguage Resource: "*" CodePipeline: Type: AWS::CodePipeline::Pipeline Properties: Name: !Ref CodePipelineName ArtifactStore: Type: S3 Location: !Ref ArtifactStore RoleArn: !GetAtt CodePipelineRole.Arn Stages: - Name: Source Actions: - Name: CodeCommitRepo ActionTypeId: Category: Source Owner: AWS Version: 1 Provider: CodeCommit OutputArtifacts: - Name: SourceOutput Configuration: RepositoryName: !Ref CodeCommitRepoName BranchName: !Ref RepoBranchName RunOrder: 1 - Name: BuildDeploy Actions: - Name: WebApp InputArtifacts: - Name: SourceOutput ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild Configuration: ProjectName: !Ref CodeBuild RunOrder: 1 CodePipelineRole: Type: AWS::IAM::Role Properties: Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Principal: Service: - codepipeline.amazonaws.com Effect: Allow Action: - sts:AssumeRole Policies: - PolicyName: CodeCommit PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - codecommit:GetBranch - codecommit:GetCommit - codecommit:UploadArchive - codecommit:GetUploadArchiveStatus - codecommit:CancelUploadArchive Resource: - !Sub "arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:${CodeCommitRepoName}" - PolicyName: S3ReadWrite PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:Get* - s3:Head* - s3:List* - s3:CreateMultipartUpload - s3:CompleteMultipartUpload - s3:AbortMultipartUpload - s3:CopyObject - s3:PutObject* - s3:DeleteObject* - s3:Upload* Resource: - !Sub "arn:aws:s3:::${ArtifactStore}" - !Sub "arn:aws:s3:::${ArtifactStore}/*" - PolicyName: CodeBuildStart PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - codebuild:BatchGetBuilds - codebuild:StartBuild Resource: !GetAtt CodeBuild.Arn # custom resource to cleanup S3 buckets S3Cleanup: Type: Custom::S3Cleanup Condition: ShouldCleanupBuckets Properties: ServiceToken: !GetAtt S3CleanupLambda.Arn Buckets: - !Ref ArtifactStore - !Ref WebAppBucket - !If - NeedsParentOrigin - !Ref ParentPageBucket - !Ref AWS::NoValue # Lambda function for custom resource S3CleanupLambda: Type: AWS::Lambda::Function Condition: ShouldCleanupBuckets Properties: Code: S3Bucket: !Ref CustomResourceCodeBucket S3Key: !Ref CustomResourceCodeObject Handler: s3-cleanup.handler Role: !GetAtt S3CleanupLambdaRole.Arn Runtime: python3.7 Timeout: 120 TracingConfig: Mode: Active S3CleanupLambdaRole: Type: AWS::IAM::Role Condition: ShouldCleanupBuckets Properties: Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Principal: Service: - lambda.amazonaws.com Effect: Allow Action: - sts:AssumeRole Policies: - PolicyName: LogsForLambda PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*" - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:*" - PolicyName: S3All PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - s3:* Resource: - !Sub "arn:aws:s3:::${ArtifactStore}" - !Sub "arn:aws:s3:::${ArtifactStore}/*" - !Sub "arn:aws:s3:::${WebAppBucket}" - !Sub "arn:aws:s3:::${WebAppBucket}/*" - !If - NeedsParentOrigin - !Sub "arn:aws:s3:::${ParentPageBucket}" - !Ref AWS::NoValue - !If - NeedsParentOrigin - !Sub "arn:aws:s3:::${ParentPageBucket}/*" - !Ref AWS::NoValue - PolicyName: XRay PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - xray:PutTraceSegments - xray:PutTelemetryRecords Resource: "*" - PolicyName: AllowVPCSupport PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - ec2:DescribeNetworkInterfaces - ec2:CreateNetworkInterface - ec2:DeleteNetworkInterface Resource: "*" - PolicyName: LambdaUpgrades PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - lambda:UpdateFunctionCode Resource: "*" Outputs: PipelineName: Value: !Ref CodePipeline Description: Name of CodePipeline pipeline WebAppUrl: Value: !Sub "https://${LexWebUiDistribution.DomainName}/index.html" Description: URL of the web application WebAppBase: Value: !Sub "https://${LexWebUiDistribution.DomainName}" Description: Base url portion of the web application WebAppDomainName: Value: !Sub "${LexWebUiDistribution.DomainName}" Description: DomainName of the web application ParentPageUrl: Value: !Sub "https://${LexWebUiDistribution.DomainName}/parent.html" Description: URL of the sample parent page Condition: NeedsParentOrigin LoaderScriptUrl: Value: !Sub "https://${LexWebUiDistribution.DomainName}/lex-web-ui-loader.min.js" Description: URL of the loader script Condition: NeedsParentOrigin SnippetUrl: Value: !Sub "https://${LexWebUiDistribution.DomainName}/iframe-snippet.html" Description: URL of a page showing the snippet to load the chatbot UI as an iframe Condition: NeedsParentOrigin RestApiId: Value: !Sub "${RestApi.Outputs.RestApiId}" Description: Rest API ID if required by other elements Condition: EnableLiveChat