aws上に作成したansibleサーバーでテストサイトを構築する(8) WordPressの設定

# はじめに
[前回](https://qiita.com/yoshino_dd/items/1da42dc2d1446ec20526)で、WordPressから接続して使用するDBをRDS上に準備しましたので、WordPressのDB接続など、初期設定を行っていきます。

- aws上に作成したansibleサーバーでテストサイトを構築する
  1. [Ansibleサーバー構築](https://qiita.com/yoshino_dd/items/1e0969fd6dab1b51e1e0)
  1. [AWSネットワーク構成](https://qiita.com/yoshino_dd/items/d9be528837803ebb4bd3)
  1. [EC2インスタンスの作成](https://qiita.com/yoshino_dd/items/4368e468c6aa5353bf3c)
  1. [サーバー共通の設定](https://qiita.com/yoshino_dd/items/3fa56fc09e9162d6ad4a)
  1. [Webサーバーの構成](https://qiita.com/yoshino_dd/items/1292d6b3beeae26433f7)
  1. [RDSの構成-1](https://qiita.com/yoshino_dd/items/8d559b60d5b9f316d8bb)
  1. [RDSの構成-2](https://qiita.com/yoshino_dd/items/1da42dc2d1446ec20526)
  1. [WordPressの設定](https://qiita.com/yoshino_dd/items/d41694d468c5c64d78a0)
  1. 参考にしたサイトなど


# DB接続情報の設定

WordPressのDB接続情報は、`wp-config.php`に設定するようになっています。
前回までのPlaybookを実行すると、WordPress標準の初期設定ページに接続でき、そこでDB接続情報から設定していけるようになっていますが、ここではDBへの接続設定もAnsibleで実施するようにしたいと思います。

まず、WordPressのパッケージに含まれている`wp-config-sample.php`をコピーします。

```yaml:roles/wordpress/tasks/main.yml(追加分)
- name: copy from wp-cofnig-sample.php to wp-config.php
  shell: 'cp -p {{ wordpress_home }}/wp-config-sample.php {{ wordpress_home }}/wp-config.php && sleep 1'
  args:
    creates: '{{ wordpress_home }}/wp-config.php'
```

次に改行コードを変更します。

`https://ja.wordpress.org/`から取得したtar.gzでは`wp-config-sample.php`の改行コードがCR/LFとなっていました。

ansibleのモジュール(lineinfileなど)でファイルの変更をするとその部分だけLFの行となってしまうので、あらかじめ全体の改行コードをLFに変更しておきます。

```yaml:roles/wordpress/tasks/main.yml(追加分)
- name: Change CR/LF in wp-config.php to LF
  replace:
    path: '{{ wordpress_home }}/wp-config.php'
    regexp: '(.*)\r\n'
    replace: '\1\n'
``` 

WordPressのDB接続情報としては以下の4つの情報が必要となりますが、DBホスト名以外は`group_vars/all.yml`上で定義されています。

- DBホスト名
- データベース名
- データベース接続ユーザー名
- データベース接続パスワード

DBホスト名はAWS RDSのエンドポイント名となりますが、これはRDSインスタンス作成毎に代わるので以下のように情報を取得するタスクを追加します。

```yaml:role/wordrepss/tasks/main.yml(追加)
- name: Get RDS infomation
  connection: local
  run_once: true
  rds:
    command: facts
    instance_name: '{{ wordpress.dbname }}'
    region: '{{ vpc.region }}'
  register: rds_info
```

RDS情報の取得はIAMロールで権限を割り当てているAnsibleサーバーから実施することになるので、`connection: local`を指定しています。
また、複数のWebサーバーがあっても1度実行されればよいため、`run_once: true`も指定しています。

このタスクを実行すると`rds_info`の内容は以下のようになります。

```shell-session:command
ok: [web01] => {
    "rds_info": {
        "changed": false, 
        "failed": false, 
        "instance": {
            "DBName": "wordpress", 
            "allocated_storage": 5, 
            "auto_minor_version_upgrade": false, 
            "availability_zone": "ap-northeast-1a", 
            "backup_retention": 1, 
            "backup_window": "19:34-20:04", 
            "character_set_name": null, 
            "create_time": 1510712290.593, 
            "db_name": "wordpress", 
            "db_subnet_groups": {
                "description": "private subnet group for database", 
                "name": "database", 
                "status": "complete", 
                "subnets": [
                    {
                        "availability_zone": {
                            "name": "ap-northeast-1a", 
                            "provisioned_iops_capable": false
                        }, 
                        "identifier": "subnet-5ba42412", 
                        "status": "active"
                    }, 
                    {
                        "availability_zone": {
                            "name": "ap-northeast-1c", 
                            "provisioned_iops_capable": false
                        }, 
                        "identifier": "subnet-99768fc2", 
                        "status": "active"
                    }
                ], 
                "vpc_id": "vpc-8b59b5ec"
            }, 
            "endpoint": "wordpress.cskmve1egshc.ap-northeast-1.rds.amazonaws.com", 
            "engine": "mariadb", 
            "engine_version": "10.1.23", 
            "id": "wordpress", 
            "instance_type": "db.t2.micro", 
            "iops": null, 
            "latest_restorable_time": 1510719000.0, 
            "license_model": "general-public-license", 
            "maintenance_window": "fri:20:26-fri:20:56", 
            "multi_zone": false, 
            "option_groups": [
                {
                    "option_group_name": "default:mariadb-10-1", 
                    "status": "in-sync"
                }
            ], 
            "parameter_groups": [
                {
                    "parameter_apply_status": "in-sync", 
                    "parameter_group_name": "default.mariadb10.1"
                }
            ], 
            "pending_modified_values": {
                "allocated_storage": null, 
                "backup_retention_period": null, 
                "db_instance_class": null, 
                "db_instance_identifier": null, 
                "engine_version": null, 
                "iops": null, 
                "master_user_password": null, 
                "multi_az": null, 
                "port": null
            }, 
            "port": 3306, 
            "publicly_accessible": false, 
            "read_replica_source_dbinstance_identifier": null, 
            "replication_source": null, 
            "secondary_avaialbility_zone": null, 
            "status": "available", 
            "username": "wordpress", 
            "vpc_security_groups": "sg-b98a62c0"
        }
    }
}
```

上記の実行結果の`rds_info.instance.endpoint`がDBホスト名となります。
他の項目(DBユーザー等)と合わせて、`wp-config.php`を修正するタスクを追加していきます。

```yaml:roles/wordpress/tasks/main.yml(追加分)
- name: DB name is set
  replace:
    path: '{{ wordpress_home }}/wp-config.php'
    regexp: 'database_name_here'
    replace: '{{ wordpress.dbname }}'

- name: DB user is set
  replace:
    path: '{{ wordpress_home }}/wp-config.php'
    regexp: 'username_here'
    replace: '{{ wordpress.dbuser }}'

- name: DB password is set
  replace:
    path: '{{ wordpress_home }}/wp-config.php'
    regexp: 'password_here'
    replace: '{{ wordpress.dbpass }}'

- name: DB host name is set
  replace:
    path: '{{ wordpress_home }}/wp-config.php'
    regexp: 'localhost'
    replace: '{{ rds_info.instance.endpoint }}'
```

# WordPressの認証用ユニークキー設定

WordPressにログインした時に発行されるCookieの情報を暗号化する際に使用する情報としていくつかのユニークキーを設定する必要があります。

このキーは、WordPressのサイトに[オンラインジェネレーター](https://api.wordpress.org/secret-key/1.1/salt/)が設置されているので、そちらから情報を取得して設定するようにします。

なお、こちらのタスクについては、全面的に翔泳社の[Ansible徹底入門](http://www.shoeisha.co.jp/book/detail/9784798149943)を参照しています。

## ユニークキーの取得

このタスクは、デバッグなどで複数回実行されることが考慮されており、block/rescueを使用して設定されて以下のように構成されています。

1. 前回実行時に取得したユニークキーがファイルに保存されていた場合にはそれを読み込む。
1. もし、ファイルの読み込みに失敗した場合は、オンラインジェネレーターからユニークキーを取得する。(rescue節)
1. 先行の2タスクの結果のうち、有効なものを変数にセットする。(always節-1)
    * この処理は、commandモジュールでファイルからcatした結果とuriモジュールでAPIから取得した結果が、同じ方法で参照できない(contentとstdout)ために必要となります。
1. 変数にセットされたユニークキーを各Webサーバーでファイルに格納する。(always節-2)

今回は同じサイトを複数のフロントエンドサーバーで構成することようにしますが、同じサイトに複数のユニークキーがあると問題なので、1、2、3の処理については、1つのホストのみで実行されるよう`run_once: true`をつけています。

逆に、4の処理についてはPlaybook再実行時にどのホストで実行されてもよいように、すべてのホストで同じ情報を保存しておくため、`run_once`は使用していません。

```yaml:roles/wordpress/tasks/main.yml(追加分)
- block:
    - name: Read Unique key file
      run_once: true
      command: "cat {{ wordpress_home }}/unique_keys"
      changed_when: false
      register: cat_unique_keys
  rescue:
    - name: Generate Unique key
      run_once: true
      uri:
        url: https://api.wordpress.org/secret-key/1.1/salt/
        return_content: true
      register: get_unique_keys
  always:
    - name: Set Unique key to `unique_keys`
      run_once: true
      set_fact:
        unique_keys: "{{ (get_unique_keys.content if cat_unique_keys | failed else cat_unique_keys.stdout) | trim }}"
    - name: Store Unique key in a file
      copy:
        backup: true
        content: "{{ unique_keys }}"
        dest: "{{ wordpress_home }}/unique_keys"
```

## WordPressへユニークキーを設定

前の節で取得、保存したユニークキーをWordPressの設定ファイル`wp-config.php`に書き込みます。

編集前の当該箇所は以下のようになっています。

```php:wp-config.php(対象部分)
/**#@+
 * 認証用ユニークキー
 *
 * それぞれを異なるユニーク (一意) な文字列に変更してください。
 * {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org の秘密鍵サービス} で自動生成することもできます。
 * 後でいつでも変更して、既存のすべての cookie を無効にできます。これにより、すべてのユーザーを強制的に再ログインさせる
ことになります。
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

/**#@-*/
```

そこで、lineinfileモジュールを使用して、最後のdefine行を前節の`unique_keys`に置換します。
`unique_keys`には複数の行が含まれていますが、問題なく置換できました。

```yaml:roles/wordpress/tasks/main.yml(追加分)
- name: Write unique keys in wp-config.php
  lineinfile:
    path: '{{ wordpress_home }}/wp-config.php'
    regexp: "'NONCE_SALT',.*'put your unique phrase here'"
    line: "{{ unique_keys }}"
    backrefs: true
```

その後、不要な行の削除を行います。

```yaml:roles/wordpress/tasks/main.yml(追加分)
- name: Delete unnecessary setting lines
  lineinfile:
    path: '{{ wordpress_home }}/wp-config.php'
    regexp: "^define.*put your unique phrase here'"
    state: absent
```

ここまでで、テスト用インフラとしてのWordPressのインストールは完了とします。

Playbookを実行後、`http://<IPアドレス>/wordpress/`にアクセスすることでDB設定後のWordPressインストールページにアクセスできます。
設定を進めていくとWordPressを使用することができるようになっています。

# 次回

次回は、Webサーバーを複数に増やし、ロードバランサーの作成を行っていきます。

---
---