カテゴリー
AWS WordPress

AWS ALB配下のWordPressにCloudFrontを適用した

色んなブログを参照しながら実施したものの、ドハマリしたのでメモしておく。

OriginとなるALBの設定

CloudFrontの配信元(オリジン)となるALBが、マルチホスト(複数のドメイン名を相乗りさせている)の場合は、CloudFrontのディストリビューション毎にリスナーポートを分けておいた方が無難。

こだわるならCloudFront~ALB間もHTTPS転送すべきではあるが。。。いったんHTTPで。

HTTP 8080が今回のCloudFront配信対象となるこのブログ専用のリスナー。

CloudFrontの作成

ACMを使って証明書管理するなら、N.Virginiaで証明書を発行しておく。

ALB を配信元にしてCloudFrontディストリビューションを作成。

CloudFrontのデフォルトのキャッシュ設定をする

通常の記事を表示したり、管理画面へのアクセスの時に空白ページが出たりするので、必ずHostヘッダやForwarded-Protoヘッダを通しておく。

CookieもWordpress関連のものを素通しするのと、プレビューや検索クエリのためにQuery Stringもほぼ素通ししてやる。

参考にしたブログ:
WordPress 製のサイトに CloudFront を導入してバリバリキャッシュさせようと検討したときの記録 https://hacknote.jp/archives/38406/

CloudFrontのパス毎のキャッシュ除外設定をする

WordPress固有の除外設定を追加しておく。
対象となる代表的なパスは以下の通り。

  • /wp-json/*
  • /wp-admin/*
  • wp-login.php
  • *.php

キャッシュ設定では以下のところを必ず変更しておく。

  • Cache Based on Selected Request Headers (Whitelist または All)
  • Forward Cookies (Whitelist または All)
  • Query String Forwarding and Caching (Forward all, cache based on all)

CloudFrontのエラーページのキャッシュ設定

4xx, 5xx系のエラーは変にキャッシュされても困るので、とりあえず10秒程度に短くしておく。

WordPressのPHP書き換え

wp-config.phpの一部をCloudFront対応に書き換える

$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        $_SERVER['HTTPS'] = 'on';
} elseif (isset( $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']) && $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] === 'https') {
        $_SERVER['HTTPS'] ='on';
}

DNSレコードの書き換え

AレコードおよびAAAAレコードがCloudFrontのディストリビューションを指すように変更して動作を確認する。

その他参考にしたブログ

AWS CloudFront→ALB→EC2(WordPress) https://www.yuulinux.tokyo/10815/

カテゴリー
AWS

AWS ALB配下にWordPressを入れたら繋がらない

前にAzure Front Door経由でWordpressを公開したときも同じハマり方をしたような気がするけども……。

原因は、リバースプロキシ配下だとHTTPS経由で通信しているかどうか判別できないためにリダイレクトし続けてしまうため。

対処法は、https://wordpress.org/support/article/administration-over-ssl/#using-a-reverse-proxy にもあるが $_SERVER[‘HTTP_X_FORWARDED_PROTO’] をみてリバースプロキシ配下にいるかどうかを判別してやるコードを wp-config.php に書き加えてやること。
※ 下記のコード例は、参考URLにあったものを少し手直ししている。

if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
  $_SERVER['HTTPS']='on';
  $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
  $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
カテゴリー
AWS

Amazon EC2ではないサーバからDocker-composeのログをCloudwatch Logsに転送する

Docker-composeのログをCloudwatch Logsに転送する場合、Amazon EC2であればIAM Roleをインスタンスプロファイルとして設定すれば自動的にAPIクレデンシャルを取得してログを出力してくれる。

ところが、Azure VMなどAmazon EC2でないサーバからDocker-composeでログ出力しようとすると、~/.aws/credentialsにAPIキーを設定しても以下のようなエラーメッセージが出て上手く行かないことがある。

ERROR: for jitakurack_web_1 Cannot start service web: failed to initialize logging driver: failed to create Cloudwatch log stream: NoCredentialProviders: no valid providers in chain. Deprecated.
Starting jitakurack_streaming_1 … error

このエラーは、DockerサービスがAPIキーを上手く取得出来ていない。手元の環境だとsystemd環境だと起こるような気がする。なので、systemd経由でAPIキーをDockerサービスに引き渡してあげると動くようになる。

で、 https://wdullaer.com/blog/2016/02/28/pass-credentials-to-the-awslogs-docker-logging-driver-on-ubuntu/ の情報に従って、Dockerサービスの環境変数を追加する。

$ sudo mkdir -p /etc/systemd/system/docker.service.d/
$ sudo touch /etc/systemd/system/docker.service.d/aws-credentials.conf

[Service]
Environment=”AWS_REGION=<aws_region>”
Environment=”AWS_ACCESS_KEY_ID=<aws_access_key_id>”
Environment=”AWS_SECRET_ACCESS_KEY=<aws_secret_access_key>”

$ sudo systemctl restart docker.service

$ docker-compose logs
Attaching to jitakurack_streaming_1, jitakurack_web_1, jitakurack_sidekiq_1
sidekiq_1 | WARNING: no logs are available with the ‘awslogs’ log driver
streaming_1 | WARNING: no logs are available with the ‘awslogs’ log driver
web_1 | WARNING: no logs are available with the ‘awslogs’ log driver

あとはCloudwatch Logsのコンソールを確認すればログが出ている。