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.
-
Install this plugin:
npm i arc-plugin-s3-image-bucket
-
Then add the following line to the
@plugins
pragma in your Architect project manifest (usuallyapp.arc
):@plugins arc-plugin-s3-image-bucket
-
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. -
If you defined any Lambda triggers, run
arc create
to generate the source directories for the Lambda triggers. These will be created undersrc/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 theconfig.arc
file inside the Lambda trigger source directory. -
Edit each trigger Lambda's
index.js
file, just as you would any classic arc@http
,@events
, etc. function. -
Run locally via
arc sandbox
, or deploy to AWS witharc deploy
.
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.
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 |
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 |
AllowedMethods |
See AWS documentation for AllowedMethods |
CORS |
AllowedOrigins |
See AWS documentation for AllowedOrigins |
CORS |
ExposedHeaders |
See AWS documentation for ExposedHeaders |
CORS |
ExposedHeaders |
See AWS documentation for ExposedHeaders |
CORS |
MaxAge |
See AWS documentation for MaxAge |
CORS |
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 |
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.
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!
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!
Thanks for considering contributing to this project! Check out the contribution guidelines for details.