Configuration de AWS S3 avec ActiveStorage pour Ruby on Rails

Dans ce tuto nous allons apprendre à comment configurer AWS S3 pour stocker les assets de votre app.

Nous supposons que vous avez une application avec a minima Ruby on Rails 6.0

  1. Créer son bucket (un espace de stockage).
  2. Créer une stratégie d’accès pour les futurs utilisateurs.
  3. Créer un utilisateur et lui associer une stratégie.

0. Setup

Le setup étant terminé pour l’environnement local, nous allons installer AWS sur la prod. Tout d’abord il faut ajouter la gem AWS dans le Gemfile et l’installer avec bundle install

# Gemfile
gem "aws-sdk-s3", require: false
$ bundle install

Pour créer un compte, allez sur le site d’Amazon Web Services.Ensuite connectez vous à la console AWS. La configuration du compte se fera en 3 temps.

1. Créer son bucket

Vous devez cliquer sur Services puis recherchez S3. Ensuite vous cliquez sur Créer un compartiment. Dans le nom du compartiment vous mettez le nom de votre app. Et pour la région, il faut choisir l’Irlande si vous êtes chez Heroku.

AWS S3

2. Créer une stratégie

Vous faites une nouvelle recherche dans Services et vous recherchez IAM. Nous allons maintenant créer une stratégie.

On va choisir un service, c’est à dire S3. Pour les actions manuelles, il faut cocher Toutes les actions S3 et sélectionnez toutes les ressources. On clique sur Examiner une stratégie.

Pour le nom il faut être le plus clair possible en explicitant le nom du bucket et quels sont les droits (ici full access, c’est à dire que l’utilisateur peut lire et écrire).

Stratégie S3

Examiner une Stratégie

3. Créer un utilisateur

Pour les utilisateurs il faut choisir un nom d’utilisateur et ensuite un service. Ici ça sera encore une fois S3. Ensuite on va sur l’onglet Attacher les stratégies pour ajouter celle qu’on a crée juste avant. Pour les étapes 3 et 4 on peut mettre OK. AWS va ensuite nous donner les clés API que l’on doit mettre sur Heroku sous le nom de S3_ACCESS_KEY_ID et S3_SECRET_ACCESS_KEY.

Définissez les informations utilisateurs

Définir des autorisations

Et pour le type d’accès ça sera programatique c’est à dire que c’est un programme (et non un humain) qui va y accéder. Il n’y aura donc pas de mot de passe mais un token.

sélectionnez un type d'accès

4. Configuration des variables d’environnement.

Il faut maintenant spécifier qu’Active Storage doit utiliser Amazon sur l’environnement de production.

# config/storage.yml

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

amazon:
  service: S3
  access_key_id: <%= ENV['S3_ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['S3_SECRET_ACCESS_KEY'] %>
  bucket: "airbnb-copycat"
  # Rempacer airbnb-copycat par le bucket que vous avez crée
  region: "eu-west-1"
  # Si vous avez choisi un bucket à Paris
  # region: "eu-west-3"
# config/environments/production.rb
Rails.application.configure do
  # [..]
  config.active_storage.service = :amazon
  # [..]
end

[BONUS] Seeder des images

# db/seeds.rb
flat = Flat.create!(
  user:        User.last,
  address:     "55 rue du Faubourg Saint Honoré, 75008 Paris",
  surface:     120,
  price:       250,
  room:        4,
  description: "Amazing Office",
  max_guests:  8,
)

my_first_image_path = Rails.root.join('app', 'assets', 'images', 'my_first_image.png')
my_second_image_path = Rails.root.join('app', 'assets', 'images', 'my_second_image.png')
flat.images.attach(io: File.open(my_first_image_path), filename: 'image_name.png', content_type: 'image/png')
flat.images.attach(io: File.open(my_second_image_path), filename: 'image_name.png', content_type: 'image/png')