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
を使った方がメンテナンスしやすいだろうなぁと思いました。