How to setup AWS S3 Bucket for Rails Active Storage
Active Storage in Rails simplifies file uploads to cloud storage services like Amazon S3. Here’s a comprehensive guide to setting up an AWS S3 bucket for Rails Active Storage.
Step 1: Create an S3 Bucket in AWS
- Log in to your AWS Management Console and navigate to the S3 service.
- Click on the Create bucket button.
- Enter a unique name for your bucket (e.g.,
rails-active-storage
) and select a default region. - In the Object Ownership section, select ACIs enabled.
- In the Block Public Access settings for this bucket section, uncheck the following options and acknowledge the current settings:
- Block all public access
- Block public access to buckets and objects granted through new access control lists (ACLs)
- Block public access to buckets and objects granted through any access control lists (ACLs)
- Click on Create bucket.
Step 2: Create an IAM Policy in AWS
- Navigate to the IAM section and select Policies.
- Click on Create policy and configure:
- Service: s3
- Actions: Set access levels:
- List: ListBucket
- Read: GetObject
- Write: PutObject, DeleteObject
- Permissions management: PutObjectAcl
- Resources: Select Specific, then add two ARNs for your bucket (e.g.,
rails-active-storage
andrails-active-storage/*
).
- Proceed to the next page, specify a name for the policy (e.g.,
rails-active-storage-s3
), and click on Create policy.
Step 3: Create an IAM User in AWS
- In the IAM section, navigate to Users and click on Add user.
- Enter a user name (e.g.,
rails-active-storage
) and under Permissions options, select Attach policies directly. - Find and select the policy you've just created, then continue to create the user.
- Open the user's Security credentials tab, click on Create access key, and note down the access key ID and secret access key.
Step 4: Configure CORS in AWS Bucket
- Go to your AWS bucket, select Permissions, and navigate to Cross-origin resource sharing (CORS).
- Edit and paste the following configuration:
Step 5: Configure Rails Application
-
Add the access key and secret key to your Rails credentials:
EDITOR="nano" bin/rails credentials:edit
Paste the keys as follows:
aws: access_key_id: <your_access_key_id> secret_access_key: <your_secret_access_key>
To exit nano, press
Ctrl+X
, thenY
, and hitEnter
. -
Edit
config/storage.yml
to include your S3 configuration: -
In
config/environments/development.rb
, add:config.active_storage.service = :amazon
-
Add the AWS SDK S3 gem to your
Gemfile
:Then run
bundle install
.
Step 6: Setup Active Storage Tables
Generate and migrate Active Storage tables:
rails active_storage:install
rails db:migrate
Step 7: Attach files to records
Active Storage provides macros for attaching files:
-
Single File Attachments: Use
has_one_attached
for a one-to-one relationship. Example for an Employee model: -
Attach a photo:
employee.photo.attach(params[:photo])
and check attachment:employee.photo.attached?
-
Multiple File Attachments: Use
has_many_attached
for a one-to-many relationship.
Example for a Product model:
- Attach images:
@product.images.attach(params[:images])
and check attachments:@product.images.attached?
Step 8: Attaching and Removing Files locally
- Attach locally stored files:
@product.image.attach(io: File.open('/path/to/file'), filename: 'file.pdf', content_type: 'application/pdf')
. - Remove attached files:
@employee.photo.purge
.
Step 9: Create and Download Links
- Generate a download link:
rails_blob_path(@employee.photo, disposition: "attachment")
. - Download a file:
file_content = @employee.photo.download
.
Another method for configuring AWS credentials is by employing the following options:
-
Using environment variables:
With this approach, we don't have to explicitly pass the credentials as aws-sdk gem will handle by itself.
Add following lines in your .env file.
Edit
config/storage.yml
to include your S3 configuration: -
Using (~/.aws/credentials) file:
Create .aws folder in the root of you rails applications and create a credentials file (.aws/credentials)
Add your credentials as default:
default aws_access_key_id = YOUR_ACCESS_KEY_ID aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
Create/Edit the /config/initializers/aws-sdk.rb
Aws.config.update( credentials: Aws::SharedCredentials.new, region: <your_bucket_region> public: true )
Security Note Never commit the ~/.aws/credentials or .env or master.key file to version control to avoid exposing your credentials, instead add it to .gitignore.
Conclusion
With these steps, your Rails app is now configured to use AWS S3 for storage with Active Storage. This setup allows for efficient management of file uploads in your application.