Skip to content

Architect (arc.codes) serverless framework plugin that creates an S3 bucket that users can upload to directly, with optional Lambda triggers

License

Notifications You must be signed in to change notification settings

filmaj/arc-plugin-s3-image-bucket

Repository files navigation

arc-plugin-s3-image-bucket

Architect serverless framework plugin that creates an S3 bucket that users can upload to directly, with optional Lambda triggers

This plugin enables your arc.codes app to define an S3 bucket with specific CORS rules, static asset hosting and/or Lambda triggers. It bundles native ImageMagick binaries into any Lambda triggers it defines via the use of a Lambda Layer.

With this combination, you can enable direct-to-bucket uploads from clients accessing your webapp by providing a server-side API that generates a time-limited signed set of parameters to the client used to issue POST requests containing binary payloads directly to the S3 bucket.

This plugin takes heavy inspiration / straight up lifting from @brianleroux's macro-upload and arc-example-macro-upload repos, which are based on Leonid Shevtov's deep dive into enabling direct-from-client S3 uploads using browser-based POST requests to S3.

Requirements

⚠️ At this time this plugin only works with Architect 8.6.0 up to 9.x; Architect 10 is not supported.

Installation

  1. Install this plugin: npm i arc-plugin-s3-image-bucket

  2. Then add the following line to the @plugins pragma in your Architect project manifest (usually app.arc):

     @plugins
     arc-plugin-s3-image-bucket
    
  3. Add a new @image-bucket pragma, and provide any of the options to customize your bucket, any Lambda triggers and their behaviours. See the Usage section for details.

  4. If you defined any Lambda triggers, run arc create to generate the source directories for the Lambda triggers. These will be created under src/image-bucket. Lambda triggers will have ImageMagick binaries installed thanks to a publicly available Lambda Layer. If you intend to use ImageMagick, it is recommended to bump the memory allocated to the Lambda trigger by customizing the config.arc file inside the Lambda trigger source directory.

  5. Edit each trigger Lambda's index.js file, just as you would any classic arc @http, @events, etc. function.

  6. Run locally via arc sandbox, or deploy to AWS with arc deploy.

Usage

This plugin creates a single S3 bucket and wires up any number of Lambdas that trigger on events created by the bucket. Below is a list of options that are to be specified unindented directly under the @image-bucket pragma in your app.arc file. Each option also accepts sub-options that can be specified indented under the option. Check out the app.arc manifest under the sample-app/ directory for an example.

StaticWebsite

The StaticWebsite option configures public access to your image bucket over HTTP or HTTPS. Useful for serving user-uploaded content directly from the bucket. Setting this option turns on static website hosting for your S3 bucket, making it accessible to the internet.

StaticWebsite provides the following sub-options:

Sub-Option Description Example
Map Configures an HTTP GET route between your arc app's API Gateway instance and a path on your image bucket. Takes two required string parameters: an API Gateway route (the route web clients will use) and maps it to a route on the bucket. You must use the string {proxy+} in the first parameter to denote a variable representing a greedy URL path, and you must use the string {proxy} (without the +) in the second parameter to denote how that path maps to a path in your image bucket. Note that you must quote these parameters due to the special character usage. Note that if this sub-option is ommitted, you will only have HTTP access to your bucket contents using the bucket's static website hosting (whereas mapping an API Gateway route to a route on your bucket gives you HTTPS access "for free")
StaticWebsite
  Map "/img/{proxy+}" "/thumb/{proxy}"

CORS

The CORS option configures CORS rules for the image bucket.

You can define multiple CORS rule sets by defining this option multiple times. You can also add characters after the CORS characters for this option; this is helpful for naming / documenting the rules if you are using multiple CORS rule sets.

CORS supports sub-options that map directly to the AWS Cloudformation-supported S3 CORS Rules Properties, indented and one per line:

Sub-Option Description Example
AllowedHeaders See AWS documentation for AllowedHeaders
CORS
  AllowedHeaders *
AllowedMethods See AWS documentation for AllowedMethods
CORS
  AllowedMethods GET POST
AllowedOrigins See AWS documentation for AllowedOrigins
CORS
  AllowedOrigins https://myapp.com https://*.myapp.com
ExposedHeaders See AWS documentation for ExposedHeaders
CORS
  ExposedHeaders *
ExposedHeaders See AWS documentation for ExposedHeaders
CORS
  ExposedHeaders *
MaxAge See AWS documentation for MaxAge
CORS
  MaxAge 300

Lambda

Configure Lambda notification triggers for the image bucket. You can configure multiple Lambda triggers by adding this option multiple times. The option name must start with Lambda and must be proceeded by more characters; this suffix will be used to differentiate between Lambdas (and generate their name and source directory path). Each Lambda must specify at least one sub-property indented below the Lambda which specifies which S3 event triggers the Lambda (see here for a full list of available events).

Lambda supports the following sub-options:

Sub-Option Description Example
[event-name] [prefix/suffix] [path] Each Lambda must specify an S3 event name that will trigger the Lambda (see here for a full list of available events). Optionally, after the S3 event name, you may specify one or more event filtering rules associated to the event. Follow the S3 event string with pairs of space-separated strings: first one of prefix or suffix followed by the expected prefix or suffix string to filter event notifications by (these map to [S3 Filter Rules - click here for more details][s3-filter-rules]). You may add up to two prefix-path string pairs, and you can add up to a maximum of one prefix and one suffix filter rule.
LambdaRawImageHandler
  s3:ObjectCreated:* prefix raw
  s3:ObjectRemoved:* prefix raw
LambdaOnPngUpload
  s3:ObjectCreated:* suffix png

Sample Application

There is a sample application located under sample-app/. cd into that directory, npm install and you can run locally via arc sandbox or deploy to the internet via arc deploy.

The sample application uses a Lambda trigger on uploads to the image bucket to resize uploaded images to a maximum 100 pixel width/height, and writes these thumbnails under the thumb/ directory of the S3 image bucket this plugin creates.

The sample app also configures an HTTP proxy such that requests to img/* get redirected to thumb/* on the S3 image bucket.

Testing Locally

To try the sample out locally, cd into sample-app, run npm install and then run arc sandbox. Load http://localhost:3333, upload an image and see it resized to a max 100px width / height!

Testing the Deployed Version

To try the deployed sample out, cd into sample-app, run npm install and then run arc deploy. Load the URL outputted after deploy, upload an image and see it resized to a max 100px width / height!

Contributing

Thanks for considering contributing to this project! Check out the contribution guidelines for details.

About

Architect (arc.codes) serverless framework plugin that creates an S3 bucket that users can upload to directly, with optional Lambda triggers

Resources

License

Stars

Watchers

Forks

Packages

No packages published