【IT未経験】AWSで3層アーキテクチャを構築してみた。
CLF、SAAを取得してAWSのサービス内容も少しずつわかるようになってきたので、3層アーキテクチャを構築してみた。
題材はAWSのHPで見つけた初心者向け題材。3層アーキテクチャはシンプルながらインフラの基礎なのかなと感じ、選定。この題材を元に、自分なりに構成図や設定を変えてみた上で構築。
(HP記載の構成)

(その構成を元に変更してみた構成)

【構築にあたって意識したこと】
・可用性:EC2、RDSをマルチAZ配置にして、一つのAZに障害が起きてもサイトがダウンしない構成に。リードレプリカと違って同期的にRDSのセカンダリに情報が保存されるので、より高可用。
・安全性:サーバ用のプライベートサブネットを作成しEC2を配置、ALB経由での接続とすることでよりセキュリティを上げる。RDSのプライベートサブネットと分けることで、サブネットごとのセキュリティ設定(サーバ用、DB用)をしやすく。NATゲートウェイを配置することで、サーバからのネットへのアウトバウンドを安全に可能にする(wordpressを使う場合、更新作業などで何かしらネット接続が必要になるのでは、との想像)。
【構成図を作成している時に気になったこと】
・この構成の時のストレージはRDSとなってるけど、S3じゃダメなんかな。何が理由でRDSにしてるんやろ。
→Wordpressのデータ(投稿、ユーザ、設定等)がMySQLで管理されているため、RDSが最適。S3はオブジェクトストレージでSQLが使えないためWordpressの管理には不適切。
・AWS Systems Manegerってこういうとき使えるのか。
→使えそう。SSH、踏み台サーバ、キーペアを使わずに3層構成ができる。
【構築】
-
VPC作成

1つのAZ内にパブリックサブネット×1、プライベートサブネット×2を設置。マルチAZ構成にしたいので、AZは2つ。

CIDRは今回1aのAZは奇数、1cのAZは偶数となるように設定。サブネットマスクは24で設定。ここは練習なのでアドレス数をあまり気にせず。
NATゲートウェイは今回作るとすべてのプライベートサブネットに紐づいてしまうので、別途作成予定。 -
EC2作成

・AMI:Linux
・セキュリティグループ(インバウンド):
SSH22 マイIP、
HTTPS443 ALBのセキュリティグループにしたいが、未作成なので作成後に追加予定。
・キーペア:新規作成。今回は使わないがTeraformに接続する際に使う。
・その他設定はデフォルトのまま。
(細かい設定面については、今後学習していかなあかんわ。)
・ユーザデータについては、以下のスクリプトを記載(AWSハンズオンより抜粋)。
#!/bin/bash
dnf install -y httpd wget php-fpm php-mysqli php-json php php-devel mariadb105
wget http://ja.wordpress.org/latest-ja.tar.gz -P /tmp/
tar zxvf /tmp/latest-ja.tar.gz -C /tmp
cp -r /tmp/wordpress/* /var/www/html/
chown apache:apache -R /var/www/html
systemctl enable httpd.service
systemctl start httpd.service

プライベートサブネット1cの分は、先ほど作成したEC2の「アクション」→「同じものを起動」を選べば簡単に同じものが複製できる。
(今後も複製する場合は、「イメージを作成」からAMIを作成することで可能。)
- ALBの作成
ALBの作成にあたり事前にターゲットグループとセキュリティグループを作成。(ALBの作成フローの中でも、別ページに遷移して作成することは可能。)
(ALB用のターゲットグループの作成画面)

・ターゲットの種類:インスタンス(今回バランスしてほしいのはEC2だから)
・プロトコル:HTTPS、ポート443
・VPC:先ほど作成したVPC
・プロトコルバージョン:
・ヘルスチェック:WordPress が HTTPS ステータスコード 200 を返すように、ヘルスチェックパスを「/wp-includes/images/blank.gif」に変更。その他ヘルスチェック項目はデフォルトのまま。 ※ここはAWSハンズオンから抜粋。ヘルスチェックの詳細は後述。
・
(ALB用のセキュリティグループの作成画面)

・インバウンド:HTTPSのみ許可
→アラーム出た。セキュリティグループを作成して既知のIPアドレスからのアクセスに制限するのをおすすめされたけど、今回はWEBサイトの想定なのでCIDRの制限なくてよさそう。
・アウトバウンド:プライベートサブネットのEC2のセキュリティグループを指定
→そうすることで、アクセス先を制限しALB経由で他リソースへのアクセスを防ぐ。
(ALBの作成)

・VPC:先ほど作成したものを選択。
・サブネット:パブリック1aとパブリック1cを選択。
・セキュリティグループ:ALB用に作成したものを選択。
・リスナーとルーティング:ターゲットグループはALB用に作成したものを選択。
・ACM証明書:新しく発行の上、選択。(ACMの作成、ALBへの関連付けは無料)
→証明書がなかなか有効にならず結構待った。(1日ぐらい)HTTPにしてたら気付かんかった。すぐに設定できない工程もあるんやな。
→適当なドメイン名にしてたから全然承認されなかったことに気付く。ドメインを簡易で作って承認までもっていく。
- RDSの作成
RDS作成の前に、セキュリティグループとサブネットグループを作成。
(DB用のセキュリティグループ作成)

・インバウンド:MySQL、EC2のセキュリティグループ
・アウトバウンド:デフォルト設定のまま
(DB用サブネットグループ作成)

・VPC:今回作成したもの。
・AZ、サブネット:2つのAZを選択、RDSを配置予定のプライベートサブネットを各AZ内から1つ選択。(今回はマルチAZ構成なため。)
(RDSの作成)

・テンプレート:開発/テスト
・エンジンオプション:MySQL
・デプロイオプション:マルチAZDBインスタンス(クラスターデプロイにしたらさらに冗長性が向上するが、今回は予定通りのマルチAZ配置を選択)。
・認証情報管理:セルフマネージド(SecretsManagerの方が安全やけど、今回はハンズオンなので無料のセルフマネージドを選択)。
・インスタンスタイプ:tクラス(一番安価なため。本当は目的にあったクラスを選びたい。)
・ストレージ:汎用SSD、20GiB(最小単位)。
・拡張モニタリング:無効化(CPU使用率等の確認ができる。ログが溜まるとコストがかかるので、今回は無効のまま。)
・EC2への接続は今はせずにRDS作成後、実施。
・DBサブネットグループ、セキュリティグループ:上記で作成したDB用を選択。
・パブリックアクセス:なし
・データベースの選択肢:wordpress
・自動バックアップ:オフ
・その他の設定はデフォルト設定のまま。
-
NATゲートウェイの作成
・サブネット:パブリックサブネット
・ElasticIP:割り当て -
wordpressの設定
AWSハンズオンのHPの手順にて実施。 -
可用性の確認
(EC2)
片方のEC2を停止させたうえで、ALBで異常確認後、サイトの表示を確認。無事に見れた。
(RDS)
フェイルオーバー実施にチェックを入れた上で再起動。フェイルオーバー中にサイトの表示を確認。無事に見れた。 -
作成したリソースの削除
EC2、RDS、ALB、ElasticIP、NATゲートウェイ等、費用がかかるリソースも多いためハンズオンが終われば早めの削除がおすすめ。(AWSハンズオンのHPも要参照)
ElasticIPは紐づいているALB、NATゲートウェイを先に削除する必要あり。
NATゲートウェイを削除するには、VPCエンドポイント(今回はEC2 Instance Connect Endpoint)を先に削除する必要あり。
【構築でつまづいたところ】
つまづくポイントは多かった。
・ACMの証明書を作成するにあたってのドメイン名(適当にドメイン名を記載してた…)。
・ALBのヘルスチェック確認したらhealthyにならない(EC2をプライベートサブネットに置いてるからネット接続されてなかった。NATゲートウェイを作らないと確認の意味がないことになかなか気付けず。)
・NATゲートウェイ配置してもネット接続できず→EC2を置くべきプライベートサブネットを間違っていた。
・ネットに繋がってなかったので、ユーザデータで保存したスクリプト実行できておらず。wordpressインストールのためにEC2の停止→ユーザデータを更新→再起動が必要みたいやけど再起動しても起動せず。SSHでコーディングしようとしてもTeratermで起動できず(プライベートサブネットにEC2を配置されてたので外部からの通信できず。VPCエンドポイント(今回はEC2 Instance Connect Endpoint)が必要。NATゲートウェイはアウトバウンド。他のリソースからのインバウンドにはVPCエンドポイント経由のため。ClaudeCodeの助けを借りてコーディング。)
と設定の不具合を修正するのにかなり手こずった。こういう時にも生成AIは役に立った。わからない箇所をひたすら壁打ち、確認や修正を繰り返したおかげで不具合を修正できた。自分だと思い込みで気付けない箇所もあり、AIに第三者目線から指摘してもらえたのは助かった。
【ALB用のターゲットグループを作成時/ヘルスチェック】
ヘルスチェック:サーバが正常に動いているか確認すること。
→ALBのヘルスチェックは定期的に「HTTP(S)のリクエストを投げる→『200 OK』が返ってくるか」という流れで確認している。
ヘルスチェックのリクエスト先としてよい条件は、
・軽い(負荷が低い、CPUへの負荷を最小限に抑えられるため。)
・静的(DB不要、アクセスが多いためDBへの接続試行でサーバのリソースを食ってしまうため。)
この条件を満たすのが「/wp-includes/images/blank.gif」。空っぽの画像でファイルサイズ極小であり、wordpressに最初から存在するファイルであるため、wordpressが動いているかを確認するために指定されている。
※ただ「200 OK」と返ってきていても、DB接続エラー、PHPがクラッシュしてる、等の場合があるため、これで必ずサーバが動いているかはわからない。その対策としては、wordpress内で極小ファイル(/health)を作成し、「DBにクエリを投げて1件取得できたら200を返す」という処理を記述したパスをALBに指定すること、である。
【所感】
・CLF、SAAの知識があったため、ハンズオンでも構成をイメージしやすかった。ただ実際に手を動かすと迷うところ、知らないことが多くあったので、とてもよい勉強になった。
・効率のよい作業順序があるのもわかった(EC2とNATゲートウェイの作成順序など)。今回でいうとRDSやALBは特に作成順序で時短できそうと感じた。もう一度練習で同じハンズオンをしてみよう。
・今後、AWS WAFやAuto Scalingは追加してみたい。構成の引き出しを増やしていく。またSQLコマンドは覚えた方がよさそう。AIに聞けるけど知識がないと正しいのかの判断もできんかった。
(追記)ハンズオン費用について
このハンズオンをするのに、かかった費用は約1.3ドル。起動時間で言うと、RDS、ALBが4時間(ElasticIPも同様)、NATゲートウェイが2時間。EC2は使うときだけ開始にして他は停止していたので時間不明、4時間ぐらいは起動してるはず。

Discussion