Skip to content

Instantly share code, notes, and snippets.

@halilim
Last active September 10, 2015 07:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halilim/8b8ecd92e21fd2b09ebe to your computer and use it in GitHub Desktop.
Save halilim/8b8ecd92e21fd2b09ebe to your computer and use it in GitHub Desktop.
Paperclip S3 storage with IAM user per bucket and region support

Amazon

I'm assuming you have already created an Amazon AWS account and an S3 bucket.

  1. Open the IAM console

  2. Create a group:

    • Groups
    • Create New Group
    • (Enter a name, e.g. user_per_bucket) Next Step
    • (Don't attach a policy) Next Step
    • Create Group
  3. Attach the following policy to the group:

    • (Click on the name of the group)
    • Inline Policies
    • "click here"
    • (Custom Policy) Select
    • Policy Name: AllowUsersFullAccessToTheirOwnBuckets
    • Policy Document:
    {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Sid": "AllowUsersFullAccessToTheirOwnBuckets",
               "Effect": "Allow",
               "Action": [
                   "s3:*"
               ],
               "Resource": [
                   "arn:aws:s3:::${aws:username}", "arn:aws:s3:::${aws:username}/*"
               ]
           }
       ]
    }

    (We are making use of policy variables)

    • Apply Policy

    With this policy, whenever you create a bucket and a user with the same name, the user will be authorised on the bucket automatically. Your users' names must be valid bucket names.

  4. Create a user with no policy and add it to the group.

Paperclip

  1. Add to the Gemfile:

     gem 'aws-sdk', '~> 1.6'
    

    The version is required since aws-sdk v2 is out and Paperclip is not yet compatible with it expected to support it in 4.4.

  2. Create a config/initializers/paperclip.rb file with the contents:

    Paperclip::Attachment.default_options.merge!(
        {
            storage: :s3,
            s3_credentials: {
                access_key_id: ENV['AWS_ACCESS_KEY_ID'],
                secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
                bucket: ENV['AWS_BUCKET']
            },
            path: Paperclip::Attachment.default_options[:url].sub(/\A\/system/, ''),
            s3_protocol: '', # Protocol relative
            url: ':s3_domain_url',
        }
    ) if ENV['PAPERCLIP_USE_S3'].present?

    By using :s3_domain_url, we will have shorter URLs and will not have to indicate a region since Amazon automatically handles it by CNAME'ing bucket.s3.amazonaws.com to s3-w.eu-central-1.amazonaws.com and rerouting the request to the appropriate bucket.

    Refer to the Paperclip S3 documentation for more information on the options.

  3. Set the env. var.s using your choice of env. manager (e.g. dotenv, application.yml, heroku set etc). An example for dotenv format:

     PAPERCLIP_USE_S3=true
     AWS_ACCESS_KEY_ID=***
     AWS_SECRET_ACCESS_KEY=***
     AWS_REGION=eu-central-1
     AWS_BUCKET=YOUR-BUCKET-NAME
    

    Leave PAPERCLIP_USE_S3 empty in development if you want to use the local filesystem, e.g.:

     PAPERCLIP_USE_S3=
    

Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment