Skip to content

Latest commit

 

History

History
185 lines (130 loc) · 6.18 KB

File metadata and controls

185 lines (130 loc) · 6.18 KB

Storage

The storage construct deploys S3 buckets to store files.

Quick start

serverless plugin install -n serverless-lift
service: my-app
provider:
  name: aws

constructs:
    avatars:
        type: storage

plugins:
    - serverless-lift

On serverless deploy, a preconfigured S3 bucket will be created.

How it works

The storage construct creates and configures the S3 bucket for production:

  • Files stored in the bucket are automatically encrypted (S3 takes care of encrypting and decrypting data on the fly, without change to our applications).
  • File versioning is enabled to prevent any accidental data loss. Old versions are automatically purged after 30 days to avoid extra costs.
  • Storage costs are optimized automatically via intelligent tiering.

To learn more about the architecture of this construct, read this article.

Variables

All storage constructs expose the following variables:

  • bucketName: the name of the deployed S3 bucket
  • bucketArn: the ARN of the deployed S3 bucket

This can be used to reference the bucket from Lambda functions, for example:

constructs:
    avatars:
        type: storage

functions:
    myFunction:
        handler: src/index.handler
        environment:
            BUCKET_NAME: ${construct:avatars.bucketName}

How it works: the ${construct:avatars.bucketName} variable will automatically be replaced with a CloudFormation reference to the S3 bucket.

Permissions

By default, all the Lambda functions deployed in the same serverless.yml file will be allowed to read/write into the bucket.

In the example below, there are no IAM permissions to set up: myFunction will be allowed to read and write into the avatars bucket.

constructs:
    avatars:
        type: storage

functions:
    myFunction:
        handler: src/index.handler
        environment:
            BUCKET_NAME: ${construct:avatars.bucketName}

Automatic permissions can be disabled: read more about IAM permissions.

Configuration reference

Encryption

By default, files are encrypted using the default S3 encryption mechanism (free).

Alternatively, for example to comply with certain policies, it is possible to use KMS:

constructs:
    avatars:
        # ...
        encryption: kms

Lifecycle rules

You can configure custom S3 lifecycle rules to automatically delete or transition objects:

constructs:
    avatars:
        type: storage
        lifecycleRules:
            - prefix: tmp/
              expirationInDays: 1
            - prefix: cache/
              expirationInDays: 7

The configuration maps directly to CloudFormation LifecycleConfiguration Rules with the following conveniences:

  • Status: Enabled is added by default (can be overridden)
  • Property names can be written in camelCase (e.g. expirationInDays) or PascalCase (e.g. ExpirationInDays)

These rules are added to the default lifecycle rules that Lift adds (intelligent tiering and old version cleanup).

ACL support

Since April 2023, S3 buckets have ACLs disabled by default. However, many tools and libraries (including PHP's Flysystem, used by Laravel) send ACL headers on S3 operations. Without enabling ACLs, these operations will fail.

To let the bucket accept ACL headers while keeping the bucket owner in full control:

constructs:
    storage:
        type: storage
        allowAcl: true

This sets the S3 bucket's Object Ownership to BucketOwnerPreferred and grants s3:GetObjectAcl and s3:PutObjectAcl permissions to Lambda functions.

CORS

To allow browser-based uploads (e.g. via presigned URLs), you can configure CORS on the bucket.

Simple form — allow a single origin with default methods (GET, PUT, DELETE) and all headers:

constructs:
    storage:
        type: storage
        cors: "${construct:website.url}"

Use cors: "*" to allow all origins.

Full form — define complete CORS rules (property names can be camelCase or PascalCase):

constructs:
    storage:
        type: storage
        cors:
            -   allowedOrigins:
                    - "${construct:website.url}"
                allowedMethods:
                    - PUT
                allowedHeaders:
                    - "*"

The full form maps directly to CloudFormation CorsRules.

Extensions

You can specify an extensions property on the storage construct to extend the underlying CloudFormation resources. In the exemple below, the S3 Bucket CloudFormation resource generated by the avatars storage construct will be extended with the new AccessControl: PublicRead CloudFormation property.

constructs:
    avatars:
        type: storage
        extensions:
            bucket:
                Properties:
                    AccessControl: PublicRead

Available extensions

Extension key CloudFormation resource CloudFormation documentation
bucket AWS::S3::Bucket Link

More options

Feel like a common extension pattern should be implemented as part of the construct configuration? Open a GitHub issue.