先日、社内のAnsible勉強会(TUF研修)にてAnsibleを扱ったのですが、冒頭で挙げた方法があるか調べることがありました。今回はその調査結果と実際にplaybookにどのように落とし込んだのか、その書き方をまとめます。
※TUF研修ってなに?チョット気になるという方に向けてリンクを貼っておきます。
「実績がないならつくればいいーーAPCが挑むエンジニア育成のベストプラクティス」
結論から言うとAnsibleでも一般的なプログラミングでいうif文のような条件分岐をさせることは可能です。
今回はhandlersとstatの2つを採用しました。
Handlers
まずhandlersの書き方です。
・ここでは、以下の3つのタスクがあるとします。
- 常に実行するwordpress.tar.gzのダウンロードというget wp
- wordpress.tar.gzの展開というunarchive wp
- wordpress.tar.gzの中身のファイル群の所有者(オーナー)の変更をするchown wp user
・またunarchive wpとchown wp userは、get wpの実行前と実行後で差分が見られる場合(ここでは、初めてwordpress.tar.gzをダウンロードした場合)のみ実行するタスクとします。
いわば、get wpはunarchive wpとchown wp userにとってトリガーというわけです。
それでは、Handlersを使ってplaybookを書いてみましょう。
tasks:
- name: get wp #トリガー
get_url:
url: "{{ wp_url }}"
dest: "{{ wp_saved_at }}"
notify:
- unarchive wp #トリガーとなるタスクを実行後、実行前と比較して差分が見られる場合(changedとなる場合)、実行
- chown wp user #同上
handlers:
- name: unarchive wp #差分が見られる場合(changedとなる場合)、実行するタスク
unarchive:
src: "{{ wp_saved_at }}"
dest: "{{ wp_unarchived_at }}"
copy: no
- name: chown wp user #差分が見られる場合(changedとなる場合)、実行するタスク
file:
path: "{{ wp_unarchived_at }}/wordpress" #*1
owner: ansible
group: ansible
recurse: yes
*1 変数とベタ書きとを組み合わせて任意の値を指定することができます。
詳しくは[Ansible]変数とベタ書きとを組み合わせて値を指定する方法(超小ネタ)で取り上げているのでご参照ください。
ポイントは、トリガーの実行結果を踏まえてタスクの実行の有無を決めたいタスクはシーケンス形式(一般的なプログラミング言語では、配列、リストと同じような扱い)で定義するという点です。
なお、シーケンス形式で記載したタスク同士のいずれかをトリガーとするようなことはできるかは不明です。
stat
続いてstatです。
ところでなぜHandlersだけではなく、statも扱うことにしたのでしょう?
それは、statはHandlersと違ってif文のように想定した条件に合致した場合、指定したタスクを実行することができるからです。
今回、私はwordpress.tar.gzを外部からダウンロードするのは1度だけにしたかったので、wordpress.tar.gzの存在が確認できない場合のみ、ダウンロードするというタスクを実行することとしました。
---
- hosts: web
become: yes
vars:
wp_url: http://wordpress.org/latest.tar.gz
wp_saved_at: /tmp/wordpress.tar.gz
wp_unarchived_at: /var/www/html/
tasks:
- stat:
path: "{{ wp_saved_at }}" # *1 ls {{ wp_saved_at }}
register: already_saved # *2 *1の結果
- name: get wp
when: not already_saved.stat.exists # *3 *2で保存した*1の正常出力が確認できない場合
when: already_saved.stat.exists #正常出力が確認できる場合
get_url:
url: "{{ wp_url }}"
dest: "{{ wp_saved_at }}"
notify:
- unarchive wp
- chown wp user
実行するとこんな感じで出力されます。
TASK [get wp] ******************************************************************
skipping: [192.168.33.210]
追記
社内の@akira6592さんからフィードバックをいただき、下記のように書くとスマート!と教えていただいたので共有します。
chownのところをunarichiveに含めたかたちですね。
フィードバックありがとうございます。
tasks:
- name: unarchive wp
unarchive:
src: "{{ wp_url }}"
dest: "{{ wp_unarchived_at }}"
owner: ansible
group: ansible
参考
- [Handlers: Running Operations On Change - Ansible Documentation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html#handlers-running-operations-on-change
- Ansiblejp Slack Community #qa
- Using Ansible to check version before install or upgrade - The Accidental Developer
P.S. Twitterもやってるのでフォローしていただけると泣いて喜びます!
@gkzvoice