【Railsチュートリアル13章】本番環境での画像アップロードでS3を使う時の流れ(AWSキーを公開しないように.envを使う)

#はじめに
[Railsチュートリアル13章](https://railstutorial.jp/chapters/user_microposts?version=6.0#sec-image_upload_in_production)では、本番環境での画像アップロードのためにAWSのS3を導入しています。
しかし、初学者の私は導入完了までに２点ほどつまづいたので、下記に備忘録としてまとめます。

一つ目は、AWSシステムでS3を設定する流れについてです。
二つ目は、.envファイルを用い、AWSキー等をGitHubに公開しない方法についてです。

ちなみに私はGitHubの設定をPublicにしていたにも関わらず、.envファイルを使わなかったため、AWSキーを晒してしまいました...
AWSから何度もメールで警告を受けました...
そのメールが無かったら恐ろしいことになっていたかもしれません...
[【実録】アクセスキー流出、攻撃者のとった行動とその対策](https://dev.classmethod.jp/articles/accesskey-leak/)

S3の設定にあたっては下記のUdemyを参考にしました。
S3以外についても丁寧に解説されているのでとてもおすすめです。
[AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得](https://www.udemy.com/share/101YbyAEETd1xSRX8D/)

#1. gemのインストール
`aws-sdk-s3`gem をインストールして、本番アプリケーションでクラウドストレージを使えるよう設定します。

```
gem 'aws-sdk-s3',  '1.46.0', require: false
```
を記載し、

```
$ bundle install
```
を実行。

#2. S3の設定
※AWSアカウントがある前提で進みます。まだアカウントがない方は上記のUdemyを参考にしてください。

まずAWSのマネジメントコンソールを開いて、S3のダッシュボードに移動します。
![スクリーンショット 2020-12-21 11.11.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/e7e35bd0-7b83-83b0-e394-6da92882bbff.png)
右上の「バケットを作成」をクリックします。
![スクリーンショット 2020-12-21 11.11.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/f7f3d110-df67-6ef1-faf0-5b54d2c54126.png)
「バケット名」を入力します。
「リージョン」は東京を選択してください。
「既存のバケットから設定をコピー」は無視します。
![スクリーンショット 2020-12-21 11.13.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/6b27d4a2-b62c-f7c2-5121-17ccfc3a68bc.png)
**「ブロックパブリックアクセスのバケット設定」は全てチェックを外します。**
![スクリーンショット 2020-12-21 11.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/18488eda-9d7b-675e-1ef0-fe82c3eaa9e4.png)
その他については今回はデフォルトのままにしようと思います。
「バケットを作成」をクリックします。
![スクリーンショット 2020-12-21 11.26.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/6a80c112-8890-d81b-22df-1efc475535b5.png)
上記の画像のようにS3のバケットが作成できていれば完了です。
ちなみに、バケットの名前とリージョン(ap-northeast-1)の情報は、これから先で必要になります。あとでコピペします。

#3. IAMの設定
IAMのダッシュボードに移動します。
「ユーザー」をクリックし、次に「ユーザーを追加」をクリックします。

![スクリーンショット 2020-12-21 15.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/b952f3bc-08bd-0555-4e90-523142abe946.png)
「ユーザー名」を入力し、「プログラムによるアクセス」を選択します。

![スクリーンショット 2020-12-21 15.25.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/cf9bd9b4-6f34-088d-eceb-2ece7eef9491.png)
「既存のポリシーを直接アタッチ」を選択します。
また検索ボックスにS3と入力し、ポリシー名に表示された「AmazonS3FullAccess」を選択します。

![スクリーンショット 2020-12-21 15.25.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/d40f4728-7ab7-f228-f20c-9d6a1cd2866b.png)
「タグの追加」は空欄のままにして、「次のステップ：確認」をクリックします。

![スクリーンショット 2020-12-21 15.26.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/50cc7d1a-a8d6-e853-a27a-7c91c890d81b.png)
「ユーザーの作成」をクリックします。

![スクリーンショット 2020-12-21 15.26.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771363/90a68fd0-f277-00be-d4c0-62ee3ac6fc8e.png)
成功画面が表示されるので、.csvをダウンロードします。
上記で表示されているアクセスキーIDとシークレットキーをこれから先で使用しますが、csvファイルに記載されているので、この画面は閉じるをクリックして問題ありません。

#4. Herokuの変数設定
ターミナルに戻って、Herokuの設定をします。
②までで作成した「アクセスキーID」「シークレットキー」「リージョン」「バケットの名前」をそれぞれ下記に入力し、コマンドを実行します。

```
$ heroku config:set AWS_ACCESS_KEY=<accessキー>
$ heroku config:set AWS_SECRET_KEY=<secretキー>
$ heroku config:set AWS_REGION=ap-northeast-1(別リージョンなら別リージョン名)
$ heroku config:set AWS_BUCKET=<bucket名>
```

ちなみに、入力が正しかったか確認したい時は下記コマンドを実行します。

```
$ heroku config
```

#5. envファイルの作成
上記で入力したシークレットキー等はconfig/storage.ymlに記載する必要がありますが、直接記載してGitHubにpushしてしまうと公開されてしまいます。
GitHubのリポジトリをPrivateにしていれば問題ありませんが、Publicに変える可能性がある場合、コミット履歴まで削除するのは難しいです...(初学者の私にはできませんでした)
そのため、envファイルを使用し、直接記載するのを避けます。
下記の記事を参考にしました。

[Railsで使える環境変数を管理できるgem(dotenv-rails)や.envの導入方法](https://qiita.com/ryosuketter/items/ceb592dc6b23a20e51b5)


まず下記のgemをインストールします。
全ての環境で使えるように、Gemfileの一番上の集団のところに記載します。

```
gem 'dotenv-rails'
```

```
$ bundle install
```



config/storage.ymlに下記を記載します。
**【注意】そのままコピペして下さい！実際のKEYの値などはenvファイルに記載します。**

```yml:config/storage.yml

amazon:
  service: S3
  access_key_id:     <%= ENV['AWS_ACCESS_KEY'] %>
  secret_access_key: <%= ENV['AWS_SECRET_KEY'] %>
  region:            <%= ENV['AWS_REGION'] %>
  bucket:            <%= ENV['AWS_BUCKET'] %>
```


アプリケーションのトップに.envファイルを作成(Gemfile等と同じ位置)し、実際のKEY等を記載します。

```env:.env
ACCESS_KEY_ID = <あなたのaccessキー>
SELECT_ACCESS_KEY = <あなたのsecretキー>
REGION = ap-northeast-1(別リージョンなら別リージョン名)
BUCKET = <あなたのbucket名>
```

そして、.gitignoreファイル(隠しファイルで通常だと見えないかもしれないです)に.envを記載します。


```:.gitignore

.env
```

#6. config/environments/production.rbの編集
Active Storageサービス設定パラメータを下記のように記載します。


```:config/environments/production.rb

# アップロードされたファイルをAWSに保存する
  config.active_storage.service = :amazon
```

#最後に
コミットしてデプロイします。

```
$ git add -A
$ git commit -m "任意のメッセージ"
$ git push
$ heroku pg:reset DATABASE
$ heroku run rails db:migrate
$ heroku run rails db:seed
```

Githubでは.envファイルが見れないことを確認してください。