Created
January 26, 2021 22:54
-
-
Save AdonousTech/50bff8a46acb1478067db2af90a474c8 to your computer and use it in GitHub Desktop.
A Cloud Coach - Tutorial - Serverless Stripe Store - 008 - SPA Infra CloudFormation Template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "AWSTemplateFormatVersion": "2010-09-09", | |
| "Description": "SPA Infrastructure Template", | |
| "Parameters": { | |
| "CodeBuildProjectNameParameter": { | |
| "Type": "String", | |
| "Description": "A name for the CodeBuild project. The name must be unique across all of the projects in your AWS account." | |
| }, | |
| "CodeBuildImageParameter": { | |
| "Type": "String", | |
| "Description": "Code Build image to use" | |
| }, | |
| "DeploymentFunctionS3Key": { | |
| "Type": "String", | |
| "Description": "S3 key for CB/CP deployment lambda function." | |
| }, | |
| "DeploymentFunctionFileLocation": { | |
| "Type": "String", | |
| "Description": "Source code location for deployment lambda function." | |
| }, | |
| "DeploymentCacheFunctionFileLocation": { | |
| "Type": "String", | |
| "Description": "Source code location for deployment cache invalidation lambda function." | |
| }, | |
| "PipelineName": { | |
| "Type": "String", | |
| "Description": "Unique name for the CodePipeline" | |
| }, | |
| "UserPoolClientName": { | |
| "Type": "String", | |
| "Description": "Unique name for user pool client application" | |
| }, | |
| "IdentityPoolName": { | |
| "Type": "String", | |
| "Description": "Name of the identity pool" | |
| }, | |
| "DBTableName": { | |
| "Type": "String", | |
| "Description": "Name of the DB table" | |
| }, | |
| "DBHashKey": { | |
| "Type": "String", | |
| "Description": "Primary/partition/hash key for the table" | |
| }, | |
| "ExistingHostedZone": { | |
| "Type": "String", | |
| "Description": "Id of the existing hosted zone." | |
| }, | |
| "CloudfrontCName": { | |
| "Type": "String", | |
| "Description": "CNAME for Cloudfront distribution" | |
| }, | |
| "SSLCertArn": { | |
| "Type": "String", | |
| "Description": "ARN for the ACM SSL Cert" | |
| }, | |
| "NoReplyEmail": { | |
| "Type": "String", | |
| "Description": "Canonical No Reply email address." | |
| }, | |
| "NoReplyEmailArn": { | |
| "Type": "String", | |
| "Description": "ARN of the canonical No Reply email address." | |
| }, | |
| "NoReplyFromEmail": { | |
| "Type": "String", | |
| "Description": "From email display for No Reply email address." | |
| } | |
| }, | |
| "Resources": { | |
| "BucketCodeBuildSource": { | |
| "Type": "AWS::S3::Bucket", | |
| "Properties": { | |
| "PublicAccessBlockConfiguration": { | |
| "BlockPublicAcls": true, | |
| "BlockPublicPolicy": true, | |
| "RestrictPublicBuckets": true, | |
| "IgnorePublicAcls": true | |
| }, | |
| "BucketEncryption" : { | |
| "ServerSideEncryptionConfiguration": [ | |
| { | |
| "ServerSideEncryptionByDefault": { | |
| "SSEAlgorithm": "AES256" | |
| } | |
| } | |
| ] | |
| }, | |
| "VersioningConfiguration": { | |
| "Status": "Enabled" | |
| } | |
| } | |
| }, | |
| "BucketCodeBuildOutput": { | |
| "Type": "AWS::S3::Bucket", | |
| "Properties": { | |
| "PublicAccessBlockConfiguration": { | |
| "BlockPublicAcls": true, | |
| "BlockPublicPolicy": true, | |
| "RestrictPublicBuckets": true, | |
| "IgnorePublicAcls": true | |
| }, | |
| "BucketEncryption" : { | |
| "ServerSideEncryptionConfiguration": [ | |
| { | |
| "ServerSideEncryptionByDefault": { | |
| "SSEAlgorithm": "AES256" | |
| } | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "BucketCodePipeline": { | |
| "Type": "AWS::S3::Bucket", | |
| "Properties": { | |
| "PublicAccessBlockConfiguration": { | |
| "BlockPublicAcls": true, | |
| "BlockPublicPolicy": true, | |
| "RestrictPublicBuckets": true, | |
| "IgnorePublicAcls": true | |
| }, | |
| "BucketEncryption" : { | |
| "ServerSideEncryptionConfiguration": [ | |
| { | |
| "ServerSideEncryptionByDefault": { | |
| "SSEAlgorithm": "AES256" | |
| } | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "BucketCodePipelineFunctions": { | |
| "Type": "AWS::S3::Bucket", | |
| "Properties": { | |
| "PublicAccessBlockConfiguration": { | |
| "BlockPublicAcls": true, | |
| "BlockPublicPolicy": true, | |
| "RestrictPublicBuckets": true, | |
| "IgnorePublicAcls": true | |
| }, | |
| "BucketEncryption" : { | |
| "ServerSideEncryptionConfiguration": [ | |
| { | |
| "ServerSideEncryptionByDefault": { | |
| "SSEAlgorithm": "AES256" | |
| } | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "StaticWebsiteBucket" : { | |
| "Type" : "AWS::S3::Bucket", | |
| "Properties": { | |
| "WebsiteConfiguration": { | |
| "IndexDocument": "index.html", | |
| "ErrorDocument": "error.html" | |
| }, | |
| "PublicAccessBlockConfiguration": { | |
| "BlockPublicAcls": true, | |
| "BlockPublicPolicy": true, | |
| "RestrictPublicBuckets": true, | |
| "IgnorePublicAcls": true | |
| }, | |
| "BucketEncryption" : { | |
| "ServerSideEncryptionConfiguration": [ | |
| { | |
| "ServerSideEncryptionByDefault": { | |
| "SSEAlgorithm": "AES256" | |
| } | |
| } | |
| ] | |
| }, | |
| "CorsConfiguration": { | |
| "CorsRules": [ | |
| { | |
| "AllowedHeaders": ["*"], | |
| "AllowedMethods": [ | |
| "GET", | |
| "HEAD" | |
| ], | |
| "AllowedOrigins": ["*"] | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "OriginAccessIdentity": { | |
| "Type": "AWS::CloudFront::CloudFrontOriginAccessIdentity", | |
| "Properties": { | |
| "CloudFrontOriginAccessIdentityConfig": { | |
| "Comment": "OAI" | |
| } | |
| } | |
| }, | |
| "StaticWebSiteBucketPolicy": { | |
| "Type": "AWS::S3::BucketPolicy", | |
| "DependsOn": ["StaticWebsiteBucket", "OriginAccessIdentity", "CodePipelineLambdaExecutionRole"], | |
| "Properties": { | |
| "Bucket": {"Ref": "StaticWebsiteBucket"}, | |
| "PolicyDocument": { | |
| "Statement": [ | |
| { | |
| "Sid": "Grant a CloudFront Origin Identity access to support private content", | |
| "Effect": "Allow", | |
| "Principal": { | |
| "CanonicalUser": { | |
| "Fn::GetAtt": ["OriginAccessIdentity", "S3CanonicalUserId"] | |
| } | |
| }, | |
| "Action": "s3:GetObject", | |
| "Resource": {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "StaticWebsiteBucket", "Arn" ]}, "/*" ] ] } | |
| }, | |
| { | |
| "Sid": "Grant a CloudFront Origin Identity access to support private content", | |
| "Effect": "Allow", | |
| "Principal": { | |
| "CanonicalUser": { | |
| "Fn::GetAtt": ["OriginAccessIdentity", "S3CanonicalUserId"] | |
| } | |
| }, | |
| "Action": "s3:ListBucket", | |
| "Resource": {"Fn::GetAtt" : [ "StaticWebsiteBucket", "Arn" ]} | |
| }, | |
| { | |
| "Sid": "Allow CodePipeline Lambda execution role access to objects", | |
| "Effect": "Allow", | |
| "Principal": { | |
| "AWS": {"Fn::GetAtt" : [ "CodePipelineLambdaExecutionRole", "Arn" ]} | |
| }, | |
| "Action": "s3:*", | |
| "Resource": {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "StaticWebsiteBucket", "Arn" ]}, "/*" ] ] } | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "CodeBuildOutputBucketPolicy": { | |
| "Type": "AWS::S3::BucketPolicy", | |
| "DependsOn": ["BucketCodeBuildOutput", "CodeBuildRole", "CodePipelineLambdaExecutionRole"], | |
| "Properties": { | |
| "Bucket": {"Ref" : "BucketCodeBuildOutput"}, | |
| "PolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Sid": "Enables CodeBuild role access to source output bucket", | |
| "Effect": "Allow", | |
| "Principal": { | |
| "AWS": {"Fn::GetAtt" : [ "CodeBuildRole", "Arn" ]} | |
| }, | |
| "Action": "s3:*", | |
| "Resource": {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodeBuildOutput", "Arn" ]}, "/*" ] ] } | |
| }, | |
| { | |
| "Sid": "Enables Lambda execution role access to source output bucket", | |
| "Effect": "Allow", | |
| "Principal": { | |
| "AWS": {"Fn::GetAtt" : [ "CodePipelineLambdaExecutionRole", "Arn" ]} | |
| }, | |
| "Action": "s3:GetObject", | |
| "Resource": {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodeBuildOutput", "Arn" ]}, "/*" ] ] } | |
| }, | |
| { | |
| "Sid": "Enables Lambda execution role access to list bucket objects.", | |
| "Effect": "Allow", | |
| "Principal": { | |
| "AWS": {"Fn::GetAtt" : [ "CodePipelineLambdaExecutionRole", "Arn" ]} | |
| }, | |
| "Action": "s3:ListBucket", | |
| "Resource": {"Fn::GetAtt" : [ "BucketCodeBuildOutput", "Arn" ]} | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "CodePipelineBucketPolicy": { | |
| "Type": "AWS::S3::BucketPolicy", | |
| "DependsOn": ["BucketCodePipeline"], | |
| "Properties": { | |
| "Bucket": {"Ref" : "BucketCodePipeline"}, | |
| "PolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Sid": "DenyUnEncryptedObjectUploads", | |
| "Effect": "Deny", | |
| "Principal": "*", | |
| "Action": "s3:PutObject", | |
| "Resource": {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodePipeline", "Arn" ]}, "/*" ] ] }, | |
| "Condition": { | |
| "StringNotEquals": { | |
| "s3:x-amz-server-side-encryption": "aws:kms" | |
| } | |
| } | |
| }, | |
| { | |
| "Sid": "DenyInsecureConnections", | |
| "Effect": "Deny", | |
| "Principal": "*", | |
| "Action": "s3:*", | |
| "Resource": {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodePipeline", "Arn" ]}, "/*" ] ] }, | |
| "Condition": { | |
| "Bool": { | |
| "aws:SecureTransport": "false" | |
| } | |
| } | |
| } | |
| ] | |
| } | |
| } | |
| }, | |
| "CloudFrontDistribution": { | |
| "Type": "AWS::CloudFront::Distribution", | |
| "DependsOn": [ | |
| "StaticWebSiteBucketPolicy", | |
| "OriginAccessIdentity" | |
| ], | |
| "Properties": { | |
| "DistributionConfig": { | |
| "Aliases": [{"Ref": "CloudfrontCName"}], | |
| "DefaultCacheBehavior": { | |
| "AllowedMethods": [ | |
| "GET", | |
| "HEAD", | |
| "OPTIONS" | |
| ], | |
| "Compress": "true", | |
| "ForwardedValues": { | |
| "Headers": [ | |
| "Origin" | |
| ], | |
| "Cookies": { | |
| "Forward": "none" | |
| }, | |
| "QueryString": "false" | |
| }, | |
| "TargetOriginId": "s3_origin", | |
| "ViewerProtocolPolicy": "redirect-to-https" | |
| }, | |
| "DefaultRootObject": "index.html", | |
| "Enabled": "true", | |
| "HttpVersion": "http2", | |
| "ViewerCertificate": { | |
| "AcmCertificateArn": {"Ref": "SSLCertArn"}, | |
| "MinimumProtocolVersion": "TLSv1.2_2018", | |
| "SslSupportMethod": "sni-only" | |
| }, | |
| "CustomErrorResponses": [ | |
| { | |
| "ErrorCachingMinTTL": 0, | |
| "ErrorCode": 500 | |
| }, | |
| { | |
| "ErrorCachingMinTTL": 300, | |
| "ErrorCode": 403, | |
| "ResponseCode": 200, | |
| "ResponsePagePath": "/index.html" | |
| }, | |
| { | |
| "ErrorCachingMinTTL": 300, | |
| "ErrorCode": 404, | |
| "ResponseCode": 200, | |
| "ResponsePagePath": "/index.html" | |
| } | |
| ], | |
| "Origins": [ | |
| { | |
| "DomainName": { | |
| "Fn::GetAtt": [ | |
| "StaticWebsiteBucket", | |
| "DomainName" | |
| ] | |
| }, | |
| "Id": "s3_origin", | |
| "S3OriginConfig": { | |
| "OriginAccessIdentity": {"Fn::Sub": "origin-access-identity/cloudfront/${OriginAccessIdentity}"} | |
| } | |
| } | |
| ], | |
| "PriceClass": "PriceClass_All" | |
| } | |
| } | |
| }, | |
| "CodeBuildRole": { | |
| "Type": "AWS::IAM::Role", | |
| "DependsOn": [ | |
| "BucketCodeBuildSource", | |
| "BucketCodePipeline", | |
| "BucketCodeBuildOutput", | |
| "StaticWebsiteBucket" | |
| ], | |
| "Properties": { | |
| "AssumeRolePolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Effect": "Allow", | |
| "Principal": { | |
| "Service": "codebuild.amazonaws.com" | |
| }, | |
| "Action": "sts:AssumeRole" | |
| } | |
| ] | |
| }, | |
| "Policies": [ | |
| { | |
| "PolicyName": "CodeBuildRootPolicy", | |
| "PolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Effect": "Allow", | |
| "Resource": [ | |
| {"Fn::Sub": "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*"} | |
| ], | |
| "Action": [ | |
| "logs:CreateLogGroup", | |
| "logs:CreateLogStream", | |
| "logs:PutLogEvents" | |
| ] | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Resource": [ | |
| {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodeBuildSource", "Arn" ]}, "/build-source.zip" ] ] } | |
| ], | |
| "Action": [ | |
| "s3:GetObject", | |
| "s3:GetObjectVersion" | |
| ] | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Resource": [ | |
| {"Fn::GetAtt" : [ "BucketCodePipeline", "Arn" ]}, | |
| {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodePipeline", "Arn" ]}, "/*" ] ] } | |
| ], | |
| "Action": "s3:*" | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Resource": [ | |
| {"Fn::GetAtt" : [ "BucketCodeBuildOutput", "Arn" ]}, | |
| {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodeBuildOutput", "Arn" ]}, "/*" ] ] } | |
| ], | |
| "Action": "s3:*" | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Resource": [ | |
| {"Fn::GetAtt" : [ "StaticWebsiteBucket", "Arn" ]} | |
| ], | |
| "Action": "s3:*" | |
| } | |
| ] | |
| } | |
| } | |
| ] | |
| } | |
| }, | |
| "CodeBuildProject": { | |
| "Type": "AWS::CodeBuild::Project", | |
| "DependsOn": ["CodeBuildRole", "BucketCodeBuildSource", "BucketCodeBuildOutput"], | |
| "Properties": { | |
| "Name": {"Ref" : "CodeBuildProjectNameParameter"}, | |
| "Description": "Builds static SPA as part of CodePipeline", | |
| "Source": { | |
| "Type": "S3", | |
| "Location": {"Fn::Join" : [ "", [ {"Ref" : "BucketCodeBuildSource"}, "/build-source.zip" ] ] } | |
| }, | |
| "Artifacts": { | |
| "Type": "S3", | |
| "Location": {"Ref" : "BucketCodeBuildOutput"}, | |
| "Name": "build-output", | |
| "Packaging": "ZIP" | |
| }, | |
| "Environment": { | |
| "ComputeType": "BUILD_GENERAL1_MEDIUM", | |
| "Image": {"Ref": "CodeBuildImageParameter"}, | |
| "Type": "LINUX_CONTAINER", | |
| "EnvironmentVariables": [ | |
| {"Name": "NODE_OPTIONS", "Value": "--max-old-space-size=6144"} | |
| ] | |
| }, | |
| "ServiceRole": {"Fn::GetAtt" : [ "CodeBuildRole", "Arn" ]}, | |
| "TimeoutInMinutes": 60 | |
| } | |
| }, | |
| "CodePipelineRole": { | |
| "Type": "AWS::IAM::Role", | |
| "Properties": { | |
| "AssumeRolePolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Sid": "", | |
| "Effect": "Allow", | |
| "Principal": { | |
| "Service": "codepipeline.amazonaws.com" | |
| }, | |
| "Action": "sts:AssumeRole" | |
| } | |
| ] | |
| }, | |
| "Policies": [ | |
| { | |
| "PolicyName": "StaticSiteCodePipelineRootPolicy", | |
| "PolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Action": [ | |
| "s3:GetObject", | |
| "s3:GetObjectVersion", | |
| "s3:GetBucketVersioning" | |
| ], | |
| "Resource": "*", | |
| "Effect":"Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "s3:PutObject" | |
| ], | |
| "Resource": [ | |
| "arn:aws:s3:::codepipeline*", | |
| "arn:aws:s3:::elasticbeanstalk*" | |
| ], | |
| "Effect": "Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "codecommit:CancelUploadArchive", | |
| "codecommit:GetBranch", | |
| "codecommit:GetCommit", | |
| "codecommit:GetUploadArchiveStatus", | |
| "codecommit:UploadArchive" | |
| ], | |
| "Resource": "*", | |
| "Effect": "Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "codedeploy:CreateDeployment", | |
| "codedeploy:GetApplicationRevision", | |
| "codedeploy:GetDeployment", | |
| "codedeploy:GetDeploymentConfig", | |
| "codedeploy:RegisterApplicationRevision" | |
| ], | |
| "Resource": "*", | |
| "Effect": "Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "elasticbeanstalk:*", | |
| "ec2:*", | |
| "elasticloadbalancing:*", | |
| "autoscaling:*", | |
| "cloudwatch:*", | |
| "s3:*", | |
| "sns:*", | |
| "cloudformation:*", | |
| "rds:*", | |
| "sqs:*", | |
| "ecs:*", | |
| "iam:PassRole" | |
| ], | |
| "Resource": "*", | |
| "Effect": "Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "lambda:InvokeFunction", | |
| "lambda:ListFunctions" | |
| ], | |
| "Resource": "*", | |
| "Effect": "Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "opsworks:CreateDeployment", | |
| "opsworks:DescribeApps", | |
| "opsworks:DescribeCommands", | |
| "opsworks:DescribeDeployments", | |
| "opsworks:DescribeInstances", | |
| "opsworks:DescribeStacks", | |
| "opsworks:UpdateApp", | |
| "opsworks:UpdateStack" | |
| ], | |
| "Resource": "*", | |
| "Effect": "Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "cloudformation:CreateStack", | |
| "cloudformation:DeleteStack", | |
| "cloudformation:DescribeStacks", | |
| "cloudformation:UpdateStack", | |
| "cloudformation:CreateChangeSet", | |
| "cloudformation:DeleteChangeSet", | |
| "cloudformation:DescribeChangeSet", | |
| "cloudformation:ExecuteChangeSet", | |
| "cloudformation:SetStackPolicy", | |
| "cloudformation:ValidateTemplate", | |
| "iam:PassRole" | |
| ], | |
| "Resource": "*", | |
| "Effect": "Allow" | |
| }, | |
| { | |
| "Action": [ | |
| "codebuild:BatchGetBuilds", | |
| "codebuild:StartBuild" | |
| ], | |
| "Resource": "*", | |
| "Effect": "Allow" | |
| } | |
| ] | |
| } | |
| } | |
| ] | |
| } | |
| }, | |
| "CodePipelineLambdaExecutionRole": { | |
| "Type": "AWS::IAM::Role", | |
| "DependsOn": ["BucketCodeBuildOutput", "StaticWebsiteBucket"], | |
| "Properties": { | |
| "AssumeRolePolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": { | |
| "Effect": "Allow", | |
| "Principal": { | |
| "Service": "lambda.amazonaws.com" | |
| }, | |
| "Action": "sts:AssumeRole" | |
| } | |
| }, | |
| "Path": "/", | |
| "Policies": [{ | |
| "PolicyName": "root", | |
| "PolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Effect": "Allow", | |
| "Action": [ | |
| "logs:*" | |
| ], | |
| "Resource": "arn:aws:logs:*:*:*" | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Action": [ | |
| "codepipeline:PutJobSuccessResult", | |
| "codepipeline:PutJobFailureResult" | |
| ], | |
| "Resource": "*" | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Action": [ | |
| "s3:*" | |
| ], | |
| "Resource": [ | |
| {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "BucketCodeBuildOutput", "Arn" ]}, "/*" ] ] }, | |
| {"Fn::Join" : [ "", [ {"Fn::GetAtt" : [ "StaticWebsiteBucket", "Arn" ]}, "/*" ] ] } | |
| ] | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Action": [ | |
| "cloudfront:CreateInvalidation", | |
| "cloudfront:ListInvalidations" | |
| ], | |
| "Resource": [ | |
| "*" | |
| ] | |
| } | |
| ] | |
| } | |
| }] | |
| } | |
| }, | |
| "CodebuildDeployLambdaFunction": { | |
| "Type": "AWS::Lambda::Function", | |
| "DependsOn": ["BucketCodeBuildOutput","StaticWebsiteBucket"], | |
| "Properties": { | |
| "Code": { | |
| "ZipFile": {"Ref": "DeploymentFunctionFileLocation"} | |
| }, | |
| "Handler": "index.handler", | |
| "MemorySize": 128, | |
| "Role": {"Fn::GetAtt" : [ "CodePipelineLambdaExecutionRole", "Arn" ]}, | |
| "Runtime": "nodejs12.x", | |
| "Timeout": 30, | |
| "Environment": { | |
| "Variables": { | |
| "SourceBucket": {"Ref": "BucketCodeBuildOutput"}, | |
| "DestBucket": {"Ref": "StaticWebsiteBucket"} | |
| } | |
| } | |
| } | |
| }, | |
| "CodebuildInvalidateCacheLambdaFunction": { | |
| "Type": "AWS::Lambda::Function", | |
| "DependsOn": ["CodePipelineLambdaExecutionRole", "CloudFrontDistribution"], | |
| "Properties": { | |
| "Code": { | |
| "ZipFile": {"Ref": "DeploymentCacheFunctionFileLocation"} | |
| }, | |
| "Handler": "index.handler", | |
| "MemorySize": 128, | |
| "Role": {"Fn::GetAtt" : [ "CodePipelineLambdaExecutionRole", "Arn" ]}, | |
| "Runtime": "nodejs12.x", | |
| "Timeout": 30, | |
| "Environment": { | |
| "Variables": { | |
| "CloudfrontDistId": {"Ref": "CloudFrontDistribution"} | |
| } | |
| } | |
| } | |
| }, | |
| "CodePipeline": { | |
| "Type": "AWS::CodePipeline::Pipeline", | |
| "DependsOn": ["BucketCodePipeline", | |
| "CodePipelineRole", | |
| "BucketCodeBuildSource", | |
| "CodeBuildProject", | |
| "CodebuildDeployLambdaFunction", | |
| "CodebuildInvalidateCacheLambdaFunction" | |
| ], | |
| "Properties": | |
| { | |
| "ArtifactStore": { | |
| "Type": "S3", | |
| "Location": {"Ref" : "BucketCodePipeline"} | |
| }, | |
| "Name": {"Ref": "PipelineName"}, | |
| "RestartExecutionOnUpdate": true, | |
| "RoleArn": {"Fn::GetAtt" : [ "CodePipelineRole", "Arn" ]}, | |
| "Stages": [ | |
| { | |
| "Name": "Source", | |
| "Actions": [ | |
| { | |
| "Name": "Source", | |
| "ActionTypeId": { | |
| "Category": "Source", | |
| "Owner": "AWS", | |
| "Provider": "S3", | |
| "Version": "1" | |
| }, | |
| "OutputArtifacts": [ | |
| { | |
| "Name": "StaticAppPayload" | |
| } | |
| ], | |
| "Configuration": { | |
| "S3Bucket": {"Ref": "BucketCodeBuildSource"}, | |
| "S3ObjectKey": "build-source.zip" | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "Name": "Build", | |
| "Actions": [ | |
| { | |
| "InputArtifacts": [ | |
| { | |
| "Name": "StaticAppPayload" | |
| } | |
| ], | |
| "Name": "CodeBuild", | |
| "ActionTypeId": { | |
| "Category": "Build", | |
| "Owner": "AWS", | |
| "Provider": "CodeBuild", | |
| "Version": "1" | |
| }, | |
| "OutputArtifacts": [ | |
| { | |
| "Name": "StaticAppBuild" | |
| } | |
| ], | |
| "Configuration": { | |
| "ProjectName": {"Ref" : "CodeBuildProject"} | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "Name": "DeployStaticAssets", | |
| "Actions": [ | |
| { | |
| "InputArtifacts": [], | |
| "Name": "StaticAssetDeploy", | |
| "ActionTypeId": { | |
| "Category": "Invoke", | |
| "Owner": "AWS", | |
| "Provider": "Lambda", | |
| "Version": "1" | |
| }, | |
| "OutputArtifacts": [], | |
| "Configuration": { | |
| "FunctionName": {"Ref" : "CodebuildDeployLambdaFunction"} | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "Name": "InvalidateCache", | |
| "Actions": [ | |
| { | |
| "InputArtifacts": [], | |
| "Name": "CacheInvalidation", | |
| "ActionTypeId": { | |
| "Category": "Invoke", | |
| "Owner": "AWS", | |
| "Provider": "Lambda", | |
| "Version": "1" | |
| }, | |
| "OutputArtifacts": [], | |
| "Configuration": { | |
| "FunctionName": {"Ref" : "CodebuildInvalidateCacheLambdaFunction"} | |
| } | |
| } | |
| ] | |
| } | |
| ] | |
| } | |
| }, | |
| "UserPool": { | |
| "Type": "AWS::Cognito::UserPool", | |
| "Properties": { | |
| "UserPoolName": {"Ref": "UserPoolClientName"}, | |
| "AutoVerifiedAttributes": ["email"], | |
| "EmailConfiguration": { | |
| "EmailSendingAccount": "DEVELOPER", | |
| "From": {"Ref": "NoReplyEmail"}, | |
| "ReplyToEmailAddress": {"Ref": "NoReplyFromEmail"}, | |
| "SourceArn": {"Ref": "NoReplyEmailArn"} | |
| }, | |
| "Policies": { | |
| "PasswordPolicy": { | |
| "MinimumLength" : 8, | |
| "RequireLowercase" : true, | |
| "RequireNumbers" : true, | |
| "RequireSymbols" : true, | |
| "RequireUppercase" : true | |
| } | |
| }, | |
| "Schema": [ | |
| { | |
| "AttributeDataType" : "String", | |
| "DeveloperOnlyAttribute" : false, | |
| "Mutable" : true, | |
| "Name" : "email", | |
| "Required" : true | |
| } | |
| ] | |
| } | |
| }, | |
| "UserPoolClient": { | |
| "Type": "AWS::Cognito::UserPoolClient", | |
| "DependsOn": ["UserPool"], | |
| "Properties": { | |
| "ClientName": {"Ref": "UserPoolClientName"}, | |
| "UserPoolId": {"Ref": "UserPool"}, | |
| "ExplicitAuthFlows": ["ADMIN_NO_SRP_AUTH","USER_PASSWORD_AUTH"] | |
| } | |
| }, | |
| "IdentityPool": { | |
| "Type": "AWS::Cognito::IdentityPool", | |
| "DependsOn": ["UserPool","UserPoolClient"], | |
| "Properties": { | |
| "IdentityPoolName": {"Ref": "IdentityPoolName"}, | |
| "AllowUnauthenticatedIdentities": true, | |
| "CognitoIdentityProviders": [ | |
| { | |
| "ClientId": {"Ref": "UserPoolClient"}, | |
| "ProviderName": {"Fn::Join" : | |
| [ "", [ {"Fn::Sub": "cognito-idp.${AWS::Region}.amazonaws.com/"}, | |
| {"Ref": "UserPool"} | |
| ] | |
| ] } | |
| } | |
| ] | |
| } | |
| }, | |
| "IdentityPoolAuthenticatedRole": { | |
| "Type": "AWS::IAM::Role", | |
| "DependsOn": ["IdentityPool", "DBTable"], | |
| "Properties": { | |
| "Path": "/", | |
| "AssumeRolePolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Effect": "Allow", | |
| "Principal": { | |
| "Federated": "cognito-identity.amazonaws.com" | |
| }, | |
| "Action": "sts:AssumeRoleWithWebIdentity", | |
| "Condition": { | |
| "StringEquals": { | |
| "cognito-identity.amazonaws.com:aud": {"Ref": "IdentityPool"} | |
| }, | |
| "ForAnyValue:StringLike": { | |
| "cognito-identity.amazonaws.com:amr": "authenticated" | |
| } | |
| } | |
| } | |
| ] | |
| }, | |
| "Policies": [{ | |
| "PolicyName": "root", | |
| "PolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Effect": "Allow", | |
| "Action": [ | |
| "lambda:InvokeFunction" | |
| ], | |
| "Resource": [ | |
| "*" | |
| ] | |
| }, | |
| { | |
| "Effect": "Allow", | |
| "Action": [ | |
| "mobileanalytics:PutEvents", | |
| "cognito-sync:*", | |
| "cognito-identity:*" | |
| ], | |
| "Resource": [ | |
| "*" | |
| ] | |
| }, | |
| { | |
| "Action": [ | |
| "dynamodb:*" | |
| ], | |
| "Effect": "Allow", | |
| "Resource": {"Fn::Join" : [ "", [{"Fn::Sub": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/"}, {"Ref" : "DBTable"}] ] } | |
| } | |
| ] | |
| } | |
| }] | |
| } | |
| }, | |
| "IdentityPoolUnAuthenticatedRole": { | |
| "Type": "AWS::IAM::Role", | |
| "DependsOn": ["IdentityPool"], | |
| "Properties": { | |
| "Path": "/", | |
| "AssumeRolePolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Effect": "Allow", | |
| "Principal": { | |
| "Federated": "cognito-identity.amazonaws.com" | |
| }, | |
| "Action": "sts:AssumeRoleWithWebIdentity", | |
| "Condition": { | |
| "StringEquals": { | |
| "cognito-identity.amazonaws.com:aud": {"Ref": "IdentityPool"} | |
| }, | |
| "ForAnyValue:StringLike": { | |
| "cognito-identity.amazonaws.com:amr": "unauthenticated" | |
| } | |
| } | |
| } | |
| ] | |
| }, | |
| "Policies": [{ | |
| "PolicyName": "root", | |
| "PolicyDocument": { | |
| "Version": "2012-10-17", | |
| "Statement": [ | |
| { | |
| "Effect": "Allow", | |
| "Action": [ | |
| "mobileanalytics:PutEvents", | |
| "cognito-sync:*" | |
| ], | |
| "Resource": [ | |
| "*" | |
| ] | |
| } | |
| ] | |
| } | |
| }] | |
| } | |
| }, | |
| "IdentityPoolRoleAttachment": { | |
| "Type": "AWS::Cognito::IdentityPoolRoleAttachment", | |
| "DependsOn": ["IdentityPool", "IdentityPoolAuthenticatedRole", "IdentityPoolUnAuthenticatedRole"], | |
| "Properties": { | |
| "IdentityPoolId": {"Ref": "IdentityPool"}, | |
| "Roles": | |
| { | |
| "authenticated": {"Fn::GetAtt" : [ "IdentityPoolAuthenticatedRole", "Arn" ]}, | |
| "unauthenticated": {"Fn::GetAtt" : [ "IdentityPoolUnAuthenticatedRole", "Arn" ]} | |
| } | |
| } | |
| }, | |
| "DBTable": { | |
| "Type": "AWS::DynamoDB::Table", | |
| "Properties": { | |
| "TableName": {"Ref": "DBTableName"}, | |
| "BillingMode": "PAY_PER_REQUEST", | |
| "SSESpecification": { | |
| "SSEEnabled": true | |
| }, | |
| "KeySchema": [ | |
| { | |
| "AttributeName": {"Ref": "DBHashKey"}, | |
| "KeyType": "HASH" | |
| } | |
| ], | |
| "AttributeDefinitions": [ | |
| { | |
| "AttributeName": {"Ref": "DBHashKey"}, | |
| "AttributeType": "S" | |
| } | |
| ] | |
| } | |
| }, | |
| "R53RecordSet": { | |
| "Type": "AWS::Route53::RecordSet", | |
| "DependsOn": ["CloudFrontDistribution"], | |
| "Properties": { | |
| "HostedZoneId": {"Ref": "ExistingHostedZone"}, | |
| "Name": {"Ref": "CloudfrontCName"}, | |
| "Type": "CNAME", | |
| "TTL": "300", | |
| "ResourceRecords": [ | |
| {"Fn::GetAtt": ["CloudFrontDistribution", "DomainName"]} | |
| ] | |
| } | |
| } | |
| }, | |
| "Outputs": { | |
| "OAI": { | |
| "Description": "OAI for use with Cloudfront", | |
| "Value": {"Ref": "OriginAccessIdentity"} | |
| }, | |
| "CodePipelineArtifactBucketLocation": { | |
| "Description": "Location of the Code Pipeline artifact S3 bucket.", | |
| "Value": {"Fn::Join" : [ "", ["s3://", {"Ref" : "BucketCodePipeline"}] ] } | |
| }, | |
| "CodePipelineArtifactBucketName": { | |
| "Description": "Name of the Code Pipeline artifact S3 bucket.", | |
| "Value": {"Ref" : "BucketCodePipeline"} | |
| }, | |
| "CodeBuildSourceBucket": { | |
| "Description": "Codebuild source bucket name", | |
| "Value": {"Ref": "BucketCodeBuildSource"} | |
| }, | |
| "CodeBuildSourceBucketArn": { | |
| "Description": "Codebuild source bucket Arn", | |
| "Value": {"Fn::GetAtt" : [ "BucketCodeBuildSource", "Arn" ]} | |
| }, | |
| "CodeBuildOutputBucket": { | |
| "Description": "Codebuild output bucket name", | |
| "Value": {"Ref": "BucketCodeBuildOutput"} | |
| }, | |
| "CodePipelineFunctionsBucketArn": { | |
| "Description": "Codepipeline functions bucket Arn", | |
| "Value": {"Fn::GetAtt" : [ "BucketCodePipelineFunctions", "Arn" ]} | |
| }, | |
| "CodePipelineFunctionsBucketName": { | |
| "Description": "Codepipeline functions bucket name", | |
| "Value": {"Ref": "BucketCodePipelineFunctions"} | |
| }, | |
| "CodeBuildOutputBucketArn": { | |
| "Description": "Codebuild output bucket Arn", | |
| "Value": {"Fn::GetAtt" : [ "BucketCodeBuildOutput", "Arn" ]} | |
| }, | |
| "CloudFrontDistributionId": { | |
| "Description": "Cloudfront distribution ID", | |
| "Value": {"Ref": "CloudFrontDistribution"} | |
| }, | |
| "CloudFrontDistributionDomain": { | |
| "Description": "Cloudfront distribution domain", | |
| "Value": {"Fn::GetAtt": ["CloudFrontDistribution", "DomainName"]} | |
| }, | |
| "CodeBuildProjectArn": { | |
| "Description": "CodeBuild Project Arn", | |
| "Value": {"Fn::GetAtt": ["CodeBuildProject", "Arn"]} | |
| }, | |
| "LambdaPipelineFunctionExecutionRole": { | |
| "Description": "Execution role for Lambda pipeline functions.", | |
| "Value": {"Fn::GetAtt" : [ "CodePipelineLambdaExecutionRole", "Arn" ]} | |
| }, | |
| "CodePipelineName": { | |
| "Description": "Code deployment pipeline name.", | |
| "Value": {"Ref" : "CodePipeline"} | |
| }, | |
| "UserPoolId": { | |
| "Description": "The ID of the Cognito User Pool.", | |
| "Value": {"Ref" : "UserPool"} | |
| }, | |
| "UserPoolWebClientId": { | |
| "Description": "The ID of the Cognito User Pool Web Client", | |
| "Value": {"Ref": "UserPoolClient"} | |
| }, | |
| "IdentityPoolId": { | |
| "Description": "The ID of the Federated Identity Pool", | |
| "Value": {"Ref": "IdentityPool"} | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment