こんにちは、かっぺいです。
ブログサイトを作ろうと、ドメインを取得したけれど、全然行っていませんでした。
Bloggerで何となくやっていたけど、やっぱりWordPressでやり直そうと一念発起しました。
構成案
検索して、よく出てくるのはLightsailを使って、構築を自動化してくれるものばかり。
でも、程よくコストを抑えて、簡単にhttpsサイトをと思うと、自分で構築した方が良さそうでした。
よくある、プライベートサブネットにDBとWebSVを置いて、ELBでhttpsリスナーからプライベートのEC2へ転送という形ですが、プライベートサブネットにNATGWが無いとWordPressの更新とか使えないので、全然利用していなくてもコストがかかる。
個人利用なのでコストは抑えたい。

全てシングルAZにして、DBサーバだけプライベートに、パブリックにWebSVを置いてセキュリティグループでALBだけアクセス可能に。
一見安くなりそうだが、ALBが時間課金なので、使っていなくてもコストが発生する。RDSも初期の規模が小さい時には無駄な気がします。
httpsをオフロードしてくれるサービスは、ELBかCloudFrontなのでCloudFrontで利用する案に変更することに。
最終構成
コストを抑えるために、以下の方針で構築
- EBSの汎用SSD (GP3)を使えばIOPS3000を確保できるので、初期はRDSを使わずにEC2のローカルにMariaDBを構築する
- EC2のEBSサイズを抑える目的で、コンテンツはプライベートサブネットのEFS配下に配置する
- WebSVはパッケージ更新などの目的で、インターネット接続が可能なパブリックサブネットに配置するが、インバウンド接続は、セキュリティグループ設定でCloudFrontからのアクセスのみに制限する
- パブリックサブネットにWebSVがいるので、念の為にCloudFrontにはWAFを設定する

WebSVへのリモート接続
パブリックサブネットに置いたWebSVには、通常は公開鍵SSHでログインするのが普通ですが、今回はインバウンド接続はCloudFrontのみに制限したいので、SSHでのログインは使えません。
代わりに、セッションマネージャーというサービスを使います。これ、ブラウザさえあればリモートログインできるようになるので、設定しておくと非常に便利です。
IAMでロールを作成し、以下をアタッチします。
- AmazonEC2RolerforSSM
- AmazonS3FullAccess
※ファイル送受信に、S3を使うので一緒にポリシーをアタッチする
このロールをWebSVのインスタンスにアタッチします。
EC2起動〜WordPressインストール
インスタンスタイプは、t4g.microでEBSは50GBのGP3、OSはAmazonLinux2で構築。
起動したら、セッションマネージャでログインします。
必要なパッケージをインストールして、最低限のパラメータ設定をしてWebSVとMariaDBを起動。
WordPressのtar.gzをwgetで取得して展開。
wp-config.phpを設定。以下を追加で記述。
/* Add any custom values between this line and the "stop editing" line. */
define( 'WP_HOME', 'https://独自ドメイン名' );
define( 'WP_SITEURL', 'https://独自ドメイン名' );
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_ENV['HTTPS'] = 'on';
$_SERVER['HTTPS'] = 'on';
} elseif (isset( $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']) && $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] === 'https') {
$_ENV['HTTPS'] = 'on';
$_SERVER['HTTPS'] ='on';
}
インストール後、wp-contentsフォルダをEFSに移動して、シンボリックリンクでwp-contentsをEFS配下を向くように設定する
CloudFront用のセキュリティグループ設定
現在の、AWSが利用しているIPアドレスレンジというのが公開されています。ここから、CloudFrontとして利用されているレンジをセキュリティグループに設定します。
全部で、130個近くあるのでデフォルトではセキュリティグループの最大ルール設定数に抵触します。
なので、セキュリティグループを3個使って分割登録するphpを作成。そんなに頻繁に変わらないと思うので、定期的に実行すれば良いかなという感じで、作成。
WAFのルール
AWS WAFを選び、WebACLsを選びます
リージョンは、Global (CloudFront)を選んで、「Create web ACL」
ルールは、以下を選択
- AWS-AWSManagedRulesKnownBadInputsRuleSet
- AWS-AWSManagedRulesWordPressRuleSet
- AWS-AWSManagedRulesSQLiRuleSet
- AWS-AWSManagedRulesLinuxRuleSet
- AWS-AWSManagedRulesAmazonIpReputationList
- AWS-AWSManagedRulesAnonymousIpList
「Core rule set」を選びたい衝動に駆られるけれど、これを入れるとファイルアップロードがブロックされます。
CloudFront構築
CloudFrontのオリジンにEC2のサイトを指定する。しかし、インスタンスが再起動することによるIPアドレス変更があると面倒なので、EC2のネットワークをElasticIPに変更して、アドレス変動が起こらないようにする。
CloudFrontから、ディストリビューションの作成を実行する
- オリジンドメインには、EC2のパブリックDNS名を指定する
- プロトコルはhttpのみ
- オリジンシールドを有効にし、EC2インスタンスと同じリージョンを選ぶ
- キャッシュビヘイビアのビューワーは、RedirectHTTP to HTTPSを選ぶ
- 許可されたHTTPメソッドは、PUT,POSTを含む全てを選ぶ
- キャッシュキーは、Legacyを選び、ヘッダーに「CloudFront-Forwarded-Proto」「HOST」を選ぶ
- クエリ文字と、Cookieは全てを選ぶ
- WAFオプションは、予め作成したウェブACLを選択します
- 代替ドメインは、SSL証明書のドメインを設定し、カスタムSSL証明書は予めACMで作成した証明書を選択します
ディストリビューション作成後、管理者サイト用のビヘイビアを作成します
作成された、ディストリビューションを選び、「ビヘイビアを作成」を選びます
- パスパターンは、/wp-admin/*
- ビューワーは、RedirectHTTP to HTTPSを選ぶ
- 許可されたHTTPメソッドは、PUT,POSTを含む全てを選ぶ
- キャッシュキーは、Legacyを選び、ヘッダーに「CloudFront-Forwarded-Proto」「HOST」を選んだのち、カスタムを追加で「User-agent」を追加
- クエリ文字と、Cookieは全てを選ぶ
- オブジェクトキャッシュは、Customizeを選んで全てのTTLに0を入力してキャッシュを無効にする
Route53設定
ブログのホストを、CloudFrontへ転送する設定を追加します。
ゾーン設定に移動し、レコードの追加を選びます。
- シンプルルーティングを選び、レコード名にブログのホスト名を入力
- レコードタイプにAを選ぶ
- トラフィックルーティング先に、CloudFrontディストリビューションへのエイリアスを選び、対象のディストリビューションを選択する
アクセス確認
これで、独自ドメインでアクセスできるようになったので、ブラウザから
https://独自ドメイン/wp-admin/install.php
を開き、インストール画面が崩れなく表示されることを確認したのち、インストールを実行する。
キーポイント
ポイントは2個あります。
CloudFrontのヘッダーが正しくないと、管理者モードのグラフィカルエディタが起動できません。
WAFの設定で、Coreルールがセットされているとアップロード関連がブロックされてしまいます。