How to save up on AWS S3 Buckets while deploying with serverless framework
Tags: aws, todayilearned, s3, serverless
Published: 2022-05-08 17:44:10

## The Problem:

When deploying one or several services through **serverless framework**, it creates a bucket similar to this: `<<your-service-name>>-<<stage>>-serverlessdeploymentbucket-12i2nulwb47go`, which contains the cloudformation template of the resources we have created, the zipped code, and a `serverless-state.json` file.

At first, this might not be a problem, except when we manage several services and several environments (e.g: `dev,qa,stg`), which can exceed the default limit of 100 buckets or even the hard cap limit of 1000 buckets very easily, besides being complicated to manage them in case you no longer use a service and want to delete it.

![Multiple Buckets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q6z04pzgz4vno61g65kk.png)

## How do we solve this?

Serverless framework lets you define a predefined bucket, which will help us centralize every other serverless deployment bucket into one. The plugin is skilled enough to separate our services into different stages as prefixes.

Let's start by creating an S3 bucket and a Parameter store with the bucket's name as a value.

> Note: I will use aws cdk to create these resources; feel free to skip this part. If you want to learn more about cdk or how to use it, I recommend following this [CDK Workshop](https://cdkworkshop.com/)

Create a bucket that will be used to centralize our serverless deployments. Set public read access as false and versioning as false (if you like you can also enable it, but that will create different versions of objects for every deployment which might not be recommended). 
{% gist https://gist.github.com/bdllerena/85901fbdb82effb3086cd37d5846acfd %}

{% gist https://gist.github.com/bdllerena/448771914580b0d11506947315018dbd 
 %}

Create a Parameter Store which will have as a value the name of our Bucket; this will help us define the Bucket's name in our `serverless.yml` programmatically as we can use a value name with a variable in another region.

![Parameter Store](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1fn72xxhsc7ggsoaz4l.png)

In our `serverless.yml`, we add these lines, which will indicate the bucket in which our code resides, referencing the variable we created.

> Note: In most cases we don't need to install or add the serverless-deployment-bucket plugin

```YAML
provider:
  name: aws
  runtime: go1.x
  stage: dev
  region: us-east-1
  deploymentBucket:
    name: ${ssm(us-east-1):/GLOBAL/DEPLOYMENT_BUCKET}
```
After deploying our service, we noticed that two prefixes were created, which refer to the DEV and QA environments, saving us two buckets in one.

![Multiple stages](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vmh96wnwfcsbu4qzyxrp.png)

However, what if we have different services in different regions? In this case, the buckets need to be in the same region as our services; otherwise, we would see this error.

![Failed region](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16kjoiupfpjxhn1tw67j.png)

To solve this, we need to create a bucket in the same region as our services and create another Parameter Store that will refer to that bucket's name.

Reference: [Serverless Deployment Bucket](https://www.serverless.com/plugins/serverless-deployment-bucket)