Ansible の block ディレクティブを使ってみて良かったこと
インフラグループの Morikawa です。
今回は Ansible 2.0 でリリースされた block ディレクティブ について、ここ 1 年半ほど使ってみて便利だったシーンをピックアップしてみようと思います。
個人的に良くなったと思うのは以下の 3 つでした。
- tags 設定が集約できる
- 条件分岐の集約ができる
- タスクの階層が見た目でも分かりやすい
これらのメリットについて、PostgreSQL サーバのインストールを例にとって説明したいと思います。
block ディレクティブの無い Playbook
block ディレクティブを用いずに書いた場合の Playbook の一例が以下となります。
なお、個々のタスクを処理内容ごとに部分的に実行可能とするため、私が Playbook を書く際は原則タスクに対して tags の設定を行うことにしており、下記の Playbook もそのようなルールで書いています。
- yum:
name: postgresql-server
tags:
- postgresql-server
- postgresql-server-install
- stat:
path: /var/lib/pgsql/data/postgresql.conf
register: postgresql_conf
tags:
- postgresql-server
- postgresql-server-init
- shell: /usr/bin/initdb -D /var/lib/pgsql/data -E UTF-8 --no-locale
become: yes
become_user: postgres
tags:
- postgresql-server
- postgresql-server-init
when: postgresql_conf.stat.exists == false
- stat:
path: /var/lib/pgsql/data/postgresql.conf
register: postgresql_conf
tags:
- postgresql-server
- postgresql-server-config
- lineinfile:
dest: /var/lib/pgsql/data/postgresql.conf
regexp: ^[#\s]*listen_addresses\s*=
line: "listen_addresses = '*'"
tags:
- postgresql-server
- postgresql-server-config
when: postgresql_conf.stat.exists == true
- lineinfile:
dest: /var/lib/pgsql/data/postgresql.conf
regexp: ^[#\s]*log_filename\s*=
line: "log_filename = 'postgresql-%Y-%m-%d_%H%M%S'"
tags:
- postgresql-server
- postgresql-server-config
when: postgresql_conf.stat.exists == true
- lineinfile:
dest: /var/lib/pgsql/data/postgresql.conf
regexp: ^[#\s]*log_filename\s*=
line: "log_filename = 'postgresql-%Y-%m-%d_%H%M%S'"
tags:
- postgresql-server
- postgresql-server-config
when: postgresql_conf.stat.exists == true
- service:
name: postgresql
state: started
enabled: yes
tags:
- postgresql-server
- postgresql-server-start
block ディレクティブで書き換えた Playbook
上記 Playbook を block ディレクティブを使って書き直すと、例えば以下のようになります。
- block:
- yum:
name: postgresql-server
tags: postgresql-server-install
- block:
- stat:
path: /var/lib/pgsql/data/postgresql.conf
register: postgresql_conf
- shell: /usr/bin/initdb -D /var/lib/pgsql/data -E UTF-8 --no-locale
become: yes
become_user: postgres
when: postgresql_conf.stat.exists == false
tags: postgresql-server-init
- block:
- stat:
path: /var/lib/pgsql/data/postgresql.conf
register: postgresql_conf
- block:
- lineinfile:
dest: /var/lib/pgsql/data/postgresql.conf
regexp: ^[#\s]*listen_addresses\s*=
line: "listen_addresses = '*'"
- lineinfile:
dest: /var/lib/pgsql/data/postgresql.conf
regexp: ^[#\s]*log_filename\s*=
line: "log_filename = 'postgresql-%Y-%m-%d_%H%M%S'"
- lineinfile:
dest: /var/lib/pgsql/data/postgresql.conf
regexp: ^[#\s]*log_filename\s*=
line: "log_filename = 'postgresql-%Y-%m-%d_%H%M%S'"
when: postgresql_conf.stat.exists == true
tags: postgresql-server-config
- service:
name: postgresql
state: started
enabled: yes
tags: postgresql-server-start
tags:
- postgresql-server
block ディレクティブにより得られるメリット
tags 設定が集約できる
block ディレクティブがない状態では、個々のタスクごとに tags を書く以外には、rule や include 単位で tags を設定する方法しか無く、一つの Playbook ファイル内に記載するタスクを役割ごとに分けたり、特定の処理群に tags を設定するのは結構な手間でした。
block ディレクティブにより、複数のタスクは block 内に含め、その block に対して tags を設定する方法が取れるようになったため、tags を記述する手間が省けるとともに、特定の tags に含まれるタスクがどれか、といったことも視覚的に把握しやすくなりました。
上記の例でいうと、 postgresql-server-config など綺麗にまとめることができています。
条件分岐の集約ができる
tags 以外に、when 句による条件分岐についても block ディレクティブで集約が可能です。
上記の例では、設定ファイルの変更について /var/lib/pgsql/data/postgresql.conf の存在を確認した結果を用いて、対象の設定ファイルの書き換えを行っています。
従来の場合タスクごとに when の記載が必要ですが、block を利用することで when の記載が 1 箇所で済みます。また、視覚的にも把握がしやすいメリットがあります。
タスクの階層が見た目でも分かりやすい
tags や when の記載の有無を別にしても、block によりタスクをグルーピングすることができるため、従来のようにタスクが全てフラットに並ぶ書き方に比べ、一連の処理群についてまとまりを視覚的に把握しやすいと言えるでしょう。
まとめ
今回は Ansible 2.0 で追加された block ディレクティブについて、実際に使ってきた経験を踏まえて簡単な記事にさせてもらいました。
ソースコードの読みやすさが大切なように、 Playbook も読みやすさは重要と思います。最近私が Playbook を記述する際はほぼ必ず block ディレクティブは利用するようにしていますし、過去書いたものも時間があれば block ディレクティブで書き直すなどしています。
余談ですが、block に rescue や always を組み合わせて利用することで、タスクの例外処理も可能になります。これまで ignore_errors を用いたり結果のステータスを保存した変数で条件分岐していたりしていた部分もより簡潔にかけるはずなので、活用してみたいと考えています。
たまたまトライコーンの場合はインフラ周りのエンジニアからサーバ構築・運用のコスト軽減のために Ansible の導入を進めてきましたが、最近は開発系のエンジニアもいじるようになってくれており、徐々にサーバの構成管理もコード化が進んできていて、良い感じです。
それでは




ディスカッション
コメント一覧
まだ、コメントがありません