Serverless Framework: Reusing S3 bucket for multiple projects deploy

  1. An AWS CloudFormation template is created from your serverless.yml.
  2. If a Stack has not yet been created, then it is created with no resources except for an S3 Bucket, which will store zip files of your Function code.
  3. The code of your Functions is then packaged into zip files.
  4. Serverless fetches the hashes for all files of the previous deployment (if any) and compares them against the hashes of the local files.
  5. Serverless terminates the deployment process if all file hashes are the same.
  6. Zip files of your Functions’ code are uploaded to your Code S3 Bucket.
  7. Any IAM Roles, Functions, Events and Resources are added to the AWS CloudFormation template.
  8. The CloudFormation Stack is updated with the new CloudFormation template.
  9. Each deployment publishes a new version for each function in your service.

Anatomy of “deploymentBucket” option

# serverless.yml
service:
...
provider:
...
deploymentBucket:
name: com.serverless.${self:provider.region}.deploys
maxPreviousDeploymentArtifacts: 10
blockPublicAccess: true
serverSideEncryption: AES256
sseKMSKeyId: arn:aws:kms:us-east-1:xxxxxxxxxxxx:key/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
sseCustomerAlgorithim: AES256
sseCustomerKey: string
sseCustomerKeyMD5: md5sum
tags:
key1: value1
key2: value2
  • name: Deployment bucket name. Default is generated by the framework
  • maxPreviousDeploymentArtifacts: On every deployment, the framework prunes the bucket to remove artifacts older than this limit. The default is 5
  • blockPublicAccess: Prevents public access via ACLs or bucket policies. Default is false
  • serverSideEncryption: server-side encryption method
  • sseKMSKeyId: when using server-side encryption
  • sseCustomerAlgorithim: when using server-side encryption and custom keys
  • sseCustomerKey: when using server-side encryption and custom keys
  • sseCustomerKeyMD5: when using server-side encryption and custom keys
  • tags: Tags that will be added to each of the deployment resources

Using “deploymentBucket” in multiple projects

  • A serverless.yml to define our bucket
  • A serverless.yml for serviceA
  • A serverless.yml for serviceB
  • A serverless.yml for serviceC
resources/
s3/
serverless.yml
services/
serviceA/
serverless.yml
serviceB/
serverless.yml
serviceC/
serverless.yml
org: your-org-name
app: shared-app-name
service: ${self:app}-shared-bucket-artifacts
provider:
name: aws
runtime: nodejs12.x
stage: ${opt:stage, "dev"}
region: ${opt:region, "us-west-2"}
profile: ${opt:profile, "default"}
custom:
basename: ${self:service}-${self:provider.stage}
bucketname: ${self:custom.basename}-${self:provider.region}-artifacts
resources:
Resources:
S3SharedBucketArtifacts:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.bucketname}
outputs:
S3SharedBucketArtifactsName:
Ref: S3SharedBucketArtifacts
S3SharedBucketArtifactsArn:
Fn::GetAtt: S3SharedBucketArtifacts.Arn
org: your-org-name
app: shared-app-name
service: ${self:app}-serviceA
provider:
name: aws
runtime: nodejs12.x
stage: ${opt:stage, "dev"}
region: ${opt:region, "us-west-2"}
profile: ${opt:profile, "default"}
deploymentBucket:
name: ${self:custom.sharedBucketName}
custom:
basename: ${self:service}-${self:provider.stage}
sharedBucketName: ${output:${self:app}-shared-bucket-artifacts.S3SharedBucketArtifactsName}
package:
exclude:
- ./**
include:
- index.js
functions:
test:
name: ${self:custom.basename}-test
handler: index.handler
description: Returns "Hello World". Dummy function for API deployment
events:
- http:
path: /test
method: any
cors: true

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store