deployment_helper.yaml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. AWSTemplateFormatVersion: "2010-09-09"
  2. Transform: AWS::Serverless-2016-10-31
  3. Description: Amazon S3 Find and Forget Deployment helper
  4. Globals:
  5. Function:
  6. Runtime: python3.9
  7. Timeout: 900
  8. Layers: !Ref CommonLayers
  9. Parameters:
  10. ApiUrl:
  11. Type: String
  12. ArtefactName:
  13. Type: String
  14. Default: build/s3f2.zip
  15. AthenaExecutionRole:
  16. Type: String
  17. CloudFrontDistribution:
  18. Type: String
  19. CodeBuildArtefactBucket:
  20. Type: String
  21. CognitoIdentityPoolId:
  22. Type: String
  23. CognitoUserPoolClientId:
  24. Type: String
  25. CognitoUserPoolId:
  26. Type: String
  27. CommonLayers:
  28. Type: CommaDelimitedList
  29. DeployWebUI:
  30. Type: String
  31. DeployCognito:
  32. Type: String
  33. ECRRepository:
  34. Type: String
  35. LogLevel:
  36. Type: String
  37. Default: INFO
  38. AllowedValues:
  39. - CRITICAL
  40. - FATAL
  41. - ERROR
  42. - WARNING
  43. - INFO
  44. - DEBUG
  45. - NOTSET
  46. PreBuiltArtefactsBucket:
  47. Type: String
  48. ResourcePrefix:
  49. Type: String
  50. Version:
  51. Type: String
  52. WebUIBucket:
  53. Type: String
  54. Conditions:
  55. WithoutCloudFront: !Equals [!Ref CloudFrontDistribution, "none"]
  56. ShouldDeployWebUI: !Equals [!Ref DeployWebUI, "true"]
  57. Resources:
  58. CodeBuildBackendServiceRole:
  59. Type: AWS::IAM::Role
  60. Properties:
  61. Path: /
  62. AssumeRolePolicyDocument:
  63. Statement:
  64. - Effect: Allow
  65. Principal:
  66. Service: codebuild.amazonaws.com
  67. Action: sts:AssumeRole
  68. Policies:
  69. - PolicyName: root
  70. PolicyDocument:
  71. Statement:
  72. - Resource: "*"
  73. Effect: Allow
  74. Action:
  75. - logs:CreateLogGroup
  76. - ecr:GetAuthorizationToken
  77. - Resource: !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:*
  78. Effect: Allow
  79. Action:
  80. - logs:CreateLogStream
  81. - logs:PutLogEvents
  82. - Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
  83. Effect: Allow
  84. Action:
  85. - s3:Get*
  86. - s3:List*
  87. - Resource: !Sub arn:${AWS::Partition}:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepository}
  88. Effect: Allow
  89. Action:
  90. - ecr:GetDownloadUrlForLayer
  91. - ecr:BatchGetImage
  92. - ecr:BatchCheckLayerAvailability
  93. - ecr:PutImage
  94. - ecr:InitiateLayerUpload
  95. - ecr:UploadLayerPart
  96. - ecr:CompleteLayerUpload
  97. CodeBuildFrontendServiceRole:
  98. Type: AWS::IAM::Role
  99. Properties:
  100. Path: /
  101. AssumeRolePolicyDocument:
  102. Statement:
  103. - Effect: Allow
  104. Principal:
  105. Service: codebuild.amazonaws.com
  106. Action: sts:AssumeRole
  107. Policies:
  108. - PolicyName: root
  109. PolicyDocument:
  110. Statement:
  111. - Resource: "*"
  112. Effect: Allow
  113. Action: logs:CreateLogGroup
  114. - Resource: !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:*
  115. Effect: Allow
  116. Action:
  117. - logs:CreateLogStream
  118. - logs:PutLogEvents
  119. - Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
  120. Effect: Allow
  121. Action:
  122. - s3:Get*
  123. - s3:List*
  124. - !If
  125. - ShouldDeployWebUI
  126. - Resource: !Sub arn:${AWS::Partition}:s3:::${WebUIBucket}/*
  127. Effect: Allow
  128. Action: s3:PutObject*
  129. - !Ref AWS::NoValue
  130. - !If
  131. - WithoutCloudFront
  132. - !Ref AWS::NoValue
  133. - Resource: !Sub arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}
  134. Effect: Allow
  135. Action: cloudfront:CreateInvalidation
  136. CodeBuildBackend:
  137. Type: AWS::CodeBuild::Project
  138. Properties:
  139. Artifacts:
  140. Type: CODEPIPELINE
  141. Source:
  142. Type: CODEPIPELINE
  143. BuildSpec: |
  144. version: 0.2
  145. phases:
  146. pre_build:
  147. commands:
  148. - $(aws ecr get-login --no-include-email)
  149. - IMAGE_URI="${REPOSITORY_URI}"
  150. build:
  151. commands:
  152. - docker load -i backend/ecs_tasks/python_3.9-slim.tar
  153. - docker build --tag "$IMAGE_URI" -f backend/ecs_tasks/delete_files/Dockerfile .
  154. post_build:
  155. commands:
  156. - docker push "$IMAGE_URI"
  157. EncryptionKey: alias/aws/s3
  158. Environment:
  159. ComputeType: BUILD_GENERAL1_SMALL
  160. Image: aws/codebuild/docker:18.09.0
  161. Type: LINUX_CONTAINER
  162. EnvironmentVariables:
  163. - Name: AWS_DEFAULT_REGION
  164. Value: !Ref AWS::Region
  165. - Name: REPOSITORY_URI
  166. Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.${AWS::URLSuffix}/${ECRRepository}
  167. Name: !Sub ${ResourcePrefix}BackendBuild
  168. ServiceRole: !Ref CodeBuildBackendServiceRole
  169. CodeBuildFrontend:
  170. Type: AWS::CodeBuild::Project
  171. Condition: ShouldDeployWebUI
  172. Properties:
  173. Artifacts:
  174. Type: CODEPIPELINE
  175. Source:
  176. Type: CODEPIPELINE
  177. BuildSpec: |
  178. version: 0.2
  179. phases:
  180. pre_build:
  181. commands:
  182. - BUCKET="${WEB_UI_BUCKET}"
  183. - ACL="private"
  184. - |
  185. if [ "${CLOUDFRONT_DISTRIBUTION}" = "none" ]; then
  186. ACL="public-read"
  187. fi
  188. - echo "${WEB_SETTINGS}" > frontend/build/settings.js
  189. build:
  190. commands:
  191. - cd frontend/build
  192. - aws s3 cp . s3://$BUCKET --acl $ACL --recursive
  193. post_build:
  194. commands:
  195. - |
  196. if [ "${CLOUDFRONT_DISTRIBUTION}" = "none" ]; then
  197. echo "Skipping CloudFront invalidation"
  198. else
  199. aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION --paths "/*"
  200. fi
  201. EncryptionKey: alias/aws/s3
  202. Environment:
  203. ComputeType: BUILD_GENERAL1_SMALL
  204. Image: aws/codebuild/docker:18.09.0
  205. Type: LINUX_CONTAINER
  206. EnvironmentVariables:
  207. - Name: AWS_DEFAULT_REGION
  208. Value: !Ref AWS::Region
  209. - Name: CLOUDFRONT_DISTRIBUTION
  210. Value: !Ref CloudFrontDistribution
  211. - Name: WEB_SETTINGS
  212. Value: !Sub |
  213. window.s3f2Settings = {
  214. apiUrl: "${ApiUrl}",
  215. athenaExecutionRole: "${AthenaExecutionRole}",
  216. cognitoIdentityPool: "${CognitoIdentityPoolId}",
  217. cognitoUserPoolId: "${CognitoUserPoolId}",
  218. cognitoUserPoolClientId: "${CognitoUserPoolClientId}",
  219. region: "${AWS::Region}",
  220. version: "${Version}"
  221. };
  222. - Name: WEB_UI_BUCKET
  223. Value: !Ref WebUIBucket
  224. Name: !Sub ${ResourcePrefix}FrontendBuild
  225. ServiceRole: !Ref CodeBuildFrontendServiceRole
  226. CodePipelineServiceRole:
  227. Type: AWS::IAM::Role
  228. Properties:
  229. Path: /
  230. AssumeRolePolicyDocument:
  231. Statement:
  232. - Effect: Allow
  233. Principal:
  234. Service: codepipeline.amazonaws.com
  235. Action: sts:AssumeRole
  236. Policies:
  237. - PolicyName: root
  238. PolicyDocument:
  239. Statement:
  240. - Effect: Allow
  241. Resource: "*"
  242. Action:
  243. - ecs:DescribeServices
  244. - ecs:DescribeTaskDefinition
  245. - ecs:DescribeTasks
  246. - ecs:ListTasks
  247. - ecs:RegisterTaskDefinition
  248. - ecs:UpdateService
  249. - Effect: Allow
  250. Resource:
  251. - !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildBackend}
  252. Action:
  253. - codebuild:BatchGetBuilds
  254. - codebuild:StartBuild
  255. - !If
  256. - ShouldDeployWebUI
  257. - Effect: Allow
  258. Resource:
  259. - !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildFrontend}
  260. Action:
  261. - codebuild:BatchGetBuilds
  262. - codebuild:StartBuild
  263. - !Ref AWS::NoValue
  264. - Effect: Allow
  265. Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}
  266. Action:
  267. - s3:GetBucket*
  268. - s3:List*
  269. - Effect: Allow
  270. Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
  271. Action:
  272. - s3:GetObject
  273. - s3:GetObjectVersion
  274. - s3:PutObject
  275. CodePipeline:
  276. Type: AWS::CodePipeline::Pipeline
  277. Properties:
  278. RoleArn: !GetAtt CodePipelineServiceRole.Arn
  279. ArtifactStore:
  280. Type: S3
  281. Location: !Ref CodeBuildArtefactBucket
  282. Stages:
  283. - Name: Source
  284. Actions:
  285. - Name: App
  286. ActionTypeId:
  287. Category: Source
  288. Owner: AWS
  289. Version: "1"
  290. Provider: S3
  291. Configuration:
  292. S3Bucket: !Ref CodeBuildArtefactBucket
  293. S3ObjectKey: !Ref ArtefactName
  294. OutputArtifacts:
  295. - Name: S3F2
  296. RunOrder: 1
  297. - !If
  298. - ShouldDeployWebUI
  299. - Name: Frontend
  300. Actions:
  301. - Name: Build
  302. ActionTypeId:
  303. Category: Build
  304. Owner: AWS
  305. Version: "1"
  306. Provider: CodeBuild
  307. Configuration:
  308. ProjectName: !Ref CodeBuildFrontend
  309. InputArtifacts:
  310. - Name: S3F2
  311. OutputArtifacts:
  312. - Name: BuildFrontendOutput
  313. RunOrder: 1
  314. - !Ref AWS::NoValue
  315. - Name: Backend
  316. Actions:
  317. - Name: Build
  318. ActionTypeId:
  319. Category: Build
  320. Owner: AWS
  321. Version: "1"
  322. Provider: CodeBuild
  323. Configuration:
  324. ProjectName: !Ref CodeBuildBackend
  325. InputArtifacts:
  326. - Name: S3F2
  327. OutputArtifacts:
  328. - Name: BuildBackendOutput
  329. RunOrder: 2
  330. CopyBuildArtefactFunction:
  331. Type: AWS::Serverless::Function
  332. Properties:
  333. Handler: copy_build_artefact.handler
  334. CodeUri: ../backend/lambdas/custom_resources/
  335. Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
  336. Policies:
  337. - Statement:
  338. - Effect: Allow
  339. Action: s3:PutObject*
  340. Resource: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
  341. - Effect: Allow
  342. Action: s3:GetObject
  343. Resource: !Sub arn:${AWS::Partition}:s3:::${PreBuiltArtefactsBucket}/*
  344. CleanupBucketFunction:
  345. Type: AWS::Serverless::Function
  346. Properties:
  347. Handler: cleanup_bucket.handler
  348. CodeUri: ../backend/lambdas/custom_resources/
  349. Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
  350. Policies:
  351. - Statement:
  352. - Effect: Allow
  353. Action:
  354. - s3:DeleteObject*
  355. - s3:GetBucketVersioning
  356. - s3:ListBucket*
  357. - s3:ListObject*
  358. Resource:
  359. - !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}
  360. - !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*
  361. - !Sub arn:${AWS::Partition}:s3:::${WebUIBucket}
  362. - !Sub arn:${AWS::Partition}:s3:::${WebUIBucket}/*
  363. CleanupRepositoryFunction:
  364. Type: AWS::Serverless::Function
  365. Properties:
  366. Handler: cleanup_repository.handler
  367. CodeUri: ../backend/lambdas/custom_resources/
  368. Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
  369. Policies:
  370. - Statement:
  371. - Effect: Allow
  372. Action:
  373. - ecr:BatchDeleteImage
  374. - ecr:ListImages
  375. Resource: !Sub arn:${AWS::Partition}:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepository}
  376. WaitForContainerBuildFunction:
  377. Type: AWS::Serverless::Function
  378. Properties:
  379. Handler: wait_container_build.handler
  380. CodeUri: ../backend/lambdas/custom_resources/
  381. Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
  382. Policies:
  383. - Statement:
  384. - Effect: Allow
  385. Action:
  386. - lambda:AddPermission
  387. - lambda:RemovePermission
  388. - events:PutRule
  389. - events:DeleteRule
  390. - events:PutTargets
  391. - events:RemoveTargets
  392. Resource: "*"
  393. - Effect: Allow
  394. Action: s3:GetObject*
  395. Resource: !Sub "arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}/*"
  396. - Effect: Allow
  397. Action: ecr:DescribeImages
  398. Resource: !Sub arn:${AWS::Partition}:ecr:${AWS::Region}:${AWS::AccountId}:repository/${ECRRepository}
  399. RedeployApiFunction:
  400. Type: AWS::Serverless::Function
  401. Properties:
  402. Handler: redeploy_apigw.handler
  403. CodeUri: ../backend/lambdas/custom_resources/
  404. Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
  405. Policies:
  406. - Statement:
  407. - Effect: Allow
  408. Action:
  409. - apigateway:POST
  410. Resource:
  411. - !Sub
  412. - arn:${AWS::Partition}:apigateway:${AWS::Region}::/restapis/${ApiId}/deployments
  413. - ApiId: !Select [0, !Split [".", !Select [2, !Split ["/", !Ref ApiUrl]]]]
  414. RerunPipelineFunction:
  415. Type: AWS::Serverless::Function
  416. Properties:
  417. Handler: rerun_pipeline.handler
  418. CodeUri: ../backend/lambdas/custom_resources/
  419. Description: Custom Lambda resource for the Amazon S3 Find and Forget Cloudformation Stack
  420. Policies:
  421. - Statement:
  422. - Effect: Allow
  423. Action:
  424. - codepipeline:StartPipelineExecution
  425. Resource:
  426. - !Sub arn:${AWS::Partition}:codepipeline:${AWS::Region}:${AWS::AccountId}:${CodePipeline}
  427. CleanupCodeBuildArtefactBucket:
  428. Type: Custom::Setup
  429. Properties:
  430. ServiceToken: !GetAtt CleanupBucketFunction.Arn
  431. LogLevel: !Ref LogLevel
  432. Bucket: !Ref CodeBuildArtefactBucket
  433. CleanupWebUIBucket:
  434. Type: Custom::Setup
  435. Properties:
  436. ServiceToken: !GetAtt CleanupBucketFunction.Arn
  437. LogLevel: !Ref LogLevel
  438. Bucket: !Ref WebUIBucket
  439. DeployWebUI: !Ref DeployWebUI
  440. CleanupECRRepository:
  441. Type: Custom::Setup
  442. Properties:
  443. ServiceToken: !GetAtt CleanupRepositoryFunction.Arn
  444. LogLevel: !Ref LogLevel
  445. Repository: !Ref ECRRepository
  446. CopyBuildArtefact:
  447. Type: Custom::Setup
  448. DependsOn: CodePipeline
  449. Properties:
  450. ServiceToken: !GetAtt CopyBuildArtefactFunction.Arn
  451. ArtefactName: !Ref ArtefactName
  452. CodeBuildArtefactBucket: !Ref CodeBuildArtefactBucket
  453. CodeBuildArtefactBucketArn: !Sub arn:${AWS::Partition}:s3:::${CodeBuildArtefactBucket}
  454. LogLevel: !Ref LogLevel
  455. Region: !Ref AWS::Region
  456. PreBuiltArtefactsBucket: !Ref PreBuiltArtefactsBucket
  457. Version: !Ref Version
  458. WaitForContainerBuild:
  459. Type: Custom::Setup
  460. DependsOn: CopyBuildArtefact
  461. Properties:
  462. ServiceToken: !GetAtt WaitForContainerBuildFunction.Arn
  463. ArtefactName: !Ref ArtefactName
  464. CodeBuildArtefactBucket: !Ref CodeBuildArtefactBucket
  465. ECRRepository: !Ref ECRRepository
  466. LogLevel: !Ref LogLevel
  467. Version: !Ref Version
  468. RedeployApi:
  469. Type: Custom::Setup
  470. Properties:
  471. ServiceToken: !GetAtt RedeployApiFunction.Arn
  472. LogLevel: !Ref LogLevel
  473. ApiId: !Select [0, !Split [".", !Select [2, !Split ["/", !Ref ApiUrl]]]]
  474. ApiStage: !Select [3, !Split ["/", !Ref ApiUrl]]
  475. DeployCognito: !Ref DeployCognito
  476. RerunPipeline:
  477. Type: Custom::Setup
  478. Properties:
  479. ServiceToken: !GetAtt RerunPipelineFunction.Arn
  480. LogLevel: !Ref LogLevel
  481. PipelineName: !Ref CodePipeline
  482. DeployWebUI: !Ref DeployWebUI