連載
» 2016年06月23日 05時00分 公開

実際に検証済み!OSS徹底比較(3)サーバ構築自動化【前編】:OSSのサーバ構築自動化ツール、4製品徹底検証 2016年版 (8/9)

[森元敏雄,TIS]

AnsibleのplaybookのTIPS

1.playbookへのパラメータ受け渡し

 playbookで作成したファイルの紹介の部分でも記載したが、playbook内で使用するパラメータ変数の引き渡しは、playbookフォルダ内のsite.yamlの格納フォルダ直下のgroup_vars/host_varsから行われる。group_varsのファイル名はhostsファイルの[]の中のグループ名、host_varsのファイル名はホスト名となる。グループ名のファイルがない場合、group_vars/allの設定が読み込まれる。

 group_varsを読み込んだ後、host_varsのパラメータ値で上書きされるため、共通のパラメータをgroup_varsに、サーバ個々の設定をhost_varsに記述する形が運用上良さそうである。

 なお、group_vars/host_varsのファイルがyaml形式である。ファイル名に拡張子.yamlを付けても同じ処理が行われる。

$ cat ~/playbook/wordpress_sample/hosts
[wordpress-server]
tissvv096
$ cat ./playbook/wordpress_sample/group_vars/wordpress-server
# wordpress-server Paramaters
mysql_root_pass:  'password'
wordpress_latest: 'https://wordpress.org/latest.tar.gz'
wp_os_user:       'root'
wp_os_group:      'root'
wp_db_name:       'wordpress'
wp_db_user:       'wordpress'
wp_db_pass:       'password'
wp_unique_phrase:  'bMvc7W2eLuhKFewafVyirWJaXDhbSf'
$ cat ./playbook/wordpress_sample/host_vars/tissvv096
# Paramaters
mysql_root_pass : 'FM11AD2+'
wp_db_name:       'WordPress'
wp_db_user:       'wp_admin'
wp_db_pass:       'HB-F1XDJ'
wp_unique_phrase:  'FX702PFX801PPB100FX860PPB700PB500PB750PAI1000'

 playbookの内部では{{ 変数名 }}で参照することができる。

- name: modify /root/.my.cnf
  replace:
    dest=/root/.my.cnf
      regexp='@mysql_root_pass@'
      replace='{{ mysql_root_pass }}'

2.playbookの記述方法

 Ansibleのplaybookの記述方法は、公式サイトのAnsible Documentationに詳しく記載されているので、こちらを参照いただきたい。

(1)yumコマンドでのパッケージの制御

 yumコマンドでのパッケージのインストールはyum:モジュールを使用する。パッケージは1個ずつインストールする。

# install packages
- name: install mariadb-server
  yum: name=mariadb-server state=installed
- name: install
  yum: name=httpd state=installed

(2)serviceの起動制御

 serviceの起動(CentOS 7.2の場合、systemctlコマンド)の実行はservice:モジュールで行う。下記の例ではサービスの起動とenabledを設定している。

# start/enable mariadb
- name: start and enable mariadb
  service: name=mariadb state=running enabled=yes

(3)node上でのコマンドを実行

 playbook内でnode側で任意のコマンドを実行させることが可能である。コマンドは以下の2種類が提供されている。

コマンド 特長 用途
command: パラメータに指定されたコマンドをsh -cで実行する。node側の実行ユーザーの環境変数/PATH/aliasなどの影響がない。通常コマンドラインで使用できる "|" / ">" / "<" / "&"が使用できない node上での単純なコマンドの実行
shell: パラメータに指定されたコマンドをbashコマンドで実行する。codeのパラメータをいったん、/tmp以下の一時ファイルに作成するため、シェルスクリプトの制御処理を記述することもできる。さらに実行ユーザーの環境変数/PATH/aliasも使用できる。 処理制御やnode側の環境変数が必要な一時シェルスクリプトの実行

 command:もshell:も基本的な書式は同じである。単一行の場合はcommand:やshell:の後ろに1行で記載する。複数行の場合はcommand:やshell:の後ろに ">"を記述し、その次の行から実行したいコマンドを記載する。コマンドの行末は必ず ";"でなければならない。

 サンプルのplaybookではWordpressのtarファイル解凍後のchownの処理は、ファイルのownerとgroupを確認してchownが未完了の件数を取得し、その件数が0件以外だったらchownを実行するようにしている(shell:実行結果をregisterで変数に格納し、後続の判定に使用している)。

# chown wordpress files
- name: check wordpress files owner/group
  shell: 'find /var/www/wordpress -not -user {{ wp_os_user }} -or -not -group {{ wp_os_group }} | wc -l'
  register: lowcnt
- name: chown wordpress files
  shell: 'chown -R {{ wp_os_user }}:{{ wp_os_group }} /var/www/wordpress'
  when: not lowcnt.stdout == "0"

 shell:モジュールを複数行で実行させる方法を使えば、このような記述も可能である。ステップ数が短くなるメリットもあるが、実行された場合、中でchownが実施されたのかどうかまではplaybookでは判定できないデメリットもある。

# chown wordpress files
- name: chown wordpress files
  shell: >
    if test `find /var/www/wordpress -not -user {{ wp_os_user }} -or -not -group {{ wp_os_group }} | wc -l` != 0: then;
      shell: 'chown -R {{ wp_os_user }}:{{ wp_os_group }} /var/www/wordpress';
    fi;

(4)templateを使用したファイルの作成

 設定ファイルなどを新規に作成する場合、template:モジュールreplace:モジュールを組み合わせて使用する。template:モジュールはサーバ側であらかじめ作成しておいた設定のtemplateファイルをnode側にコピーする処理を行う。

$ cat ./playbook/wordpress_sample/roles/wordpress/templates/my.cnf
[client]
user = root
password = "@mysql_root_pass@"
[mysqladmin]
user = root
password = "@mysql_root_pass@"

 replace:モジュールはファイル中の文字列の書き換えを行う。書き換えには正規表現も使用できる。

 前述のtemplateファイルの書き換え部分の変数の前後に"@"を付与しているが、書式で規定されたものではなく、書き換え部分を明確にして、誤った書き換えを防止したい意図で付与している。

- name: modify wp-config.php unique phrase
  replace:
    dest=/var/www/wordpress/wp-config.php
      regexp='(^.*)put your unique phrase here(.*$)'
      replace='\1{{ wp_unique_phrase }}\2'

(5)設定処理の実行要否の判定

 再実行時の設定処理の実行要否の判定のためにはwhen:のパラメータが準備されており、ほぼ全てのモジュールで使用できる。when: "条件式" は条件式が"teue"の場合に、when: not "条件式" の場合は逆に"false"の場合に処理が実行される。ただ、「when:」の 後ろでは条件式が解釈できるのみで、コマンドが実行できるわけではない。そのため、ファイルの有無や件数などの確認は、shell:モジュールやstat:モジュールを実行して、事前に結果を取得することになる。

 ファイルの有無のチェックの例は以下の通りだ。resigterで取得できる値はstat:モジュールのマニュアルに記載されている。

# create /root/.my.cnf
- name: check /root/.my.cnf exists
  stat: path=/root/.my.cnf
register: flck
- name: copy /root/.my.cnf template
  template:
    src=my.cnf
    dest=/root/.my.cnf
    mode='600'
  when: not flck.stat.exists

 コマンドの実行による判定の例は以下の通りだ。resigterで取得できる値はshell:モジュールのマニュアルに記載されている。

 chown wordpress files
- name: check wordpress files owner/group
  shell: 'find /var/www/wordpress -not -user {{ wp_os_user }} -or -not -group {{ wp_os_group }} | wc -l'
  register: lowcnt
- name: chown wordpress files
  shell: 'chown -R {{ wp_os_user }}:{{ wp_os_group }} /var/www/wordpress'
  when: not lowcnt.stdout == "0"

(6)firewall設定用のモジュール

 firewallの設定変更には、firewall:モジュールを使用する。使用例は以下の通りだ。パラメータの最後にimmediate=yesを付けないと、firewall-cmd --reloadが実行されず、反映にfirewalldの再起動が必要となる。

# open httpd port in firewall
- name: open httpd port in firewall
  firewalld: zone=public service=http permanent=true state=enabled immediate=yes

(7)MySQL設定用のモジュール

 Ansibleには以下のMySQLの設定用のモジュールが提供されている。

 内部ではmysqlコマンドが使用されており、mariadbであっても使用が可能である。今回は、dbを作成するmysql_db:モジュールとユーザーを作成するmysql_user:モジュールを使用している。

 mysql_user:モジュールの使用例では、rootアカウントのパスワードを設定している。rootパスワード設定後はmariadbサービスを再起動する必要があるが、本モジュール側で対処されているため、再起動の処理を記述することは不要となる。

# set mariadb root password
- name: mariadb root password setting
  mysql_user:
    login_user='root'
    name='root'
    password='{{ mysql_root_pass }}'
    update_password=always

 次はmysql_db:モジュールの使用例である。作成したdbへのアクセス権の設定はmysql_user:モジュールで行うこととなる。

# create wordpres db/user
- name: create wordpress db create
  mysql_db:
    login_user='root'
    login_password='{{ mysql_root_pass }}'
    name='{{ wp_db_name }}'
    state=present

 なお、mysqlモジュールを利用する場合、node側にMySQL-pythonのインストールが必須となる。

(8)ファイルのダウンロード

 インターネット上のサイトなどからファイルをダウンロードするためにget_url:モジュールが提供されている。このモジュールを利用することで、url上のファイルとダウンロードしたファイルの日時やサイズを比較し、差異がある場合のみダウンロードを行うチェック処理も併せて行ってくれる。

- name: wordpress download
  get_url:
    url='{{ wordpress_latest }}'
    dest=/var/www/wordpress-latest.tgz

(9)圧縮ファイルの解凍、ファイルのコピー

 圧縮ファイルの解凍やファイルのコピーに利用できるunarchive:モジュールが提供されている。ただ、現行のバージョンで利用すると、"ERROR! file or module does not exist: [ファイル名]"のエラーが出力されてしまう。そのため、現状ではshell:モジュールを使用し、cpやtarコマンドで処理を行っている。この件はAnsibleのissues/932にも上がっている。

- name: copy wp-config-sample.php to wp-config.php
  shell: 'cp -p /var/www/wordpress/wp-config-sample.php /var/www/wordpress/wp-config.php'
- name: wordpress unarchive
  shell: 'tar zxvf /var/www/wordpress-latest.tgz'
  args:
   chdir: /var/www 

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。