123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- AWSTemplateFormatVersion: "2010-09-09"
- Transform: AWS::Serverless-2016-10-31
- Description: Amazon S3 Find and Forget Deployment helper
- Globals:
- Function:
- Runtime: python3.9
- Timeout: 900
- Layers: !Ref CommonLayers
- Parameters:
- ApiUrl:
- Type: String
- ArtefactName:
- Type: String
- Default: build/s3f2.zip
- AthenaExecutionRole:
- Type: String
- CloudFrontDistribution:
- Type: String
- CodeBuildArtefactBucket:
- Type: String
- CognitoIdentityPoolId:
- Type: String
- CognitoUserPoolClientId:
- Type: String
- CognitoUserPoolId:
- Type: String
- CommonLayers:
- Type: CommaDelimitedList
- DeployWebUI:
- Type: String
- DeployCognito:
- Type: String
- ECRRepository:
- Type: String
- LogLevel:
- Type: String
- Default: INFO
- AllowedValues:
- - CRITICAL
- - FATAL
- - ERROR
- - WARNING
- - INFO
- - DEBUG
- - NOTSET
- PreBuiltArtefactsBucket:
- Type: String
- ResourcePrefix:
- Type: String
- Version:
- Type: String
- WebUIBucket:
- Type: String
- Conditions:
- WithoutCloudFront: !Equals [!Ref CloudFrontDistribution, "none"]
- ShouldDeployWebUI: !Equals [!Ref DeployWebUI, "true"]
- Resources:
- CodeBuildBackendServiceRole:
- Type: AWS::IAM::Role
- Properties:
- Path: /
- AssumeRolePolicyDocument:
- Statement:
- - Effect: Allow
- Principal:
- Service: codebuild.amazonaws.com
- Action: sts:AssumeRole
- Policies:
- - PolicyName: root
- PolicyDocument:
- Statement:
- - Resource: "*"
- Effect: Allow
- Action:
- - logs:CreateLogGroup
- - ecr:GetAuthorizationToken
- - Resource: !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:*
- Effect: Allow
- Action:
- - logs:CreateLogStream
- - logs:PutLogEvents
- - Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
- Effect: Allow
- Action:
- - s3:Get*
- - s3:List*
- - Resource: !Sub arn:${AWS::Partition}:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepository}
- Effect: Allow
- Action:
- - ecr:GetDownloadUrlForLayer
- - ecr:BatchGetImage
- - ecr:BatchCheckLayerAvailability
- - ecr:PutImage
- - ecr:InitiateLayerUpload
- - ecr:UploadLayerPart
- - ecr:CompleteLayerUpload
- CodeBuildFrontendServiceRole:
- Type: AWS::IAM::Role
- Properties:
- Path: /
- AssumeRolePolicyDocument:
- Statement:
- - Effect: Allow
- Principal:
- Service: codebuild.amazonaws.com
- Action: sts:AssumeRole
- Policies:
- - PolicyName: root
- PolicyDocument:
- Statement:
- - Resource: "*"
- Effect: Allow
- Action: logs:CreateLogGroup
- - Resource: !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:*
- Effect: Allow
- Action:
- - logs:CreateLogStream
- - logs:PutLogEvents
- - Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
- Effect: Allow
- Action:
- - s3:Get*
- - s3:List*
- - !If
- - ShouldDeployWebUI
- - Resource: !Sub arn:${AWS::Partition}:s3:::${WebUIBucket}/*
- Effect: Allow
- Action: s3:PutObject*
- - !Ref AWS::NoValue
- - !If
- - WithoutCloudFront
- - !Ref AWS::NoValue
- - Resource: !Sub arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}
- Effect: Allow
- Action: cloudfront:CreateInvalidation
- CodeBuildBackend:
- Type: AWS::CodeBuild::Project
- Properties:
- Artifacts:
- Type: CODEPIPELINE
- Source:
- Type: CODEPIPELINE
- BuildSpec: |
- version: 0.2
- phases:
- pre_build:
- commands:
- - $(aws ecr get-login --no-include-email)
- - IMAGE_URI="${REPOSITORY_URI}"
- build:
- commands:
- - docker load -i backend/ecs_tasks/python_3.9-slim.tar
- - docker build --tag "$IMAGE_URI" -f backend/ecs_tasks/delete_files/Dockerfile .
- post_build:
- commands:
- - docker push "$IMAGE_URI"
- EncryptionKey: alias/aws/s3
- Environment:
- ComputeType: BUILD_GENERAL1_SMALL
- Image: aws/codebuild/docker:18.09.0
- Type: LINUX_CONTAINER
- EnvironmentVariables:
- - Name: AWS_DEFAULT_REGION
- Value: !Ref AWS::Region
- - Name: REPOSITORY_URI
- Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/${ECRRepository}
- Name: !Sub ${ResourcePrefix}BackendBuild
- ServiceRole: !Ref CodeBuildBackendServiceRole
- CodeBuildFrontend:
- Type: AWS::CodeBuild::Project
- Condition: ShouldDeployWebUI
- Properties:
- Artifacts:
- Type: CODEPIPELINE
- Source:
- Type: CODEPIPELINE
- BuildSpec: |
- version: 0.2
- phases:
- pre_build:
- commands:
- - BUCKET="${WEB_UI_BUCKET}"
- - ACL="private"
- - |
- if [ "${CLOUDFRONT_DISTRIBUTION}" = "none" ]; then
- ACL="public-read"
- fi
- - echo "${WEB_SETTINGS}" > frontend/build/settings.js
- build:
- commands:
- - cd frontend/build
- - aws s3 cp . s3://$BUCKET --acl $ACL --recursive
- post_build:
- commands:
- - |
- if [ "${CLOUDFRONT_DISTRIBUTION}" = "none" ]; then
- echo "Skipping CloudFront invalidation"
- else
- aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION --paths "/*"
- fi
- EncryptionKey: alias/aws/s3
- Environment:
- ComputeType: BUILD_GENERAL1_SMALL
- Image: aws/codebuild/docker:18.09.0
- Type: LINUX_CONTAINER
- EnvironmentVariables:
- - Name: AWS_DEFAULT_REGION
- Value: !Ref AWS::Region
- - Name: CLOUDFRONT_DISTRIBUTION
- Value: !Ref CloudFrontDistribution
- - Name: WEB_SETTINGS
- Value: !Sub |
- window.s3f2Settings = {
- apiUrl: "${ApiUrl}",
- athenaExecutionRole: "${AthenaExecutionRole}",
- cognitoIdentityPool: "${CognitoIdentityPoolId}",
- cognitoUserPoolId: "${CognitoUserPoolId}",
- cognitoUserPoolClientId: "${CognitoUserPoolClientId}",
- region: "${AWS::Region}",
- version: "${Version}"
- };
- - Name: WEB_UI_BUCKET
- Value: !Ref WebUIBucket
- Name: !Sub ${ResourcePrefix}FrontendBuild
- ServiceRole: !Ref CodeBuildFrontendServiceRole
- CodePipelineServiceRole:
- Type: AWS::IAM::Role
- Properties:
- Path: /
- AssumeRolePolicyDocument:
- Statement:
- - Effect: Allow
- Principal:
- Service: codepipeline.amazonaws.com
- Action: sts:AssumeRole
- Policies:
- - PolicyName: root
- PolicyDocument:
- Statement:
- - Effect: Allow
- Resource: "*"
- Action:
- - ecs:DescribeServices
- - ecs:DescribeTaskDefinition
- - ecs:DescribeTasks
- - ecs:ListTasks
- - ecs:RegisterTaskDefinition
- - ecs:UpdateService
- - Effect: Allow
- Resource:
- - !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildBackend}
- Action:
- - codebuild:BatchGetBuilds
- - codebuild:StartBuild
- - !If
- - ShouldDeployWebUI
- - Effect: Allow
- Resource:
- - !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildFrontend}
- Action:
- - codebuild:BatchGetBuilds
- - codebuild:StartBuild
- - !Ref AWS::NoValue
- - Effect: Allow
- Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}
- Action:
- - s3:GetBucket*
- - s3:List*
- - Effect: Allow
- Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
- Action:
- - s3:GetObject
- - s3:GetObjectVersion
- - s3:PutObject
- CodePipeline:
- Type: AWS::CodePipeline::Pipeline
- Properties:
- RoleArn: !GetAtt CodePipelineServiceRole.Arn
- ArtifactStore:
- Type: S3
- Location: !Ref CodeBuildArtefactBucket
- Stages:
- - Name: Source
- Actions:
- - Name: App
- ActionTypeId:
- Category: Source
- Owner: AWS
- Version: "1"
- Provider: S3
- Configuration:
- S3Bucket: !Ref CodeBuildArtefactBucket
- S3ObjectKey: !Ref ArtefactName
- OutputArtifacts:
- - Name: S3F2
- RunOrder: 1
- - !If
- - ShouldDeployWebUI
- - Name: Frontend
- Actions:
- - Name: Build
- ActionTypeId:
- Category: Build
- Owner: AWS
- Version: "1"
- Provider: CodeBuild
- Configuration:
- ProjectName: !Ref CodeBuildFrontend
- InputArtifacts:
- - Name: S3F2
- OutputArtifacts:
- - Name: BuildFrontendOutput
- RunOrder: 1
- - !Ref AWS::NoValue
- - Name: Backend
- Actions:
- - Name: Build
- ActionTypeId:
- Category: Build
- Owner: AWS
- Version: "1"
- Provider: CodeBuild
- Configuration:
- ProjectName: !Ref CodeBuildBackend
- InputArtifacts:
- - Name: S3F2
- OutputArtifacts:
- - Name: BuildBackendOutput
- RunOrder: 2
- CopyBuildArtefactFunction:
- Type: AWS::Serverless::Function
- Properties:
- Handler: copy_build_artefact.handler
- CodeUri: ../backend/lambdas/custom_resources/
- Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
- Policies:
- - Statement:
- - Effect: Allow
- Action: s3:PutObject*
- Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
- - Effect: Allow
- Action: s3:GetObject
- Resource: !Sub arn:${AWS::Partition}:s3:::${PreBuiltArtefactsBucket}/*
- CleanupBucketFunction:
- Type: AWS::Serverless::Function
- Properties:
- Handler: cleanup_bucket.handler
- CodeUri: ../backend/lambdas/custom_resources/
- Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
- Policies:
- - Statement:
- - Effect: Allow
- Action:
- - s3:DeleteObject*
- - s3:GetBucketVersioning
- - s3:ListBucket*
- - s3:ListObject*
- Resource:
- - !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}
- - !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
- - !Sub arn:${AWS::Partition}:s3:::${WebUIBucket}
- - !Sub arn:${AWS::Partition}:s3:::${WebUIBucket}/*
- CleanupRepositoryFunction:
- Type: AWS::Serverless::Function
- Properties:
- Handler: cleanup_repository.handler
- CodeUri: ../backend/lambdas/custom_resources/
- Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
- Policies:
- - Statement:
- - Effect: Allow
- Action:
- - ecr:BatchDeleteImage
- - ecr:ListImages
- Resource: !Sub arn:${AWS::Partition}:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepository}
- WaitForContainerBuildFunction:
- Type: AWS::Serverless::Function
- Properties:
- Handler: wait_container_build.handler
- CodeUri: ../backend/lambdas/custom_resources/
- Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
- Policies:
- - Statement:
- - Effect: Allow
- Action:
- - lambda:AddPermission
- - lambda:RemovePermission
- - events:PutRule
- - events:DeleteRule
- - events:PutTargets
- - events:RemoveTargets
- Resource: "*"
- - Effect: Allow
- Action: s3:GetObject*
- Resource: !Sub "arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*"
- - Effect: Allow
- Action: ecr:DescribeImages
- Resource: !Sub arn:${AWS::Partition}:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepository}
- RedeployApiFunction:
- Type: AWS::Serverless::Function
- Properties:
- Handler: redeploy_apigw.handler
- CodeUri: ../backend/lambdas/custom_resources/
- Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
- Policies:
- - Statement:
- - Effect: Allow
- Action:
- - apigateway:POST
- Resource:
- - !Sub
- - arn:${AWS::Partition}:apigateway:${AWS::Region}::/restapis/${ApiId}/deployments
- - ApiId: !Select [0, !Split [".", !Select [2, !Split ["/", !Ref ApiUrl]]]]
- RerunPipelineFunction:
- Type: AWS::Serverless::Function
- Properties:
- Handler: rerun_pipeline.handler
- CodeUri: ../backend/lambdas/custom_resources/
- Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
- Policies:
- - Statement:
- - Effect: Allow
- Action:
- - codepipeline:StartPipelineExecution
- Resource:
- - !Sub arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${CodePipeline}
- CleanupCodeBuildArtefactBucket:
- Type: Custom::Setup
- Properties:
- ServiceToken: !GetAtt CleanupBucketFunction.Arn
- LogLevel: !Ref LogLevel
- Bucket: !Ref CodeBuildArtefactBucket
- CleanupWebUIBucket:
- Type: Custom::Setup
- Properties:
- ServiceToken: !GetAtt CleanupBucketFunction.Arn
- LogLevel: !Ref LogLevel
- Bucket: !Ref WebUIBucket
- DeployWebUI: !Ref DeployWebUI
- CleanupECRRepository:
- Type: Custom::Setup
- Properties:
- ServiceToken: !GetAtt CleanupRepositoryFunction.Arn
- LogLevel: !Ref LogLevel
- Repository: !Ref ECRRepository
- CopyBuildArtefact:
- Type: Custom::Setup
- DependsOn: CodePipeline
- Properties:
- ServiceToken: !GetAtt CopyBuildArtefactFunction.Arn
- ArtefactName: !Ref ArtefactName
- CodeBuildArtefactBucket: !Ref CodeBuildArtefactBucket
- CodeBuildArtefactBucketArn: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}
- LogLevel: !Ref LogLevel
- Region: !Ref AWS::Region
- PreBuiltArtefactsBucket: !Ref PreBuiltArtefactsBucket
- Version: !Ref Version
- WaitForContainerBuild:
- Type: Custom::Setup
- DependsOn: CopyBuildArtefact
- Properties:
- ServiceToken: !GetAtt WaitForContainerBuildFunction.Arn
- ArtefactName: !Ref ArtefactName
- CodeBuildArtefactBucket: !Ref CodeBuildArtefactBucket
- ECRRepository: !Ref ECRRepository
- LogLevel: !Ref LogLevel
- Version: !Ref Version
- RedeployApi:
- Type: Custom::Setup
- Properties:
- ServiceToken: !GetAtt RedeployApiFunction.Arn
- LogLevel: !Ref LogLevel
- ApiId: !Select [0, !Split [".", !Select [2, !Split ["/", !Ref ApiUrl]]]]
- ApiStage: !Select [3, !Split ["/", !Ref ApiUrl]]
- DeployCognito: !Ref DeployCognito
- RerunPipeline:
- Type: Custom::Setup
- Properties:
- ServiceToken: !GetAtt RerunPipelineFunction.Arn
- LogLevel: !Ref LogLevel
- PipelineName: !Ref CodePipeline
- DeployWebUI: !Ref DeployWebUI
|