WordPress, AWS

AWS CloudFront→ALB→EC2(WordPress)

CloudFrontはS3に設置したJS, CSS, 画像といった静的コンテンツに適したCDNの利用が王道だけれど、WordPressのような参照の多いサイトでのページキャッシュに利用することも効果的です!

 

環境

  • AWS
  • Amazon Linux2

 

この構成の意図

  • Nginxでのリバースプロキスにページキャッシュの場合は単一障害点になりますが、リバースプロキシの役割をCloudFrontに持たせることによってスケールすることが出来ます。
    キャッシュのTTLは任意で設定して下さい、また任意のタイミングで【invalidation】機能によりパス単位でのキャッシュ削除が可能です。

 

 

CloudFrontページキャッシュ構成の良いところ

  • CDNとして詳細設定が可能
    Cookieのキーを指定することで、ログイン中はキャッシュしないといったことが手軽に設定出来る
  • ALBと組み合わせてスケール、メンテナンス性の向上
    更にALBを間に挟むことで、EC2のメンテナンス性向上し将来的なスケールが容易になります。
  • Cloudfront転送料金 13円/1GB
    EC2から配信する場合と転送料金はほとんど大差ない、
    CloudFrontを挟めるなら挟もう

 

一時的なキャンペーンであれば

事前にCloudFrontのキャッシュ保持を行うTTLを長くして、CloudFrontにページキャッシュを十分にストックしておけばOK!

万が一CloudFrontのバックエンドに流れることが不安なら、ALB配下にEC2サーバを任意の数で待機しCPU監視によるオートスケール設定をかけておけばよいでしょう。

 

注意

  • ネイキッドドメイン(example.net等)でWEBを運用している場合は利用できない
    CloudFlare等ネイキッドドメインでも運用できるCDNがあるがRFC違反なので、メールなどで異常動作がでるかも?ハック的な実装になる。
    不具合が出た場合に常にこのネイキッドドメイン+CDNの実装が原因であるという疑惑が払拭できないので私はやらない。
  • 設計はシンプルにまっすぐいくべきと考えています。

 

プロトコルの流れ

USER →(HTTPS)→  CloudFront    →(HTTPS)→ ELB →(HTTP)→   EC2(Apache&WordPress)
              www.example.net       alb.example.net      www.example.net

USER → 443 → CloudFront → 443 → ALB → 80 → EC2

こういう流れになります。ALBとEC2の通信を80にすることで、AWS ACMを利用した証明書自動更新環境が作れます。

 

条件

下記ドメインの証明書をAWS ACM ヴァージニアリージョンで取得しておく

  • CloudFront適用/EC2 Apache設定用ドメイン
    www.example.net
  • ALB適用ドメイン
    alb.example.net

 

 

EC2設定

 

必要モジュールのインストール

# amazon-linux-extras install php7.2
# yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm -y
# yum-config-manager --disable mysql80-community
# yum-config-manager --enable mysql57-community
# yum install -y httpd php mysql-community-server

 

起動、自動起動設定

# systemctl start httpd mysqld
# systemctl enable mysqld httpd

 

WordPress DB作成

# mysql -u root -p
Enter password:<パスワード入力>


rootパスワード再設定
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'DSFakjo45@f';


DB作成
mysql> CREATE DATABASE wpdb;


DBユーザ作成
mysql> GRANT ALL PRIVILEGES ON wpdb.* TO wpdbuser@localhost IDENTIFIED BY 'TAeesfjk@4' WITH GRANT OPTION;


mysql> exit
Bye

 

WordPressのダウンロード

# cd /var/www/html/
# wget https://ja.wordpress.org/latest-ja.tar.gz
# tar -xzvf latest-ja.tar.gz
# rm -rf latest-ja.tar.gz

 

バーチャルホスト設定

# vi /etc/httpd/conf.d/Globalsetting.conf

<VirtualHost *:80>
  ServerName www.example.net
  DocumentRoot /var/www/html/wordpress
  ErrorLog logs/www.example.net-error.log
  CustomLog logs/www.example.net-access.log elb-customlog env=!nolog
  ## ALB httpで来たらhttpsにリダイレクトする
  <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Port} !^443$
    RewriteCond %{HTTP_USER_AGENT} !^ELB-HealthChecker
    RewriteRule ^(.*)?$ https://www.example.net$1 [R=301,L]
  </IfModule>

  <Directory "/var/www/html/wordpress/">
    # 2.2系
    #AllowOverride All
    #Order allow,deny
    #Allow from all

    # 2.4系対策
    AllowOverride All
    Require all granted
  </Directory>
</VirtualHost>


# alb.example.netをwww.example.netにリダイレクト
<VirtualHost *:80>
    ServerName alb.example.net
    ServerAlias www.example.net
    DocumentRoot /var/www/html/wordpress/

    RedirectMatch 301 .* https://www.example.net/
</VirtualHost>

 

ヘルスチェックファイル設定

# vi /var/www/html/healthcheck.php


<?php

echo "<h1>Don'T Remove!!</h1><br/>";
echo "<h2>LoadBalanser HealthCheck File</h2><br/>";
echo "このファイルを削除するとLBの死活監視で\"unhealthy\"となり、<br/>";
echo "アクセス障害が発生します。<br/>";

 

ヘルスチェックファイル サーバ内パス設定

# vi /etc/httpd/conf.d/healthcheck.conf

# ヘルスチェックURL
Alias /healthcheck.php /var/www/html/healthcheck.php

# ヘルスチェックのALBのアクセスはログを取らない 
SetEnvIf User-Agent "ELB-HealthChecker.*" nolog

 

# chmod 444 /var/www/html/healthcheck.php

 

サーバログのパラメータ

%{X-Forwarded-For}i アクセス元IP
%h ホスト名
%l クライアント情報
%u 認証ユーザ
%t リクエスト日時
%r リクエスト Request
%s ステータス
%b バイト数
%{Referer}i リファラ
%{User-Agent}i ユーザエージェント
%{X-Forwarded-Proto}i プロトコル


%{Hoge}i リクエストヘッダのHogeの中身を出力
%{Hoge}o レスポンスヘッダHogeの内容
%{FOOBAR}e 環境変数FOOBARの値

 

remoteipモジュールの確認

# httpd -M | grep remoteip
 remoteip_module (shared)

これがないとクライアントIPが取得できない。

 

 

ログフォーマット設定

# vi /etc/httpd/conf/httpd.conf


<IfModule log_config_module>
    #
    # The following directives define some format nicknames for use with
    # a CustomLog directive (see below).
    #
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-Proto}i\"" elb-customlog ←追加

 

反映

# systemctl restart httpd

 

WordPress設定ファイルをサンプルからコピーして有効化

# cp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php

 

WordPress設定ファイルの編集

  • DBの設定
  • リダイレクトループ対応
  • サイト名対応

 

コンフィグファイル設定

  • DB設定
  • ALBのリダイレクトループ対策
  • サイトURL定義
# vi /var/www/html/wordpress/wp-config.php


// ** MySQL 設定 - この情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define('DB_NAME', 'wpdb');

/** MySQL データベースのユーザー名 */
define('DB_USER', 'wpdbuser');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', 'TAeesfjk@4');

/** MySQL のホスト名 */
define('DB_HOST', 'localhost');

/** データベースのテーブルを作成する際のデータベースの文字セット */
define('DB_CHARSET', 'utf8');

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define('DB_COLLATE', '');

# AWS ELB(ALB) リダイレクトループ対策
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
    $_SERVER['HTTPS']='on';
}

※下記を挿入する

# AWS ELB(ALB) リダイレクトループ対策
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
    $_SERVER['HTTPS']='on';
}

# WP_SITEURL, WP_HOME設定
define( 'WP_SITEURL', 'https://www.example.net' );
define( 'WP_HOME', 'https://www.example.net' );

 

 

CloudFront初期設定

 

Origin Domain Name
 alb.example.net

Origin Path
 ※空白

Origin ID
 Custom-alb.example.net/alb.example.net
 ※自動入力される


Minimum Origin SSL Protocol
 TLSv1

Origin Protocol Policy
 HTTPS Only


Origin Response Timeout
 30

Origin Keep-alive Timeout
 5

HTTP Port
 80

HTTPS Port
 443



Path Pattern
 Default (*)

Viewer Protocol Policy
 Redirect HTTP to HTTPS


Allowed HTTP Methods
 GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE


Cache Based on Selected Request Headers
 Whitelist
  Authorization
  管理画面にベーシック認証を入れる時などに必要です。

  CloudFront-Forwarded-Proto
  Origin側へプロトコルを通知します。

  Host
  Origin側へアクセス先ホスト名を通知します。




Object Caching
 Customize


Minimum TTL
 60

Maximum TTL
 60

Default TTL
 60



Forward Cookies
 whitelist

  Whitelist Cookies
   wp-settings*
   wordpress_logged_in*


Query String Forwarding and Caching
 Forward all, cache based on all


Alternate Domain Names(CNAMEs)
 www.example.net


SSL Certificate
 Custorm SSL Certificate
  www.example.net ←証明書(ヴァージニアで取得)を選択

Logging
 On

Bucket for Logs
 ※自動指定

 

 

CloudFront作成後、[Behaviors]-[Create Behavior]から

指定したパスに対してTTL=0, メソッドをCloudFrontにスルーさせてキャッシュをしないようにする

  • /wp-login.php
    このままだとログインが出来ない、ログイン出来るようにしよう。
  • /wp-admin/*
    管理系の情報をキャッシュしてはいけない
  • *.php
    動的なスクリプトをキャッシュさせてはいけない

 

・/wp-admin/*
・/wp-login.php
・*.php


Viewer Protocol Policy
 Redirect HTTP to HTTPS

Allowed HTTP Methods
 GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE


Object Caching
 Customize
  Minimum TTL 0
  Maximum TTL 0
  Default TTL 0


Forward Cookies
 All
 

Query String Forwarding and Caching
 Forward all, cache based on all

 

ErrorのTTLを短く!Error Caching Minimum TTL

4xx, 5xx系のエラーキャッシュのデフォルトのTTLはなんと5分!

  • 各10秒程度に変更するのが良い

これをやっておかないと、復旧してもキャッシュされたエラーページが5分もクライアントに返すことになる。

 

ALB

【ターゲットグループ】 → 【ヘルスチェック】

  • プロトコル: http
  • ヘルスチェックパス:healthcheck.php

 

 

アクセスして表示されるか確認しよ~!

https://www.example.net

 

 

CloudFront動作確認

 

通常のアクセス(2回目)

x-cacheヘッダーにて「Hit from cloudfront」を確認 → キャッシュされている

 

 

ログイン中

x-cacheヘッダーにて「Miss from cloudfront」を確認 → キャッシュなし

キャッシュされてちゃだめですよ!

 

お疲れ様です。

 

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)