🖼️

Active Storageの画像をAWSのS3へ保存する

2024/07/14に公開




開発環境

  • macOS
  • VSCode
  • Rails-7.1.3.3
  • ruby-3.2.3
  • PostgreSQL-16.2

行いたいこと

  • Herokuのデプロイ環境では、アプリケーションのファイルシステムは揮発性ストレージを使用しています。そのため、デプロイやアプリケーションの再起動時にファイルシステムの変更が失われてしまいます。
  • 今回は画像のデータを永続的に保存するために、AWSS3を導入したのでその流れを記載します。

前提として

  • 既にActive Storageで画像を正しく保存できている
  • AWSのアカウントは作成済み
  • Herokuにはデプロイ済み




AWSのS3でバケットを作成する

・リージョンを東京に変更する。(デフォルトはバージニア北部となっている)

Image from Gyazo

・検索欄にS3と入力しS3を選択する。

Image from Gyazo

バケットを作成する。

Image from Gyazo

バケットの一般的な設定(この設定以外はデフォルト)

・任意のバケット名を記載する。
Image from Gyazo

バケットのブロックパブリックアクセス設定

パブリックアクセスをすべてブロックのチェックを外す。
・画像のように下の2つにチェックを入れる。 ⇨ 表示される承認しますにチェックを入れる。
バケットを作成を選択
Image from Gyazo




IAMポリシーの作成

・検索欄でIAMと入力しIAMを選択する。 ⇨ ポリシーを選択する。 ⇨ ポリシーの作成

IAMを選択
Image from Gyazo
ポリシーを選択
Image from Gyazo
ポリシーの作成
Image from Gyazo

・アクセス許可を指定

・サービスを選択でS3を選択 ⇨ 次へ
Image from Gyazo

S3タブを展開しリスト読み取り書き込み許可の管理、をそれぞれ選択する
Image from Gyazo

・リスト ⇨ ListBucket
Image from Gyazo
・読み取り ⇨ GetObject
Image from Gyazo
・書き込み ⇨ DeleteObjectPutObject
Image from Gyazo
・許可の管理 ⇨ PutObjectAcl
Image from Gyazo

・リソース⇨bucketのみARNを追加を選択し記載
Image from Gyazo
リソースバケット名に作成したバケット名を記載する(リソースARNは自動で記載される)
 ⇨ ARNを追加 ⇨ 次へ
Image from Gyazo

・ポリシーの詳細

ポリシー名のみ記載(説明-オプションは不要)
Image from Gyazo
・ポリシーの作成
Image from Gyazo




IAMユーザーの作成

・ユーザータブを選択 ⇨ ユーザーの作成

ユーザータブ
Image from Gyazo
ユーザーを作成
Image from Gyazo

・許可を設定

ポリシーを直接アタッチするを選択する ⇨ 検索欄で先ほど作成したIAMポリシーを検索する
 ⇨ ポリシーを選択 ⇨ 次へ
Image from Gyazo
・ユーザーの詳細、許可の概要を確認して ⇨ ユーザーの作成
Image from Gyazo




アクセスキーを作成

ユーザータブ ⇨ ユーザー名を選択

Image from Gyazo

・セキュリティ認証情報タブ ⇨ アクセスキーを作成

セキュリティ認証情報タブ
Image from Gyazo
アクセスキーを作成
Image from Gyazo

・主要なベストプラクティスと代替案にアクセスするの設定

AWS の外部で実行されるアプリケーションを選択する ⇨ 次へ
Image from Gyazo

・説明タグを設定-オプション

説明タグを設定-オプションは不要なのでそのままアクセスキーを作成
Image from Gyazo




バケットポリシーの設定

・作成したバケットへ移動しアクセス許可タブを選択する

Image from Gyazo

・バケットポリシーの編集を選択

Image from Gyazo

・画像のように記載しました。

コード
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "ユーザーページからARNをコピーして貼り付け"
      },
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::バケット名",
        "arn:aws:s3:::バケット名/*"
      ]
    }
  ]
}
ユーザーページからARNをコピー

・ユーザータブ⇨ユーザー名を選択
Image from Gyazo
・こちらをコピー
Image from Gyazo

Image from Gyazo




ファイルへの記載

・gem 'aws-sdk-s3'の追加

Gemfileに追記

Gemfile
gem 'aws-sdk-s3'

bundle installを実行

ターミナル
$ bundle install

・config/credentials.yml.enc への記載(隠しファイル)

記載内容

アクセスキーシークレットアクセスキーリージョンバケット名の4つを記載していく

・このファイルはエディターから直接記載ができないのでvimで記載していく

・コンテナに入り

ターミナル
$ docker-compose exec web bash

・ファイルを指定しvimで開く

ターミナル(コンテナ内)
$ EDITOR="vim" rails credentials:edit

・このような記載になっていると思うので...

(コンテナ内 / config/credentials.yml.enc / 修正前)
# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: ・・・・・・・・・・・・・・・・・・・省略・・・・・・・・・・・・・・・・・・・

・必要事項を追記する(:の後のスペースや改行に気をつける)

(コンテナ内 / config/credentials.yml.enc / 修正後)
# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: ・・・・・・・・・・・・・・・・・・・省略・・・・・・・・・・・・・・・・・・・

aws:
  access_key_id: アクセスキー
  secret_access_key: シークレットアクセスキー
  region: リージョン
  bucket: バケット名

・保存コードの確認方法

コンソールから確認(Rails.application.credentials.aws)

・コンソールを開く

ターミナル
$ rails c

Rails.application.credentials.aws

ターミナル
irb(main):001> Rails.application.credentials.aws
=> {:access_key_id=>"アクセスキー", :secret_access_key=>"シークレットアクセスキー", 
    :region=>"リージョン", :bucket=>"バケット名"}
コンテナから確認(rails credentials:show)

・コンテナに入る

ターミナル
$ docker-compose exec web bash 

rails credentials:show

ターミナル(コンテナ内)
root@b7f741d3e5aa:/myapp# rails credentials:show

・ファイルのコードがそのまま表示される

ターミナル(コンテナ内)
# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: ・・・・・・・・・・・・・・・・・・・省略・・・・・・・・・・・・・・・・・・・

aws:
  access_key_id: アクセスキー
  secret_access_key: シークレットアクセスキー
  region: リージョン
  bucket: バケット名

・保存に成功した場合と失敗した場合の表示

成功と失敗の表示例

・保存に成功した表示
Image from Gyazo
・保存に失敗した表示(画像はインデントとスペースのエラー)
Image from Gyazo

・config/storage.yml への記載

vimで記載した隠しファイルconfig/credentials.yml.encを正しく参照できるように、
 インデント改行に気をつける。

config/storage.yml
local:
  service: S3
  access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
  region: <%= ENV['AWS_REGION'] %>
  bucket: <%= ENV['AWS_BUCKET'] %>

amazon:
  service: S3
  access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
  region: <%= ENV['AWS_REGION'] %>
  bucket: <%= ENV['AWS_BUCKET'] %>

・config/environments/development.rb への記載

config/environments/development.rb
config.active_storage.service = :amazon

・config/environments/production.rb への記載

config/environments/production.rb
config.active_storage.service = :amazon




Herokuに環境変数を記載

・Herokuのダッシュボードから、設定設定変数 価値に値を入力し追加

設定タブ
Image from Gyazo
価値に値を入力し追加
Image from Gyazo
環境変数を記載(config/storage.ymlファイルが参照できるように正しく記載)
Image from Gyazo

・ターミナルからHerokuの環境変数を確認する

Herokuの環境変数を確認(heroku config)

heroku config

ターミナル
$ heroku config

・Herokuに登録されている環境変数が全て表示される

ターミナル
AWS_ACCESS_KEY_ID:        アクセスキー
AWS_BUCKET:               バケット名
AWS_REGION:               リージョン
AWS_SECRET_ACCESS_KEY:    シークレットアクセスキー




開発環境にも環境変数を記載する

・隠しファイル.envに環境変数を記載する

.env
AWS_ACCESS_KEY_ID=アクセスキー
AWS_SECRET_ACCESS_KEY=シークレットアクセスキー
AWS_REGION=リージョン
AWS_BUCKET=バケット名

以上でAWSのS3へ保存の設定は完了です。






GitHubで編集を提案

Discussion