RailsをKamalでデプロイするためのAWS環境を構築する
.png&w=3840&q=75)
今回はデプロイツールのKamalを使ってRailsアプリケーションをデプロイするための簡易的なAWS環境を作成します。
全体像
webサーバー(EC2) + DBサーバー(RDS)の構成で構築します。
冗長化、HTTPS通信などは考慮していません。

AWSアカウントを作成済みであることを前提に進めていきます。
VPC
まずはVPCを作成します。

VPCとは
VPCとはAWSクラウド上の仮想ネットワークです。
自分のアカウントの仮想ネットワーク空間を定義してその中にAWSリソースを構築、起動していきます。
作成手順
VPCは1つのリージョン(地理的に離れた領域)に属することになります。

今回はアジアパシフィック(東京) ap-northeast-1を選択しています。

AWSでアカウントを作成すると各リージョンに1つずつデフォルトでVPC(デフォルトVPC)が作成されていますが、これとは別で新規で作成します。

VPCのページにアクセスし、「VPCを作成」をクリックします。
作成するリソースで「VPCなど」を選択して他のネットワークリソースを同時に作成することもできますが、今回は個別に作成していきます。
以下の内容でVPCを作成します。
項目 | 値 |
---|---|
作成するリソース | VPCのみ |
名前タグ | rails-kamal-vpc |
IPv4 CIDR ブロック | 10.0.0.0/21 |
IPv6 CIDR ブロック | IPv6 CIDR ブロックなし |
テナンシー | デフォルト |

正常に作成されたら完了です。

サブネット
サブネットを作成します。

サブネットとは
サブネットとはVPC内部で分割されたIPアドレスの範囲です。
特定のサブネットにEC2インスタンスなどの AWSリソースを作成していきます。
VPCが1つのリージョンに所属するのに対し、サブネットは1 つのアベイラビリティーゾーン(リージョン内の独立したデータセンター)に所属する必要があります。

作成手順
EC2用を配置するパブリックサブネットを1つ、RDS用を配置するプライベートサブネットを2つ作成します。
RDSは2つ以上のアベイラビリティゾーンをまたがるサブネットをグルーピングしたサブネットグループに紐付ける必要があるため、ap-northeast-1a, ap-northeast-1cに1つずつ作成します。
※厳密にはこのサブネット作成時点ではパブリックサブネットという区別はできません。
後に作成するインターネットゲートウェイ、ルートテーブルなどの設定が完了後、パブリックサブネットとなります。
サブネットのページにアクセスし、「サブネットを作成」をクリックします。
作成したVPCを選択します。
項目 | 値 |
---|---|
VPC ID | rails-kamal-vpc |

パブリックサブネット
EC2を配置するパブリックサブネットを1つ作成します。
項目 | 値 |
---|---|
サブネット名 | rails-kamal-public-subnet-1a |
アベイラビリティーゾーン | ap-northeast-1a |
IPv4 サブネットCIDRブロック | 10.0.0.0/24 |

プライベートサブネット
RDSを配置するプライベートサブネットを2つ作成します。
「新しいサブネットを追加」をクリックしてそのまま追加していきます。
項目 | 値 |
---|---|
サブネット名 | rails-kamal-private-subnet-1a |
アベイラビリティーゾーン | ap-northeast-1a |
IPv4 サブネットCIDRブロック | 10.0.2.0/24 |

項目 | 値 |
---|---|
サブネット名 | rails-kamal-private-subnet-1c |
アベイラビリティーゾーン | ap-northeast-1c |
IPv4 サブネットCIDRブロック | 10.0.3.0/24 |

「サブネットを作成」をクリックして3つのサブネットが正常に作成されたら完了です。

インターネットゲートウェイ
インターネットゲートウェイを作成します。

インターネットゲートウェイとは
VPC とインターネットとの間の通信を可能にするVPC コンポーネントです。
インターネットゲートウェイを利用することで後に作成するパブリック内のEC2インスタンスとインターネット間の接続が可能になります。
作成手順
インターネットゲートウェイのページにアクセスして「インターネットゲートウェイの作成」をクリックします。
項目 | 値 |
---|---|
名前タグ | rails-kamal-internet-gateway |

「インテーネットゲートウェイを作成」をクリックして正常に作成されたことが確認できたら「VPCへアタッチ」をクリックします。

作成したVPCを選択して「インターネットゲートウェイのアタッチ」をクリックします。
これでVPCとインターネット間の通信の準備ができました。
ルートテーブル
インターネットゲートウェイとパブリックサブネット間の通信を行えるようにするためルートテーブルを作成します。

ルートテーブルとは
ルートテーブルとはサブネットやインターネットゲートウェイなどからの通信の経路のルールを定義するものです。
ルートテーブルには多くのルールの概念がありますが、今回は以下の2つのルールが定義されたルートテーブルを作成します。
1 送信先とターゲットの定義
2 ルートテーブルの関連付け
1ではインターネットからインターネットゲートウェイへのアクセスの許可、2ではインターネットゲートウェイとサブネット間の通信の許可を行います。
ここで関連付けが行われたインターネットと通信可能なサブネットをパブリックサブネットと呼びます。
作成手順
ルートテーブルのページから「ルートテーブを作成」をクリックします。
項目 | 値 |
---|---|
名前 - オプション | rails-kamal-route-table |
VPC | rails-kamal-vpc |

作成後、アクション内のメニューもしくはルートタブの「ルートを編集」をクリックします。

ルートを追加して全てのIPアドレス範囲からのインターネットゲートウェイへの通信を許可します。
項目 | 値 |
---|---|
送信先 | 0.0.0.0 |
ターゲット | rails-kamal-internet-gateway |

「変更を保存」を押してルートを更新します。
続けてパブリックサブネットとの関連付けを行います。
アクション内のメニューもしくはサブネットとの関連付けタブの「サブネットの関連付けを編集」をクリックします。

パブリックサブネット(rails-kamal-public-subnet-1a)を選択して「関連付けを保存」をクリックします。

関連付けが正常に更新されたら完了です。

セキュリティグループ
EC2, RDS用のセキュリティグループを作成します。

※便宜上サブネットの中にセキュリティグループが存在するような図にしていますが、厳密には後に作成するそれぞれのサブネットに配置するEC2, RDSに対してセキュリティグループを関連付けする形になります。
セキュリティグループとは
セキュリティグループは関連付けたリソース(今回はEC2, RDS)に到達する通信(インバウンドルール)、帰っていく通信(アウトバウンドルール)を制御するものです。
今回はEC2用にSSH, HTTP接続を許可、RDS用にEC2用のセキュリティグループからの通信を許可するセキュリティグループを作成します。
作成手順
EC2用にSSH, HTTP接続を許可するセキュリティグループを作成します。

セキュリティグループのページにアクセスし、「セキュリティグループを作成」をクリックします。
項目 | 値 |
---|---|
セキュリティグループ名 | rails-kamal-ec2-security-group |
説明 | rails-kamal-ec2-security-group |
VPC | rails-kamal-vpc |

インバウンドルール
HTTPとSSHを許可します。
タイプ | ソース |
---|---|
HTTP | Anywhere-IPv4 |
SSH | Anywhere-IPv4 |

アウトバウンドルール
デフォルトのままにしておきます。
「セキュリティグループを作成」をクリックして正常に作成されたら完了です。

続けてRDS用のセキュリティグループを作成します。
項目 | 値 |
---|---|
セキュリティグループ名 | rails-kamal-rds-security-group |
説明 | rails-kamal-rds-security-group |
VPC | rails-kamal-vpc |

タイプ | ソース |
---|---|
PostgreSQL | カスタム - rails-kamal-ec2-security-group |
先ほど作成したEC2用のセキュリティグループからのアクセスを許可します。

アウトバウンドルール
デフォルトのままにしておきます。
「セキュリティグループを作成」をクリックして正常に作成されたら完了です。

EC2
パブリックサブネットに配置する仮想サーバーのEC2を作成します。

EC2インスタンスの起動
EC2のページにアクセスし、「インスタンスを起動」をクリックします。
名前とタグ
項目 | 値 |
---|---|
名前 | rails-kamal-ec2 |

アプリケーションおよび OS イメージ(Amazon マシンイメージ)
項目 | 値 |
---|---|
Amazon マシンイメージ (AMI) | Ubuntu Server. 24.04 LTS(HVM), SSD Volume Type(無料枠の対象) |
アーキテクチャ | 64 ビット (×86) |
OSはUbuntuを選択します。
デフォルトで選択されているAmazon Linuxで進めるとKamalへのデプロイ時にサポートされていないディストリビューションであるというエラーが発生するので注意が必要です。


インスタンスタイプ
項目 | 値 |
---|---|
インスタンスタイプ | t2.micro |

キーペア
ec2インスタンスにSSH接続するためのキーペアを作成します。
項目 | 値 |
---|---|
キーペア名 | rails-kamal-ec2-key-pair |
キーペアのタイプ | RSA |
プライベートキーファイル形式 | .pem |
「キーペアを作成」をクリックするとキーペアのファイルが自動的にダウンロードされるので分かりやすい場所に保存しておきます。

ネットワーク設定
「編集」をクリックします。
項目 | 値 |
---|---|
VPC | rails-kamal-vpc |
サブネット | rails-kamal-public-subnet-1a |
パブリックIPの自動割り当て | 無効化 |
ファイアウォール(セキュリティグループ) | 既存のセキュリティグループを選択する - rails-kamal-ec2-security-group |

以降の項目はデフォルトのままにしておきます。
「インスタンスを起動」をクリックします。
しばらくして、インスタンスが「実行中」、ステータスチェックが「2/2のチェックに合格しました」となれば正常に起動ができています。

ElasticIPアドレスを割り当てる
EC2インスタンスの設定でパブリックIPの自動割り当てを「無効化」としましたが、これを「有効化」とするとインスタンスを一度停止して再起動するとパブリックIPが変わってしまいます。
今回はElasticIPアドレスという固定のIPアドレスをEC2インスタンスに対して割り当てることにします。
EC2のページから「Elastic IP」にアクセスし、「Elastic IPアドレスを割り振る」をクリックします。

特に設定などは変更せず「割り振る」をクリックします。
正常に割り振られたことが確認できたら詳細ページにアクセスし、「Elastic IPアドレスを関連付ける」をクリックします。
項目 | 値 |
---|---|
リソースタイプ | インスタンス |
インスタンス | rails-kamal-ec2 |

「関連付ける」をクリックして正常に関連付けられたら完了です。
SSH接続
起動したEC2インスタンスにSSH接続をしてみます。
ターミナルを開いてキーペアを保存したディレクトリまで移動、以下のコマンドを実行します。
$ ssh -i rails-kamal-key-pair.pem ubuntu@パブリックIPアドレス
続けるか聞かれるのでyesと入力します。
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
権限に関する次の警告が出ます。
Permissions 0644 for 'rails-kamal-key-pair.pem' are too open.
自分以外のユーザーが読み込むことができないように権限を変更します。
$ chmod 400
再度接続します。
$ ssh -i rails-kamal-key-pair.pem ubuntu@パブリックIPアドレス
以下のように表示され接続が完了します。
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-1021-aws x86_64)
pemファイルなしでSSH接続
キーペアなしでSSH接続を可能にします。
exit
で一度ローカルに戻り~/.ssh
に移動し、ssh-keygen
を実行します。
$ cd ~/.ssh
$ ssh-keygen
~/.ssh
内に id_rsa(秘密鍵
)とid_rsa.pub(公開鍵)
が作成されます。
id_rsa.pub
の中身を表示してコピーしておきます。
$ cat id_rsa.pub
再度SSH接続して以下のコマンドを実行します。
vi ~/.ssh/authorized_keys
ここには起動時に指定したキーペアの公開鍵が配置されています。
これを先ほどコピーした公開鍵に変更します。
dd
で行を削除、i
でインサートモードに切り替え、コピーした公開鍵をペーストして:wq
で保存・終了します。
一度exit
で接続を終了し、設定に問題がなければキーファイルの指定なしでSSH接続が可能になります。
$ ssh ubuntu@パブリックIPアドレス
EC2側の~/.ssh/authorized_keys
の内容を更新したことで先ほどのpemファイルを指定してのSSH接続はできなくなっています。
$ ssh -i rails-kamal-key-pair.pem ubuntu@パブリックIPアドレス
ubuntu@パブリックIPアドレス: Permission denied (publickey).
RDS
最後にリレーショナルデータベースサービスのRDSを作成します。

サブネットグループを作成
RDS用に作成した2つのサブネットをグルーピングするサブネットグループを作成します。
RDSのページにアクセスして「サブネットグループ」→「サブネットグループを作成」をクリックします。
項目 | 値 |
---|---|
名前 | rails-kamal-subnet-group |
説明 | rails-kamal-subnet-group(任意の値) |
VPC | rails-kamal-vpc |
アベイラビリティゾーン | ap-northeast-1a, ap-northeast-1c |
サブネット | rails-kamal-private-subnet-1a, rails-kamal-private-subnet-1c |

「作成」を押して正常に作成されたら完了です。

RDSを作成
データベースの作成方法を選択
標準作成

エンジンのオプション
項目 | 値 |
---|---|
エンジンのタイプ | PostgreSQL |

テンプレート
無料利用枠

設定
項目 | 値 |
---|---|
DBインスタンス識別子 | database-1(任意の識別子) |
マスターユーザー名 | postgres |
認証情報管理 | セルフマネージド |
マスターパスワード・確認 | 任意のパスワード |

接続
項目 | 値 |
---|---|
コンピューティングリソース | コンピューティングリソースに接続しない |
ネットワークタイプ | IPv4 |
VPC | rails-kamal-vpc |
DB サブネットグループ | rails-kamal-subnet-group |
VPC セキュリティグループ | rails-kamal-rds-security-group |

以降の設定はデフォルトのままにしておきます。
「データベースの作成」をクリックします。
しばらくするとデータベースが起動中になります。
以上でAWS環境の構築は完了です。
参考
https://zenn.dev/redheadchloe/articles/3441d06b95d70e
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-key-pairs.html