【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう

フロントエンドエンジニアですが、AWS 始めてみます

そんな訳で、UI デザイナー > Flex ディベロッパー > マークアップエンジニアと、今日までフロントエンド一辺倒で来た私 wakamsha ですが、とある事情から Amazon Web Services ( 以下、AWS ) と戯れてみることになりました。とはいえインフラ関連の知識がほぼゼロな自分が一からお勉強するというのもなかなかどうして学習コストがかかるので他の人にお任せするという選択肢もあったのですが、こんな機会でもない限りずっとやらないだろうということで、軽い気持ちで始めてみようかと思います。

それにしても、前職はAWSヒャッハーッ!な会社に属していたにも関わらず全くと言ってよいほど自分から触ろうとしなかったのに、人は変わるもんですねぇ…(適当)。

前提条件

  • AWS アカウントを取得済みである
  • EC2 にキーペアを登録済みである1)EC2 Management Console 画面でキーペアを生成出来ますが、そのサービスを使わずにローカル環境で生成して公開鍵だけを AWS 上に通知するのがあるべき形との意見があります。
  • Mac 環境である (Windows 環境だと SSH 接続の方法が異なるので、適宜読み替えて頂く必要があります)

構成図

ミニマムな構成と一言で言っても AWS の各種サービスをただ個別に動かすだけではあまりに芸が無いので、なるべく実戦でも使えるような本格的な構成を目指したいと思います。とはいえ今回は障害耐性や冗長化、負荷分散、オートスケーリングといったところまでは特に考えておらず、今回は将来より実践的な構成を構築出来るようになるための第一弾として見て頂ければと思います。

vpc-minimum

Amazon VPC という仮想ネットワーク構築基盤の上に、アプリケーション・サーバーと DB サーバーをそれぞれ一つ立てています。アプリケーション・サーバーは EC2 の Amazon Linux、DB は RDS の MySQL サーバーを使います。

VPC 内には 2 種類のサブネットを作成します。アプリサーバーが置かれているサブネットはインターネットと通信するのでpublic subnetと呼びます。ユーザーからのリクエストを受け付けるためにElastic IPによってグローバル IP を付与します。

DB サーバーが置かれているサブネットはインターネットから遮断されており、内部のネットワーク間でのみ通信するのでprivate subnetと呼びます。DB サーバーはアプリサーバーからのみアクセスされます。

また、DB サーバーは Multi-AZ 構成という物理的に離れたデータセンターにホットスタンバイ用のサーバーをもう一つ建てることで、障害対応やバックアップなどの対応が可能になるので、構成図にそれを含めています。本番運用のサービスなどでは Multi-AZ 構成にするのが一般的かと思いますが、当然利用料金も2倍になるので学習目的である今回は実際には立てません。

Amazon VPC 環境の構築

Amazon Virtual Private Cloud (Amazon VPC) を使用すると、定義した仮想ネットワーク内にアマゾン ウェブ サービス(AWS)リソースを起動できます。仮想ネットワークは、ご自身のデータセンターで操作していた従来のネットワークとよく似ていますが、AWS のスケーラブルなインフラストラクチャを使用できるというメリットがあります。

Amazon VPC とは

まずは仮想ネットワーク構築基盤であるVPC環境から構築していきます。Start VPC Wizardから始めると詳細な設定をしない代わりに簡単に構築できるのですが、今回はお勉強ということであえて一つ一つ自分で設定してみるとします。

VPC の作成

  1. 左メニューからYour VPCsを選択し、Create VPCという青いボタンをクリック
  2. あとで見分けがつくようにName tagに適当な名前をつける
  3. 今回作成するネットワーク全体を表すCIDRを入力する。今回は10.0.0.0/16とする。
  4. TenancyはDefaultのままにしてYes,Createボタンをクリック

create_vpc

Subnet の作成

左メニューからSubnetsを選択して VPC - Subnets 管理画面を開きます。ここでサブネットを作成するわけですが、EC2 インスタンス(Webサーバー)用と RDS インスタンス(MySQL)用、RDS Multi-AZ 構成用とで計3つ作成します。

  1. Create Subnetという青いボタンをクリック
  2. あとで見分けがつくようにName tagに適当な名前をつける
  3. VPCに先ほど作成したものを指定する
  4. Availability Zone はどこでもOK
  5. CIDR block10.0.0.0/24と入力

create_subnet

各サブネットの作成内容は以下になります。

Name tag VPC Availability Zone CIIDR block
public subnet: web_server example-vpc ap-northeast-1a 10.0.0.0/24
private subnet: db1 example-vpc ap-northeast-1a 10.0.1.0/24
private subnet: db2 example-vpc ap-northeast-1c 10.0.2.0/24

3つ目のサブネットは、RDS の Multi-AZ 構成で利用するものなので、2つ目のサブネットとは異なる Availability Zone を指定します。本エントリーの構成では RDS を単一 AZ 構成で構築しますので、このサブネットは今回は利用しません。

Internet Gateway の作成

Internet Gateway は VPC 内のサーバがインターネットと接続するための出入口です。このゲートウェイを設置しなければ、完全にインターネットから遮断された状態となり、VPN 接続のみで利用するような用途のネットワーク(※ 本エントリーの解説範囲外)を構築することができます。

  1. 左メニューからInternet Gatewaysを選択し、Create Internet Gatewayという青いボタンをクリック
  2. あとで見分けがつくようにName tagに適当な名前をつける
  3. Yes,Createボタンをクリック

create_igw

次に作成した Internet Gateway を VPC と紐付けます。Attach to VPCボタンをクリックし、先ほど作成した VPC を選択します。

attach_vpc

Route Table の確認 & 作成

Route Table とは、各サブネットに対して仮想的に配置されるルーターのルーティングテーブルのようなものです。左メニューからSubnetsを選択し、作成したサブネット一覧を見てみましょう。自動作成された Route Table がデフォルトで割り当てられているのがわかります(下の図ではrtb-******950となっています)。

list_subnets

Route Table は、Public subnetに関してはインターネット(外界)への出口(Internet Gateway)が必要であり、Private subnetに関しては不要となります。したがって、自動生成された Rout Table は Private subnet 用として使います。

Route Table の作成

  1. 左メニューからRoute Tablesを選択し、Create Route Table という青いボタンをクリック
  2. あとで見分けがつくようにName tagに適当な名前をつける
  3. VPCに先ほど作成したものを指定する
  4. Yes,Createボタンをクリック

create_routetable

次に今作成した Route Table を Public subnet に設定します。

  1. 一覧から今作成した Route Table を選択し、画面下のRoutesというタブを開いてEditという青いボタンをクリックする
  2. Destination に0.0.0.0/0と入力する
  3. Target に先ほど作成した InternetGateway を選択する
  4. Saveボタンをクリック

edit_routetable

最後にいま作成した Route Table を先ほど作成した Public subnet に設定します。

  1. 左メニューからSubnetsを選択し、サブネット一覧からpublic subnetを選択
  2. Route tableタブを開いてEditという青いボタンをクリック
  3. Change to:に作成した Route Table を選択して一覧に追加されたのを確認したら、Saveボタンをクリック

add_routetable

Security Group の作成

セキュリティグループは、インスタンスの仮想ファイアウォールとして機能し、インバウンドトラフィックとアウトバウンドトラフィックをコントロールします。VPC 内でインスタンスを起動した場合、そのインスタンスは最大 5 つのセキュリティグループに割り当てることができます。セキュリティグループは、サブネットレベルでなくインスタンスレベルで動作します。このため、VPC 内のサブネット内のインスタンスごとに異なるセキュリティグループのセットに割り当てることができます。起動時に特定のグループを指定しないと、インスタンスは VPC のデフォルトのセキュリティグループに自動的に割り当てられます。

VPC のセキュリティグループ

セキュリティグループは用途に合わせて複数作成します。今回は2つ作成します。

  • アプリケーション・サーバー用のセキュリティグループ
    • Internet からの接続(80番)
    • SSH からの接続(22番)
  • DB用のセキュリティグループ
    • アプリケーション・サーバーからの接続(3306番)

では実際に作っていきましょう。左メニューからSecurity Groupを選択します。すると一覧にすでにセキュリティグループがありますが、新規に作成するとします。Create Security Groupという青いボタンをクリックしてポップアップを表示します。

create_securitygroup

入力したらYes, Createをクリックします。作成したセキュリティグループを一覧から選択してInbound Rulesタブを選択します。Editボタンをクリックして以下の図のように入力しましょう。

edit_inboundrules

各セキュリティグループの設定内容は以下のとおりです。

アプリケーションサーバー用のセキュリティグループ
Name tag Group name Description VPC
vpc-example vpc-example:web_server It is a security group on http of vpc-example. example-vpc
Type Protocol Port Range Source
SSH (22) TCP (6) 22 0.0.0.0/0
HTTP (80) TCP (6) 80 0.0.0.0/0
DB サーバー用のセキュリティグループ
Name tag Group name Description VPC
vpc-example vpc-example:db It is a security group on db of vpc-example. example-vpc
Type Protocol Port Range Source
MySQL (3306) TCP (6) 3306 Web サーバー用のセキュリティグループID

DB Subnet Group - RDSからVPCを利用するための設定

おもむろに RDS Management Console を開きます。

  1. 左メニューからSubnet Groupsを選択
  2. Create DB Subnet Groupという青いボタンをクリック
  3. 適当な Name と Description を入力
  4. VPC IDに先ほど作成したものを指定
  5. Availability ZoneSubnet IDをそれぞれ選択して2つの private subnet を指定

create_dbsg

Availability Zone Subnet ID CIIDR block
ap-northeast-1a subnet-******** 10.0.1.0/24
ap-northeast-1c subnet-******** 10.0.2.0/24

長くなりましたが、以上で VPC のセットアップは完了です。ではこれより、このネットワークの上に各種サーバーを構築していくとします。

DB サーバーの構築

おもむろに RDS Management Console を開きます。

左メニューからInstancesを選択し、Launch DB Instanceという青いボタンをクリックします。

launch_db

はじめに DB の種類を選択します。今回は MySQL にしましょう。

select_db

Multi-AZ すなわち異なるデータセンターにそれぞれ DB を建てることによって堅牢性を担保するかどうかという設定です。本番環境であれば余程のことがないかぎりYesにするべきでしょうが、当然ながらその分費用も2倍になります。今回はお勉強ということでNoとしておきましょう。

no_multi-az_db

DB のバージョンやサイズを選択します。特にこだわりがなければバージョンは最新版で OK です。インスタンスクラスもお勉強ということで一番小さいdb.t2.microにしておきます。DB のユーザー名やパスワードを設定したらNext Stepボタンをクリックします。

spec_db

  1. VPCに先ほど作成したしたものを指定する
  2. Subnet Groupには紐付けた DB セキュリティグループが選択されるはず
  3. VPC Security Group(s)には DB 用に作成したものを選択
  4. Backup Retention Period1 dayと指定しておく
  5. ここまで設定したらLaunch DB Instanceボタンをクリック

create_db_advance

これで DB サーバーの構築は完了です。

アプリケーションサーバーの構築

おもむろに EC2 Management Console を開きます。

左メニューからInstancesを選択し、Launch Instanceという青いボタンをクリックします。最初にマシンイメージを選択するわけですが、特にこだわりがなければAnazon Linux AMI を選択します。

select_amazon_linux

インスタンスタイプは、とりあえずお勉強ということで一番小さいt2.microを選択します。

select_ec2_t2micro

Networkに作成した VPC を選択し、Subnetには作成した Public Subnet を選択します。

select_ec2_vpc

今回はストレージはそのままで OK です。あとで見分けがつくようにName tagに適当な名前を付けておきます。

Web サーバー用のセキュリティグループを選択します。

select_ec2_sg

最後にReview and Launchをクリックして設定内容の確認をします。問題無さそうであればLaunchボタンをクリックして表示されたポップアップ上で、登録済みのキーペアを選択したらLaunch Instancesボタンをクリック。EC2インスタンスの起動が開始されます。

select_keypair

Elastic IP の作成 & インスタンスに割り当て

左メニューからElastic IPsを選択し、Allocate New Addressという青いボタンをクリックします。

create_eip

特に設定項目はありません。そのままYes, AllocateボタンをクリックするとIPが作成されて一覧に追加されます。続けてAssociate Addressボタンをクリックして作成したIPをEC2インスタンスに割り当てます。

associate_eip

これで全ての準備は完了です。

アプリケーションサーバーに SSH 接続してみる

ターミナルを起動して先ほど起動させたアプリケーション・サーバー(EC2)にSSH接続してみましょう。

$ ssh -i ~/.ssh/wakamsha_aws.pem ec2-user@***.***.***.**
       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|___|___|
https://aws.amazon.com/amazon-linux-ami/2015.03-release-notes/
[ec2-user@ip-10-0-0-104 ~]$

いかがでしょう?無事にサーバーに入ることが出来ましたでしょうか?

アプリケーション・サーバーから MySQL にアクセスしてみる

先ほど作成した RDS インスタンスはグローバル IP を持っていないので外部(インターネット上)から直接アクセスすることは出来ませんが、アプリケーション・サーバーからのアクセスは許可されています。

まずはアプリケーション・サーバーにmysqlをインストールします。

# yum のアップデートを最初にやっておきます
$ sudo yum -y update
読み込んだプラグイン:priorities, update-motd, upgrade-helper
⋮
⋮
完了しました!
# mysqlインストール
$ sudo yum -y mysql
読み込んだプラグイン:priorities, update-motd, upgrade-helper
依存性の解決をしています
⋮
⋮
完了しました!

インストールが完了したらホスト名に RDS インスタンスのエンドポイントを指定してアクセスしてみます。ユーザー名とパスワードは RDS インスタンス作成時に入力したものです。

mysql -h ********.**********.ap-northeast-1.rds.amazonaws.com -P 3306 -u awsuser -p
Enter password:
elcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 22
Server version: 5.6.22-log MySQL Community Server (GPL)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql>

やりました。問題なくアクセスできましたね。

httpd をインストールしてみる

最後にアプリケーション・サーバーに httpd をインストールして、外部から HTTP リクエストを受けられるかどうかを確認して終わりにするとします。


インストールが完了したら httpd を起動します。一応サーバーを再起動しても httpd が起動したままになるように設定しておくとします。

$ sudo service httpd start
Starting httpd: httpd: apr_sockaddr_info_get() failed for ip-10-0-0-104
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
$sudo chkconfig httpd on

httpd が起動したら、Web ブラウザからアクセスしてみましょう。URL は EC2 インスタンスに紐付けた Elastic IP の IP アドレスです。

httpd_firstview

無事にアクセスできました。これにてセットアップは完了です。

おわりに

AWS 関連の情報はググれば初心者向けから上級者向けまでたくさん出てきます。しかしAWS自体のアップデート頻度が異常に早いがために半年前のエントリーでもすでに古くなってしまっていることがあるので、何かと困惑することが多かったです。また、ずっとフロントエンド一辺倒でやってきたためかネットワーク関連の知識が圧倒的に不足しており、セキュリティグループ周りが中々理解できずにいたのが悔しいところであります。サブネットとか瞬時に頭の中で計算できん…。

とはいえ何とか最初の一歩は踏み出せたかなという実感は少なからず持てました。インフラ専門の方々には到底及びませんが、フロントエンドエンジニアでもちょっとしたネットワーク環境の構築は出来るんだよと、少しでも励みになれば幸いです。

脚注

脚注
1 EC2 Management Console 画面でキーペアを生成出来ますが、そのサービスを使わずにローカル環境で生成して公開鍵だけを AWS 上に通知するのがあるべき形との意見があります。