Ansible blockinfile v0.3

Ansible Logo

だいぶ前Ansibleblockinfile モジュール・ロール を作って公開したのですが、使ってくれる人が案外多かったようで、 GitHub プロジェクト ではスターをつけてくれる人だけでなく プルリクエストやイシューの作成をしてくれる人も出てきました。

作成当初からの TODO として lineinfile モジュール 的な insertafter/insertbefore オプションの追加がありましたが、 やはりこれがユーザの要望としては大きいようなので、 今回これを追加するべくコードを書きなおし、 v0.3 としてリリースしました。

新機能: insertafter/insertbefore オプション

blockinfile モジュールの insertafter/insertbefore オプションを使うと テキストブロックを新たに挿入する際にその場所を決めることができます。 すでにブロックが存在して、 その内容を更新する場合にはこれらのオプションは無視されます。

次の例では HTML ファイルの <body> タグの後ろに content オプションで指定したブロックを挿入しています。 (?i) は大文字小文字の違いを無視する Python 正規表現 の指定です。

- blockinfile:
    dest: /var/www/html/index.html
    marker: <!-- {mark} ANSIBLE MANAGED BLOCK -->
    content: |
      <h1>It works!</h1>
      <p>Welcome to {{ansible_hostname}}</p>
    insertafter: (?i)<body>

insertafter: regex を使うと regex にマッチした行の後ろに、 insertbefore: regex を使うと regex にマッチした行の前にブロックを挿入します。 特別な指定として、ファイルの末尾に挿入する insertafter: EOF と ファイルの先頭に挿入する insertbefore: BOF が使えます。

基本的に lineinfile モジュール と同じように行指向な動作をするため、 上記の例では HTML ファイル中の <body> に続いて同じ行に別のタグがあると 期待通りの動作をしないかもしれないことに注意してください。 そのときは事前に replace モジュール を使って <body> の直後に改行がなければ挿入しておくのがよいでしょう。

- replace:
    dest: /var/www/html/index.html
    regexp: (?i)(<body>)(?=.)
    replace: \1\n

なお今回の例では、モジュールにオプションを渡すのに key=value の文字列ではなくディクショナリの形式を使用しています (Playbook Language Example 参照)。 これは空白や改行、 クオート類を含むテキストをオプションに渡したいときには特に便利です。 自分は今ではほとんどこの形式のみでプレイブックを記述しています。

更新履歴

v0.2 では プルリクエスト での指摘を受けて follow オプションを使えるようにしました。 これは Ansible 1.8 で追加された共通モジュールオプションで、 シンボリックリンクを追跡するかどうかを指定します。

v0.3 では lineinfile モジュールを参考にしてほとんど書き直し、 insertafter/insertbefore オプションを追加しました。 不慣れな Python ですが、これでリストとスライス表記の扱いにだいぶ慣れた気がします。

さて、これで blockinfile モジュールの開発も一区切りつきましたので、次はいよいよ ansible-modules-extras に入れてもらうことを目指したいと思っています。

2015/04/26 01:44:43 JST