【AWS】学習記録#02_スケーラブルウェブサイト構築ハンズオンをやってみた

2022年12月4日

aws-st-scalable-website-0

こんにちは、キクです。

「AWS初心者だけど、何かしらの形でアウトプットしていきたい!!」

本記事は、そんな思いから「AWS学習記録」として気ままにアウトプットしていくシリーズです。
今回は『スケーラブルウェブサイトの構築』をテーマに書いていきたいと思います!

本記事の内容

それでは、よろしくお願いします。

本記事に登場する主なAWSサービス(アルファベット順)

・EC2
・ELB
・RDS
・VPC

注意事項

本記事はAWS初心者である筆者が学習の一環でアウトプットすることを目的の1つとしています。
そのため、読者の方にとっては有益な情報でない可能性もあります。
あらかじめご了承いただけますと幸いです。

はじめに

まずはじめに、今回の作業内容について簡単にご紹介します。
今回は以下のAWS公式ハンズオンを試してみました。

講座名:スケーラブルウェブサイト構築編

作業記録

本章では、実際にAWSでの操作内容を書いていこうと思います。

1. VPCの作成

本項では、今回の作業環境の土台となる「VPC」を作成していきます。

■1-1. VPC管理画面にて「VPCを作成」ボタンをクリック

■1-2.「VPCを作成」画面にて、以下の設定パラメータを指定して「VPCを作成」をクリック

設定パラメータ

作成するリソース :VPCなど
名前タグの自動生成
 自動生成 :Test-VPC
IPv4 CIDRブロック:10.0.0.0/16
IPv6 CIDR ブロック :IPv6 CIDR ブロックなし
テナンシー :デフォルト
アベイラビリティーゾーンの数 :2

▼AZのカスタマイズ
 第1アベイラビリティーゾーン :ap-northeast-1a
 第2アベイラビリティーゾーン :ap-northeast-1c
パブリックサブネットの数:2
プライベートサブネットの数:2

▼サブネットCIDRブロックをカスタマイズ
 ap-northeast-1a のパブリックサブネット CIDR ブロック:10.0.0.0/24
 ap-northeast-1c のパブリックサブネット CIDR ブロック:10.0.1.0/24
 ap-northeast-1a のプライベートサブネット CIDR ブロック:10.0.2.0/24
 ap-northeast-1c のプライベートサブネット CIDR ブロック:10.0.3.0/24

NATゲートウェイ :なし
VPCエンドポイント :なし

DNSオプション
 DNSホスト名を有効化 :チェックなし
 DNS解決を有効化 :チェックあり

項目名「作成するリソース」として「VPCなど」を選択することで、VPC以外にも以下の図に記載のリソースが一括で作成されます。

VPCやサブネットに加えて、インターネットゲートウェイを含むルートテーブルなども作成されるので少し作業がラクになりますよね。
ただ、この方法で作成した場合にはそれぞれのリソース名にデフォルトの値が設定されるため、後続作業ではそれらを分かりやすい名前に変更していきます。

■1-3.「お使いのVPC」画面にて、作成したVPCの名前を変更

設定パラメータ

変更前 :Test-VPC-vpc
変更後 :Test-VPC

■1-4. 左ペインより「仮想プライベートクラウド -> サブネット」をクリック

■1-5.「サブネット」画面にて自動作成されたサブネットの名前を変更

設定パラメータ

変更前1 :Test-VPC-subnet-public1-ap-northeast-1a
変更後1 :パブリックサブネット-1a

変更前2 :Test-VPC-subnet-public1-ap-northeast-1c
変更後2 :パブリックサブネット-1c

変更前3 :Test-VPC-subnet-private1-ap-northeast-1a
変更後3 :プライベートサブネット-1a

変更前4 :Test-VPC-subnet-private1-ap-northeast-1c
変更後4 :プライベートサブネット-1c

変更前
変更後

2. EC2インスタンスの作成

本項では、ウェブサイトとして稼働する1台目の「EC2インスタンス」を作成していきます。
なお、2台目のEC2インスタンスについては、1台目から自作したAMIを利用した方法で後ほど作成していきます。

■2-1. EC2の管理画面より「インスタンスを起動」ボタンをクリック

■2-2.「インスタンスを起動」画面にて、以下の設定パラメータ①〜③を指定して「インスタンスを起動」をクリック

設定パラメータ①

名前 :Test-EC2#1
AMI :Amazon Linux2 AMI
インスタンスタイプ:t2.micro
キーペア名 :キーペアなしで続行

「ネットワーク設定」の横にある「編集」をクリックして、以下の設定パラメータを指定する

設定パラメータ②

VPC :Test-VPC
サブネット :パブリックサブネット-1a
パブリックIPの自動割り当て:有効化
ファイアウォール(セキュリティグループ):セキュリティグループを作成する
セキュリティグループ名:web-sg

セキュリティグループルール1
 タイプ :ssh
 プロトコル :TCP
 ポート範囲 :22
 ソースタイプ :カスタム
 ソース :0.0.0.0/0

セキュリティグループルール2
 タイプ :HTTP
 プロトコル :TCP
 ポート範囲 :80
 ソースタイプ :カスタム
 ソース :0.0.0.0/0

「高度な詳細」の「ユーザーデータ」にて以下のスクリプトを入力する

設定パラメータ③

#!/bin/bash

yum -y update
yum -y install php httpd mysql
PHP_VERSION=php -v | head -n 1 | awk '{print $2}' | awk -F "." '{print $1}'
while [ ${PHP_VERSION} -ne 7 ]
do
amazon-linux-extras install php7.4 -y
PHP_VERSION=php -v | head -n 1 | awk '{print $2}' | awk -F "." '{print $1}'
done

yum -y install php-mbstring php-xml

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

※上記設定パラメータ①〜③以外の項目についてはデフォルト値を利用します

メモ

以前先頭の「#!/bin/bash」を忘れてしまい、EC2インスタンス作成時にスクリプトが実行されなかったことがあったので、忘れずに入力しましょう‼︎

■2-3. 無事に1台目のEC2インスタンスが作成されたことを確認

3. RDSの作成

本項では、ウェブサイト(WordPress)の裏側となるデータベースとして、「RDSのDBインスタンス」を作成していきます。

なお、本項は以下のステップで作業を実施します。

  1. DBインスタンス用セキュリティグループの作成
  2. DBインスタンス用サブネットグループの作成
  3. DBインスタンス(データベース)の作成

DBインスタンス用セキュリティグループの作成

■3-1. EC2管理画面の左ペインにて「ネットワーク&セキュリティ -> セキュリティグループ」をクリック

■3-2.「セキュリティグループを作成」ボタンをクリックし、DBインスタンス用のセキュリティグループの作成を開始

■3-3.「セキュリティグループを作成」画面にて、以下の設定パラメータを指定して「セキュリティグループを作成」をクリック

設定パラメータ

セキュリティグループ名 :db-sg
VPC :Test-VPC

インバウンドルール
 タイプ :MySQL/Aurora
 プロトコル :TCP
 ポート範囲 :3306
 ソースタイプ :カスタム
 ソース :web-sg

アウトウンドルール
 タイプ :すべてのトラフィック
 プロトコル :すべて
 ポート範囲 :すべて
 ソースタイプ :カスタム
 ソース :0.0.0.0/0

※その他の部分はデフォルト

インバウンドルールの「ソース」には先ほどウェブサイト用EC2インスタンスに割り当てたセキュリティグループ(web-sg)を指定します。
これによりDBインスタンスのフロントとして稼働するウェブサイト用EC2インスタンス群からのみアクセスが可能となり安全性が高まります

DBインスタンス用サブネットグループの作成

■3-4. RDS管理画面の左ペインにて「サブネットグループ」をクリック

■3-5. 右ペインにて「DBサブネットグループを作成」ボタンをクリック

■3-6.「DBサブネットグループを作成」画面にて、以下の設定パラメータを指定して「作成」をクリック

設定パラメータ

名前 :db-subnetgroup
VPC :Test-VPC
アベイラビリティーゾーン:ap-northeast-1a,
             ap-northeast-1c
サブネット :プライベートサブネット-1a(10.0.2.0/24),
       プライベートサブネット-1c(10.0.3.0/24)

DBインスタンス(データベース)の作成

■3-7. RDS管理画面の左ペインにて「データベース」をクリック

■3-8. 右ペインにて「データベースの作成」ボタンをクリック

■3-9.「データベースの作成」画面にて、以下の設定パラメータを指定して「データベースの作成」をクリック

設定パラメータ

データベースの作成方法を選択:標準作成
エンジンのタイプ :MySQL
バージョン :MySQL8.0.28(デフォルト)
テンプレート :無料利用枠

DBインスタンス識別子 :test-rds-1
マスターユーザー名 :admin
マスターパスワード :********

コンピューティングリソース:EC2コンピューティングリソースに接続しない
Virtual Private Cloud :Test-VPC
DBサブネットグループ :db-subnetgroup
パブリックアクセス :なし
VPCセキュリティグループ:既存の選択
既存のVPCセキュリティグループ:db-sg
アベイラビリティーゾーン:ap-northeast-1a
データベース認証オプション:パスワード認証

▼追加設定
 最初のデータベース名 :wordpress
 自動バックアップを有効にします:チェックなし

※その他の部分はデフォルト

メモ

「▼追加設定」の「最初のデータベース名」の入力を忘れてしまうと、後続のWordPressからのデータベース接続作業で失敗してしまうので忘れずに入力しましょう。

■3-10. 無事にDBインスタンスが作成されたことを確認

■3-11. 対象DBインスタンスの「DB識別子(青字)」をクリック

■3-12.「接続とセキュリティ」欄に記載されている「エンドポイント」を控える
既に作成済みのWordPressとDBインスタンスとを連携する手順で後ほど使用するため、エンドポイント情報を控えておきます

エンドポイント:test-rds-1.xxxxxxxxx.ap-northeast-1.rds.amazonaws.com

4. ELBの作成

本項では、後続手順で冗長化されるEC2インスタンスへの通信を負荷分散するために「ELB」を作成していきます。

なお、本項は以下のステップで作業を実施します。

  1. ELB用セキュリティグループの作成
  2. ELB用ターゲットグループの作成
  3. ロードバランサー(ALB)の作成

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

■4-1. EC2管理画面の左ペインにて「ネットワーク&セキュリティ -> セキュリティグループ」をクリック

■4-2.「セキュリティグループを作成」ボタンをクリックし、ELB用のセキュリティグループの作成を開始

■4-3.「セキュリティグループを作成」画面にて、以下の設定パラメータを指定して「セキュリティグループを作成」をクリック

設定パラメータ

セキュリティグループ名 :elb-sg
VPC :Test-VPC

インバウンドルール
 タイプ :HTTP
 プロトコル :TCP
 ポート範囲 :80
 ソースタイプ :Anywhere-IPv4
 ソース :0.0.0.0/0

アウトウンドルール
 タイプ :すべてのトラフィック
 プロトコル :すべて
 ポート範囲 :すべて
 ソースタイプ :カスタム
 ソース :0.0.0.0/0

ELB用ターゲットグループの作成

■4-4. EC2管理画面の左ペインにて「ロードバランシング -> ターゲットグループ」をクリック

■4-5.「ターゲットグループの作成」をクリック

■4-6.「グループの詳細の設定」画面にて、以下の設定パラメータを指定して「次へ」をクリック

設定パラメータ

ターゲットタイプの選択 :インスタンス
ターゲットグループ名 :elb-targetgroup
プロトコル/ポート :HTTP/80
VPC :Test-VPC
プロトコルバージョン :HTTP1

ヘルスチェックプロトコル :HTTP
ヘルスチェックパス :/wp-includes/images/blank.gif

※その他の部分はデフォルト

■4-7.「ターゲットの登録(Register targets)」画面にて対象ターゲット(Test-EC2#1)にチェックを入れて、「保留中として以下を含める(Include as pending below)」をクリック

■4-8.「ターゲットを確認(Review targets)」欄に対象ターゲット(Test-EC2#1)が表示されていることを確認して、「ターゲットグループの作成(Create target group)」をクリック

ロードバランサー(ALB)の作成

■4-9. EC2管理画面の左ペインにて「ロードバランシング -> ロードバランサー」をクリック

■4-10.「ロードバランサーの作成」をクリック

■4-11.「ロードバランサータイプの選択」画面の「Application Load Balancer」配下にある「作成」ボタンをクリック

■4-12.「Application Load Balancerを作成」画面にて、以下の設定パラメータを指定して「ロードバランサーの作成」をクリック

設定パラメータ

ロードバランサー名 :Test-ELB
スキーム :インターネット向け
IPアドレスタイプ :IPv4

VPC :Test-VPC
マッピング
 ap-northeast-1a :チェック
  サブネット :パブリックサブネット-1a
 ap-northeast-1c :チェック
  サブネット :パブリックサブネット-1c

セキュリティグループ :elb-sg

リスナーとルーティング
 プロトコル :HTTP
 ポート :80
 デフォルトアクション(転送先):elb-targetgroup

※その他の部分はデフォルト

■4-13. 無事にELBが作成されたことを確認

■4-14. 対象ELBの「DNS名(DNS name)」を控える
EC2インスタンスへの接続で後ほど利用するので、対象ELBに設定されたDNS名を控えておきます

DNS名:test-elb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com

5. WordPressの初期設定

本項では、EC2インスタンス内で稼働しているWordPressの初期設定を実施していきます。

■5-1. WordPress(EC2インスタンス)にELB経由で接続
ブラウザで先ほど控えたELBのDNS名にHTTP接続します。

http://test-elb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com/

■5-2. WordPressの初期設定画面に接続できたことを確認し、「さあ、始めましょう!」をクリック

なお、現状EC2インスタンスは1台のみなので、ELB(Test-ELB)を経由してTest-EC2#1に接続されている状態となります。

■5-3. 下記設定画面にて各パラメータを入力し、「送信」ボタンをクリック

設定パラメータ

データベース名 :wordpress
ユーザー名 :admin
パスワード :手順3-9で設定した「マスターパスワード」を入力
データベースのホスト名:手順3-12で確認したRDSの「エンドポイント」を入力
テーブル接頭辞 :wp_

■5-3. 下記画面にて「インストール実行」をクリック

■5-4.「ようこそ」画面にて、各パラメータを入力して「WordPressをインストール」ボタンをクリック

設定パラメータ

サイトのタイトル :はじめてのAWS
ユーザー名 :admin
パスワード :********
メールアドレス :適当なメールアドレスを入力
検索エンジンでの表示:チェックあり

ポイント

ユーザー名やパスワードが複数登場してややこしいですが、ここで設定しているのはWordPress管理用の情報になります。
例えば「WordPressでブログを更新する」などの作業時に必要なログイン情報です。

■5-5. WordPressのインストールが無事に完了したことを確認し、「ログイン」をクリック

■5-6. 手順5-4で設定したユーザー情報を入力し、WordPressの管理画面にログインする

■5-7. ログインが完了し「WordPressへようこそ!」画面が表示されたことを確認

6. AMIの作成

本項では、Webサーバ冗長化の準備として「AMI」を作成していきます。

■6-1. EC2管理画面の左ペインより「インスタンス」をクリック

■6-2. AMIの土台となる対象インスタンス(Test-EC2#1)にチェックを入れて以下を実施する
1.「アクション」をクリック
2.「イメージとテンプレート」をクリック
3.「イメージを作成」をクリック

■6-3.「イメージを作成」画面にて、以下の設定パラメータを指定して「イメージを作成」をクリック

設定パラメータ

イメージ名 :Test-AMI-WordPress
再起動しない :チェックなし

※その他の部分はデフォルト

ポイント

「再起動しない」はAMIの作成時に対象のEC2インスタンで再起動が発生するかどうかを決める項目。
本番環境など「再起動しては困る」というようなケースではチェックを入れたりする。

■6-4. 無事にAMIが作成されたことを確認

■6-5. 作成したAMIの「ストレージ」タブを選択し、対象インスタンス(Test-EC2#1)のEBSスナップショットが取得できていることを確認

7. 作成したAMIからのEC2インスタンスの作成

本項では、前項で作成したAMIから2台目の「EC2インスタンス」を作成します。

■7-1. 対象AMIを選択した状態で「AMIからインスタンスを起動」ボタンをクリック

■7-2.「インスタンスを起動」画面にて、以下の設定パラメータ①〜②を指定して「インスタンスを起動」をクリック

設定パラメータ①

名前 :Test-EC2#2
AMI :Test-AMI-WordPress
インスタンスタイプ:t2.micro
キーペア :キーペアなしで続行

「ネットワーク設定」の横にある「編集」をクリックして、以下の設定パラメータを指定する

設定パラメータ②

VPC :Test-VPC
サブネット :パブリックサブネット-1c
パブリックIPの自動割り当て:有効化
ファイアウォール(セキュリティグループ):既存のセキュリティグループを選択する
共通のセキュリティグループ:web-sg

※その他の部分はデフォルト

ポイント

1台目の作成時には「ユーザーデータ」を利用してWordPressの導入を実施しましたが、今回は既にWordPress導入済みのAMIを利用しているため不要。

■7-3. 無事に2台目のEC2インスタンスが作成されたことを確認

■7-4.「ストレージ」タブを選択し、「ボリュームID(青字)」をクリック

■7-5.「詳細」欄に表示されている「スナップショット」のスナップショットIDが手順6-5で確認したEBSのスナップショットと一致していることを確認

▲手順6-5で確認した内容

8. EC2インスタンスの冗長化設定

本項では、先ほど作成した2台目のEC2インスタンスを「ELBのターゲットグループ」に登録してきます。

■8-1. EC2管理画面の左ペインにて「ロードバランシング -> ターゲットグループ」をクリック

■8-2. 対象ターゲットグループ(elb-targetgroup)にチェックを入れる

■8-3.「ターゲット(Targets)」タブにて「ターゲットの登録(Register targets)」ボタンをクリック

■8-4.「ターゲットの登録(Register targets)」画面にて対象ターゲット(Test-EC2#2)にチェックを入れて、「保留中として以下を含める(Include as pending below)」をクリック

■8-5.「ターゲットを確認(Review targets)」欄に対象ターゲット(Test-EC2#2)が表示されていることを確認して、「ターゲットグループの作成(Register pending targets)」をクリック

■8-6. 2台目のEC2インスタンスもターゲットグループに登録されたことを確認

9. RDSのマルチAZ化

本項では、RDSのマルチAZ設定として「スレーブDBインスタンス」を作成していきます。

■9-1. RDS管理画面の左ペインにて「データベース」をクリック

■9-2. 右ペインにて、対象DBインスタンスを選択して「変更」ボタンをクリック

■9-3.「DBインスタンスを変更」画面の「可用性と耐久性」にて、以下の変更をして「続行」をクリック

設定パラメータ

マルチAZ配置
 変更前:スタンバイインスタンスを作成しないでください
 変更後:スタンバイインスタンスを作成する(本番稼働環境向けに推奨)

※その他の部分はデフォルト

■9-4. 以下を実行して、「DBインスタンスを変更」をクリック
1.「変更サマリー」の「New value」が「あり」になっていることを確認
2.「変更のスケジューリング」にて「すぐに適用」を選択

■9-5. 対象DBインスタンスのステータスが「変更中」から「利用可能」になったことを確認し、「DB識別子(青字)」をクリック

■9-6.「設定」タブの「マルチAZ」欄が「あり」になっていることを確認

10. 構築した環境での可用性確認

本項では、EC2インスタンスおよびRDSの冗長化設定が正常に機能するかを確認します。

なお、本項は以下のステップで作業を実施します。

  1. アプリケーション層(EC2)の可用性確認
  2. データベース層(RDS)の可用性確認

アプリケーション層(EC2)の可用性確認

■10-1. ELB経由でEC2インスタンス群(2/2台稼働)に接続

http://test-elb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com/

下記画像のように、正常にサンプルページが表示されることを確認します。

■10-2. EC2管理画面より1台のEC2インスタンスを停止

■10-3. 改めてELB経由でEC2インスタンス群(1/2台稼働)に接続

http://test-elb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com/

正常にサンプルページが表示されることを確認します。

■10-4. EC2管理画面より停止したEC2インスタンスを起動

データベース層(RDS)の可用性確認

■10-5. RDS管理画面の左ペインにて「データベース」をクリック

■10-6.「アクション -> 再起動」をクリックしてDBインスタンスを再起動する

■10-7.「DBインスタンスの再起動」画面にて「フェイルオーバーで再起動しますか?」にチェックを入れて、「確認」をクリック

■10-8. DBインスタンスの再起動が開始され、ステータスが「再起動中」になっていることを確認

■10-9. ELB経由でWordPressに接続

http://test-elb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com/

正常にサンプルページが表示されることを確認します。

ポイント

内部的にはDBインスタンスのフェイルオーバーが実施されているため、タイミングによっては「504 Gateway Timeout」が表示されることがあります。

11. リソースの終了

作成したAWSリソースを削除して、本ハンズオンは終了となりました。

削除対象リソース

1. RDS
 ・データベース
 ・サブネットグループ

2. EC2
 ・インスタンス
 ・AMI
 ・EBSスナップショット
 ・ロードバランサー
 ・ターゲットグループ

3. VPC
 ・全関連リソース ※VPCの削除で自動的に削除される

調べたこと

ここからは僕が作業中に疑問に思ったことや調べた内容について、備忘録的に書いていこうと思います。
超初歩的な内容もあるかもしれませんがご了承ください・・・。

1. VPC関連

本項では、VPC関連で生じた疑問を整理していきます。

1-1. VPC作成時の選択項目「テナンシー」とは?

VPCの作成で指定するパラメータの中に「テナンシー」というものがあり、次のどちらかを選択できます。
・デフォルト
・専有
ハンズオンでは「デフォルト」を選択していました。
しかし、正直なところこれがどのような設定なのか分かっていませんでした。

調べてみると、どうやらこのVPCで稼働するEC2インスタンスのデフォルトのテナンシーであることが分かりました。
つまりEC2インスタンスを以下どちらの方法で稼働させるかのデフォルトを決めるもの。
・共有ハードウェアで稼働させる
・専有ハードウェアで稼働させる

VPC側のテナンシー設定「デフォルト」を選択すれば前者、「専有」を選択すれば後者がEC2インスタンスのテナンシー設定でのデフォルトということになるのだと思います。

1-2. VPC作成時の選択項目「DNSオプション」とは?

テナンシーと同様に、ハンズオンをしている時にはあまりイメージができませんでしたが、それぞれ以下の内容であることが分かりました。

  1. DNSホスト名を有効化
    ・VPCがパブリックIPアドレスを持つインスタンスへのパブリックDNSホスト名の割り当てをサポートするかどうかを決定する
    ・VPCがデフォルトVPCでない場合、この属性のフォルト値は「無効」となっている
  2. DNS解決を有効化
    ・ VPCがAmazon提供のDNSサーバを介したDNS名前解決をサポートするかどうかを決定する
     この項目を「有効」にした場合、Amazon提供のDNSサーバへのクエリは成功する

参考:VPCのDNS属性

1-3. Amazon Provided DNS(Amazon Route 53 Resolver)について

上記「DNSオプション」を調べている最中に「Amazon Provided DNS」という言葉が出てきたのですが、正直「何者?」という状態でした。

調べてみると次のような役割があることが分かりました。
・VPCのインターネットゲートウェイを介した通信を必要とするインスタンスでのDNS名前解決に利用される
・VPCで利用する特定のDNSサーバを指定していない場合にはデフォルトで利用される

このようなDNSを作成した覚えはありませんでしたが、どうやらVPC毎に自動的に作成されるようです。
DNSサーバ自身に割り当てられるIPアドレスは、VPCのプライマリCIDRブロックの第4オクテッドに2を加えたIPアドレスとのこと。
例えばVPCで「10.0.0.0/16」を設定している場合、DNSサーバには「10.0.0.2」が割り当てられるという解釈で良さそうです。

参考:VPCのDNS属性
参考:Amazon Provided DNS (Amazon Route 53 Resolver) とは

2. EC2関連

本項では、EC2関連で生じた疑問を整理していきます。

2-1. EC2の「インスタンスに接続」機能の「EC2 Instance Connect」とは?

ハンズオンで「EC2 Instance Connect」という機能を利用してEC2インスタンス内部に接続するという作業を行いました。
しかし、ハンズオンでは接続しただけで終わってしまい仕組みなどのイメージもあまりできなかったので、もう少し深掘りしてみようと思います。

「インスタンスに接続」で選択できる項目としては次のようなものがありました。

インスタンスに接続

  1. SSHクライアント
  2. EC2 Instatnce Connect
  3. AWS Systems Manager Session Manager
  4. EC2 シリアルコンソール

ハンズオンでは、この中の「2. EC2 Instatnce Connect」を利用してEC2インスタンスに接続したわけですね。
ただ「EC2 Instatnce Connect」においても、さらに以下のような分類があるみたいです。

EC2 Instance Connect

  1. Amazon EC2コンソール
  2. Amazon EC2 Instance Connect CLI
  3. 任意のSSHクライアント接続

これらを総称して「EC2 Instance Connect」と呼んでいることが分かりました。

EC2 Instance Connectの公式説明として以下の内容を確認できました。

Amazon EC2 Instance Connect は、Secure Shell (SSH) を使用して Linux インスタンスに接続するシンプルで安全な方法を提供します。
EC2 Instance Connect では、AWS Identity and Access Management (IAM) ポリシーおよびプリンシパルを使用して、インスタンスへの SSH によるアクセスをコントロールします。
SSH キーを共有および管理する必要はありません。
EC2 Instance Connect を使用したすべての接続リクエストは、AWS CloudTrail にログとして記録されるため、接続リクエストを監査できます。

IAMなどが登場してきましたが、実際の接続はどのようにされているのか。
調べた内容を整理すると、以下のような流れではないかと考えられます。

  1. EC2 Instance Connectを使用してインスタンスに接続要求
  2. Instance Connect APIから1回限定のSSHパブリックキーがインスタンスメタデータにプッシュされる(60秒間保持)
  3. IAMユーザにアタッチされたIAMポリシーにより、IAMユーザはパブリックキーをインスタンスメタデータにプッシュすることを許可される
  4. SSHデーモンはEC2 Instance Connectのインストール時に設定される「AuthorizedKeysCommand」および「AuthorizedKeyCommandUser」によりインスタンスメタデータからパブリックキーを見つけて認証を行い、ユーザをインスタンスに接続

参考:EC2 Instance Connect を使用した Linux インスタンスへの接続

ちなみに、EC2 Instance Connectを利用するためにはインスタンス内に「ec2-instance-connect」というパッケージをインストールするなどのセットアップ作業が必要であることが分かりました。

以下のAMIを利用した場合にはデフォルトでインストール済みのようです。
・Amazon Linux 2 2.0.20190618以降
・Ubuntu 20.04以降
今回のハンズオンでは最新の「Amazon Linux 2」を利用しており、既にインストール済みであったことからそれほど意識することなくEC2 Instance Connectが利用できたんですね。

参考:EC2 Instance Connect セットアップ

念のため、最新のAmazon Linux 2のAMIで作成したばかりのEC2インスタンスでインストール済みパッケージを確認したら「ec2-instance-connect」が存在していることが確認できました。

2-2. DNS名について

EC2インスタンスに割り当てられるDNS名について、その用途や内容をあまりイメージできなかったので少しだけ調べました。

メモ

■プライベートIP DNS名(IPv4専用)
同じVPC内のインスタンス間の通信に使用

■パブリックIPv4 DNS
Amazon DNSサーバがパブリックDNSホスト名を解決すると、(インスタンスのネットワークの外部の場合)インスタンスのパブリックIPv4アドレスおよび(インスタンスのネットワーク内からの場合) インスタンスのプライベートIPv4アドレス となる
次のような書式となっている
・us-east-1リージョンの場合 :ec2-<public-ipv4-address>.compute-1.amazonaws.com
・その他のリージョンの場合 :ec2-<public-ipv4-address>.<region>.compute.amazonaws.com

参考:VPCのDNS属性

2-3. AMI作成の裏側について

今回のハンズオンで、WordPressをセットアップしたEC2インスタンスからAMIを作成し、そのAMIから2台目のEC2インスタンスを作成するという作業を実施しました。

しかし、リソース終了作業の中で「AMIに関連したEBSスナップショットの削除」がありましたが、「なぜにEBSスナップショットが登場する?」という状態でした。
つまりAMIについての理解が浅かったのです。
なので、改めてその内容を整理していこうと思います。

AMIは「Amazon Machine Image」の略で、インスタンスの起動に必要な情報がまとまっている起動テンプレートのこと。
次のような情報を持っています。

AMIが持つ主な情報

・OS情報
・ミドルウェア情報
・ルートデバイスのストレージ情報
・起動許可設定情報

EBSスナップショットは、AMI作成時に選択したEC2インスタンスにアタッチされているEBSのデータを保存するために取得されているのだと理解しました。
これがあることでAMIから作成したEC2インスタンスは最初から同じデータを持った状態で起動できるということなんですね。

しかし、EBSスナップショットだけではEC2インスタンス作成のための情報としては不足しており、上記すべてが揃って初めてAMIからのEC2インスタンス作成が可能になるというわけですね。

参考:【AWS初学者向け・図解】AMIとは?現役エンジニアがわかりやすく解説

3. RDS関連

本項では、RDS関連で生じた疑問を整理していきます。

3-1. データベースのエンドポイントとは?

WordPressの初期設定時にRDSのエンドポイントを指定してデータベースに接続しました。
しかし「実際このエンドポイントは何者か?」という疑問がありました。

データベースのエンドポイントとは、RDSのDBインスタンスを起動した際に自動的に発行される専用のDNS名のことです。
ユーザやアプリケーションは、このエンドポイントを経由してRDSを利用する形となっているということが分かりました。
今回の場合だと、WordPress(アプリケーション)をインストールしたEC2インスタンスからエンドポイントを経由してバックエンドのデータベース(RDS)に接続したということですね。
参考:[5]RDSのつまずきポイント、DBサーバーと思うと失敗する

また、RDSでマルチAZ化した際には、特にエンドポイントを複数WordPressに紐付けるということはしませんでした。
そのため「各DBインスタンスとエンドポイントはどのような形で紐づいているのか?」という部分も気になりました。

ハンズオンではほとんど意識することはありませんでしたが、どうやらマスターおよびスレーブのDBインスタンスにはそれぞれIPアドレスが設定されており、エンドポイントにはマスターDBインスタンスのIPアドレスが紐付けられているという状態であることが分かりました。
通常時であればエンドポイントに接続するとマスター側に通信が流れることになります。

マスター側に障害が発生した場合、エンドポイントとマスターIPアドレスの紐付けが解除され、新たにスレーブIPアドレスが自動的に紐付けられるという動作になっているみたいです。
これにより、RDSのフェイルオーバが成立しているんですね。

3-2. DBサブネットグループとは?

今回、DBインスタンス作成前に事前にDBサブネットグループを作成しました。
しかし、このDBサブネットグループの役割がいまいち理解できていませんでした。

DBサブネットグループとは、RDSのDBインスタンスが配置される可能性のあるVPCサブネット群をグループ化したもののこと。
そして、DBサブネットグループには特定のAWSリージョン内の「少なくとも2つのAZ上のサブネット」を指定する必要があることが分かりました。
DBインスタンス作成時にはDBサブネットグループを指定する必要があり、指定したDBサブネットグループに含まれるサブネット上にDBインスタンスが作成されるという流れのようです。

なお、上述の「3-1. データベースのエンドポイントとは?」で各DBインスタンスにはIPアドレスが割り当てられているということに触れましたが、このIPアドレスはDBインスタンスが作成されたサブネットに設定されているネットワーク内で割り当てられるとのこと。
たとえば、「10.0.2.0/24」のサブネットであればその中の1つがDBインスタンスに割り当てられるということですね。

参考:VPC 内の DB インスタンスの使用
参考:RDSってなんでAZ(Availability Zone)を指定する項目がふたつあるの?

よくよく確認してみると、DBサブネットグループの選択時にも以下の画像のように説明が施されていました。

DBサブネットグループは、選択したVPCでDBクラスターが使用できるサブネットとIP範囲を定義します。

各DBインスタンスにIPアドレスが割り当てられているので、それぞれに個別で接続することは可能と思われます。
しかし、公式情報ではデータベースへの接続に関してはIPアドレスではなくDNS名(エンドポイント)を利用することが強く推奨されていました。
これは、既に触れた通り「エンドポイントと各DBインスタンスのIPアドレスの紐付け」が関与しています。
仮にアプリケーションからIPアドレスでデータベースに接続していた場合、そのIPアドレスを保有するDBインスタンスで障害が発生すればデータベースに接続できなくなってしまいます。

一方で、エンドポイントで接続していれば自動的にスレーブIPアドレスへと接続先が切り替わるので、継続してデータベースへの接続が可能になるというメリットがあります。
そういう意味で「エンドポイントの利用が推奨」ということだと理解しました。

参考:DB サブネットグループの概要とそれが必要な理由は何ですか?

3-3. マルチAZへの設定変更はなぜ長い?

ハンズオンにてDBインスタンスのマルチAZ化を実施しましたが、その時に感じたのは「なかなか完了しないな・・・」ということ。
調べてみると、どうやら次のような処理が行われているということが分かりました。

マルチAZ化時の内部処理

1. プライマリインスタンスのスナップショット作成
2. 取得したスナップショットから別のAZに新しいスタンバイインスタンスを作成
3. 同期レプリケーション関係をプライマリインスタンス/スタンバイインスタンス(スレーブ)間で確立

よくよく考えてみれば、1台目のDBインスタンスを作成する時もそれなりに時間がかかっていましたし、加えて上記のようにスナップショット取得なども実施しているのであれば時間がかかるのも仕方ないのかと納得しました。

また、スタンバイインスタンスが完成するまでのプライマリインスタンスへの影響ですが、両インスタンス間のデータが一致するまでの間はレイテンシが増加する可能性があることが分かりました。
スタンバイインスタンス作成中もプライマリインスタンスのデータが更新されている場合、なかなか両インスタンス間での同期も完了しない可能性があり、その結果レイテンシが増加してしまうというのもなんとなくイメージができました。

参考:Amazon RDS インスタンスをシングル AZ からマルチ AZ に変換するとどうなりますか?

3-4. マルチAZ化しているのにタイムアウトしたのはなぜ?

ハンズオンの中で、冗長構成の動作確認としてあえてDBインスタンスを再起動した状態での接続を行いました。
実施前は「マルチAZ化してるから継続してWordPressのサンプルページは見れるだろう」と思っていました。
しかし、何度か画面をリフレッシュしていると「504 Gateway Time-out」の文字列が。
数秒後には正常に接続できるようになったのですが、純粋に「なんでだろう?」と思いました。

後々調べてみると、マルチAZの状態であってもフェイルオーバ時には数秒のダウンタイムは生じることが分かりました。
これは先の「エンドポイントとIPアドレス紐付けの切り替え」などが内部で行われているからということだと思います。
公式的にも「ダウンタイムは発生するもの」と確認できたので、ひとまずは納得しました。
本番環境で実施するようなケースではメンテナンス期間を設けるなどの対応が必要になってくるという感じなんですかね。

参考:RDSのメンテナンスでフェイルオーバーした時にやった手順【ダウンタイムを気にする場合など】
参考:必要な Amazon RDS メンテナンスの実行時におけるダウンタイムを最小限に抑えるにはどうすればよいですか?

3-5. 現在稼働中のDBインスタンスはどれ?

「マルチAZ化しているけど、現在利用中のDBインスタンスはどれなんだろう」と疑問に思いました。
これについては、データベース管理画面の「リージョンとAZ」に表示されるアベイラビリティーゾーンを確認するのが良さそうですね。

DBサブネットグループで複数のAZを選択していることもあり、フェイルオーバ時には現在稼働していたAZとは異なるAZのDBインスタンスが利用されるようになることもあります。
そのタイミングで「リージョンとAZ」に表示される内容も更新されるので「今〇〇のAZのDBインスタンスを利用しているのか」と判断できます。

参考:Amazon RDS for MySQL のハードウェアメンテナンスの際に、ダウンタイムやフェールオーバーが発生するかを教えてください

4. ELB関連

本項では、ELB関連で生じた疑問を整理していきます。

4-1. ターゲットグループとは?

ハンズオンでは、ELB作成前にターゲットグループを作成していましたが、この「ターゲットグループ」とは何者なのか。
調べてみると、ターゲットグループはトラフィックを分散する複数のターゲットを含んだグループのことで、ターゲットには以下のようなものが選択可能となっていることが分かりました。

ターゲットとして選択可能な主なリソース

・EC2インスタンス
・コンテナ
・IPアドレス
・Lambda関数
・仮想アプライアンス

ハンズオンでは「EC2インスタンス」をターゲットとして選択していました。

また、今回ELBとしては「Application Load Balancer(ALB)」を選択しましたが、ターゲットグループにターゲットを登録することでトラフィックがルーティングされるようです。

4-2. ターゲットグループで複数AZを登録しているのにELB作成時にもAZを指定する理由は?

ハンズオンでは「ターゲットグループの作成 → ロードバランサーの作成」という順番で実施していました。
先にターゲットグループで複数のAZを登録し、ロードバランサーの作成時にはそのターゲットグループを指定するという流れ。
「指定したターゲットグループ内のリソースに対しては負荷分散が可能」という状態は整っていると思っていたのですが、ロードバランサー作成の項目の中でネットワークマッピングとしてAZを指定する項目があるのが気になりました。

調べてみると、どうやらELB(ロードバランサー)自身にAZを登録しておかないとそもそもそのAZ内にあるターゲットに対してはルーティングがされないということが分かりました。

おそらくですが次のような感じであると認識しました。

  1. ネットワークマッピング:ELBが負荷分散できるAZをどこにする
  2. ターゲットグループ:実際に負荷分散をするAZはどこにするか

ネットワークマッピングに含まれていないAZに関しては、ターゲットグループに含まれていも負荷分散ができない状態になるのかなと思いました。
逆にネットワークマッピングに含まれていてもターゲットグループに含まれていない場合はそのAZのリソースには負荷分散はしないのかなと思います。
つまり「できない」と「しない」の違いがありそうです。

おわりに

いかがだったでしょうか。

今回はスケーラブルウェブサイトの構築についての内容でした。
とても基礎的な構成でしたが、あらゆるアーキテクチャの土台にもなるような構成だと思うので、非常に勉強になりました。

「エンドポイント」や「DNS名」など自動的に設定されるが故にイメージしにくいものもありましたが、スケーラブルなウェブサイトが成り立っているのだなと実感しました。

疑問事項もたくさんありましたが、その都度調べて少しずつスキルに繋げていけたらなと思います。

本記事を最後まで読んでいただき、ありがとうございました。
ではでは!

-AWS
-,