EC2とRDSを利用してRails 6 + MySQL 5のアプリケーションをAWS上で起動する

インフラ

こんにちは。Enjoy IT Life管理人の仁科(@nishina555)です。

先日、【AWS環境構築手順】VPCとEC2を作成し、実際にアクセスしてみるでAWSのEC2を構築する手順について紹介しました。

【AWS環境構築手順】VPCとEC2を作成し、実際にアクセスしてみる

WebアプリケーションをAWSで運用する場合、EC2だけでなくRDSを組み合わせて運用するのが一般的です。
そこで今回はRailsアプリケーションを例にとり、EC2とRDSを構築する手順について紹介します。

今回のゴール
  • EC2からRDSのデータベースにアクセスできる環境を整える
  • EC2上でRailsアプリケーションを起動し、外部からアクセスできる環境を構築する

今回作成するAWS環境

今回作成するAWS環境のイメージ図は以下の通りです。

仕様は以下の通りです。

今回の仕様
  • パブリックサブネットにEC2、プライベートサブネットにRDSを配置する
  • 『Rails 6 + MySQL 5』のアプリケーションを配置する
  • gitを利用してRailsアプリケーションを配置する
  • 作業ユーザーは事前に作成したroot権限を持つ『webuser』ユーザーで作業する
  • ソースコードは『rails new』ではなく『git』を利用し、『/srv』ディレクトリに配置
  • アプリケーション名は『rails-app』

VPCの構成詳細は下記の通りです。

サブネット

名前 目的 IPv4 CIDRブロック アベイラビリティゾーン
public-subnet インターネットと接続できる領域の確保 10.0.0.0/24 ap-northeast-1a
private-subnet1 セキュアな領域の確保 10.0.1.0/24 ap-northeast-1a
private-subnet2 セキュアな領域の確保 10.0.2.0/24 ap-northeast-1c

DBサブネットグループ

名前 サブネット
sample-db-subnet private-subnet[1 2]

ルートテーブル

名前 ルール サブネット関連付け
public-route デフォルトルートをInternet Gateway public-subnet

セキュリティグループ

名前 インバウンドルール 用途
sample-web SSHと3000番(Railsで利用されるポート)を許可 EC2用
sample-db MySQLをEC2からのみ許可 RDS用

EC2

名前 サブネット セキュリティグループ パブリックIP
sample-web public-subnet sample-web 無効

RDS

名前 サブネットグループ セキュリティグループ
database-1 sample-db-subnet sample-db

各種バージョンは下記の通りです。

$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"

$ node -v
v12.18.0

$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]

$ rails -v
Rails 6.0.3.1

$ gem list | grep puma
puma (4.3.5)

$ mysql --version
mysql  Ver 15.1 Distrib 5.5.64-MariaDB, for Linux (x86_64) using readline 5.1

MySQL [(none)]> status
Server version: 5.7.22-log Source distribution

下記の項目については今回の環境構築の対象外とします。

対象外の内容
  • DNS設定
  • SSL化
  • Webサーバーとの連携
  • 本番環境での起動(今回は開発環境で起動)

VPC、EC2インスタンスの作成

外部からアクセスできるEC2インスタンスをVPC内に構築します。

EC2をVPCに作成する手順については『【AWS環境構築手順】VPCとEC2を作成し、実際にアクセスしてみる』を参照してください。

【AWS環境構築手順】VPCとEC2を作成し、実際にアクセスしてみる

RDSの環境構築

RDSとはRelational Database Serviceの略で、AWSのリレーショナルデータベースに関するサービスです。

Railsアプリケーションで必要になるRDSの環境を構築していきます。

サブネットの作成

『VPCダッシュボード』を開き、『サブネット』→『サブネットの作成』を選択します。

必要事項を入力し、『作成』を選択します。

各項目の意味は以下の通りです。

  • 名前タグ: サブネットの識別子
  • VPC: サブネット作成対象のVPC
  • アベイラビリティゾーン: サブネットを作成するアベイラビリティゾーン。特に希望がなければ『指定なし』でOK
  • IPv4 CIDRブロック: サブネットで利用するアドレスの範囲を記述。ブロックサイズは『/16』から『/28』の間までである必要がある。
RDSを配置する際は2つ以上のアベイラビリティゾーンからサブネットを指定する必要があります。

VPC内のサブネットが1箇所のアベイラビリティゾーンのみで構成されている場合は、異なるアベイラビリティゾーンのサブネットを作成します。

今回はRDS用のサブネットとして下記のサブネットを作成しました。

名前 IPv4 CIDRブロック アベイラビリティゾーン
private-subnet1 10.0.1.0/24 ap-northeast-1a
private-subnet2 10.0.2.0/24 ap-northeast-1c

DBサブネットグループの作成

DBサブネットグループとはRDSを起動するサブネットをグループ化したものです。DBサブネットグループは異なる2つ以上のアベイラビリティゾーンから構成されなければいけません。

先ほど用意した2つのRDS用のサブネットを利用して、DBサブネットグループを作成していきます。

AWSマネージメントコンソールで『RDS』を選択します。

RDSダッシュボードの『サブネットグループ』→『DBサブネットグループの作成』を選択します。

先ほど用意したprivate-subnet[1 2]をサブネットに追加します。今回はsample-db-subnetという名前のDBサブネットグループを作成しました。

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

セキュリティグループとはグループ外との通信を制御するためのファイアウォールです。『インバウンド』と『アウトバウンド』の制御をすることができます。

ALBを作成する過程でセキュリティグループが必要になるため、まずはセキュリティグループの準備を行います。

『VPCダッシュボード』を開き、『セキュリティグループ』→『セキュリティグループを作成』を選択します。

必要事項を入力し、『セキュリティグループを作成』を選択します。

各項目の意味は以下の通りです。

  • セキュリティグループ名: セキュリティグループの識別子
  • 説明: セキュリティグループの説明
  • VPC: セキュリティグループ作成対象のVPC
  • インバウンドルール: 外からの通信に対するルール
  • アウトバウンドルール: 外への通信に対するルール

今回はRDS用のセキュリティグループのため、インバウンドルールでEC2が配置されているサブネットからのMySQL接続の許可を追加しました。

セキュリティグループ名はsample-dbとし、今回利用するVPCsample-devで利用できるように設定しました。

RDSの作成

RDSダッシュボードの『データベースの作成』選択します。

データベースの作成画面が表示されるので必要事項を入力します。

今回は『標準作成』で以下のようなスペックのRDSを作成しました。

今回作成したRDSのスペック
  • エンジンのオプション: MySQL 5.7.22
  • テンプレート: 無料利用枠
  • マルチAZ配列: なし(本番稼働じゃないのでそもそも指定できない)
  • VPC: sample-dev
  • サブネットグループ: sample-db-subnet
  • パブリックアクセス可能: なし
  • VPCセキュリティグループ: sample-db
  • アベイラビリティゾーン: ap-northeast-1a

動作確認

RDSの環境が用意できたので、RDSのマスターユーザーでログインでMySQLにアクセスできることを確認します。
作業はEC2で行います。

$ sudo yum update
$ sudo yum install -y mysql


### EC2からMySQLにログインできることを確認
$ mysql -h xxxxap-northeast-1.rds.amazonaws.com -u [マスターユーザー] -p
# -h: ホスト名
# -u: ユーザ名
# -p: パスワード

Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.22-log Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

なお、RDSのホスト名はRDSの『接続とセキュリティ』の『エンドポイント』を指定します。

Railsアプリケーションの環境構築

EC2にRailsアプリケーションの環境を構築します。

この項目で紹介する『Rails 6 + MySQL』の開発環境の構築手順については『Rails6 + MySQL8の開発環境をCentOS8に構築する手順』で紹介していますので、コマンドの意味の詳細などについてはそちらの記事を参考にしてください。

サーバ上での作業はroot権限を持つwebuserという名前のユーザーで行います。
ユーザー作成手順は【CentOS】sudo権限を持つユーザーにパスワード無しで変更する方法を参考にしてください。

Rails6 + MySQL8の開発環境をCentOS8に構築する手順

【CentOS】sudo権限を持つユーザーにパスワード無しで変更する方法

Rubyのインストール

rubyのバージョン管理ができるrbenvを利用してRubyのインストールを行います。1 2 3 4

### gitのインストール
$ sudo yum install -y git

### rbenvのインストール
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ ~/.rbenv/bin/rbenv init
→ 手順が出力されるのでそれに従う

### 推奨ライブラリのインストール
$ sudo yum install -y gcc.x86_64 bzip2 openssl-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel libyaml-devel

### ruby-buildのインストール
$ mkdir -p "$(rbenv root)"/plugins
$ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

### セットアップが正しく完了したかチェックする
$ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash

Checking for `rbenv' in PATH: /home/webuser/.rbenv/bin/rbenv
Checking for rbenv shims in PATH: OK
Checking `rbenv install' support: /home/webuser/.rbenv/plugins/ruby-build/bin/rbenv-install (ruby-build 20200520-2-gf00582b)
Counting installed Ruby versions: none
  There aren't any Ruby versions installed under `/home/webuser/.rbenv/versions'.
  You can install Ruby versions like so: rbenv install 2.2.4
Checking RubyGems settings: OK
Auditing installed plugins: OK

### rubyのインストール
$ rbenv install -v 2.7.1
$ rbenv global 2.7.1
$ rbenv versions
→ バージョンが表示されればOK

* 2.7.1 (set by /home/webuser/.rbenv/version)

Node.jsのインストール

Rails 6ではデフォルトでWebpacekrを利用します。Webpackerを利用するにはNode.jsが必要なのでインストールをします。

nodeはnodenvを利用してインストールします。手順はrubyをrbenvを利用してインストールしたときのそれとほとんど同じです。5 6 7

### nodenvのインストール
$ git clone https://github.com/nodenv/nodenv.git ~/.nodenv
$ echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile
$ ~/.nodenv/bin/nodenv init
→ 手順が出力されるのでそれに従う

### 推奨ライブラリのインストール
$ sudo yum install -y python36.x86_64 gcc-c++ make

### node-buildのインストール
$ mkdir -p "$(nodenv root)"/plugins
$ git clone https://github.com/nodenv/node-build.git "$(nodenv root)"/plugins/node-build

### セットアップが正しく完了したかチェックする
$ curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash

Checking for `nodenv' in PATH: /home/webuser/.nodenv/bin/nodenv
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /home/webuser/.nodenv/plugins/node-build/bin/nodenv-install (node-build 4.9.0)
Counting installed Node versions: none
  There aren't any Node versions installed under `/home/webuser/.nodenv/versions'.
  You can install Node versions like so: nodenv install 2.2.4
Auditing installed plugins: OK

### nodeのインストール
$ nodenv install -v 12.18.0
$ nodenv global 12.18.0
$ nodenv versions
→ バージョンが表示されればOK

* 12.18.0 (set by /home/webuser/.nodenv/version)

Yarnのインストール

Webpacekrで必要になるYarnのインストールを行います。8

$ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
$ sudo yum install -y yarn

もしくは

$ curl -o- -L https://yarnpkg.com/install.sh | bash


### インストールされたか確認
$ yarn -v

1.22.4

Railsアプリケーションの配置

Railsアプリケーションの配置と起動の準備を行います。

### アプリケーションディレクトリの作成
$ cd /srv
$ sudo mkdir rails-app
$ sudo chown webuser:webuser rails-app

### rails-appディレクトリでgit clone
$ cd rails-app
$ git clone git@github.com:xxxx/rails-app.git .

### mysql2 gemのインストールで必要なmysql-develを用意
$ sudo yum install -y mysql-devel

### gemのインストール
$ bundle install

### Webpackerのインストール
$ bin/rails webpacker:install

データベースの準備

Railsアプリケーション側のデータベース接続設定と、データべース接続ユーザーの作成を行います。

データベース接続情報の設定

今回はwebuserというユーザーがwebpassというパスワードでデータベースへ接続できるようにします。

config/database.ymlを下記のように修正し、 webuserwebpassでRDSへ接続できるようにします。

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  socket: /var/lib/mysql/mysql.sock
+ username: webuser
+ password: webpass
+ host: [RDSのエンドポイント]

development:
  <<: *default
  database: rails-app_development

test:
  <<: *default
  database: rails-app_test

production:
  <<: *default
  database: rails_app_production
  username: rails_app
  password: <%= ENV['RAILS_APP_DATABASE_PASSWORD'] %>

データべース接続ユーザーの作成と権限付与

接続ユーザーであるwebuserの作成と、webuserへの権限付与を行います。

$ mysql -h xxx.rds.amazonaws.com -u [マスターユーザー] -p


### ユーザー作成
mysql> create user webuser@'%' identified by 'webpass';

### webuserに権限付与
mysql> 
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO 'webuser'@'%' WITH GRANT OPTION;
# 『show grants for [マスターユーザー]@'%';』の結果を元に権限付与

データベースの作成

データベースの作成とマイグレーションを実行します。

$ bin/rails db:create
$ bin/rails db:migrate

Railsアプリケーションの起動

$ bin/rails s -b 0.0.0.0
# -b 0.0.0.0: 外部からアクセスできるようにする

http://[IPアドレス]:3000/ で以下のような画面になればOKです。

たとえば、Eventというモデルを画面から作成すると、MySQLに接続すればデータが保存されます。

$ mysql -h xxx.rds.amazonaws.com -u webuser -p

mysql> use rails-app_development;
mysql> select * from events;

 select * from events;
+----+-------+----------------------------+----------------------------+
| id | title | created_at                 | updated_at                 |
+----+-------+----------------------------+----------------------------+
|  1 | test  | 2020-06-17 19:38:23.703149 | 2020-06-17 19:38:23.703149 |
+----+-------+----------------------------+----------------------------+
1 row in set (0.00 sec)

まとめ

以上でEC2とRDSを利用したRailsアプリケーションの環境構築の紹介を終わります。

この記事がいいなと思いましたらTwitter(@nishina555)のフォローもよろしくお願いします!

AWSオススメ参考書