lineinfile
Ansibleでファイルに行を追記したり置換したりした場合、lineinfileを使うことが多いと思いますが、複数行追加したい場合だと、ちょっとやりずらいところがあります。
下記のように書くと、テキスト内に指定した行の内容がなければ末尾に追加されるので、それを繰り返すことによって末尾に複数行入れられます。
tasks: - name: 末尾に複数行追加 lineinfile: dest=./test.txt line={{ item }} with_items: - '1行目' - '2行目'
これが特定の箇所に入れようとすると面倒になります。
たとえば、insertafterを使って指定した行の後に入れようとして、下記のように書くと、、
tasks: - name: 特定の場所に追加 lineinfile: dest=./test.txt insertafter='^# xxxx' line={{ item }} with_items: - '1行目' - '2行目'
順番が逆に並ぶことになります。
# xxxxx 2行目 1行目
これは、insertafterにマッチした箇所の後に追加するといったことを単に2回繰り返しているためなので、
# xxxxx 1行目
# xxxxx 2行目 1行目
といった形で入っていくためです。
blockinfile
そもそもlineinfileは複数行を扱うのに向いていないので、複数行を扱えるモジュールのblockinfileを使うと良さそうです。
blockinfileは、extraモジュールに現在はあるように見える(GitHubのリポジトリには存在する)のですが、Ansibleのバージョンが古いとextraにいないので、その場合には ansible-galaxy でインストールします。(1.9.4 では入ってませんでした)
ansible-galaxy install yaegashi.blockinfile
blockinfileを使うと、contentに指定した内容をそのまま入れることができます。(rolesにansible-galaxyでインストールしたblockinfileのロールを指定する必要があります)
- hosts: all roles: - yaegashi.blockinfile tasks: - name: 特定の場所に追加 blockinfile: dest: ./test.txt insertafter: '^# xxxx' content: | 1行目 2行目
内容の前後にmarkerで指定した内容が入ります。デフォルトだと下記のような感じです。
# xxxxx # BEGIN ANSIBLE MANAGED BLOCK 1行目 2行目 # END ANSIBLE MANAGED BLOCK
markerの範囲を一つの内容として扱うので、中身を書き換えるのも結構楽です。
たとえば、先ほどのテキスト内容から、下記を実行すると、
tasks: - name: 特定の場所に追加 blockinfile: dest: ./test.txt insertafter: '^# xxxx' content: | #1行目 2行目
markerの範囲のものを置き換えてくれます。
# xxxxx # BEGIN ANSIBLE MANAGED BLOCK #1行目 2行目 # END ANSIBLE MANAGED BLOCK
後から追加した行の内容が変わる可能性があるならば、1行だったとしても、blockinfileを使った方がメンテナンスしやすいだろうなぁと思いました。