71
64

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

サルでもできる!? Rails6 のアプリをAWS EC2にデプロイするまでの全手順【後半】(独自ドメイン, HTTPS化, S3, CloudFront)

Last updated at Posted at 2020-11-26

この記事では,画像投稿機能の付いた Rails 6 のアプリを AWS EC2 にデプロイするまでの全過程を解説します。

【前半】 でRailsアプリのデプロイはひとまず完了しましたが,まだまだすべきことがたくさんあります。続きも気を抜かずに頑張りましょう!

タイトル
【前半】
1章 はじめに
2章 VPC
3章 RDS
4章 EC2
5章 サーバー構築
6章 デプロイ(Capistrano)
【後半】 <-- こちら
7章 独自ドメイン
8章 HTTPS化(ACM, ALB)
9章 デプロイ関連事項
10章 S3
11章 CloudFront
12章 削除方法

7. 独自ドメイン

Railsアプリを公開することができましたが,現状では2つ大きな問題を抱えています。

  • サイトの URL が不自然
    • google.com のような 独自ドメイン ではない
  • HTTPSではない
    • Google Chrome で「このサイトへの接続は保護されていません」という警告が出る

まずは前者から解決していきましょう。

aws-sample-app.com のような URL でアクセスできるようにするには, ドメイン を取得する必要があります。

ドメイン は有料ですが,こだわらなければ初年度は数百円程度で取得できます。

この記事では昔から代表的な レジストラ である「お名前.com」で取得する前提で解説します。

7.1 ドメインの購入

  • 「お名前.com」にアクセス

  • 検索窓に取得したいドメイン名を入力し,「検索」ボタンをクリック

    • ドメインに使用できる文字は「半角英数字」と「ハイフン -」です
    • 「アンダースコア _」 は使用できません

7_1a.png

  • .com などのドメインを選択し,「料金確認へ進む」ボタンをクリック

    • 自動選択されているチェックを外し忘れないように注意しましょう
    • こだわりがなければ初年度の安いドメインを取得してもよいでしょう
  • 購入処理を行って下さい。「Whois情報公開代行」は必須ですが,その他のオプションは全て不要です

    • 「サーバー」は「利用しない」をチェック
    • 「Whois情報公開代行メール転送オプション」などは全てチェック不要
  • 「お申し込みを受け付けました。」と表示されたら「ドメインの設定はこちら」のリンクをクリック

【備考】後に続きの操作をおこないますので,他のタブで続きの作業を進めて下さい

【注意】初めて「お名前.com」を利用される方は,「メールアドレスの認証手続き」に関するメールが届くと思います。認証しませんと2週間後にドメインを使用できなくなりますので,届いたメールは一通り目を通して下さい。

自動更新の解除

初期設定では,ドメインの更新期限日を過ぎますと自動更新・自動課金されます。

2年目以降は料金が高くなるドメインが多いですので,自動更新を解除したい場合は以下の操作を行ってください。

  • 「お名前.com」のページ上側にあるタブの「ドメイン」を選択

  • 「更新画面から移動する」をクリック

  • アプリで使用するドメインを選択

7_1b.png

  • 「自動更新」ボタンをクリック

7_1c.png

  • 「確認画面へ進む」をクリック

  • 「自動更新設定申込内容」の項目が「解除する」になっていることを確認の上,「規約に同意し、上記内容を申し込む」ボタンをクリック

7_1d.png

  • 「解除する」ボタンをクリック

  • 「ドメイン一覧」のタブをクリック

【備考】後に続きの操作をおこないますので,続きの作業は他のタブで進めて下さい

7.2 IPアドレスとドメインの関連付け

Route 53 を利用することで,先ほど購入した ドメインIPアドレス に変換することができます。

通常の使用範囲内ならば月100円もかかりません。

  • AWS の画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択

  • 「ホストゾーンの作成」ボタンをクリック

キー
ドメイン名 取得したドメインを記載
説明 - オプション アプリ名_domain
タイプ パブリックホストゾーン

7_2a.png

  • 「ホストゾーンの作成」ボタンをクリック

  • タイプが「NS」の方の「値/トラフィックのルーティング先」に表示されている4つを ネームサーバー としてメモしておいて下さい

    • 【要注意】メモする際に,それぞれの最後についている「ドット .」は削除して下さい!

7_2b.png

7.3 ネームサーバーの変更

先ほど残しておいた「お名前.com」に移動して下さい

(タブを閉じてしまった場合は,再度「お名前.com」にアクセスし,ログインして下さい)

  • 「ドメイン一覧」の中から取得した「ドメイン名」を選択

  • 「ネームサーバー情報」の項目の「ネームサーバーの変更」をクリック

7_3a.png

  • 「2.ネームサーバーの選択」をクリック

  • 「その他」タブをクリックし,「その他のネームサーバーを使う」の方にチェックを入れ,先ほどメモした4つの ネームサーバー をコピペして下さい

    • 先ほど注意しました通り,最後についている「ドット .」は入力しないで下さい

7_3b.png

7.4 ネームサーバーの確認

ローカル環境のターミナルから以下を実行して下さい。

ローカル環境のターミナル
dig ドメイン名 NS +short

登録した4つのドメインが入っていればOKです。(順番が入れ替わっていてもOK)

デフォルトの2つしか入っていない場合は,しばらく待ってから再度先ほどのコマンドを実行しましょう。

7.5 ドメインの適用

  • AWSRoute 53 の先ほどの続きの画面から,「レコードを作成」をクリック
キー
レコード名 ※入力しない
Elastic IP を入力
レコードタイプ A

7_5.png

これで準備が完了です。まずは,ローカル環境のターミナルから以下を実行して下さい。

ローカル環境のターミナル
curl -I ドメイン名

最初に HTTP/1.1 200 OK もしくは HTTP/1.1 302 が出れば正常です。

前回は Elastic IP でなければアクセスできませんでしたが,今度は ドメイン名 でアクセスできる状態になっています。

ブラウザから ドメイン名 でアクセスし, スーパーリロード して下さい。(ショートカットキーは command + shift + r

8. HTTPS化(ACM, ALB)

次はこちらの問題に対処していきましょう。

  • HTTPSではない
    • Google Chrome で「このサイトへの接続は保護されていません」という警告が出る

【備考】 ELBApplication Load Balancer(ALB) を利用しますので,月2000円程度の費用がかかります。

8_0.png

8.1 ACM

HTTPS化 には,まず, SSL/TLS サーバー証明書 を取得する必要があります。

Let's Encrypt で取得する方法が有名ですが,AWSを利用する場合は SSL/TLS サーバー証明書ACM で取得し, ALB に関連付けるのが一般的な手法です。作業が楽で,更新の手間も不要になります。

ALB と関連付けますので, ACM 自体は無料で利用できます。

  • AWS の画面左上の「サービス」を開き、検索欄に「acm」と入力し、「Certificate Manager」を選択

  • 「証明書のプロビジョニング」の「今すぐ始める」ボタンをクリック

  • 「パブリック証明書のリクエスト」を選択した状態で「証明書のリクエスト」ボタンをクリック

  • 「この証明書に別の名前を追加」をクリック

  • 取得した「ドメイン名」と「*.ドメイン名」を入力

  • 「次へ」ボタンをクリック

8_1.png

  • 「DNS の検証」を選択した状態で「次へ」ボタンをクリック
タグ名
Name アプリ名_alb
  • 「確認」ボタンをクリック

  • 「確定とリクエスト」ボタンをクリック

  • 「続行」ボタンをクリック

8.2 DNS検証用の CNAME レコード追加

  • ドメインの欄のプルダウンを開き,「Route 53 でのレコードの作成」ボタンをクリック
    • 2つ表示されていますが,どちらか片方のみでOKです
    • プルダウンが表示されない場合は,一度リロードして下さい

8_2.png

  • 「作成」ボタンをクリック

【注意】 8.3 は先に行っても問題ありませんが, 8.4 以降の作業は,状況が「検証保留中」から「発行済み」に変わってから行って下さい

8.3 ALB 用のセキュリティグループの作成

【構成内容】 クライアント --(HTTP or HTTPS)--> ALB --(HTTP)--> EC2

ELB の内の ALB (Application Load Balancer) を使用し,先ほど取得した SSL/TLS サーバー証明書 を使用できるように設定していきましょう。

ALBEC2 の前にリクエストを受け,(一般には複数の) EC2 に分散します。このことを踏まえたセキュリティグループを作成しましょう。

  • 画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択

  • EC2 画面左のメニューバーの「セキュリティグループ」を選択し,「セキュリティグループを作成」ボタンをクリック

キー
セキュリティグループ名 アプリ名_alb_security_group
説明 アプリ名_alb_security_group
VPC アプリ名_vpc

「インバウンドルール」の「ルールを追加」を2回クリック

キー
タイプ HTTP
プロトコル TCP ※自動選択
ポート範囲 80 ※自動選択
ソース 任意の場所 (0.0.0.0/0 と ::/0 が表示)
説明 ※空白でOK
キー
タイプ HTTPS
プロトコル TCP ※自動選択
ポート範囲 443 ※自動選択
ソース 任意の場所 (0.0.0.0/0 と ::/0 が表示)
説明 ※空白でOK

8_3a.png

「アウトバウンドルール」は デフォルトの設定を削除した後 「ルールを追加」をクリックし,以下を追加

8_3b.png

キー
タイプ HTTP
プロトコル TCP ※自動選択
ポート範囲 80 ※自動選択
ソース カスタム: アプリ名_ec2_security_group
説明 ※空白でOK

8_3c.png

作成後に次の図のようにルールが定まっているかどうかを確認して下さい。

8_3d.png
8_3e.png

8.4 ロードバランサーの設定

  • 画面左のメニューバーの「ロードバランサー」を選択

  • 「ロードバランサーの作成」ボタンをクリック

  • 「HTTP, HTTPS」の方の「作成」ボタンをクリック

■ 手順 1: ロードバランサーの設定

  • 【基本的な設定】
キー
名前 アプリ名-alb ※ ハイフンに変更

他はデフォルト

  • 【リスナー】

「リスナーの追加」ボタンをクリックし,「HTTPS」を選択

  • 【アベイラビリティゾーン】
キー
VPC アプリ名_vpc
アベイラビリティーゾーン 「ap-northeast-1a」を選択し「アプリ名_public_1a_subnet」を選択
アベイラビリティーゾーン 「ap-northeast-1c」を選択し「アプリ名_public_1c_subnet」を選択

「次の手順: セキュリティ設定の構成」ボタンをクリック

8_4a.png

■ 手順 2: セキュリティ設定の構成

  • 「証明書の名前」がアプリ用のドメインであることを確認し,「セキュリティグループの設定」をクリック

8_4b.png

■ 手順 3: セキュリティグループの設定

  • 「アプリ名_alb_security_group」を選択し,「次の手順: ルーティングの設定」ボタンをクリック

8_4c.png

■ 手順 4: ルーティングの設定

  • ターゲットグループ
キー
ターゲットグループ 新しいターゲットグループ
名前 アプリ名-target-group ※ ハイフンに変更
ターゲットの種類 インスタンス ※デフォルト
プロトコル HTTP ※自動設定
ポート 80 ※自動設定
  • ヘルスチェック

デフォルト設定でOK

「次の手順: ターゲットの登録」ボタンをクリック

8_4d.png

■ 手順 5: ターゲットの登録

  • 「インスタンス」欄から、「アプリ名_instance」にチェックを入れた状態で「登録済みに追加」ボタンをクリック

8_4e.png

  • 「次の手順: 確認」をクリック

  • 「作成」ボタンをクリック

8.5 Route 53の設定を修正

ドメインを EC2 から先ほど作成した ALB に割り当てるように設定を変更しましょう。

  • AWS の画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択

  • 「ホストゾーン」をクリック

  • アプリで使用するドメインをクリック

8_5a.png

  • 「タイプA」の「ドメイン名」のレコードをクリックし,右上に現れた「レコードを編集」ボタンをクリック

9.41.13.png

  • 「値」の近くにある「エイリアス」をオンにする

  • 「トラフィックのルーティング先」の箇所を変更して下さい

    • 「Application Load Balancer と Classic Load Balancer へのエイリアス」を選択
    • 「アジアパシフィック (東京) [ap-northeast-1]」を選択
    • 「アプリ名-alb」を含むロードバランサーを選択

9.48.29.png

  • 「保存」ボタンをクリック

8.6 セキュリティグループの修正

ALB 経由でアクセスされるように変更したため, EC2ALB からのアクセスに限定すべきです。そのため, EC2 用のセキュリティグループを修正します。

  • AWS の画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択

  • 画面左のメニューバーの「セキュリティグループ」を選択

  • 「アプリ名_ec2_security_group」にチェックを入れ,「アクション」ボタンをクリックし,「インバウンドルールを編集」ボタンをクリック

8_6a.png

  • タイプが HTTP のものを全て削除し,「ルールを追加」をクリックし,以下を設定
    • SSH は削除しないこと

8_6b.png

キー
タイプ HTTP
ソース カスタム: アプリ名_alb_security_group
説明 ※空白でOK

8_6c.png

  • 「ルールを保存」ボタンをクリック

8.7 Nginx の設定ファイルを修正

ALB への接続に使用するプロトコルが HTTPS であることを識別できるよう,Nginx の設定ファイルを修正し,再起動しておきましょう。

(こちらを実行しないと,例えば POST リクエスト時にエラーが発生します)

サーバー環境のターミナル
sudo sed -i s/X-Forwarded-Proto\ \$scheme\;/X-Forwarded-Proto\ https\;/ /etc/nginx/conf.d/$APP_NAME.conf
sudo sed -i s/X-Forwarded-Proto\ http\;/X-Forwarded-Proto\ https\;/ /etc/nginx/conf.d/$APP_NAME.conf
sudo service nginx restart

【補足】最初の2行は, /etc/nginx/conf.d/$APP_NAME.conf 内の X-Forwarded-Proto $scheme;X-Forwarded-Proto http; を両方 X-Forwarded-Proto https; に置換するコマンドです。

それでは, HTTPS でアクセスできるかを確認しましょう。まずはターミナルから以下を実行して下さい。

ターミナル(ローカル側でもサーバー側でもOK)
curl -I https://ドメイン名

最初に HTTP/2 200 もしくは HTTP/2 302 が表示されれば正常です。次にブラウザから https://ドメイン名 にアクセスし, スーパーリロード して下さい。(ショートカットキーは command + shift + r

ブラウザのURLの左隣に「鍵マーク」が表示され,アプリが問題なく開けばOKです!

8_7.png

8.8 HTTPS にリダイレクト

【参考】 https://aws.amazon.com/jp/premiumsupport/knowledge-center/elb-redirect-http-to-https-using-alb/

最後に, HTTP でのアクセスを HTTPS にリダイレクトするように設定しましょう。

  • EC2の画面左のメニューバーの「ロードバランサー」をクリック

  • (「アプリ名-alb」を選択した状態で)「リスナー」タブをクリック

  • HTTP : 80 の方の 「ルールの表示/編集」をクリック

8_8a.png

  • 上の「鉛筆」マークをクリックし,下に出現した「鉛筆」マークをクリック

8_8b.png

  • 「THEN」の項目の転送先にある「ゴミ箱」マークをクリックして削除

8_8c.png

  • 「アクションの追加」を選択し,「リダイレクト先」をクリック

  • 「HTTPS」になっていることを確認し,ポートに 443 を入力

  • 「チェックマーク」をクリック

  • 右上の「更新」ボタンをクリック

8_8d.png

これで http でアクセスした場合も https に自動変換されるようになりました。ターミナルから以下を実行してみましょう。

ターミナル(ローカル側でもサーバー側でもOK)
curl -I http://ドメイン名

最初に HTTP/1.1 301 Moved Permanently が表示され,最後に Location: https://アプリ名:443/ が表示されていればOKです。

ブラウザでも http://ドメイン名 でアクセスしてみましょう。URLの左隣に鍵マークが付いていればOKです!

お疲れ様でした!

8.9 最後に

作業が終わりましたので,ローカル環境で定義したグローバル変数 $APP_NAME は消しておくこととしましょう。

ローカル環境のターミナル
# zsh の場合
vi ~/.zshrc

# bash の場合
vi ~/.bash_profile

一番最後の行にある export APP_NAME=アプリ名 を削除して下さい。

8.10 EC2のユーザーにパスワードを設定(任意)

実運用しないポートフォリオならスキップしても良いですが,セキュリティを高めるためEC2のユーザーにパスワードを設定し, sudo コマンド実行時にパスワードを求められるように設定することをお勧めします。

(作業を楽にするため,EC2のユーザーはパスワード無しで sudo コマンドを使用できる状態にしていました)


【注意】以下の操作はくれぐれも慎重に行って下さい。操作を間違えた場合,EC2の構築からやり直すこととなる可能性があります。セキュリティを高めるための操作ですが,個人のポートフォリオでは必須ではありませんので,自信がない場合は次の章に進んでもOKです。


サーバー環境のターミナル
sudo passwd `whoami`
設定したいEC2のパスワードを入力
EC2のパスワードを再入力

「EC2のパスワード」は必ずメモしておいて下さい。

サーバー環境のターミナル
sudo visudo

Vim で開かれたら,一番最後の行の NOPASSWD: の箇所のみ削り,次の状態にして下さい。

sudoers
ユーザー名 ALL=(ALL) ALL

【注意】ユーザー名 ALL=(ALL) NOPASSWD: ALL を「全て」削ってはいけません!編集を間違えると,二度と sudo コマンドを実行できなくなる恐れがありますので,慎重に行ってください。

これで sudo コマンドを実行した際に今後はパスワードを尋ねられるようになります。

以下を実行し,パスワードを求められるかどうか,パスワードを入力してコマンドを実行できるかどうかを確かめて下さい。

サーバー環境のターミナル
sudo ls

さて,このままでは,デプロイ実行時に sudo が実行できずエラーが出るようになります。その対策を行いましょう。

Gemfile
group :development do
  # 略
  # ***** sudo 実行時にパスワード入力できるようにするため以下を追加 *****
  gem 'sshkit-sudo'
  # ***** 以上を追加 *****
end
ローカル環境のターミナル
bundle install
Capfile
# ***** 以下を追加 *****
require "sshkit/sudo"
# ***** 以上を追加 *****
config/deploy.rb
# ***** 以下を追加 *****
set :pty, true
# ***** 以上を追加 *****

これで完了です。

デプロイ時に EC2ユーザーのパスワードを求められた場合は,先程設定したパスワードを入力して対応するようにしてください。

9. デプロイ関連事項

この章は必要な場合のみご覧ください。

9.1 アプリ修正時の反映方法

以下のコマンドで「GitHub」の master ブランチをAWS側に反映させることができます。

ローカル環境のターミナル
# Railsアプリのルートディレクトリに移動してから
bundle exec cap production deploy

【注意】 Heroku のデプロイで使用する git push heroku master は「ローカル」の master ブランチを反映させるコマンドです。 bundle exec cap production deploy コマンドは「ローカル」ではなく「GitHub」である点に注意しましょう。

9.2 master以外のブランチを反映させたい

config/deploy.rb
set :branch, ENV['BRANCH'] || "master"

を追加すれば,例えば以下のコマンドで「GitHub」の hoge ブランチを反映できます。

ローカル環境のターミナル
bundle exec cap production deploy BRANCH=hoge

例えば,現在のブランチをAWS側で動作確認したい場合は次の手順になります。

ローカル環境のターミナル
# add, commit の実行後
git push origin HEAD
bundle exec cap production deploy BRANCH=HEAD

9.3 AWS側で Rails コマンドや rake タスクを実行する方法

サーバー側のアプリは /var/www/$APP_NAME/current に入っています。

まずはここまで移動し,必要に応じて yarn install --check-files を実行して下さい。

サーバー環境のターミナル
cd /var/www/$APP_NAME/current
yarn install --check-files

その上で,必要なコマンドを実行しましょう。コマンド例を紹介します。

  • サーバー側で rails db:seed を実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bin/rails db:seed RAILS_ENV=production

bin/railsbundle exec rails でも問題ありませんが, rails ではダメです。また, RAILS_ENV=production が必要である点に注意して下さい。

  • サーバー側で rails db:migrate:reset を実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bin/rails db:migrate:reset RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1

本番環境のデータベースを削除(リセットを含む)したい場合は, DISABLE_DATABASE_ENVIRONMENT_CHECK=1 が必要です。

  • サーバー側で rails console を実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bin/rails c -e production

オプションが RAILS_ENV=production ではなく -e production の書き方になります。

  • サーバー側で rake タスクを実行したい場合
サーバー環境のターミナル(/var/www/$APP_NAME/current)
bundle exec rake タスク名 RAILS_ENV=production

タスク名は bundle exec rake -T で確認できます。bundle exec rakebin/rails でもOKですが rake ではダメです。

9.4 サーバー側で ログ を確認する方法

サーバー側の ログ/var/www/$APP_NAME/shared/log に入っています。

サーバー環境のターミナル
cd /var/www/$APP_NAME/shared/log
ls

でログファイルの一覧を確認できます。

エラーが出た場合は,nginx.error.log, puma_error.log, production.log を確認しましょう。

サーバー環境のターミナル(/var/www/$APP_NAME/shared/log)
# ログを全て表示したい場合
cat nginx.error.log
# 最後の30行を表示したい場合
tail -n 30 nginx.error.log
# ログの追加分のみを自動表示したい場合(control + c で終了)
tail -f nginx.error.log

10. S3

【注意】10章, 11章は, CarrierWaveActiveStorage などで画像の投稿機能を実装している場合のみ,実行して下さい。

現状でも画像の投稿は可能ですが, AWS S3 を使用することで,Webサーバー(EC2)のストレージが画像で圧迫されるのを防いだり,負荷分散ができるなど複数のメリットがあります。

さらに, CloudFront を用いることで画像転送を高速化するところまでを解説します。

10.1 S3バケットの作成

S3 は,クラウド型のオブジェクトストレージサービスです。画像に限らずいろいろなデータを保存することができ,簡単なWebサイトの公開にも使用できます。

セキュリティ・耐久性共に優れ,価格も安いのが特徴です。ポートフォリオの画像投稿機能に使用する程度であれば,大抵の場合は無料利用枠内でおさまるでしょう。

S3 を利用するには,まず, バケット を作成する必要があります。

  • 画面左上の「サービス」を開き、検索欄に「s3」と入力し、「S3」を選択

  • 「バケットの作成」を選択

  • 一般的な設定

タイトル 内容
バケット名 任意 ※世界ですでに存在する名前は付けられません
リージョン アジアパシフィック (東京) ap-northeast-1

【注】 バケット名とリージョンap-northeast-1を忘れないようにメモしておいて下さい。

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

下の2つ(ACL以外)のみをチェックし,注意喚起にもチェック

10_1a.png
10_1b.png

「バケットを作成」をクリック

10.2 アプリ用のIAMユーザーを作成

次に,アプリ側から S3 にアクセスするための アクセスキー などを入手しましょう。

  • 画面左上の「サービス」を開き、検索欄に「iam」と入力し、「IAM」を選択

  • 左のメニューから「ユーザー」を選択

  • 青いボタン「ユーザーを追加」をクリック

タイトル 内容
ユーザ名 アプリ名_user
アクセスの種類 「プログラムによるアクセス」にチェック

10_2a.png

  • 「次のステップ:アクセス権限」をクリック

  • 「既存のポリシーを直接アタッチ」ボタンをクリック

  • AmazonS3FullAccess をチェックして,「次のステップ: タグ」ボタンをクリック

    • 「参考」のようにより権限を厳しくしたポリシーをアタッチするとより安全です

10_2b.png

  • 「次のステップ: 確認」ボタンをクリック

  • 「ユーザーの作成」をクリック

  • 「.csvのダウンロード」ボタンをクリック

「ユーザー名」「アクセスキーID」「シークレットアクセスキー」をメモしておいて下さい。

  • 「閉じる」ボタンをクリック

参考: 権限の少ないポリシーを作成

AmazonS3FullAccessS3 の全ての操作ができる権限ですので,アプリに持たせる権限としては過剰すぎます。

最低限必要な権限をもつポリシーを作成し,AmazonS3FullAccess の代わりにこちらをIAMユーザーにアタッチしておくと,万一の場合の被害を軽減することができます。

参考: CarrierWave

IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObjectAcl",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "*"
        }
    ]
}

10_2c.png
10_2d.png

さらに安全を求めるならば,バケットまで制限することも可能ですが,ここでは省略します。

10.3 CarrierWaveの設定

※ 以下,画像投稿機能に CarrierWave を使用していることを前提とします

まず,Railsアプリに fog-awsGemfile に追加し,インストールしておきましょう。

ローカル環境のターミナル
bundle add fog-aws

本番環境のみで AWS S3 を使用する場合は次のように修正しましょう。

(開発環境でも使用したい場合は,条件分岐せず storage :fog のみにして下さい)

app/uploaders/image_uploader.rb
# 「storage :file」を以下に置き換える
  if Rails.env.production?
    storage :fog
  else
    storage :file
  end

次に, S3 の「アクセスキーID」などを読み込む設定を追加しましょう。

特に「シークレットアクセスキー」は,GitHubに公開してはならないので, credentials.yml.enc から読み込む形式とします。

「リージョン」と「バケット名」は公開しても問題ありませんので,直接記載することとします。

ローカル環境のターミナル
touch config/initializers/carrier_wave.rb

(開発環境でもS3を使用したい場合は,最初の行 if Rails.env.production? と最後の行 end を削りましょう)

config/initializers/carrier_wave.rb
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      provider: "AWS",
      aws_access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
      aws_secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key),
      region: "ap-northeast-1"
    }
    config.fog_directory = "S3のバケット名"
  end
end
  • credentials.yml.encを開くため,次のコマンドを実行
ターミナル
EDITOR=vi rails credentials:edit
  • アプリが S3 にアクセスするために必要な情報を credentials.yml.enc に記載しましょう
    • yaml形式なので,インデント幅にはくれぐれも注意して下さい
    • 例えば,access_key_id:の後に「半角スペース1個」がないだけでエラーになります
config/credentials.yml.enc
db:
  password: RDSのパスワード
  hostname: RDSのエンドポイント
# 以下を追加
aws:
  access_key_id: IAMユーザーのアクセスキーID
  secret_access_key: IAMユーザーのシークレットアクセスキー

10.4. 動作確認

念のため以下を実行し,「アクセスキーID」などが取得できることを確認しておいた方がよいでしょう。

ローカル環境のターミナル
rails c
# コンソール起動後
Rails.application.credentials.dig(:aws, :access_key_id)
Rails.application.credentials.dig(:aws, :secret_access_key)
# IAMユーザーのアクセスキーID, シークレットアクセスキーが表示されることを確認後
exit

コミット・プッシュ(必要があればプルリク・マージ)などを行い,GitHub の master ブランチに変更を反映した上で,AWS にデプロイを行いましょう。

ローカル環境のターミナル
bundle exec cap production deploy

【補足】 9.2 に記載した方法で,masterブランチにマージする前に確認するのが理想的です

これで本番環境では S3 に画像を投稿し,読み込みができるようになりました。

ブラウザから https://ドメイン名 にアクセスし,画像を投稿してみましょう。問題なく画像が投稿・表示できていればOKです。

念のため,AWSにログインし S3 のバケットに画像が保存されているかどうかも確認しておくとよいでしょう。

バケットを選択し,ディレクトリを選択していき,「オブジェクト URL」をクリックして投稿した画像が表示されていればOKです。

11. CloudFront

最後に CloudFront を用いて画像の表示を高速化できるようにし,さらに画像のURLを独自ドメインに変更しましょう。

CloudFront も1年間は無料利用枠があり,料金も安いのであまり気にしなくてよいでしょう。

11.1 ACM

CloudFront で ACM 証明書を使用するには、「米国東部」リージョンで証明書をリクエストする必要があります。

  • AWS の画面左上の「サービス」を開き、検索欄に「acm」と入力し、「Certificate Manager」を選択

  • 【重要!】右上の「東京」を「米国東部 (バージニア北部)us-east-1」に変更

11_1a.png

  • 「証明書のプロビジョニング」の「今すぐ始める」ボタンをクリック

  • 「パブリック証明書のリクエスト」を選択した状態で「証明書のリクエスト」ボタンをクリック

  • static.ドメイン名 を入力

    • static の箇所は任意ですが,変更する場合は以降も合わせて変更して下さい

11_1b.png

  • 「次へ」ボタンをクリック

  • 「DNS の検証」を選択した状態で「次へ」ボタンをクリック

タグ名
Name アプリ名_cloudfront

11_1c.png

  • 「確認」ボタンをクリック

  • 「確定とリクエスト」ボタンをクリック

  • 「続行」ボタンをクリック

  • DNS検証用の CNAME レコードを追加(8.2参照)

11.3 の作業は,状況が「検証保留中」から「発行済み」に変わってから行う必要があるため,ブラウザのタブは残しておきましょう

11.2 CarrierWaveの設定

次に,Railsアプリ側のCarrierWaveの設定に追記しましょう。

config/initializers/carrier_wave.rb
if Rails.env.production?
  CarrierWave.configure do |config|
    config.fog_credentials = {
      provider: "AWS",
      aws_access_key_id: Rails.application.credentials.dig(:aws, :access_key_id),
      aws_secret_access_key: Rails.application.credentials.dig(:aws, :secret_access_key),
      region: "ap-northeast-1"
    }
    config.fog_directory = "S3のバケット名"
    # ***** 以下を追加 *****
    config.asset_host = "https://static.ドメイン名"
    # ***** 以上を追加 *****
  end
end

コミット・プッシュ(必要があればプルリク・マージ)などを行い,GitHub の master ブランチに変更を反映した上で,AWS にデプロイを行いましょう。

ローカル環境のターミナル
bundle exec cap production deploy

11.3 CloudFront

【注意】 ACM の状況が「検証保留中」から「発行済み」に変わってから行って下さい

  • 画面左上の「サービス」を開き、検索欄に「cloudfront」と入力し、「CloudFront」を選択

  • 「Create Distribution」ボタンをクリック

  • 「Web」の方の「Get Started」を選択

【Origin Settings】

キー
Origin Domain Name S3のバケット名を選択
Restrict Bucket Access Yes

11_3a.png

【Default Cache Behavior Settings】

キー
Viewer Protocol Policy Redirect HTTP to HTTPS

11_3b.png

【Distribution Settings】

キー
Alternate Domain Names static.ドメイン名
SSL Certificate Custom SSL Certificate をチェックし,自分のドメインを選択

11_3c.png

他はデフォルト設定のまま,右下の「Create Distribution」ボタンをクリック

【注意】 続きの作業は「Status」が「Deployed」になってから行ってください。

11.4 Route 53

最後に CloudFront 用のAレコードを作成しましょう。

  • AWS の画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択

  • 「ホストゾーン」をクリック

  • アプリで使用するドメインをクリック

  • 「レコードを作成」ボタンをクリック

  • 「シンプルルーティング」にチェックを入れた状態で「次へ」ボタンをクリック

  • 「シンプルなレコードを定義」ボタンをクリック

キー
レコード名 static
値/トラフィックのルーティング先 CloudFront ディストリビューションへのエイリアス
米国東部 (バージニア北部)
CloudFrontのドメイン名を選択
レコードタイプ A

11_4.png

  • 「シンプルなレコードを定義」ボタンをクリック

これで全ての設定が完了です。

ブラウザから https://ドメイン名 にアクセスし,再度画像を投稿してみましょう。問題なく画像が投稿・表示できていればOKです。

念のため,AWSにログインし S3 のバケットに画像が保存されているかどうかも確認しておくとよいでしょう。

「無事全てが完了した!!」という方は是非 LGTM もお願いいたします!

12. 削除方法

AWS は有料ですので,アプリの公開が不要となったタイミングで削除することをお勧めします。

以下,削除の手順を解説しますが,特に有料となっている以下の削除を忘れないようにしましょう。

  • RDSインスタンス【高額!】
  • ALB(ロードバランサ)【高額!】
  • EC2インスタンス【高額!】
  • Elastic IP(EC2を削除すると課金対象)
  • Route 53
  • ACM
  • S3(画像投稿機能を付けた場合)
  • CloudFront(画像投稿機能を付けた場合)

12.1 Route 53 のホストゾーン削除

  • Route 53 ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「route」と入力し、「Route 53」を選択)
  • 画面左のメニューバーの「ホストゾーン」をクリック

  • アプリで使用したドメインをクリック

  • タイプが ACNAME のものにチェックを入れ,「削除」ボタンをクリックし,さらに「削除」ボタンをクリック

  • 右上の「削除」ボタンをクリック

  • 「削除」と入力し,「削除」ボタンをクリック

12.2 ALB の削除

  • EC2 ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択)
  • 画面左のメニューバーの「ロードバランサー」をクリック

  • 「アクション」ボタンをクリックし,「削除」をクリック

    • 使用しているロードバランサーが表示されない場合は,右上のリージョンが「東京」になっているか確認
  • 「削除」をクリック

12.3 CloudFront の削除

【備考】画像投稿機能を付けていない場合は,次に進んで下さい。

  • CloudFront ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「cloudfr」と入力し、「CloudFront」を選択)
  • 使用している Distribution にチェックを入れて,「Disable」ボタンをクリック

  • 「Yes, Disabled」ボタンをクリック

「Status」が「Disabled」になるまで待ちましょう

  • 使用している Distribution にチェックを入れて,「Delete」ボタンをクリック

  • 「Yes, delete」ボタンをクリック

  • 「Close」ボタンをクリック

12.4 SSL証明書 の削除

  • Certificate Manager ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「acm」と入力し、「Certificate Manager」を選択)
  • アプリで使用したドメインを選択し,「アクション」ボタンをクリックし,「削除」をクリック

  • 「削除」ボタンをクリック

【備考】画像投稿機能を付けている場合は,「東京」リージョンだけでなく「バージニア北部」リージョンのACMも削除して下さい。

12.5 EC2 の削除

  • EC2 ダッシュボードに移動
    • (画面左上の「サービス」を開き、検索欄に「ec2」と入力し、「EC2」を選択)

ターゲットグループの削除

  • 画面左のメニューバーの「ターゲットグループ」をクリック

  • アプリで使用していたものを選択した状態で「Action」のプルダウンの「Delete」をクリック

  • 「Yes, delete」ボタンをクリック

EC2 インスタンスの削除

  • 画面左のメニューバーの 「インスタンス」をクリック
  • 削除したいインスタンスを選択した状態で「アクション」ボタンをクリックし,「インスタンスの状態」「インスタンスを終了」をクリック(「停止」ではない)
  • 「終了」ボタンをクリック

Elastic IP の解放

  • 画面左のメニューバーの Elastic IP をクリック
  • 削除したい Elastic IP を選択した状態で「アクション」ボタンをクリックし,「Elastic IPアドレスの解放」をクリック
    • EC2終了後少し待たないと解放できません
  • 削除したい Elastic IP が消えたことを確認

その他

  • 「キーペア」も削除しましょう
  • 「セキュリティグループ」は VPC 削除時に自動的に削除されます

12.6 RDS の削除

  • RDS ダッシュボードに移動
    • (画面左上の「サービス」を開き、検索欄に「rds」と入力し、「RDS」を選択)

####s RDS インスタンスの削除

  • 画面左のメニューバーの「データベース」をクリック
  • 削除したい DB を選択し,「アクション」ボタンをクリックし,「削除」をクリック
  • 「最終スナップショットを作成しますか?」のチェックを外し,「インスタンスの削除後、システムスナップショットとポイントインタイムの復元を含む自動バックアップが利用不可となることを了承しました。」にチェックを入れ,フィールドに「delete me」を入力して「削除」ボタンをクリック

その他

  • 「サブネットグループ」を削除
    • RDSが削除されるまで削除できません
  • 「パラメータグループ」は残してよいでしょう。

12.7 VPC の削除

  • VPC ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「vpc」と入力し、「VPC」を選択)
  • 削除したい VPC を選択し,「アクション」ボタンをクリックし,「VPC を削除」をクリック

  • フィールドに「削除」と記入して「削除」ボタンをクリック

サブネット,インターネットゲートウェイ,ルートテーブルも同時に削除されます。

12.8 S3/IAM の削除

【備考】画像投稿機能を付けていない場合は,次に進んで下さい。

S3 の削除

  • S3 ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「s3」と入力し、「S3」を選択)
  • アプリで使用したバケットを選択し,「空にする」ボタンをクリック

  • 「完全に削除」と入力し「空にする」ボタンをクリック

  • 「終了」ボタンをクリック

  • 「削除」ボタンをクリック

  • 「バケット名」を入力し,「バケットを削除」ボタンをクリック

IAM の削除

  • IAM ダッシュボードに移動

    • (画面左上の「サービス」を開き、検索欄に「iam」と入力し、「IAM」を選択)
  • 画面左のメニューバーの「ユーザー」をクリック

  • 「アプリ名_user」にチェックを入れ,「ユーザーの削除」ボタンをクリック

    • アプリと関係ないものを削除しないように注意!
  • 「はい,削除します」ボタンをクリック

12.9 キーペアの削除

GitHub の公開鍵を削除

  • ブラウザでGitHubにアクセス
  • 右上のサムネイル画像をクリック
  • 「Settings」をクリック
  • 左メニューバーから「SSH and GPG keys」をクリック
  • 「アプリ名_git_rsa/pub」の箇所で「Delete」ボタンをクリック
  • 「I understand, please delete this SSH key」ボタンをクリック

ローカル環境のキーペアの削除

最後に,ローカル環境の秘密鍵と設定を削除しておきましょう。

ローカル環境のターミナル
cd ~/.ssh
rm -f アプリ名.pem
vi config
# Host アプリ名 の設定を削除
71
64
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
71
64

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?