落ちないWebサイト

落ちないWebサイトの構築 【WordPressを静的サイト化する】

落ちないWebサイトの構築

先日、このサイトとは別に運用しているWordPressの1つが不安定になってしまい、不具合の原因を調べたところMySQLのアップグレードが原因でutf8mb4の文字コード指定に異常が発生していた。
復旧のために対象DBの文字コードの異常を修正する必要があったので、一度Dumpしてからリストアを実行し復旧させた。
復旧は軽微な対応で済んだのだけど、今後は手間をかけずに、サーバーレス的な継続的な改善ができるようにしたい。

今回の課題

  • 現行のWordPressサイトの本番環境を手間をかけずに安定運用させる
  • まず最低限の機能で構築
  • 保守コスト優先、WordPressの管理画面をベースにする
  • CloudFrontでホスティングすることでサーバレスな機能を運用する
  • 構築後に検索やSEO対策の機能を実装する
  • WordPressなのでセキュリティリスクが発生しないように注意する

実現方法の候補

  • StaticPress
    日本人の開発者が作ったWordPressのプラグイン。
    オリジナルは3年以上メンテナンスされていないため脆弱性の懸念がある。古くからあるプラグインのため、脆弱性やバグ対策のソースコードも公開されている。
  • WP2Static
    元はSimpleStaticという名前だったWordPressのプラグイン。完全なOSSで公開されていて自由なカスタマイズが可能。WP CLIにも対応しているので自分でWordpressを管理できる人にはとても都合がよい。CDNに乗せれば高機能かつ安定運用が可能になる。
  • Hugo
    Go言語にHugoというフレームワークがあり、高機能なhtmlテンプレートエンジンとして利用が可能。CDNに乗せれば格安で高機能かつ安定運用が可能になる。ただしWordPressの機能やノウハウを捨てることになる。
  • Shifter(サービス)
    Wordpressを静的サイトで公開するホスティングサービス。価格も良心的。ただしCDN等へ配置してバックエンドをカスタマイズしたい場合は2度手間になってしまう。
  • kusanagi(サービス)
    WordpressをフルカスタマイズしたOSSソリューション。日本のベンダが提供しているためサポートも信頼できるがシステムとして導入すると価格が高い。(1インスタンス15万円)
    レンタルサーバで提供されているkusanagiを利用する場合はホスティング費用だけでよいのでコストパフォーマンスは悪くない。ただ、どの程度サポートされるのか、プラグインやテーマは全て利用可能なのか、自前でWordPressのソースやnginxもカスタマイズ可能なのか、WPとKusanagiの二重運用になりコストが高くなる。
    元がWordPressなのでGPLとしてOSS版も提供されているが、最適化のためにNginxからビルドする前提になっておりWordPressと別のノウハウも必要になるため運用コストがかかる。良くも悪くもWordPressのカスタマイズバージョン。
  • k8s
    WordPressの勉強会でREST-APIでヘッドレス運用してk8sに乗せてCDN配信する話を聞いた。CDN配信のソースをk8sへデプロイしてCIは外部のSaaSへお任せというのは贅沢で良いけど、本番が静的ページでCDNに乗せるならk8sにする意味はあるのか(S3やGCSで良いのでは?)、Pod上で静的ページだけではなくvueでREST-APIと通信しているならWordPressのような記事ベースのコンテンツでは脆弱性が含まれるのではないか。色々と疑問が残る。

WP2Staticを利用する

  • 今回の課題解決はWordPressのサイト全体を静的なhtmlに変換してくれるWP2StaticというWPプラグインを利用する。

  • ■採用の理由

    1. WordPressの機能を引き継げるので、サイトのテンプレートデザインや面倒なSEOの設定を管理しやすい
    2. プラグインのフル機能がOSSで提供されているため問題があれば改修できる
    3. WP管理画面からの操作だけでなく WP CLIにも対応しているためバッチ処理で管理できる
    4. 本番サイトを静的ページで運用できるため大部分のセキュリティリスクを回避できる
    5. AMPやSEO用のメタタグ等、多くのWordPressの便利機能を利用することができる

アーキテクチャ

  • 現在のWordPress環境はSTG環境として運用する
  • 本番サイトはAWS S3に配置してCloudFrontで配信する
  • 自動化を前提にWP CLIで運用できる構成にする
  • クローリングは可能な限りWP2Staticで行う(WP CLIで制御可能なため)
  • WP2Staticではトップページ以外のクローリングができないため、ページネーションのインデックスは独自スクリプトを構築する
  • サイト内検索はいったん排除する(後日にJavascriptのサイト内検索を設置する。検索URLのみ動的サーバへ転送することもできるがセキュリティリスクを避けて本番はサーバレス構成で運用する)
  • Lambda Edgeの処理が可能になるのでnodejsで動的処理をする
  • 汎用的な顧客の問い合わせ機能や予約フォームは、CRMやMA,GoogleForm等で提供することでセキュリティリスクを抑えて機能を提供し、かつ一元管理が可能になる
  • 顧客対応用の恒久的な問い合わせページはMauticを利用する
  • アンケートや不特定多数からの問い合わせ、予約受付等はGoogle Formを利用する
  • マイクロサービス(フロントエンドやバックエンドのAPI連携等)は、Lambda Edgeを利用する

WP2Staticの課題と対策

  • 日本語URLのクローリングとファイル出力

    • 対策
      パーマリンクを記事IDベースに変更
  • ページ分割された過去記事(pagenation)のクローリングが不完全で出力されない

    • 対策
      毎回すべての記事をページングするスクリプトを別途作成しておく
      ※1度に10件以上の投稿をしなければトップページのクロールだけで記事を正しく出力できるが、10件以上登録したときにページングの整合性があわなくなる可能性があるため対策を設計しておく
  • 投稿の属性(カテゴリ、タグ、日付)を含めたURLが出力されない

    • 対策
      前項の対策と同じようにWP CLI等で全ての記事を出力できるスクリプトを作成しておくとよい。
  • サイト内検索の機能が提供できない

    • 対策
      ※aを検討中
    • a. mecab等で検索インデックスを構築して、本番の検索フォームと紐付ける
    • b. STG環境のWordPressのAPIとPOSTで通信させる
    • c. AWS Cloud Serarch等のサイト内検索用のWebサービスを契約する(コストが高い)
  • 投稿記事(single)のAMPが出力されない

    • 対策
      WP2Staticへ明示的に"/amp"もしくは"?amp"のページを登録するとAMP用の静的ページが生成される

まとめ・雑感

  • 「WP2Static」で構築したサイトは「AMP」プラグインのページ出力も正常に機能している
  • 「WordPress ping Optimizer」は残念ながら正常に機能しなかった(元サイトのURLをベースに通知してしまう)
  • CloudFrontへ配置したサイトをLighthouseで計測すると、初回実行Performance98、2回目以降はPerformance100になった。(CDN配信なので2回めから早い)
    元が軽量なページなので高速化していないが静的サイト化で悪化するようなことはなかった。

CacooのAWS構成図自動生成機能を試す

Visioの代わりに使っている設計用の作画サービス「Cacoo」でAWSの構成図Export機能が追加された。

https://cacoo.com/ja/blog/aws-architecture-import/

紹介記事の手順ではアクセスキーを登録するリスクが心配ですが、サポートページではクロスアカウントのIAMロールで登録する方法が掲載されているので、後者を参考にすると良いです。

https://support.cacoo.com/hc/ja/articles/360010495594-AWS%E6%A7%8B%E6%88%90%E5%9B%B3

 

AWS構成図の対象

  • CloudFront+ELB(ALB)AutoScaling+EC21台(待機2台)+RDS+その他一般的なCloudWatch,SNSあり
    (※ARNやVPC名等は消去しています)

利用した感想

  • AWS構成図の自動生成で有名な「CloudCraft」と比べると、出力結果が物足りない(見た目とサービス間の情報が貧弱)
  • 競合の「CloudCraft」「lucidchart」と比べると、コストパフォーマンスが最も良い。
  • ELB/ALBに登録されているAutoScalingの情報が出力されない(競合のlucidchartは出力される)
  • CloudFrontとALBの連携が出力されない(図から省略したがCloudFrontとS3 web frontの連携は出力される)
  • CloudWatchの情報が出力されない(競合のlucidchartはCloudWatchのアラート登録が出力される)
  • DynamoDBの情報が出力されないが、構成図の出力に対応してほしい(競合のlucidchart Basicも同様に出力されない)
  • Lambdaの情報が出力されない(ALBにもマウントできるので、できれば出力してほしい)
  • S3とSNSはバケットとCloudWatchの名称だけが表示される
  • 可能であれば、ELBやCloudfrontに登録されているRoute53, Config, セキュリティグループあたりの情報もほしい
  • 未検証だが「CloudMapper」というAWSの構成図を出力できるOSSがある。
    https://github.com/duo-labs/cloudmapper
    出力結果がCLoudformationで提供されているエディタに類似していて、商用サービスよりも強力かもれない。

 

AWS構成図の生成はCloudCraftが有名でしたが、低価格のサービスで提供されるようになったのは嬉しいところです。

 

 

s3のバケットでWebホスティングしたドメインをCloudFrontのACMでhttps化するときの注意点

Amazon s3に登録したドメインをCloudFrontのACMでhttps化する設定で、小さなハマりどころがあったので、備忘録としてブログに残します。

■目的
・s3で配信しているWebページがある
・s3の配信をhttps化して、かつCloudFrontで高速に配信したい

まず、解決方法の概要から、
s3で配信するために登録したDNS(Route53)設定のままでは、CloudFrontを経由した配信にならずhttpsの通信ができない。
CloudFront用のドメインをRoute53に登録すれる事で解決した。
それだけの設定なのですが、CloudFront用のドメインに気付くまで時間が掛かってしまった。。。

※CloudFrontのドメインが表示される画面
"CloudFrontリソースグループ "の "General"を設定すると該当のドメインが割り当てられて表示される。

 

 

 

 

 

 

 

 

※Route53設定の注意点

・前提条件として、s3でのWeb配信は設定済みとする。
・s3をCloudFrontで参照するためには、赤枠で囲ったドメイン(xxxx.cloudfront.net)を、Route53の配信対象のドメインへcnameとして設定する必要がある

※CloudFrontのOrigin設定
・s3で独自ドメインを割り当てたバケットはhttpsが使えないので、"Origin Protocol Policy"には"http only"を指定する
・"Origin Domain Name"が設定済みだと、プロトコル選択(http, https)が表示されない場合がある
・"Origin Domain Name"に適当なドメイン(test.comとか)を入力すると、プロトコル選択(http,https)が表示される

※CloudFrontのBehavior設定
・"http and https"
・その他はキャッシュ範囲、キャッシュ時間等を目的にあわせて設定する