久々に AWS の設定を行う
このスクラップについて
このスクラップでは久々に AWS で EC2 インスタンスを使って WordPress を構築する過程を記録していく。
AWS Organizations を使うか否か
今回は使わない。
理由は色々とあるが将来的にアカウントごと移譲する可能性があるため。
リザーブドインスタンスをシェアできるなどメリットもあるが落とし穴もありそうなので新規にアカウントを作成していく。
メールアドレスの作成
新規アカウント用にメールアドレスを作成する。
エイリアスを使うとお金がかからない。
名前には顧客やプロジェクト名を使えば良いだろう。
アカウント作成
下記 URL にアクセスする。
新しい AWS アカウントを作成するボタンを押す
作成したメールアドレスと適当なアカウント名を入力する
メールで認証コードが届くので入力する、数字 6 桁で有効期限は 10 分。
成功するとルートユーザーパスワードの設定に進む
パスワード
パスワード生成器を使って作成する。
この辺りから認証情報のメモを作成していった方が良さそう。
このパスワードは好きな記号を含めても良さそう。
長さは 16 くらいで良いかなと思ったけど 22 がデフォルトなのでそのままにしておこう。
連絡先情報
住所や電話番号を入力する。
請求代行する場合は自分の会社の住所を入力した方が良さそう。
続いてクレジットカード
このページも特に難しいことはない。
本人確認
音声だと英語っぽいので SMS の方が良さそう。
サポートプラン
無料のベーシックサポートを選択する。
いつかエンタープライズサポートプランを使ってみたい。
アカウント作成が完了
長い道のりだった。
あとはログインすれば Web コンソールが表示される。
ここからが本番だ。
何をやるか箇条書きする
- EC2 インスタンスを起動 → 完了
- セキュリティ・グループの設定 → 完了
- Elastic IP を作成 → 完了
- SSH アクセスできるようにする → 完了
- PHP や WordPress をインストールする → 完了
- MariaDB をインストールして DB 作成 → 完了
- Amazon SES メールアドレス検証 + SMTP 設定 → 完了
- WordPress SMTP 設定 → 完了
- EC2 メール送信の申請 → 構築後に本稼働リクエスト
- IAM ロール設定 → 完了
- S3 バックアップ → 完了
- リザーブドインスタンス購入
- CloudWatch アラーム → 完了
- 毎朝再起動 → 完了
- FTP 接続 → 完了
- php.ini 設定 → 完了
PHP のバージョンなどについては下記がよくまとまっていた。
作業時間
ここまでで 37 分、記録がなければ 10 分くらいで終わるだろう。
とりあえず EC2 起動
ページ左の「インスタンス」をクリックする。
ページ上の「インスタンスを起動」ボタンをクリックする。
フォームに入力していく。
名前などをどうするか
とりあえず「WordPress」としておこう。
OS イメージは「Amazon Linux」にしよう。
インスタンスタイプは「t3.small」にする、これは後から変更できないこともないけど大変みたいなのでよく確認する。
キーペアはサインアップ直後はないので新しいキーペアを作成する。
ED25519 の方がセキュアな感じがするのでそうしとこう。
ダウンロードしたら .ssh に入れてパーミッションを変更する。
cp ~/Downloads/secret.pem ~/.ssh
chmod 400 ~/.ssh/secret.pem
セキュリティグループ
SSH, HTTP, HTTPS くらいを許可すれば良いだろうと思ったら簡単にできるようだ、すごいな。
すべてにチェックを入れる。
SSH は固定 IP を持っているのであれば指定しておきたいところ。
ちなみに既存のセキュリティグループは全てのトラフィックを受け入れるので設定しない方が良さそう。
ストレージの設定
サイズを 100 GiB、終了時に削除を「いいえ」にする。
アドバンストとシンプルがあり、アドバンストにすると細かい設定が可能。
高度な設定
とりあえずデフォルトのままにしておく。
インスタンス起動
最後に「インスタンスを起動」ボタンを押す。
ようやくインスタンスを起動できる。
その下のコマンドを確認を押すと控えの JSON データが手に入るので便利。
{
"MaxCount": 1,
"MinCount": 1,
"ImageId": "ami-0a2e10c1b874595a1",
"InstanceType": "t2.micro",
"KeyName": "xxxx",
"EbsOptimized": false,
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"Encrypted": false,
"DeleteOnTermination": false,
"Iops": 3000,
"SnapshotId": "snap-0296c4bd17a888d11",
"VolumeSize": 100,
"VolumeType": "gp3",
"Throughput": 125
}
}
],
"NetworkInterfaces": [
{
"AssociatePublicIpAddress": true,
"DeviceIndex": 0,
"Groups": [
"<groupId of the new security group created below>"
]
}
],
"TagSpecifications": [
{
"ResourceType": "instance",
"Tags": [
{
"Key": "Name",
"Value": "WordPress"
}
]
}
],
"PrivateDnsNameOptions": {
"HostnameType": "ip-name",
"EnableResourceNameDnsARecord": true,
"EnableResourceNameDnsAAAARecord": false
}
}
{
"GroupName": "launch-wizard-1",
"Description": "launch-wizard-1 created 2023-09-15T08:39:14.400Z",
"VpcId": "vpc-0acb0bc7e7d21ae65"
}
{
"GroupId": "<groupId of the security group created above>",
"IpPermissions": [
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"IpProtocol": "tcp",
"FromPort": 443,
"ToPort": 443,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
]
},
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
]
}
]
}
インスタンス起動の完了
無事に起動してよかった。
t2 → t3 インスタンス変更
Elastic IP
再起動で IP アドレスが変わると面倒なので固定しておこう。
Elatic IP 一覧ページでは右上の「Elastic IP アドレスを割り当てる」ボタンをクリックする。
今更だけどデフォルトリージョンが東京で良かった、今度する時はしっかり確認しよう。
特に設定は変える必要はない。
ページの最後の方にある「割り当て」ボタンを押す。
無事に IPv4 アドレスを取得することができた。
取得したら関連付けを忘れない。
マスクするところが多くて大変だ。
関連付けが終わると Elastic IP アドレスでインスタンスにアクセスできるようになる。
SSH 設定
Host xxxx
User ec2-user
HostName 1.2.3.4
Port 22
IdentityFile ~/.ssh/secret.pem
設定したら下記コマンドで確認してみる。
ssh xxxx
初回は下記のメッセージが表示されるので yes と入力する。
The authenticity of host '52.197.109.189 (52.197.109.189)' can't be established.
ED25519 key fingerprint is SHA256:lvs1Wt0J+QHdKJzo/PSwMTL0q2+bMTpHwdoV+PIfxQ8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
無事にログインできると素敵なアスキーアートが表示される。
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
ここまでの作業時間
今のところ順調だ。
40 分かかった、37 分と足すと 77 分、結構だな。
手順が決まってればここまで 20 分くらいで終わるだろう。
HTTP サーバー設定
スクリーンショットに疲れたのでしばらくサーバー設定をしよう。
まずは HTTP サーバーをインストールする。
# HTTP サーバーをインストールします。
sudo yum install -y httpd
# サーバーを起動します。
sudo systemctl start httpd
# 自動起動の設定を確認します。
sudo systemctl is-enabled httpd
# 自動起動を有効にします。
sudo systemctl enable httpd
# もう一度、自動起動の設定を確認します。
sudo systemctl is-enabled httpd
MySQL サーバー
今は MariaDB か。
Amazon Linux 2 の情報が出てきたが amazon-linux-extras
コマンドを使えない。
そんな時は下記のコマンドを使うと探すことができた。
sudo yum list | grep mariadb
下記がインストールコマンドになる。
sudo yum install -y mariadb105-server
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo mysql_secure_installation
mysql_secure_installation では基本 yes で良さそう。
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.
You already have your root account protected, so you can safely answer 'n'.
Switch to unix_socket authentication [Y/n]
Enabled successfully!
Reloading privilege tables..
... Success!
You already have your root account protected, so you can safely answer 'n'.
Change the root password? [Y/n]
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n]
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n]
... Success!
By default, MariaDB comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n]
- Dropping test database...
... Success!
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n]
... Success!
Cleaning up...
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
設定したパスワードで mysql -u root -p
でログインできれば OK です。
ここまで
追加で 28 分かかった、合計 105 分、ついに 100 分を超えた。
PHP インストール
バージョンは 8.1 か 8.2 が選べるようだ。
悩ましいがまずは最新バージョンの 8.2 にしておこう。
sudo yum install -y php8.2 php8.2-gd php8.2-mbstring php8.2-mysqlnd php8.2-pdo
ユーザー名とグループ名
HTTP サーバーのユーザー名はグループ名はいずれも apache であることが /etc/httpd/conf/httpd.conf を読んでわかった。
AllowOverride
/etc/httpd/conf/httpd.conf を編集する。
Directory "/var/www/html" の AllowOverride を All にする。
コマンドは下記の通り。
sudoedit /etc/httpd/conf/httpd.conf
# or
sudo vi /etc/httpd/conf/httpd.conf
多分これだけで OK のはず。
sudo systemctl start httpd
WordPress のインストール
英語版と日本語版があるけど素直に日本語版をインストールしておこう。
# ホームディレクトリに戻ります。
cd
# zip ファイルをダウンロードします。
curl -O https://ja.wordpress.org/latest-ja.zip
# zip ファイルを展開します。
unzip latest-ja.zip
# ディレクトリを移動します。
sudo mv wordpress /var/www/html/
# パーミッションを設定します。
sudo chown -R apache:apache /var/www/html/wordpress
/var/www/ か /var/www/html/ か悩ましいけど後者にしておこう。
これで IP アドレス + /wordpress にアクセスするとアクセスできる。
この前に色々とやることがある。
httpd 設定
/wordpress ではなく / でアクセスできるようにしたい。
そのためには /etc/httpd/conf/httpd.conf を編集する。
DocumentRoot を "/var/www/html/wordpress" にすれば良い。
設定を変更したらリロードを忘れない。
sudo systemctl reload httpd
これで IP アドレスだけで設定画面が表示されるようになった。
データベース作成
mysql -u root -p
# パスワードを入力する。
create database wordpress_db charset utf8mb4;
create user wordpress_user@localhost identified by 'xxxx';
grant all privileges on wordpress_db.* to wordpress_user@localhost;
xxxx の部分にはパスワードを生成して入力する。
WordPress セットアップ
今ほど作成したデータベース情報を入力していく。
ホスト名や接頭辞はそのままで良いだろう。
心の準備ができたら「インストール実行」ボタンを押す。
検索エンジンでの表示(をしない)にはとりあえずチェックを入れておこう。
無事に完了できて良かった。
ここまでの作業時間
追加で 38 分かかった、合計 143 分になった。
一応 WordPress の確認
IP アドレスでアクセスした場合
ログインした場合
メール設定
この辺りが参考になりそう。
メール設定
30 分くらいあるので試してみよう。
まずはメールアドレスの認証
検証済み ID をクリックする。
本稼働アクセスのリクエストも必要そうだな。
ID の作成ボタンをクリックする。
ID タイプとして E メールアドレスを選択する。
検証メールが届くので URL にアクセスする。
検証に成功した場合のページ
本稼働アクセスのリクエスト
アカウントダッシュボードで「本稼働アクセスのリクエスト」ボタンをクリックする。
再掲
リクエストページ
メールタイプはお問い合わせフォームなどの確認メールの場合はトランザクションで良いだろう。
ウェブサイトの URL は悩ましいがとりあえず http:// + EC2 インスタンスの IP アドレスにしておこう。
ユースケースの説明は下記のようにしておこう。
Web サイトに設置したお問い合わせフォームから確認メールを送信するために Amazon SES を利用します。
連絡する際の希望言語は Japanese にしてこう。
最後に同意にチェックを入れたら「リクエストの送信」ボタンをクリックする。
リクエストの送信完了
SMTP 設定
SMTP 設定ページから始めていく。
「SMTP 認証情報の作成ボタン」をクリックする。
特に内容は変更せずにそのまま作成する。
認証情報は再表示できないのでしっかり控えておく。
ホスト名などはどうするのかと思ったらしっかり表示されて親切だ。
ここまでの作業時間
20 分なので合計 163 分になった。
再開したら WordPress 側の設定を行おう。
本稼働リクエストはダメだった
やはり準備が整ってからではないといけないのか。
WordPress 側の SMTP 設定
ここからは WordPress での作業になる。
新規追加ボタンを押してから SMTP で検索する。
WP Mail SMTP の今すぐインストール → 有効化
ウィザードが表示された。
その他の SMTP を選ぶ。
先ほど控えた SMTP 情報を入力していく。
送信元メールアドレスの強制使用については悩ましいけど ON のままにしておいた方が良さそう。
とりあえずデフォルトのままで次へ進む。
申し訳ないがメールアドレスは消して、その代わり協力はしよう。
このページはスキップする。
テストメールが送信できなかったようだ。
メールボックスを見たら問題なくメールは来ていた。
SPF 設定などで成功判定にはらならなかったようだ。
余計なプラグインが増えた
All in One SEO と WPForms Lite は削除しておこう。
ここまで 22 分くらい
合計 185 分になった。
次は IAM ロールを作成して EC2 インスタンスに設定しよう。
そしたら wp-content と mysqldump をバックアップできるようにしよう。
自動再起動
とりあえず cron でやってみようと思っていたがせっかくなのでやってみようかな。
S3 バックアップを設定する
自動再起動の前に S3 バックアップを設定してみよう。
S3 バケット作成
「バケットを作成」ボタンを押す。
バケット名を入力して後はデフォルトのままで大丈夫。
無事にバケットが作成された。
EC2 からバケットにオブジェクトを保存
まだロールを設定していないのでできないことを確認する。
# アップロードのテスト用ファイルを作成します。
echo hello > test.txt
# バケットへのアップロードを試みます。
aws s3 cp test.txt s3://{BUCKET_NAME}/test.txt
upload failed: ./test.txt to s3://{BUCKET_NAME}/test.txt Unable to locate credentials
無事にアップロードが失敗した。
ロール作成
インスタンス ID をクリックする。
IAM ロールを変更をクリックする。
「新しい IAM ロールを作成」をクリックする。
「ロールを作成」ボタンを押す。
タイプは「AWS のサービス」のままでユースケースで「EC2」を選ぶ。
許可を追加では AmazonS3FullAccess にチェックを入れる。
ロール名に例えば「S3FullAccessRole」と入力して作成する。
ロール変更ページに戻って更新ボタンを使うと選択できるようになる。
無事にロールが設定された。
この状態で再度アップロード
aws s3 cp test.txt s3://{BUCKET_NAME}/test.txt
upload: ./test.txt to s3://{BUCKET_NAME}/test.txt
今度は成功した。
アップロードは S3 バケット詳細ページからも確認できる。
バックアップスクリプトを作成する
touch ~/s3-backup.sh
chmod 755 ~/s3-backup.sh
touch ~/.my.cnf
chmod 600 ~/.my.cnf
# アップロード先のバケット名です。
BUCKET_NAME=xxxx
# バックアップ時点の日時です。
DATE=`date --iso-8601=seconds`
# WordPress ディレクトリの zip ファイルを作成します。
cd /var/www/html && zip ~/wordpress.zip -r wordpress && cd
# S3 バケットにアップロードします。
aws s3 cp ~/wordpress.zip s3://${BUCKET_NAME}/${DATE}/wordpress.zip
# ファイルを削除します。
rm -f ~/wordpress.zip
# データベースの内容をダンプします。
mysqldump -u wordpress_user wordpress_db > ~/wordpress_db.sql
# S3 バケットにアップロードします。
aws s3 cp ~/wordpress_db.sql s3://${BUCKET_NAME}/${DATE}/wordpress_db.sql
# ファイルを削除します。
rm -f ~/wordpress_db.sql
[mysqldump]
password="xxxx"
CRON 設定
/etc/crontab に下記を追記する。
0 18 * * * ec2-user /home/ec2-user/s3-backup.sh
UTC 18:00 なので JST 3:00 にバックアップを実行する。
CRON がインストールされていない
びっくりだ。
# crond インストール
sudo yum install cronie
# 起動状態の確認(停止している)
sudo systemctl status crond
# crond 起動
sudo systemctl start crond
# 起動状態の確認(起動している)
sudo systemctl status crond
# システム開始時の起動(有効になっている)
sudo systemctl is-enabled crond
# 有効になっていない場合は有効にする。
sudo systemctl enable crond
S3 ライフサイクルポリシーの設定
バックアップファイルは作成から 2 週間で削除するようにする。
「ライフサイクルルールを作成する」ボタンを押す。
内容を入力していく。
アクションがわかりにくいが「オブジェクトの現行バージョンを有効期限切れにする」で良いようだ。
無事に設定された。
作業時間
90 分くらい作業したので合計 275 分になった。
次は CloudWatch のアラームでも設定してみよう。
自動再起動
とりあえず cron で設定してみよう。
0 20 * * * root /usr/sbin/reboot
後日 last コマンドで調べてみよう。
last reboot
9/20 (水) はここから
今日は CloudWatch のアラームでも設定してみようか。
下記が参考になりそうだ。
SNS トピック作成
Amazon SNS ページを開く。
トピックページからの方がわかりやすいかも知れない。
「トピックの作成」ボタンを押すとこのページが表示される。
メール通知の場合はタイプに「スタンダード」を指定する。
今回は名前は「StatusCheckFailed」にして表示名は「ステータスチェック」にする。
無事に作成された。
新機能
タイムリーな話らしい。
サブスクリプション作成
「サブスクリプションの作成」ボタンを押す。
プロトコルとして E メールを選択する。
サブスクリプションを作成すると確認メールが届くので Confirm subscription をクリックして受信を許可する。
メッセージ発行のテスト
トピック詳細ページにある「メッセージの発行」ボタンを押す。
適当な件名と本文を入力してから「メッセージの発行」ボタンを押す。
成功するとメールが届く。
これで SNS トピックとサブスクリプションは作成完了。
CloudWatch アラーム作成
まずは CloudWatch ページへ移動する。
すべてのアラームを表示してから「アラームの作成」ボタンを押す。
メトリクスの選択画面
設定内容は下記の通り。
- メトリクス:WordPress インスタンスの StatusCheckFailed
- 統計:5 分間の最大値
- しきい値の種類:静的
- 条件:0 より大きい
通知先として先ほど作成した SNS トピックを選択する。
アラーム名は「StatusCheckFailedAlarm」などにする。
確認画面が表示されたら内容を確認してから「アラームの作成」ボタンを押す。
無事にアラームが作成された。
作業時間
60 分くらい作業したので合計 335 分になった。
次は FTP でも設定してみよう。
FTP サーバー
下記の記事などが参考になりそう。
再起動とバックアップの確認
昨日の設定はしっかり動いているだろうか?
last reboot
reboot system boot 6.1.49-70.116.am Tue Sep 19 20:00 still running
reboot system boot 6.1.49-70.116.am Fri Sep 15 09:03 - 20:00 (4+10:56)
大丈夫なようだ。
バックアップについてもしっかり保存されている。
PHP 設定
アップロードサイズとかタイムゾーンとか設定した方が良さそう。
やることリストに追加しておこう。
9/21 (木) はここから
今日はサクッと PHP 設定でも行おう。
PHP 設定
アップロードサイズについては下記 3 点を変更する必要がある。
- post_max_size
- upload_max_filesize
- memory_limit
また必須ではないが最大処理時間も確認しておいた方が良い。
- max_input_time
- max_execution_time
タイムゾーンは Asia/Tokyo にする。
- date.timezone
動作確認
メディアの新規追加ページを使うと反映されていることが分かりやすそう。
設定変更
sudo vi /etc/php.ini
などを実行する。
- post_max_size = 128M
- upload_max_filesize = 100M
- memory_limit = 256M
- max_input_time = 300 (秒)
- max_execution_time = 300 (秒)
- date.timezone = "Asia/Tokyo"
変更した下記を実行して反映する。
sudo systemctl restart php-fpm
sudo systemctl restart httpd
php-fpm の再起動が必要なことを知らなくて小一時間ハマってしまった。
今さらだけど php-fpm も自動起動しておいた方が良いのかな?
sudo systemctl enable php-fpm
サイトヘルスが便利
メディアの新規追加ページも便利だけどサイトヘルスの方が便利
一応メディアの新規追加ページも確認しておく。
PHP 設定だけで 50 分もかかってしまった
FTP 設定もしようとしたけど時間あるだろうか。
セキュリティグループの変更
21/TCP と 60001-60010/TCP を解放する。
EC2 のセキュリティーグループ一覧ページ
「インバウンドのルールを編集」ボタンを押す。
ルールを 2 つ追加する。
vsftpd のインストール
sudo yum install -y vsftpd
vsftpd の設定
ソースは安定のクラメソさん。
userlist_deny=NO
pasv_enable=YES
pasv_min_port=60001
pasv_max_port=60010
FTP 用のユーザーを作成する。
sudo useradd ftp-user
sudo passwd ftp-user
FTP ホワイトリストに追加する。
ftp-user
サーバーを起動する。
sudo systemctl start vsftpd
sudo systemctl enable vsftpd
FileZilla などを使ってアクセスできれば OK.
パーミッションをどうしよう
今のままだと /var/www/html/wordpress にダウンロードはできるけどアップロードはできない。
ftp-user を apache グループに参加させ、g+w をすれば良いかな?
作業時間
90 分くらい作業したので合計 425 分になった。
そろそろ 8 時間になってしまう。
グループ参加
# ftp-user を apache グループに追加します。
sudo gpasswd -a ftp-user apache
# ftp-user が apache グループに追加されたかを確認します。
groups ftp-user
パーミッション設定
sudo chmod -R g+w /var/www/html/wordpress
とりあえず、これで読み書きはできるようになった。
作業時間
追加で 15 分くらいなので 440 分
これでほぼ完了したかな?
RI と SP
割引料金体系が 2 つもあると迷ってしまう。
ACM と ELB の設定
やっていこう。
ロードバランサー
ロードバランサーのページから作成できそうだ
リージョンがシドニーになっているので東京にしておこう。
ロードバランサーの作成
ALB の「作成」ボタンを押す。
名前は変更できないのでよく考えた方が良さそう。
WordPressALB にしようかな。
ネットワークマッピングでは全てのアベイラビリティゾーンにチェックを入れておく。
リスナーとルーティングでは HTTP と HTTPS を設定する。
ターゲットグループはないので作成する必要がありそうだ。
名前は DNS 名に含まれるので wordpress-alb の方が良いことが後からわかりました。
また、セキュリティグループで HTTP と HTTPS を許可する必要がありました。
ターゲットグループの作成
色々と設定があるな。
ターゲットグループ名は WordPressALB80 にしようかな。
それ以外はそのままにして作成しよう。
プロトコルごとに必要そうなので WordPressALB443 も作成しよう。
ステータスチェックで成功時のコードを 200 ではなく 301 にする必要があることが後からわかりました。
WordPressALB443 はいらなそう
インスタンスが HTTPS サーバーなら必要そうだがそうで無ければ必要無さそう。
ACM リクエスト
セキュリティポリシーの関係で ACM 証明書をまず作成する必要がありそうだ。
証明書をリクエストボタンを押す。
証明書タイプはパブリック証明書。
ドメイン名は完全修飾ドメイン名(FQDN)、例えば www.loremipsum.co.jp。
それ以外はデフォルトのままで OK。
作成後に詳細ページから DNS 設定内容を取得できるので DNS 設定担当者に渡す。
ACM 設定完了まで待つ
証明書が無いとロードバランサーは作成できないようだ。
仕方がないので設定してもらうまで待とう。
確認はこんな感じでできそうだ。
nslookup -type=CNAME www.loremipsum.co.jp
先ほどの作業時間
30 分程度だった。
phpMyAdmin のインストール
なんと公式にドキュメントがあるとは!
phpMyAdmin をインストールしてみる
# 依存関係をインストールします。
sudo dnf install php-mbstring php-xml -y
# Web サーバーを起動して反映します。
sudo systemctl restart httpd
sudo systemctl restart php-fpm
ここまでは手順通りだが既にパッケージはインストールされていたので必要なかった。
下記は少し手順を変えた。
# ホームディレクトリに移動します。
cd
# phpMyAdmin をダウンロードします。
wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz
# tar ファイルを展開します。
tar -xzf phpMyAdmin-latest-all-languages.tar.gz
# tar ファイルを削除します。
rm -f phpMyAdmin-latest-all-languages.tar.gz
# ディレクトリ名をランダムに決めます。
DIRNAME=`openssl rand -hex 16`
# ファイルを移動します。
sudo mv phpMyAdmin-5.2.1-all-languages /var/www/html/wordpress/${DIRNAME}
# 所有者を変更します。
sudo chown apache:apache -R /var/www/html/wordpress/${DIRNAME}
# ディレクトリ名を確認します。
echo ${DIRNAME}
入れるだけで表示されてしまった、すごいな。
phpMyAdmin に Basic 認証
気休めかも知れないが下記などを参考にして Basic 認証を設定しておこう。
# phpMyAdmin のディレクトリに移動します。
cd /var/www/html/wordpress/${DIRNAME}
# .htaccess ファイルを作成して下記の内容を入力します。
sudo touch .htaccess
# .htpasswd ファイルを作成します。
sudo htpasswd -c .htpasswd pma_user
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /var/www/html/wordpress/(DIRNAME をコピーします)/.htpasswd
Require valid-user
ログイン画面が表示されるようになった。
作業時間
前回 30 分、今回 45 分なので 515 分。
11/9 (木) はここから
ようやく証明書が作成されて作業を再開できるようになったので一気に終わりまで進めていこう。
メールや証明書の検証
ドメインやメールを自分で管理していない場合はクライアントにメールのリンククリックや DNS 設定を行なってもらう必要があり、作業自体は 1 分くらいで終わるはずなのだがとても時間がかかる。
今回も 1 週間以上を要したようだ。
今度計画する時はこれらを踏まえて制作計画を立てる方が良いかもしれない。
ロードバランサーの作成
下記の手順を参考にして進めていった。
無事にロードバランサーが作成された。
ロードバランサーは準備に時間がかかる
状態がプロビジョニング中になっている。
サーバーにアクセスできない
と焦っていたらスキームが https: になっていた、アクセスできるわけがない。
WordPressALB443 は削除しておこう
多分使わないだろう。
ロードバランサが作成された
ただ名前がそのまま DNS 名に含まれるので、大文字が入っていると何かと不都合なので小文字にして作り直そう。
その前にヘルスチェック
Unhealty なので削除前に問題を解決しよう。
エラーメッセージの確認
ターゲットグループの詳細ページ
Health checks failed with these codes: [301]
301 は Moved Permanently、リダイレクトを示す。
SSH でログインしたら原因がわかった。
curl -v http://localhost
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/8.2.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Date: Thu, 09 Nov 2023 02:34:28 GMT
< Server: Apache/2.4.56 (Amazon Linux)
< Expires: Thu, 09 Nov 2023 03:34:28 GMT
< Cache-Control: max-age=3600
< X-Redirect-By: WordPress
< Set-Cookie: _mw-wp-form-token=57fba3fc142a426c13c79ac4dafac23ab5215185afab2c00c0c9bd4fe35ade24; path=/; HttpOnly
< Location: http://52.197.109.189/
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
<
おそらく WordPress は HTTP リクエストのホスト部を見て設定されたホスト名と異なる場合はリダイレクトするようなしくみになっているのだろう。
だからステータスチェックの設定を変えて 301 を OK とするようにすれば大丈夫そうだ。
ステータスチェックの設定ページ、200 の部分を 301 に変更する。
Healthy に変わった
ターゲットグループの詳細ページ
しかしまだアクセスできない、セキュリティグループだろうか?
当たりだった
セキュリティグループで HTTP と HTTPS を許可する必要がある。
セキュリティーグループの詳細ページ
ロードバランサーの再作成
無事にサイトが表示されるようになったので wordpress-alb という名前で再作成しよう。
WordPress の転送について
ちなみに WordPress の方でサイトアドレスを http://12.34.56.78 のようにしていると ALB の DNS 名にアクセスしても設定されたサイトアドレスに転送されるので注意。
サイトアドレスには本番の DNS 名を設定する必要がある。
動作確認
DNS で CNAME を設定する前にローカルで hosts ファイルを編集して確認してみる。
Mac の場合は /private/etc/hosts を編集すれば良いようだ。
現在こういう問題が起こっている
ここまでの作業時間
90 分くらいなので 605 分。
問題に対処できた
wp-config.php の冒頭に下記のコードを追加したら解決した。
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
$_ENV['HTTPS'] = 'on';
}
ここまでの作業時間
15 分くらいなので 620 分。
これでほぼ終わっただろう。
トラブル発生
メモリ不足で MariaDB のプロセスが Out-of-memory (OOM) Killer にキルされる。
この現象を調べるのに 2 時間くらいかかってしまった。
対策として下記を実行しよう。
- スワップを設ける。
- MariaDB のメモリ消費量を抑制する。
- できれば MariaDB のプロセスを OOM Killer のキル対象から外す。
- プロセス監視を設定する。
参考サイト
スワップの作成
Amazon Linux ではスワップ領域が無い、この点は下記のコマンドを実行すると確認できる。
free
スワップを作成するには下記のコマンドを実行する。
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
/swapfile swap swap defaults 0 0
スワップが作成されたことは sudo swapon -s
または free
で確認できる。
完全な動作確認にはリブートした方が良い。
この辺りを参考にした。
MariaDB のメモリ使用量
こちらの記事が一番わかりやすい感じがする。
select
@@global.key_buffer_size + @@global.innodb_buffer_pool_size + @@global.innodb_log_buffer_size + @@global.net_buffer_length as global_buffer_size,
@@global.sort_buffer_size + @@global.myisam_sort_buffer_size + @@global.read_buffer_size + @@global.join_buffer_size + @@global.read_rnd_buffer_size as thread_buffer_size,
@@global.key_buffer_size + @@global.innodb_buffer_pool_size + @@global.innodb_log_buffer_size + @@global.net_buffer_length
+ (@@global.sort_buffer_size + @@global.myisam_sort_buffer_size + @@global.read_buffer_size + @@global.join_buffer_size + @@global.read_rnd_buffer_size) * @@global.max_connections as total_memory_size;
PHP FPM プロセス数調整
最終的に PHP FPM のプロセス数を調整してみた。
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 8
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 2
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.min_spare_servers = 2
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 6
作業時間
ここまで 1.5 時間くらい。
php-fpm の設定反映
sudo systemctl reload php-fpm
OOM score
PID の調べ方は下記の通り。
ps -aux | grep maria
書き換え
sudo systemctl edit mariadb.service
[Service]
OOMScoreAdjust=-1000
設定内容を末尾に書くと書き込みが失敗するので注意。
反映させるには下記を実行。
systemctl restart mariadb.service
プロセス ID を調べたらさらに下記を実行。
cat /proc/1234/oom_score
cat /proc/1234/oom_adj
cat /proc/1234/oom_score_adj
ちなみに下記を実行すると oom_score_adj がゼロではないプロセスを一覧できる。
for dir in /proc/[0-9]*; do
if [ "`cat $dir/oom_score_adj`" != 0 ]; then
echo "`cat $dir/comm` : `cat $dir/oom_score_adj`"
fi
done
最後にプロセス監視
これは AWS Systems Manager からやると良いようだ。
参考にした
CloudWatch Agent のインストール
高速セットアップを使ってみた。
CloudWatch エージェントのインストールにのみチェックを入れた。
インストール確認
sudo systemctl status amazon-ssm-agent
パラメータ作成
パラメータストアで下記を作成。
名前は CloudWatch-Alarm-Process-Check とした。
{
"metrics": {
"metrics_collected": {
"procstat": [
{
"pattern": "httpd",
"measurement": [
"pid_count"
],
"metrics_collection_interval": 60
},
{
"pattern": "mariadbd",
"measurement": [
"pid_count"
],
"metrics_collection_interval": 60
}
]
}
}
}
ロールにポリシーのアタッチ
- AmazonSSMManagedInstanceCore
- CloudWatchAgentServerPolicy
Run Command
- コマンドドキュメント: AmazonCloudWatch-ManageAgent
- Action: Configure (append)
- Optional Configuration Location: CloudWatch-Alarm-Process-Check
ターゲットで EC2 を選ぶ。
EC2 が表示されない場合は再起動してみる。
設定ファイルは下記に格納されるようだ。
/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/ssm_CloudWatch-Alarm-Process-Check
exe の調べ方
ls -ald /proc/{pid}/exe のシンボリックリンク先
アラーム作成
ImageId, InstanceId, InstanceType, pattern, pid_finder のメトリクスを使って 1 分間の平均値が 0 になったらインスタンスを再起動するアラームを作成する。
作業時間
結局 2 時間近くかかってしまった。
ALB で複数の証明書を設定する
リスナーで SNI の SSL 証明書を追加する。