Waffle.Storage.S3 (waffle v1.1.8)
The module to facilitate integration with S3 through ExAws.S3
config :waffle,
storage: Waffle.Storage.S3,
bucket: {:system, "AWS_S3_BUCKET"}
Along with any configuration necessary for ExAws.
ExAws is used to support Amazon S3.
To store your attachments in Amazon S3, you'll need to provide a bucket destination in your application config:
config :waffle,
bucket: "uploads"
You may also set the bucket from an environment variable:
config :waffle,
bucket: {:system, "S3_BUCKET"}
In addition, ExAws must be configured with the appropriate Amazon S3 credentials.
ExAws has by default the following configuration (which you may override if you wish):
config :ex_aws,
json_codec: Jason,
access_key_id: [{:system, "AWS_ACCESS_KEY_ID"}, :instance_role],
secret_access_key: [{:system, "AWS_SECRET_ACCESS_KEY"}, :instance_role]
This means it will first look for the AWS standard
AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
environment
variables, and fall back using instance meta-data if those don't
exist. You should set those environment variables to your
credentials, or configure an instance that this library runs on to
have an iam role.
specify-multiple-buckets
Specify multiple buckets
Waffle lets you specify a bucket on a per definition basis. In case you want to use multiple buckets, you can specify a bucket in the definition module like this:
def bucket, do: :some_custom_bucket_name
You can also use the current scope to define a target bucket
def bucket({_file, scope}), do: scope.bucket || bucket()
access-control-permissions
Access Control Permissions
Waffle defaults all uploads to private
. In cases where it is
desired to have your uploads public, you may set the ACL at the
module level (which applies to all versions):
@acl :public_read
Or you may have more granular control over each version. As an example, you may wish to explicitly only make public a thumbnail version of the file:
def acl(:thumb, _), do: :public_read
Supported access control lists for Amazon S3 are:
ACL | Permissions Added to ACL |
---|---|
:private | Owner gets FULL_CONTROL . No one else has access rights (default). |
:public_read | Owner gets FULL_CONTROL . The AllUsers group gets READ access. |
:public_read_write | Owner gets FULL_CONTROL . The AllUsers group gets READ and WRITE access. |
Granting this on a bucket is generally not recommended. | |
:authenticated_read | Owner gets FULL_CONTROL . The AuthenticatedUsers group gets READ access. |
:bucket_owner_read | Object owner gets FULL_CONTROL . Bucket owner gets READ access. |
:bucket_owner_full_control | Both the object owner and the bucket owner get FULL_CONTROL over the object. |
For more information on the behavior of each of these, please consult Amazon's documentation for Access Control List (ACL) Overview.
s3-object-headers
S3 Object Headers
The definition module may specify custom headers to pass through to S3 during object creation. The available custom headers include:
-
:cache_control
-
:content_disposition
-
:content_encoding
-
:content_length
-
:content_type
-
:expect
-
:expires
-
:storage_class
-
:website_redirect_location
-
:encryption
(set to "AES256" for encryption at rest)
As an example, to explicitly specify the content-type of an object,
you may define a s3_object_headers/2
function in your definition,
which returns a Keyword list, or Map of desired headers.
def s3_object_headers(version, {file, scope}) do
[content_type: MIME.from_path(file.file_name)] # for "image.png", would produce: "image/png"
end
alternate-s3-configuration-example
Alternate S3 configuration example
If you are using a region other than US-Standard, it is necessary to
specify the correct configuration for ex_aws
. A full example
configuration for both waffle and ex_aws is as follows:
config :waffle,
bucket: "my-frankfurt-bucket"
config :ex_aws,
json_codec: Jason,
access_key_id: "my_access_key_id",
secret_access_key: "my_secret_access_key",
region: "eu-central-1",
s3: [
scheme: "https://",
host: "s3.eu-central-1.amazonaws.com",
region: "eu-central-1"
]
For your host configuration, please examine the approved AWS Hostnames. There are often multiple hostname formats for AWS regions, and it will not work unless you specify the correct one.