こんにちは。
Web・iOSエンジニアの三浦です。
今回は、業務で使ったことのまとめも兼ねて、AWSを使ったWebサイトのインフラ構成を1から構築してみます。
なおここでは、ドメインの取得まではしないのであらかじめご了承ください。
構成
まずは構成を考えていきます。
今回は以下のような構成とします。
説明していきます。
VPC
サーバーやDBなどのAWSのサービスは、そのまま使うこともできますが、例えるならそれは雑居ビルのランダムな部屋を使用しているようなものです。
それでも問題があるわけではありませんが、セキュリティ周りをより厳密に設定するなどしたい場合は、 VPC
(Virtual Private Cloud)というサービスを使うことができます。
このサービスは、例えるならビルの1フロアを丸々借り上げるようなものです。
さらに VPC
の中を サブネット
という形で分けることができます。
これは借り上げたフロアの中を更に区切るもので、基本的にはこの サブネット
の中にサーバーやDBを作っていくことになります。
サブネット
には、外部からインターネットでアクセスできる パブリックサブネット
と、直接インターネットからアクセスできない プライベートサブネット
があり、外部とつながる必要のないサービスを プライベートサブネット
に入れ、直接ユーザーがアクセスする必要のあるサービスを パブリックサブネット
の中に入れる、といった使い方をします。
ちなみに VPC
を作成する際は、「リージョン」というものを選択します。
リージョンには「東京」や「オハイオ(アメリカ)」など様々な地域があり、物理的にAWSの施設がある地域のことです。
例えば日本で使うのであれば「東京」リージョンのほうが「オハイオ(アメリカ)」リージョンよりも物理的に距離が近いので、通信時間が短くなります。
またリージョンの中にはアベイラビリティゾーン(AZ)というものがあります。
東京リージョンには3つのAZがあり、このAZの住所に実際にAWSの施設が存在します。
AZが複数存在するのは、地震や停電などでいずれかのAZの機能が停止したとしても、他のAZでサービスを停止させることなく続けられるようにする、などの可用性の向上のためです。
サブネット
を作成する際は、どのAZに サブネット
を作成するかを選択します。
ちなみに プライベートサブネット
が直接インターネットからアクセスできないとは言っても、サーバーへ必要な設定をダウンロードするなどインターネットとつながっている必要があります。
「インターネットからはアクセスできない」が「インターネットとつながっている」状態を実現するため、NATゲートウェイ
(Network Address Translation Gateway)という、 VPC
内部のIPアドレス(プライベートIPアドレス)とインターネットのIPアドレス(グローバルIPアドレス)を相互に変換してくれるサービスを使用します。
NAT ゲートウェイ
を パブリックサブネット
内に配置し、 プライベートサブネット
がインターネットと何らかのやり取りをする際にそれを経由することで、セキュリティを保ったままインターネットに接続することができるようになります。
NAT ゲートウェイ
はすべての パブリックサブネット
においてもいいのですが、今回は1つの パブリックサブネット
にのみ置きます。
これは、実際に今回使用する サブネット
は パブリックサブネット
と プライベートサブネット
それぞれ1つずつのためです。
今回使用しない サブネット
を作るのは、後述するRDSやALBを使用するためには最低でも2つのAZに サブネット
が存在する必要があるためです。
EC2
Webサイトを作成するには、サーバーが必要です。
AWSのサーバーは EC2
(Elastic Compute Cloud)と呼ばれます。
先程の説明だと、この EC2
は直接ユーザーがアクセスするものなので パブリックサブネット
に置くはずだ、と思うかもしれませんが、今回は ALB
というサービス(後で説明します)を使うため、 EC2
は プライベートサブネット
に入れます。
またもう一つ、サーバーに開発者が直接ログインするため、ログイン中継用の EC2
を作成しておきます。
こういったサーバーは「踏み台サーバー」と呼ばれます。
RDS
Webサイトを構築する場合、DBを使用することも多いでしょう。
このとき、EC2
の中にDBを構築してもいいですが、AWS側が管理してくれる RDS
(Relational Database Service)を使うという手もあります。
こちらに関してはユーザーが直接アクセスする必要がないので、 プライベートサブネット
の中に入れます。
ALB
ユーザーが自分のPCからWebサイトにアクセスする場合、そのアクセスを受け付けるものが必要になります。
EC2
を パブリックサブネット
に置き、それで直接アクセスを受け付けることもできますが、ここでは ALB
(Application Load Balancer)というものを使います。
ALB
は Load Balancer 、すなわち負荷均衡化のためのサービスで、複数のサーバーを ALB
に紐付けることでアクセスの流し先を自動的に分散し、サーバーごとの負荷を減らすことができます。
またそれだけでなく、 ACM
(AWS Certificate Manager)というサービスを使うことで、自動で更新される証明書を使ってWebサイトをHTTPSにすることができます。
Route 53
最後に、ユーザーがこちらで指定するURLからアクセスできるようにするため、 Route 53
を使用します。
Route 53
は、ドメイン名(URLが https://***/index.php
のような形だった場合、 ***
の部分)を購入したり、そのドメインを ALB
や EC2
に紐付けることができます。
ここまでできれば、あとは EC2
や RDS
に必要な設定をすればWebサイトを構築することができます!
それでは実際にAWS上で構築してみましょう。
手順
1. アカウント作成
まずはこちらからアカウントを作成します。
アカウントの作成が完了したらこちらの「コンソールにサインイン」からログインしてください。
先程作成したアカウントを使用します。
無事コンソールに入ることができました!
なお右上に出ているように、デフォルトでは「オハイオ」リージョンのEC2などを使用するようになっていますが、「東京」リージョンが良ければ変更してください。
2. VPC
では、VPCを作っていきます。
まずはコンソール画面の検索ボックスに「VPC」を打ち込み、クリックします。
VPCの画面に行ったら、まずは左下にある「Elastic IP」に進みます。
Elastic IP
とは、AWSから取得できるグローバルIPアドレスです。
今回はNAT ゲートウェイに必要なため作成します。
「新しいアドレスの割当」からIPアドレスを作成しましょう。
IPアドレスの作成が完了したら、以下のような画面が表示されるはずです。
「閉じる」で画面を戻します。
続いて、VPCを作っていきます。
画面左上の「VPCダッシュボード」をクリックします。
ダッシュボード画面から「VPC ウィザードの起動」に進みましょう。
ステップ1では、「パブリックとプライベートサブネットを持つVPC」を選択します。
ステップ2では、以下のものを設定していきます。
VPC名
VPCにつける名前です。
なんでも良いですが、わかりやすいものにしましょう。
パブリックサブネットのアベイラビリティゾーン
パブリックサブネットを入れるAZです。
こちらはどこでも大丈夫です。
パブリックサブネット名
こちらもなんでもいいですが、「public」などの文字やAZのタイプ(a,c,d)などを入れるとわかりやすいです。
プライベートサブネットのAZ
プライベートサブネットを入れるAZです。
こちらもなんでもいいですが、パブリックサブネットと同じAZに入れることで、通信時間やコストをわずかでも減らすことができます。
プライベートサブネット名
こちらもなんでもいいですが、「private」などの文字やAZのタイプ(a,c,d)などを入れるとわかりやすいです。
Elastic IP 割当 ID
先ほど作成したElastic IPのIDを入力します。
その他はそのままで大丈夫です。
入力完了後に「VPCの作成」を押せば、VPCが作られます!
少し待つと、こんな画面が表示されます。
作成が完了したら、続いて残りのAZ用のパブリック・プライベートサブネットを作成します。
まずは「サブネット」へと行きます。
サブネットで「サブネットの作成」をします。
以下のように作っていきます。
名前タグ
何でも大丈夫ですが、先程のように「public/private」や「a/c/d」が入っているとわかりやすいです。
VPC
先程作ったものを選びます。
アベイラビリティゾーン
パブリック・プライベートサブネットで1つずつ選ぶようにします。
IPv4 CIDR ブロック
何でも大丈夫ですが、他のものとかぶらないようにしましょう。
作成が完了したら、パブリックサブネットのみルートテーブルを変更します。
パブリックサブネットの一つを選択し、下の「ルートテーブル」を押して、「ルートテーブルの関連付けの編集」をします。
igw-***
が表示される方のルートテーブルIDを選択し、「保存」します。
なお igw-***
はインターネットゲートウェイと呼ばれるもので、パブリックサブネットに必要なゲートウェイとなっています。
他のパブリックサブネットについても同様に設定してください(なお、最初にVPCと一緒に作成したパブリックサブネットは最初から正しい設定になっています)。
設定が完了したら、「ルートテーブル」「インターネットゲートウェイ」「Elastic IP」「NAT ゲートウェイ」に移り、作成したVPCに紐付いた各データに名前をつけると良いでしょう。
デフォルトのものもあるので、紐付いているVPC IDを見て判断してください。
こちらも適当な名前で大丈夫です。
これでVPCの作成は完了です!
3. EC2
では次に、EC2を作成します。
まずは踏み台サーバーを作りましょう。
まずは左上のAWSのロゴからコンソール画面に戻ります。
コンソール画面でEC2を入力し、移動します。
踏み台サーバーには外部からアクセスする必要があるので、まずはElastic IPを作成します。
「Elastic IPアドレスの割り当て」から作成します。
そのまま「割り当て」をクリックしてください。
以下のようになるはずです。
作成が完了したら、EC2を作っていきましょう。
まずは「インスタンス」の画面へ行きます(ちなみにAWSでは、サーバーのことをEC2インスタンス、インスタンスなどと言ったりします)。
インスタンスの画面にて、「インスタンスの作成」を行います。
まずはAMI(Amazon Machine Image)を選択していきます。
これによってサーバーのOSなどが決まってきます。
必要性に応じて選べば問題ありませんが、ここは一番上にある「Amazon Linux 2 AMI (HVM), SSD Volume Type」を選択します。
次にインスタンスタイプを選びます。
インスタンスタイプは、サーバーのCPUやメモリなどのスペックに関わってきます。
サーバーにかかる負荷によって選択する必要がありますが、もしまだアカウントを作って1年以内であれば t2.micro
が無料枠で使用できるので、今回はそちらを選びます。
選択後は、「次のステップ:インスタンスの詳細の設定」をクリックします。
インスタンスの詳細設定では、以下を設定します。
ネットワーク
最初に作成したVPCを選択します。
サブネット
パブリックサブネットのどれかを選択します。
なお今回はすべてのサービスを同じAZのサブネットで作成するので、どのAZで作ったかを覚えておいてください。
ちなみに、より詳細にサーバーの属性を設定できるIAMと呼ばれるものもありますが、今回は簡易的に行うため設定しません。
選択後、「次のステップ:ストレージの追加」をクリックします。
ストレージの追加では、サーバーのストレージを決定します。
今回は何もせず、「次のステップ:タグの追加」を選択します。
タグの追加では、作成するインスタンスにタグを追加できます。
これによりコスト確認などがより便利にできるようになりますが、今回は何もせず「次のステップ:セキュリティグループの確認」を選択します。
セキュリティグループは、インスタンスのセキュリティを担保するファイアウォールです。
以下を設定します。
セキュリティグループの割当
「新しいセキュリティグループ」を作成します。
セキュリティグループ名
適当なものを設定します。
説明
適当なものを設定します。
SSH
SSHでサーバーにログインするために必要な設定です。
自分のPCのIPアドレスを「ソース」に設定することで、自分のPCのIPアドレス以外からはSSHでアクセスできなくなります。
すべてのICMP - IPv4
ping
コマンドなどで確認できるようにするための設定です。
今回は 0.0.0.0/0
でどこからでも確認できるようにしていますが、ここのIPアドレスを絞っても良いかもしれません。
踏み台であれば以上で十分でしょう。
入力後、「確認と作成」を押します。
確認画面が問題なければ「起動」します。
起動するとキーペアについて尋ねられるので、ここでは「新しいキーペアの作成」をします。
名前は適当なものを設定し、ダウンロードしてください。
ダウンロードすると「インスタンスの作成」ができるようになります。
なおここでダウンロードしたキーペアをなくすとサーバーにログインできなくなるので、注意してください。
作成すると以下のような画面になります。必要に応じて「請求アラートの作成」をしてもいいでしょう。
問題なければ「インスタンスの表示」をします。
インスタンスを作成したら、先程のVPCのときと同じように名前をつけると良いでしょう。
また、Elastic IPとの紐付けで使うので、インスタンスIDとプライベートIPをメモなどに保存しておきます。
その後、Elastic IPへ進みます。
先程作成したIPにチェックをし、「Actions」から「Elastic IPアドレスの関連付け」を選んでください。
Elastic IPアドレスの関連付けでは、以下のように設定します。
リソースタイプ
EC2に紐付けるので、「インスタンス」を設定してください。
インスタンス
先程作成したEC2を選択してください。
プライベートIPアドレス
先程作成したEC2のプライベートIPアドレスを選択してください。
入力後、「関連付ける」を押してください。
これでサーバーの作成は完了です!
実際にログインしてみましょう。
まずは先ほどダウンロードした鍵(秘密鍵)を、秘密鍵が通常存在するディレクトリへ移動させます。
mv ~/Downloads/test-bastion-key.pem ~/.ssh/
続いて、権限を変更します。
chmod 600 ~/.ssh/test-bastion-key.pem
準備ができたら、先程作成したElastic IP先に、今の秘密鍵を使ってログインしてみます。
ちなみにユーザー名は ec2-user
です。
ssh -i ~/.ssh/test-bastion-key.pem ec2-user@{先程のElastic IP}
これで無事ログインできるはずです!
なおユーザーについては ec2-user
を使いまわしたりせず、ちゃんと各ユーザー用のものを作成しましょう。
では次に、Webサイト用のEC2を作成します。
とは言っても、今の手順のうち一部を変更するのみです。
変更する手順は、
1. Elastic IP周りを設定しない
2. パブリックサブネット内に作成する
AZは踏み台サーバーと同じところにしてください。
3. セキュリティグループは、VPC内からのみを考える
HTTPで受けるので、セキュリティグループは80番ポートを開けます。
4. 名前を適切につける
です。
これにてアプリケーションサーバーが作成され、踏み台サーバー経由でアプリケーションサーバーに入れるようになったはずです。
ダウンロードした秘密鍵を踏み台サーバーに入れることで踏み台サーバーからSSHログインしてもいいですが、ここでは ~/.ssh/config
にSSH設定ファイルをおいてログインしてみましょう。
なお今回の秘密鍵は test-application-key
という名前で作成しました。
Host test-bastion
HostName {踏み台サーバーのグローバルIPアドレス}
User ec2-user
Port 22
IdentityFile ~/.ssh/test-bastion-key.pem
Host test-application
HostName {アプリケーションサーバーのプライベートIPアドレス}
User ec2-user
Port 22
IdentityFile ~/.ssh/test-application-key.pem
ProxyCommand ssh -W %h:%p test-bastion
こうして、
ssh test-application
とすることでアプリケーションサーバーにログインできるはずです!
これにて、EC2の作成は完了しました。
4. RDS
では続いて、RDSの作成に移ります。
最初にRDS用のセキュリティグループを作ります。
EC2の画面から、そのまま「セキュリティグループ」に移動してください。
「セキュリティグループの作成」をします。
以下を設定します。
セキュリティグループ名
適当に設定します。
説明
適当に設定します。
VPC
作成したVPCを設定します。
セキュリティグループのルール:インバウンド
「MYSQL/Aurora」タイプ(3306番ポート)について、VPCのIPアドレスの範囲からのアクセスを許可します。
また、「ICMP」タイプは全許可します。
入力が完了したら「作成」をクリックしてください。
続いてコンソール画面から、RDSの画面に移ってください。
まずは「サブネットグループ」を作成します。
サブネットグループとは、RDSが存在しうるサブネットをまとめたものです。
以下を設定してください。
名前
適当に設定します。
説明
適当に設定します。
VPC
作成したVPCを設定します。
サブネットの追加
プライベートサブネットをすべて「サブネットを追加します」で追加してください。
完了したら「作成」を押します。
続いてパラメーターグループを作成します。
以下を設定してください。
パラメータグループファミリー
今回は Amazon Aurora MySQL
(AWSで開発されたクラウドに最適化されたDBで、MySQLと互換性があるもの)を使用する予定なので、 aurora-mysql5.7
とします。
タイプ
DB Parameter Group
とします。
グループ名
適当に設定します。
説明
適当に設定します。
完了したら「作成」を押します。
ここまでできたら、ダッシュボード画面から「データベースの作成」を選択してください。
以下のように設定します。
エンジンのタイプ
何でも大丈夫ですが、ここでは Amazon Aurora
の、MySQLと互換性のあるものを選びます。
バージョン
好きなもので良いですが、ここでは最新のものにします。
DBクラスター識別子
名前なので、適当につけてください。
マスターユーザー名
デフォルトのユーザー名です
マスターパスワード
ユーザーのパスワードとなります。
最初にログインするために必要なので、設定後は忘れないようにしましょう。
インスタンスサイズ
とりあえず料金が最も安いdb.t2.smallを選びます。
可能性と耐久性
今回は「Auroraレプリカを作成しない」を選択します。
なお「別のAZでAuroraレプリカ/リーダーノードを作成する」にした方が安全性は増しますが、複数台のDBを作成する必要があります。
Virtual Private Cloud (VPC)
作成したVPCを選択します。
その後「追加の接続設定」をクリックします。
サブネットグループ
先程作成したサブネットグループを選択します。
VPCセキュリティグループ
先ほど作成した、RDS用のセキュリティグループを選択します。
アベイラビリティゾーン
EC2を作成したのと同じAZを選択します。
完了したら、一番下の「データベースの作成」をクリックします。
しばらくするとDBが作成されます!
では、アプリケーションサーバーから接続してみましょう。
まずはアプリケーションサーバーにログインします。
ssh test-application
デフォルトではサーバーでmysqlコマンドが使えないので、インストールします。
sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm -y
sudo yum-config-manager --disable mysql80-community
sudo yum-config-manager --enable mysql57-community
sudo yum install mysql-community-client.x86_64
これでログインできるようになりました!
mysql -u {ユーザー名} -p -h {RDSのエンドポイント}
ちなみに、RDSのエンドポイントは以下から確認できます。
無事入れました!
5. ALB
次にALBを作成します。
コンソール画面から、またEC2の画面に飛びます。
「ロードバランサー」へ進みます。
「ロードバランサーの作成」をしましょう。
今回はApplication Load Balancer(ALB)を「作成」します。
以下を設定していきます。
名前
適当に設定します。
VPC
作成したVPCを選択します。
アベイラビリティゾーン
すべてのAZに対してサブネットを作ったはずなので、すべてチェックを入れます。
ALBはインターネットから直接アクセスできる必要があるので、パブリックサブネットとします。
完了したら「セキュリティ設定」へ進みます。
今回は先程の画面でHTTPSを選ばなかったのでここでは何もできませんが、もし選択した場合はこちらでいくつか設定をします。
Route 53などでドメインを作成して所有していると ACM
というサービスで証明書を獲得でき、それを利用すればここでWebサイトをHTTPS化できます。
そのまま「次の手順:セキュリティグループの設定」に進みます。
セキュリティグループの設定では、以下の設定をします。
セキュリティグループの割当
新しいセキュリティグループを作成します。
セキュリティグループ名
適当に設定します。
説明
適当に設定します。
ルール
HTTPとICMPの設定をします。
なお今回はALBがユーザーのアクセスを受け付けるところになるため、全IPアドレスから80番ポートへのアクセスを受け付けるようにします。
すべての設定が完了したら「次の手順:ルーティングの設定」へ進みます。
ルーティングの設定では、新しいターゲットグループを作成します。
名前は適当に設定してください。
その他はそのままで「次の手順:ターゲットの登録」に進みます。
ターゲットの選択では、先程作成したアプリケーションサーバーを選択し、「登録済みに追加」を押します。
これにより、このALBへのアクセスが指定したEC2へ流れるようになります。
なおここに複数台のサーバーを設定すれば、自動で分散してアクセスを流してくれます。
設定が完了したら「次の手順:確認」へ進みます。
問題なければ作成します。
ALBができました!
実際にできているか確認してみましょう。
以下のDNS名を host
コマンドで確認して、IPアドレスが確認できれば問題ありません!
6. Route 53
最後にRoute 53を使ってホストゾーンを指定します。
まずはコンソール画面からRoute 53の画面へ行きます。
ドメイン取得をしたい場合は「ドメインの登録」をしますが、今回は「DNS管理」をします。
「今すぐ始める」を押してください。
「ホストゾーンの作成」を行います。
遷移先で更に「ホストゾーンの作成」をクリックします。
「ドメイン名」には自分のサイトのドメイン名を、タイプには「パブリックホストゾーン」を選択します。
今回はドメイン名を取得していないので意味はありませんが、もしACMなどで取得していればここから指定したドメイン名に対するアクセスを制御できます。
入力したら「作成」します。
これでドメイン名に対するアクセスを制御する準備ができました。
次に、(もしドメイン名を取得していたら)ドメインにアクセスが来た際にアクセスを流す先を指定します。
「レコードセットの作成」をクリックします。
「名前」や「タイプ」はそのまま、「エイリアス」を「はい」にし、「エイリアス先」を先程作成したALBとして「作成」します。
これにより、ドメイン名を取得していれば、ドメイン名に対するアクセスが作成したALBに流れます。
これで今回の構成は完了です!
おわりに
業務ではほとんどTerraformというインフラ構成ツールを用いてAWSの構成を行っていたので、改めてコンソール上で構築していくのは逆に新鮮で、かつより深く理解することができました。
今回はIAMなどは使わなかったのでこれがベストプラクティスではないと思いますが、セキュリティグループなども用いてそれなりにセキュアには作れたかなと考えています。
AWSは今後も使っていく機会が多いと思いますので、色々と学んでいきたいです。
参考文献
以下のサイトを参考にさせていただきました。
ありがとうございました!
AWSでWebサーバー構築!VPC設計に必要なIPアドレスとサブネットの基礎知識(第1回)
こちらの第1回 ~ 第5回