目的
AWSのS3を使用し、画像をアップロードする。
開発環境
macOS: Big Sur
Rubyバージョン: 2.6.5
Railsバージョン: 6.0.0
前提
- S3のバケットが作成されている。
【AWS】S3バケット作成 - アプリが作成されている。
【Rails】簡単な投稿アプリの作成 - 画像アップロード機能が実装されている。
【Rails】画像アップロード機能の導入
手順
- はじめに
- Gemのインストール
- development.rbの編集
- storage.ymlの編集
- 環境変数の設定
- 環境変数の使用
- git-secretsの導入
- git-secretsの条件設定
- GitHub Desktopの利用設定
- 本番環境でのS3設定
- Heroku上での環境変数設定
はじめに
今回はAWSのS3
を用いた画像アップロードを実装していきます。
Gemのインストール
まずはローカル環境での実装を行います。
なお、以降のコードを編集する際はmasterブランチで作業していきます。
それでは早速始めていきます!
S3を使用するために必要なaws-sdk-s3
というGemをインストールします!
#中略
gem "aws-sdk-s3", require: false
% bundle install
これでインストールできました!
development.rbの編集
続いて、画像の保存先をlocal
からS3
に保存されるように設定を変更します!
まず、development.rb
に記述している画像の保存先の設定を下記のように変更します。
#省略
#config.active_storage.service = :local
config.active_storage.service = :amazon
#省略
これで画像の保存先が変更できました。
storage.ymlの編集
次に、S3で使用するバケット名
とリージョン名
を記述します。
storage.yml
に以下のコードを追記します。
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
amazon:
service: S3
region: ap-northeast-1
bucket: 「バケット名を入力」
#省略
「バケット名を入力」の箇所には、自分のバケット名を入力します!
環境変数の設定
最後に、S3にアクセスするための認証情報を設定します。
秘密情報である「Access key ID」
と「Secret access key」
は直接記載してはいけないため、それぞれの環境変数に入れてソースコードに記述します。
まずは、環境変数を設定するファイルを編集するために、vimコマンド
を使用します。
$ vim ~/.bash_profile
続いて「i」
を入力して、ファイルを編集モードにします。
ターミナル左下に「INSERT」
という文字が表示されれば文字が入力できるようになっています。
環境変数に代入する「Access key ID」
と「Secret access key」
の値を調べるため、「new_user_credentials.csv」
というcsvファイルを開き、以下のコードを追加します。
export AWS_ACCESS_KEY_ID="CSVファイルのAccess key IDの値を貼り付け"
export AWS_SECRET_ACCESS_KEY="CSVファイルのSecret access keyの値を貼り付け"
値を貼りつけたら「escキー」
→「:wq」
の順で入力し、環境変数の設定ファイルを保存します。
次にsourceコマンド
を入力し、先ほど設定した環境変数を使えるようにします。
$ source ~/.bash_profile
sourceコマンド
とは現在開いているターミナルのタブで環境変数の設定ファイルを読み込み直してくれるものです。
環境変数の使用
ここまでで、環境変数を設定することができました!
実際にソースコード内で環境変数を使用して、S3への認証情報を記述します。
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
amazon:
service: S3
region: ap-northeast-1
bucket: (自分のバケット名が記載されている状態)
access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
#省略
これで安全にソースコード内で安全に秘密情報を記述することができました!
git-secretsの導入
ここまでの作業で、環境変数は設定できました。
しかし、うっかりミスで環境変数を使用し忘れてしまい、誤って秘密情報をGitHubにpushしてしまう可能性もあります。
そのため、誤操作で秘密情報をpushしないよう対策していきます!
AWSが公開している「git-secrets」
というツールを使用して、誤ってGitHubにpushしないよう設定していきます。
git-secrets
はcommitしようとしたコードをチェックし、パスワードだと推定されるような文字列が含まれている場合は、警告を出して処理が中断してくれる機能です。
まずはgit-secrets
のインストールです。
% brew install git-secrets
git-secrets
が導入できたら、設定を適用したいアプリケーションのディレクトリに移動して、git-secrets
を有効化します。
% git secrets --install
これで、git-secrets
を使用する準備ができました!
git-secretsの条件設定
続いて、どのようなコードのcommitを防ぐのかを設定していきます。
下記のコマンドを実行し、「Access key ID」
や「Secret access key」
など、アップロードしたくないAWS関連の秘密情報を一括で設定します。
% git secrets --register-aws --global
これで条件が設定出来ました!
GitHub Desktopの利用設定
commitなどソースコード管理をGitHub Desktop
を使用して行なっている場合は、また追加で設定が必要になります。
以下のコマンドを実行してGitHub Desktop
にgit-secrets
を適用させます!
% sudo cp /usr/local/bin/git-secrets /Applications/GitHub\ Desktop.app/Contents/Resources/app/git/bin/git-secrets
このコマンドの際にパスワードの入力が必要となる場合があります。このパスワードはPCにログインする際のパスワードです。
git-secretsが適用範囲設定
ここまでの設定では、今後作成するリポジトリにはgit-secrets
が適用されません。
そのため、以下のコマンドを実行して自動で適用されるようにします!
% git secrets --install ~/.git-templates/git-secrets
% git config --global init.templatedir '~/.git-templates/git-secrets'
これで、今後作成する他のアプリケーションにも、git-secrets
が適用されるようになりました!
ここまでで、ローカル環境での設定とセキュリティ対策ができたので、実際に投稿した画像ファイルがS3に保存されるか確認してみましょう。問題がないようでしたら、成功です!
本番環境でのS3設定
続いてローカル環境での設定と同様に、画像の保存先を指定します。
現状では画像の保存先がローカルに設定されているため、S3に保存されるように設定を変更します。
まずproduction.rb
に記述している画像の保存先の設定を「:local」
→「:amazon」
に変更します。
#省略
#config.active_storage.service = :local
config.active_storage.service = :amazon
#省略
Heroku上での環境変数設定
Herokuで環境変数を扱うには、heroku config:setコマンド
を打ちます。
% heroku config:set AWS_ACCESS_KEY_ID="CSVファイルのAccess key IDの値を貼り付け"
% heroku config:set AWS_SECRET_ACCESS_KEY="CSVファイルのSecret access keyの値を貼り付け"
環境変数が正しく設定できているかを確認するために、下記のコマンドを入力してください。
% heroku config
確認できたら、コミットしてHerokuに反映させます。
% git push heroku master
その後、本番環境で挙動確認し問題がなければ完了です。
最後に
以上で、S3
を用いた画像アップロード機能実装は完了です。
では。