AWSTemplateFormatVersion: 2010-09-09 Description: > Amazon Connect contact flow APIs demo Mappings: FunctionMap: Configuration: S3Bucket: "amazon-connect-blogs2" S3Key: "2020/contactflows/" Parameters: CFS3BucketForWebSite: Type: String Default: "contactflowapi-website" AllowedPattern: '(?=^.{3,63}$)(?!^(\d+\.)+\d+$)(^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$)' ConstraintDescription: 'Invalid S3 Bucket name' Description: Enter the (globally unique) name you would like to use for the Amazon S3 bucket where we will store the website assets and the sample contact flow. This template will fail to deploy if the bucket name you chose is currently in use. backupDDBTable: Type: String Default: "contactflows" Description: > The name of the DynamoDB Table contact flows will be backed up (Ensure you do not have a table with this name already). arnMappingDDBTable: Type: String Default: "contactflowmapping" Description: > The name of the DynamoDB Table which maintains ARN mappings to target environment (Ensure you do not have a table with this name already). Metadata: 'AWS::CloudFormation::Interface': ParameterGroups: - Label: default: Amazon S3 Configuration Parameters: - CFS3BucketForWebSite - Label: default: Amazon DynamoDB Configuration Parameters: - backupDDBTable - arnMappingDDBTable ParameterLabels: CFS3BucketForWebSite: default: Website Bucket Name backupDDBTable: default: Backup table arnMappingDDBTable: default: ARN Mappings Outputs: CloudfrontEndpoint: Description: Endpoint for Cloudfront distribution Value: !Join - '' - - 'https://' - !GetAtt [CFCloudFrontDistribution, DomainName] - '/contactflowapi.html' DDBForBackup: Description: Endpoint for Cloudfront distribution Value: !Ref backupDDBTable DDBForARNMapping: Description: Endpoint for Cloudfront distribution Value: !Ref arnMappingDDBTable Resources: CFABackupDDBTable: Type: AWS::DynamoDB::Table Properties: TableName: !Ref backupDDBTable AttributeDefinitions: - AttributeName: "flowId" AttributeType: "S" KeySchema: - AttributeName: "flowId" KeyType: "HASH" ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 CFAARNMappingDDBTable: Type: AWS::DynamoDB::Table Properties: TableName: !Ref arnMappingDDBTable AttributeDefinitions: - AttributeName: "sourceARN" AttributeType: "S" KeySchema: - AttributeName: "sourceARN" KeyType: "HASH" ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 createWebSiteS3Bucket: Type: 'AWS::S3::Bucket' Properties: VersioningConfiguration: Status: Enabled BucketName: !Ref CFS3BucketForWebSite VersioningConfiguration: Status : Enabled BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True WebsiteConfiguration: IndexDocument: contactflowapi.html ErrorDocument: error.html CFS3BucketPolicy: Type: AWS::S3::BucketPolicy DependsOn: - CFCloudFrontDistributionAccessIdentity Properties: Bucket: !Ref createWebSiteS3Bucket PolicyDocument: Statement: - Action: - "s3:GetObject" Effect: "Allow" Principal: CanonicalUser: Fn::GetAtt: [ CFCloudFrontDistributionAccessIdentity , S3CanonicalUserId ] Resource: !Sub ${createWebSiteS3Bucket.Arn}/contactflowsite/* CFCloudFrontDistributionAccessIdentity: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Properties: CloudFrontOriginAccessIdentityConfig: Comment: 'CloudFront endpoint for contact flows s3' CFCloudFrontDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Origins: - DomainName: !Join - '' - - !Ref CFS3BucketForWebSite - .s3.amazonaws.com Id: !Ref CFS3BucketForWebSite OriginPath: '/contactflowsite' S3OriginConfig: OriginAccessIdentity: !Join - '' - - 'origin-access-identity/cloudfront/' - !Ref CFCloudFrontDistributionAccessIdentity Enabled: 'true' Logging: Bucket: !GetAtt createWebSiteS3Bucket.DomainName Prefix: 'logs/' IncludeCookies: 'true' Comment: CloudFront for contact flow apis DefaultRootObject: contactflowapi.html DefaultCacheBehavior: AllowedMethods: - DELETE - GET - HEAD - OPTIONS - PATCH - POST - PUT TargetOriginId: !Ref CFS3BucketForWebSite ForwardedValues: QueryString: true Cookies: Forward: all ViewerProtocolPolicy: redirect-to-https Restrictions: GeoRestriction: RestrictionType: whitelist Locations: - US CFWebsiteCreatorRole: Type: "AWS::IAM::Role" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "lambda.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" Policies: - PolicyName: !Sub ${AWS::StackName}-contact-flow-creator-policy PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - 'logs:CreateLogGroup' - 'logs:CreateLogStream' - 'logs:PutLogEvents' Resource: - !Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*" - Effect: "Allow" Action: - "s3:PutObject" - "s3:GetObject" - "s3:PutObjectAcl" Resource: - !Join - '' - - 'arn:' - !Ref 'AWS::Partition' - ':s3:::' - !Ref CFS3BucketForWebSite - '/*' - Effect: "Allow" Action: - "s3:PutBucketPublicAccessBlock" Resource: - !Join - '' - - 'arn:' - !Ref 'AWS::Partition' - ':s3:::' - !Ref CFS3BucketForWebSite - Effect: "Allow" Action: - "s3:GetObject" Resource: - !Join - '' - - 'arn:' - !Ref 'AWS::Partition' - ':s3:::' - 'amazon-connect-blogs2' - '/*' webSiteCreator: Type: "AWS::Lambda::Function" Properties: Description: > AWS Lambda Function that will create the website and upload it to the S3 bucket Handler: "index.handler" Role: !GetAtt CFWebsiteCreatorRole.Arn Runtime: "nodejs12.x" MemorySize: 256 Timeout: 120 Code: ./website-creator/ invokeWebSiteCreator: Type: Custom::CreateWebSite DependsOn: createWebSiteS3Bucket Properties: ServiceToken: !GetAtt webSiteCreator.Arn customAction: configureWebsite Region: !Ref AWS::Region destS3Bucket: !Ref CFS3BucketForWebSite destS3KeyPrefix: contactflowsite