ActiveStorageでファイルの保存先にAWS S3を利用するための準備

# もくじ

1. 【AWS】S3でBucketを作成
2. 【AWS】IAMでポリシーを作成
3. 【AWS】IAMでユーザーを作成
4. 【Rails】S3関連の設定を追加・変更

# 1. 【AWS】S3でBucketを作成

ファイルを格納するS3 Bucketを作成します。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/141934/9b237890-ae3e-70c8-ac47-416337be0a9f.png)
![02.png](https://qiita-image-store.s3.amazonaws.com/0/141934/3915e380-9e47-7c22-592b-716728c847ba.png)

設定した「バケット名」はこのあとの手順(IAMポリシー作成、ActiveStorage設定)でも利用するので、メモなどに記録しておきます

---

# 2.　【AWS】IAMでポリシーを作成

作成したS3 Bucketへの読み書きが設定されたポリシーを作成します。

> 補足：既に存在しているポリシー、ユーザーを利用する場合はこの手順はスキップ可能です

![11.png](https://qiita-image-store.s3.amazonaws.com/0/141934/6de1d40a-ca00-940e-5a69-ce9efc40e1b6.png)
![12.png](https://qiita-image-store.s3.amazonaws.com/0/141934/15621160-a119-aadc-9f1d-018a8664b37a.png)
![13.png](https://qiita-image-store.s3.amazonaws.com/0/141934/d954af89-7b04-98d7-ecdc-511f812925af.png)

入力するJSONは以下のフォーマットになります。

```json
{
   "Version": "2012-10-17",
   "Statement": [
     {
       "Effect": "Allow",
       "Action": ["s3:ListBucket"],
       "Resource": ["arn:aws:s3:::<バケット名>"]
     },
     {
       "Effect": "Allow",
       "Action": [
         "s3:PutObject",
         "s3:GetObject"
       ],
       "Resource": ["arn:aws:s3:::<バケット名>/*"]
     }
   ]
 }
```

参考：[Amazon S3: 特定の S3 バケットへの読み取りと書き込みアクセスを許可する \- AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_s3_rw-bucket.html)

![14.png](https://qiita-image-store.s3.amazonaws.com/0/141934/e8bb997a-a98c-4367-cba4-3c9ffdbf307d.png)
![15.png](https://qiita-image-store.s3.amazonaws.com/0/141934/e96c4c70-1c04-dcb0-6cad-da9bf05aaa86.png)

「ポリシー名」はこのあとの手順(IAMユーザー作成)でも利用するので、メモなどに記録しておきます。

---

# 3. 【AWS】IAMでユーザーを作成

Railsアプリで利用するユーザーを作成します。
ユーザーを作成する手順の中で事前に用意したポリシーをアタッチします。

> 補足：既に存在しているポリシー、ユーザーを利用する場合はこの手順はスキップ可能です

![21.png](https://qiita-image-store.s3.amazonaws.com/0/141934/e2970a14-452f-50d4-2cdb-c8b9044f22fc.png)
![22.png](https://qiita-image-store.s3.amazonaws.com/0/141934/0fd3239a-685e-5de6-ba83-d67df09c440f.png)
![23.png](https://qiita-image-store.s3.amazonaws.com/0/141934/f0eb4e13-021d-5be4-c86f-fcb31b0f5486.png)

![24.png](https://qiita-image-store.s3.amazonaws.com/0/141934/496c1198-6d86-3cdc-39d8-ad8ea965d611.png)

> 補足：事前に作成しておいた「ポリシー」を選択します。

![25.png](https://qiita-image-store.s3.amazonaws.com/0/141934/0bdf485e-ce8c-455c-85f9-364fe55de58d.png)
![26.png](https://qiita-image-store.s3.amazonaws.com/0/141934/4a5a2535-03a8-71e4-fae1-7a9ce8ca106e.png)

「アクセスキーID」「シークレットアクセスキー」はこのあとの手順(ActiveStorage設定)でも利用するので、メモなどに記録しておきます。

---

# 4. 【Rails】S3関連の設定を追加・変更

ActiveStorageから事前に作成したS3 Bucketへファイルを保存するように設定を追加・変更します。

## Gemfile

RailsからS3の機能を利用するためにgemを追加します。

```ruby:Gemfile
gem 'aws-sdk-s3'
```

## config/storage.yml

`amazon`の設定はデフォルトではコメントアウトされているので、コメントアウトを外して、「リージョン」と「バケット名」を設定します。

> 補足
> **region**にはS3 Bucketを作成したリージョン名を指定する
> アジアパシフィック（東京）で作成した場合は、`ap-northeast-1`となる
> **bucket**にはS3の「バケット名」を指定する

```yaml:config/storage.yml
amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: ap-northeast-1
  bucket: <バケット名>
```

## credentials.yml.enc

**credentials.yml.enc**に「アクセスキーID」「シークレットアクセスキー」を設定します。

```shell-session
# credentials.yml.enをviで開く
$ EDITOR="vi" bin/rails credentials:edit
```

`aws`の設定はデフォルトではコメントアウトされているので、コメントアウトを外して、`access_key_id`と`secret_access_key`を設定します。

```yaml
aws:
  access_key_id: <アクセスキーID>
  secret_access_key: <シークレットアクセスキー>
```

## config/environments/xxx.rb

デフォルトではファイルの保存先にローカル(`:local`)が指定されているので、`:amazon`に変更します。

```ruby:config/environments/xxx.rb
config.active_storage.service = :amazon
```

## 実装＆動作確認

あとはローカルにファイルを保存するときと同じようにActiveStorageを利用した機能を実装するだけで、ファイルがS3へ保存されるようにります。