【WordPress開発管理】(2) ansibleで複数サイトを1つのroleでデプロイする

複数サイトをansibleでデプロイするとき、同じようなroleを複数個作って管理する方法もありますが、「WordPressをデプロイする」と限ってしまえばtaskに差はなくなります。どうせなら変数だけを複数用意して、roleそのものは1つに収めたいです。

vhostの指定

前回のroles/site_wordpress/tasks/main.ymlをそのまま使うとします。

このtaskではサイトドメインを変数「{{vhost}}」としていました。
vhostはplaybookで指定します。

---
- hosts: prod
  sudo: yes
  gather_facts: yes
  roles:
    - { role: site_wordpress, vhost: 'blog.noldor.info', tags: [wp, noldor] }
    - { role: site_wordpress, vhost: 'b1.example.com'  , tags: [wp, b1] }
    - { role: site_wordpress, vhost: 'b2.example.com'  , tags: [wp, b2] }

これで同じroleで複数のドメインを管理でき、実行時にtagで対象ドメインを指定することもできます。

変数ファイル

roles/site_wordpress/vars/main.ymlは次のようにします。

---
conf:
  blog.noldor.info:
    under_construction: false
    use_ssl: no
    force_ssl: no
    force_nonssl: no
    wp_db_host:     dbhost
    wp_db_user:     dbuser
    wp_db_password: dbpass
    wp_db_name:     dbname
    wp_db_prefix:   wp_
    wp_salt:        CfaxPE8kizfMT3Be3tOsrxCJTgeskil1

  b1.example.com:
    under_construction: false
    use_ssl: true
    force_ssl: true
    force_nonssl: no
    wp_db_host:     dbhost
    wp_db_user:     dbuser
    wp_db_password: dbpass
    wp_db_name:     dbname
    wp_db_prefix:   blog_wp_
    wp_salt:      SpO9xo5CD2qjMLM7WJa5AolRt4PzYRGA

confの下にvhostの中身を持ってくることで、連想配列にします。
これでテンプレート上で「{{conf[vhost].wp_db_name}}」のように指定できます。
次の例はroles/site_wordpress/templates/wp-config.php.j2の一部です。

/** WordPress のためのデータベース名 */
define('DB_NAME', '{{conf[vhost].wp_db_name}}');

/** MySQL データベースのユーザー名 */
define('DB_USER', '{{conf[vhost].wp_db_user}}');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', '{{conf[vhost].wp_db_password}}');

/** MySQL のホスト名 */
define('DB_HOST', '{{conf[vhost].wp_db_host}}');

ユニークキーの生成

WordPressでは認証用ユニークキーを8つ用意する必要がありますが、変数ファイルに全部書くのは面倒です。自動生成してしまいましょう。
といっても、デプロイごとに変わっては毎回強制ログアウトされてしまうので、上記変数wp_saltをもとに生成します。

define('AUTH_KEY',         '{{(conf[vhost].wp_salt + "auth_key")|hash("md5")}}');
define('SECURE_AUTH_KEY',  '{{(conf[vhost].wp_salt + "secure_auth_key")|hash("md5")}}');
define('LOGGED_IN_KEY',    '{{(conf[vhost].wp_salt + "logged_in_key")|hash("md5")}}');
define('NONCE_KEY',        '{{(conf[vhost].wp_salt + "nonce_key")|hash("md5")}}');
define('AUTH_SALT',        '{{(conf[vhost].wp_salt + "auth_salt")|hash("md5")}}');
define('SECURE_AUTH_SALT', '{{(conf[vhost].wp_salt + "secure_auth_salt")|hash("md5")}}');
define('LOGGED_IN_SALT',   '{{(conf[vhost].wp_salt + "logged_in_salt")|hash("md5")}}');
define('NONCE_SALT',       '{{(conf[vhost].wp_salt + "nonce_salt")|hash("md5")}}');

jinja2のhashフィルタを使用してmd5ハッシュを生成しています。
強制ログアウトさせるにはwp_saltを別のものにすればOKです。管理画面もユーザ画面も構わず全部ログアウトですが、実用的には問題ないでしょう。

wp_hashはランダム文字列であれば何でもよいので、パスワード自動生成などを使うとよいです。
キーボードをガチャガチャしてもよいですが、記号にご注意を。

寄り道:変数ファイルにinclude_varsモジュールは使えないか?

taskの先頭でinclude_varsモジュールで次のようにして変数定義すれば、「conf[vhost]」を省略できるのではないかという発想をしました。

- include_vars: "{{vhost}}.yml"

{{vhost}}.ymlにはroles/site_wordpress/vars/main.ymlの内容をサイトごとにファイル分割して定義します。同じ変数名なら上書きされるので、期待通りに動きます。

まあ動くには動くのですが、あくまで上書きのため、ymlファイル間で定義変数に違ってしまうと厄介です。変数初期化漏れバグになり、tagの指定有無で実行結果が変わってしまいます。
具体的にはパラメータ追加時に追加漏れファイルを作りやすいです。ansible-vaultで暗号化しているでしょうからdiffも利かず、実用的ではありません。
では初期化用taskを追加すれば――とやるのもありですが、それよりはconf[vhost]の省略はあきらめて明示的に別変数にしてしまったほうが安全です。

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください