Ansibleでyamlファイルを編集する際、インデントを入れるのに苦戦しました。
忘れないように書いておきます。
ansible
ファイル編集
ファイル編集ですが、以下ような編集を行いたいと考えました。
編集前
111: aaa: bbb: ccc: ddd:
編集後
111: aaa: eee: fff: ggg: bbb: ccc: ddd:
上記の通り、eee~gggまでをaaaの次に入れるようにしたいと思いましたが、やってみると意外とうまくいきませんでした。
インデント込みの内容をファイルに反映出来ない
まずは単純に以下の方針でやろうとしました。
- ansible.builtin.lineinfileのsearch_stringで"aaa:"を検索する
- 検索にヒットした文字列の後にlineで複数行の文字列をインデント込みで挿入する
実際にはこういった感じです。
- name: Add eee-ggg ansible.builtin.lineinfile: path: /etc/xxx/xxx.yaml state: present firstmatch: yes search_string: "aaa: " line: | aaa: eee: fff: ggg:
実行結果
実行した結果、ファイルは以下の通りになります。
111: aaa: eee: fff: ggg: bbb: ccc: ddd:
aaa:の前に入れている空白2つが認識されない結果になりました。
調査
ぱっと見、最初の2つのインデントが認識されていないが、次の行からは空白が認識されているので、単純にもう2つ空白を入れればいけるかと思いましたが、結果は失敗でした。
- name: Add eee-ggg ansible.builtin.lineinfile: path: /etc/xxx/xxx.yaml state: present firstmatch: yes search_string: "aaa: " line: | aaa: eee: fff: ggg:
実行結果
111: aaa: eee: fff: ggg: bbb: ccc: ddd:
つまり、lineで複数行を指定するとき、文字列が始まるところまでの空白は認識してくれない(次の行以降は前の行で先頭から何個空白があったかは無視されるがそれ以降の空白は認識される)ことがわかりました。
ansibleの調査
ansibleでこれが回避できないか調べてみたところ、line:の後ろに数字を指定できることが判明。
line: | n
こんな感じ。
このnの意味ですが、先頭からn文字以降は文字列として認識してくれると理解しています。
なので、
- name: Add eee-ggg ansible.builtin.lineinfile: path: /etc/xxx/xxx.yaml state: present firstmatch: yes search_string: "aaa: " line: |4 aaa: eee: fff: ggg:
とやると、
111: aaa: eee: fff: ggg: bbb: ccc: ddd:
こんな感じで編集されます。
これでyamlファイルのインデントが入れられそうです。
希望のインデントを挿入する
yamlでインデントを合わせるために、以下の通りplaybookを編集。
- name: Add eee-ggg ansible.builtin.lineinfile: path: /etc/xxx/xxx.yaml state: present firstmatch: yes search_string: "aaa: " line: |2 aaa: eee: fff: ggg:
実行結果
111: aaa: eee: fff: ggg: bbb: ccc: ddd:
となりました。