常時HTTPSに対応したWordPress環境をCloudFormationで設置してみた

2019.05.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

AWSチームのすずきです。

Amazon Linux 2 のLAMP環境 (PHP7.2、MariaDB10.2) に、WordPress のインストールと設定まで UserDataで実施したEC2と、 常時HTTPS対応のためのELBを CloudFormationで設置する方法を紹介させていただきます。

構成図

設定

UserData

  • Amazon Linux2の LAMP環境の設定は、以下を踏襲しています。

Amazon Linux2 のLAMP環境、PHP7.2とMariaDB10.2.10をUserDataで初期設置してみた

mariadb設定

  • WordPress 用 の新規データベースとDBユーザを作成します。
  - [ sh, -c, "cat /root/cloud-init/mysql/wordpress-db.sql | mysql -u root" ]
  - content: |
      CREATE DATABASE IF NOT EXISTS wordpress_db;
      GRANT USAGE ON wordpress_db.* to wordpress_user@"%" IDENTIFIED BY 'bbbbbbbb';
      GRANT USAGE ON wordpress_db.* to wordpress_user@"localhost" IDENTIFIED BY 'bbbbbbbb';
      GRANT ALL PRIVILEGES ON wordpress_db.* TO wordpress_user@"%";
      GRANT ALL PRIVILEGES ON wordpress_db.* TO wordpress_user@"localhost";
      FLUSH PRIVILEGES;
    mode: '000600'
    owner: root
    group: root
    path: /root/cloud-init/mysql/wordpress-db.sql

httpd設定

  • WordPress実行用のバーチャルホスト設定を実施します。
  • 「.htaccess」の有効化と、ドキュメントルートは「/var/www/wordpress」としました。
  - cp /root/cloud-init/httpd/wordpress.conf /etc/httpd/conf.d/
  - systemctl restart httpd
  - content: |
      <VirtualHost *:80>
        DocumentRoot /var/www/wordpress
        ServerName wp.example.com
        <Directory /var/www/wordpress/>
          AllowOverride All
          Require all granted
        </Directory>
        RewriteEngine On
      </VirtualHost>
    mode: '000644'
    owner: root
    group: root
    path: /root/cloud-init/httpd/wordpress.conf

wp-cli

  • WordPress のコマンドライン操作を可能にする wp-cli をインストールします。
  - wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -P /tmp
  - mv /tmp/wp-cli.phar /usr/local/bin/wp
  - chmod +x /usr/local/bin/wp

WordPressをコマンドラインでインストールしたい

WordPress インストール

  • wp-cli を 利用して、WordPressをインストールします。
  - wp core download --locale=ja --path=/var/www/wordpress
  - [ sh, -c, "cd /root/cloud-init/wp-cli/; wp core config" ]
  - wp core install --url=https://wp.example.com --title=cm-wordpress-sample --admin_user=admin --admin_password=cccccccc --admin_email=info@example.com --path=/var/www/wordpress

wp-cli.yml

  • WordPressの設定ファイル(wp-config.php) に反映する値を設定します。
  • WP_HOMEWP_SITEURLを明示する事で、 WordPressによる意図せぬリダイレクトの発動を回避 します。
  • インターネット、ELB(ALB) 間の通信は 常時HTTPSが実現された環境となるため $_SERVER['HTTPS'] = 'on' を設定します。ELB、EC2のVPC間通信が HTTPSに誘導される事を回避します。
  • define( 'AS3CF_AWS_USE_EC2_IAM_ROLE', true ); を設定します。画像データのS3オフロードを実現するWordPressのプラグイン「WP Offload Media Lite」アクセスキー利用を回避します。
  - content: |
      path: /var/www/wordpress
      url: https://wp.example.com
      user: admin
      core download:
        locale: ja
      core config:
        dbuser: wordpress_user
        dbpass: bbbbbbbb
        dbname: wordpress_db
        dbhost: 127.0.0.1
        extra-php: |
          define( 'WP_DEBUG', false );
          define('WP_HOME', 'https://wp.example.com');
          define('WP_SITEURL', 'https://wp.example.com');
          $_SERVER['HTTPS'] = 'on';;
          define('WP_LANG', 'ja');
          define( 'AS3CF_AWS_USE_EC2_IAM_ROLE', true );
          if ( defined( 'WP_CLI' ) && WP_CLI && ! isset( $_SERVER['HTTP_HOST'] ) ) {$_SERVER['HTTP_HOST'] = 'wp.example.com';}
       core install:
          admin_user: admin
          url: https://wp.example.com
          admin_password: cccccccc
          admin_email: info@example.com
          title: "cm-sample"
    mode: '000644'
    owner: root
    group: root
    path: /root/cloud-init/wp-cli/wp-cli.yml

プラグインインストール

  • S3オフロードを実現する WordPressのプラグイン「WP Offload Media Lite」をインストールします。
  - [ sh, -c, "cd /root/cloud-init/wp-cli/; wp plugin install amazon-s3-and-cloudfront" ]
  • WordPressのプラグイン画面で「WP Offload Media Lite」を有効化、出力先のS3バケットを設定する事で利用可能になります。

参考

AWS CloudFrontを使ってWordPressのメディアファイルだけS3に配置する

S3プラグインの設定

パーマリンク設定

  • パーマリンク設定を実施、「記事名.html」となるカスタム構造の設定を実施します、
  • wp-cli では パーマリンクの動作に必要な「.htaccess」が設置されません。これを補う操作となります。
  - wp --path=/var/www/wordpress rewrite structure '/%postname%.html'
  - cp /root/cloud-init/httpd/.htaccess /var/www/wordpress/
  - content: |
      <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.php$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]
      </IfModule>
    mode: '000644'
    owner: root
    group: root
    path: /root/cloud-init/httpd/.htaccess

ユーザデータ全文

#cloud-config
repo_update: true
repo_upgrade: all
packages:
  - jq
  - httpd
runcmd:
  - yum update -y
  # lamp-mariadb10.2-php7.2
  - amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2
  # mariadb
  - yum install mariadb-server -y
  - cp -b /root/cloud-init/mysql/my.cnf /etc/my.cnf
  ## systemctl
  - systemctl start mariadb
  - systemctl enable mariadb
  ## db-init
  # httpd
  ## xml,  mbstring , intl, mcrypt, gd
  - yum install php-xml php-xmlrpc php-mbstring php-intl php-pecl-mcrypt php-xsl php-gd -y
  ## keepalive
  - cp /root/cloud-init/httpd/keepalive.conf /etc/httpd/conf.d/keepalive.conf
  ## mod_http2 off
  - sed -i -e "s/^LoadModule/#LoadModule/g" /etc/httpd/conf.modules.d/10-h2.conf
  ## systemctl
  - systemctl enable httpd
  # WordPress
  ## db-init
  - [ sh, -c, "cat /root/cloud-init/mysql/wordpress-db.sql | mysql -u root" ]
  - [ sh, -c, "cat /root/cloud-init/mysql/db-secure_installation.sql | mysql -u root" ]
  - echo -e "[client]\npassword=\"aaaaaaaa\"" > /root/.my.cnf
  - chmod 400 /root/.my.cnf
  ## wordpress.conf
  - cp /root/cloud-init/httpd/wordpress.conf /etc/httpd/conf.d/
  - systemctl restart httpd
  ## wp-cli
  - wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar -P /tmp
  - mv /tmp/wp-cli.phar /usr/local/bin/wp
  - chmod +x /usr/local/bin/wp
  ## wordpress install
  - wp core download --locale=ja --path=/var/www/wordpress
  - [ sh, -c, "cd /root/cloud-init/wp-cli/; wp core config" ]
  - wp core install --url=https://wp.example.com --title=cm-wordpress-sample --admin_user=admin --admin_password=cccccccc --admin_email=info@example.com --path=/var/www/wordpress
  - wp --path=/var/www/wordpress rewrite structure '/%postname%.html'
  - cp /root/cloud-init/httpd/.htaccess /var/www/wordpress/
  - cp /var/www/html/robots.txt /var/www/wordpress/
  - chown -R apache:apache /var/www/wordpress 
  ## s3 plugin
  - [ sh, -c, "cd /root/cloud-init/wp-cli/; wp plugin install amazon-s3-and-cloudfront" ]
  ## clean
  - yum clean all

write_files:
   # /etc/my.cnf |
  - content: |
      [client-server]
      [mysqld]
      query_cache_type=1
      query_cache_size=32M
      character-set-server=utf8
      symbolic-links=0
      !includedir /etc/my.cnf.d
    mode: '000600'
    owner: root
    group: root
    path: /root/cloud-init/mysql/my.cnf
  # mysql_secure_installation (substitution)
  - content: |
      UPDATE mysql.user SET Password=PASSWORD('aaaaaaaa') WHERE User='root';
      DELETE FROM mysql.user WHERE User='';
      DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
      DROP DATABASE test;
      DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
      FLUSH PRIVILEGES;
    mode: '000600'
    owner: root
    group: root
    path: /root/cloud-init/mysql/db-secure_installation.sql
   # httpd
  - content: |
      KeepAlive On
      KeepAliveTimeout 120
    mode: '000644'
    owner: root
    group: root
    path: /root/cloud-init/httpd/keepalive.conf
   # robots.txt
  - content: |
      User-agent: *
      Disallow: /
    mode: '000644'
    owner: root
    group: root
    path: /var/www/html/robots.txt
   # wordpress_db
  - content: |
      CREATE DATABASE IF NOT EXISTS wordpress_db;
      GRANT USAGE ON wordpress_db.* to wordpress_user@"%" IDENTIFIED BY 'bbbbbbbb';
      GRANT USAGE ON wordpress_db.* to wordpress_user@"localhost" IDENTIFIED BY 'bbbbbbbb';
      GRANT ALL PRIVILEGES ON wordpress_db.* TO wordpress_user@"%";
      GRANT ALL PRIVILEGES ON wordpress_db.* TO wordpress_user@"localhost";
      FLUSH PRIVILEGES;
    mode: '000600'
    owner: root
    group: root
    path: /root/cloud-init/mysql/wordpress-db.sql
  # wp-cli.yml
  - content: |
      path: /var/www/wordpress
      url: https://wp.example.com
      user: admin
      core download:
        locale: ja
      core config:
        dbuser: wordpress_user
        dbpass: bbbbbbbb
        dbname: wordpress_db
        dbhost: 127.0.0.1
        extra-php: |
          define( 'WP_DEBUG', false );
          define('WP_HOME', 'https://wp.example.com');
          define('WP_SITEURL', 'https://wp.example.com');
          $_SERVER['HTTPS'] = 'on';;
          define('WP_LANG', 'ja');
          define( 'AS3CF_AWS_USE_EC2_IAM_ROLE', true );
          if ( defined( 'WP_CLI' ) && WP_CLI && ! isset( $_SERVER['HTTP_HOST'] ) ) {$_SERVER['HTTP_HOST'] = 'wp.example.com';}
       core install:
          admin_user: admin
          url: https://wp.example.com
          admin_password: cccccccc
          admin_email: info@example.com
          title: "cm-sample"
    mode: '000644'
    owner: root
    group: root
    path: /root/cloud-init/wp-cli/wp-cli.yml
  # wordpress.conf
  - content: |
      <VirtualHost *:80>
        DocumentRoot /var/www/wordpress
        ServerName wp.example.com
        <Directory /var/www/wordpress/>
          AllowOverride All
          Require all granted
        </Directory>
        RewriteEngine On
      </VirtualHost>
    mode: '000644'
    owner: root
    group: root
    path: /root/cloud-init/httpd/wordpress.conf
  # .htaccess
  - content: |
      <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.php$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php [L]
      </IfModule>
    mode: '000644'
    owner: root
    group: root
    path: /root/cloud-init/httpd/.htaccess

動作確認

  • Route53に登録した、ELBのDNS登録名にアクセスする事で、WordPressのログインが可能です。

https://<ELBのDNS登録名>/wp-login.php

まとめ

AmazonLinux2を利用した WordPress環境、CloudFormation を利用して作成する事が出来ました。

常時 HTTPS に対応したWordPressが動作するEC2環境、開発、検証用などで必要な場合にお試しください。

テンプレート

今回利用したCloudFormationテンプレートです。

事前に、 Route53 の HostedZone (ELBのDNSレコード登録先) と、ELBで利用利用可能なACM証明書を事前に用意、 DB、WordPress用のパスワード、EC2のセキュリティグループに反映するIPは、適切なものに変更してご利用ください。