BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【Ansible】Ansibleを使ったテキストの書き換え

 こんにちは!
 BFT名古屋支店の佐野です。

 これまでの記事で、lineinfileとblockinfileという管理対象のテキストファイルに文字列追加、または更新を行なうモジュールを紹介してきました。
 これらのモジュール、特にlineinfile関しては指定したテキストを別のテキストに置き換えるということも可能なのですが、その場合単一の文字列の書き換えを行なうことしかできません。
 「一定の文字列になっている複数の箇所を、指定の文字列に一度に書き換えたい」といった場合には、lineinfileモジュールではなくreplaceモジュールを使用します。
 今回はテキストの書き換えを行なう上でのlineinfileモジュールとreplaceモジュールの違いと、その使用例について解説をいたします。


はじめに:lineinfileモジュールとreplaceモジュールの違い

 テキストの書き換え(変更)を行なう場合におけるlineinfileモジュールとreplaceモジュールの大きな違いは“書き換える場所を列で判断するか文字列で判断するか”になります。
 lineinfileについては以前の記事でも解説をしておりますが、1行の文字列を変更するものとなり、その行を特定するために行内に含まれるテキストを正規表現にて指定する形式を取っています。
 対してreplaceは単純に指定した文字列をテキストファイル内から探し出し、条件に合致する箇所をすべて変更する処理を行ないます。
 そのため、lineinfileと違って複数個所の変更を一度に行なうことができますが、細かな行指定といったことはできません。

 基本的には、特定の行や箇所のみをピンポイントに変える時はlineinfileモジュールを使用し、複数ある箇所に対して一斉に同じ変更を行なう場合はreplaceモジュールを使うといった形になるかと思います。

 replaceモジュールの公式ドキュメントはこちらになります。


テキストファイル内の文字列を指定したものに書き換えるPlaybook

 今回は例として、CentOS立ち上げ時にChronyに設定されている初期NTPサーバー「centos.pool.ntp.org」を、設定ファイルであるchrony.confからコメントアウトによって無効化するPlaybookを紹介します。
 本来であればreplaceモジュールによってコメントアウト後、新たなNTPサーバーをlineinfileモジュールなどを使用して追加するような形となりますが、今回はreplaceモジュールの活用にのみ着目し、NTPサーバーの追加に関しては割愛します。
 構文としては、以下のようになります。

- hosts: all

  tasks:
  - name: disable pool ntp servers
    replace:
      dest=/etc/chrony.conf
      regexp='^(server \d+.centos.pool.ntp.org iburst)'
      replace='# \1'

 オプションの解説としては、まず「dest」で編集対象となるファイルのパスを指定し、「regexp」で変更する部分の文字列を正規表現にて指定します。
 そして「replace」で、regexpで指定した部分に対して行なう変更の内容を記述するという形となります。


さいごに:replaceモジュールを使用する際の注意点

 以上がreplaceモジュールを使用したテキストの書き換え方法の解説となります。
 replaceモジュールを利用する際に注意するべき点としては、やはりregexpで指定した条件に該当する箇所すべてを変更してしまうということかと思います。
 意図しない場所が条件に該当してしまった場合、管理対象としたクライアントのテキストファイルすべてにおいて間違った変更が行われることとなってしまうからです。
 それを防ぐために、replaceモジュールを利用する際は特に「実行した際に意図しない変更が起きるかどうか」の前検討が必要となります。

 以上となります。
 お読みいただきありがとうございました。