Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configuring ActiveStorage to use S3 with IAM role

I'm trying to configure ActiveStorage to use S3 bucket as a storage backend however I don't want to pass any of access_key_id, secret_access_key, region. Instead, I'd like to use previously defined IAM role. Such configuration is mentioned here. It reads (I've added bold):

If you want to use environment variables, standard SDK configuration files, profiles, IAM instance profiles or task roles, you can omit the access_key_id, secret_access_key, and region keys in the example above. The Amazon S3 Service supports all of the authentication options described in the AWS SDK documentation.

However I cannot get it working. My storage.yml looks similar to this:

amazon:
  service: S3
  bucket: bucket_name
  credentials:
    role_arn: "linked::account::arn"
    role_session_name: "session-name"

I've run rails active_storage:install, applied generated migrations and set config.active_storage.service = :amazon in my app's config.

The issue is that when I'm trying to save a file, I'm getting an unexpected error:

u = User.first
s = StringIO.new
s << 'hello,world'
s.seek 0
u.csv.attach(io: s, filename: 'filename.csv')

Traceback (most recent call last):
        2: from (irb):3
        1: from (irb):3:in `rescue in irb_binding'
LoadError (Unable to autoload constant ActiveStorage::Blob::Analyzable, expected /usr/local/bundle/gems/activestorage-5.2.2/app/models/active_storage/blob/analyzable.rb to define it)

I'm using Rails 5.2.2.

like image 851
glu Avatar asked Mar 15 '19 17:03

glu


1 Answers

Are you trying this code inside an AWS EC2 instance or locally in your machine?

If you check the authentication methods in AWS: https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html#aws-ruby-sdk-credentials-iam

You'll see the following section:

Setting Credentials Using IAM

For an Amazon Elastic Compute Cloud instance, create an AWS Identity and Access Management role, and then give your Amazon EC2 instance access to that role. For more information, see IAM Roles for Amazon EC2 in the Amazon EC2 User Guide for Linux Instances or IAM Roles for Amazon EC2 in the Amazon EC2 User Guide for Windows Instances.

This means that for this authentication method to work, you must:

  • Create an EC2 instance on AWS
  • Create an EC2 IAM Role with permissions to write to an S3 Bucket
  • Configure your EC2 instance attaching the new IAM Role to it

With the role attached to the instance, your config/storage.yml file will look like this:

amazon:
  service: S3
  bucket: test-stackoverflow-bucket-app
  region: "us-west-1"

Note that region is a required parameter, you'll get an error if you skip it: https://github.com/aws/aws-sdk-ruby/issues/1240#issuecomment-231866239

I'm afraid this won't work locally, to use active_storage locally you must set the access_key_id, secret_access_key values.

like image 131
Carlos Martinez Avatar answered Oct 22 '22 03:10

Carlos Martinez