ときどきAnsible日記

主にITインフラ基盤の自動化に関する事を書いているブログです

AnsibleのModule:win_lineinfile

お疲れ様です。伊藤です。

すっかり年の瀬も近づき、師走の騒がしさも増してきた今日この頃。皆様いかがお過ごしでしょうか。
緩い内容をやるといった舌の根も乾かないうちですが、Moduleの記事を載せます。


基本的にAnsibleのModueは頭にwin_がついているものはWindows専用です。Windows以外のOS(と言ってもほとんどLinuxですが)では管理対象側で実行されるスクリプトpythonですが、Windowsの場合はPowerShellになります。なので、動くものは完全別物です。現在Moduleは1137本ほどありますが(2017/6/5時点)その中でWindowsの対象のものは56本しかありません。つまりLinuxでできることのホンの一部しかWindowsでできることはない、とご認識ください。

その中でもlineinfileはテキストの編集ができるModueですので、汎用性も高く比較的使う機会も多いかと思いますのでこちらに乗せたいと思います。


まずはModuleの解説です。
このモジュールは、ファイルを検索して、行が存在するかどうかを確認します。
これは、ファイル内の1行だけを変更したい場合に、主に有効です。

とのこと。つまりは1コマンドで編集できるのは1行のみ。複数行編集はできませんよと言っていますね。また、該当する行が存在する前提で話が進んでいます。これは以前記述したlineinfileと同じ問題(Ansibleでファイル編集を行いたい~そして見つかる致命的な弱点とは~ - ときどきAnsible日記)が発生する事を表しています。


とはいえ、今のところはこのModuleを使うほかはありません。というわけで引数は下記になります。

パラメータ 必須 デフォルト 選択肢 備考
backrefs no no yes or no state = presentとともに使用されます。 設定されている場合、行には、正規表現が一致した場合に読み込まれるバックリファレンス(定位置と名前付きの両方)を含めることができます。 このフラグは、モジュールの動作をわずかに変更します。 insertbeforeとinsertafterは無視され、regexpがファイル内のどこにも一致しない場合、ファイルは変更されません。正規表現が一致すると、最後に一致した行は、展開された行パラメータに置き換えられます。
backup no no yes or no タイムスタンプ情報を含むバックアップファイルを作成して、何らかの形で誤って元のファイルを戻すことができます。
create no no yes or no state = present で使用されます。 指定した場合、ファイルはまだ作成されていない場合に作成されます。 デフォルトでは、ファイルが見つからない場合は失敗します。
encoding no auto 操作するソーステキストファイルのエンコーディングを指定します。 デフォルトのautoを指定すると、モジュールはソースファイルのエンコードを自動検出し、変更されたファイルが同じエンコードで書き込まれるようにします。明示的なエンコーディングは、.NET FrameworkのSystem.Text.Encoding.GetEncoding()メソッドに渡す有効な値である文字列として渡すことができます。https://msdn.microsoft.com/en-us/library/systemを参照してください。これは、特定のエンコーディングで新しいファイルを作成する場合は、create = yesを使用すると最も便利です。 特定のエンコーディングを指定せずにcreate = yesを指定すると、デフォルトエンコーディングUTF-8、BOMなし)が使用されます。
insertafter no EOF EOF or *regex* state = presentとともに使用されます。 指定すると、指定された正規表現の最後の一致の後に行が挿入されます。 特別な値があります。 ファイルの最後に行を挿入するためのEOF。指定された正規表現にマッチがない場合は、代わりにEOFが使用されます。 バックファイルでは使用できません。
insertbefore no BOF or *regex* state = presentとともに使用されます。 指定すると、指定された正規表現の最後の一致の前に行が挿入されます。 値は利用可能です。 ファイルの先頭に行を挿入するためのBOF。指定された正規表現にマッチがない場合、その行はファイルの最後に挿入されます。 バックファイルでは使用できません。
line no state = present に必須です。 ファイルに挿入/置換する行。 backrefs が設定されている場合、正規表現が一致すると regexp キャプチャグループで展開される後方参照を含むことがあります。
newline no windows windows or unix 変更されたファイルに使用する行区切りスタイルを指定します。 これは、デフォルトではWindowsの行区切り文字(\ r \ n)になります。 指定された行区切り記号は、入力ファイルに表示される元の行区切り記号に関係なく、ファイル出力に使用されることに注意してください。
path yes 変更するファイルのパス。行の二重引用符を使用する場合は、Windowsパス区切り文字\を\\としてエスケープする必要があります。2.3以前では、このオプションはdest、destfile、およびnameとしてしか使用できませんでした。
regexp no ファイルのすべての行を検索する正規表現。 state = presentの場合、見つかった場合に置換するパターン。 見つかった最後の行だけが置換されます。 state = absentの場合、削除する行のパターン。 .NET互換の正規表現を使用します。 https://msdn.microsoft.com/en-us/library/hs600312%28v=vs.110%29.aspxを参照してください。
state no present present or absent 行が存在するかどうか。
validate no None 場所にコピーする前に実行する検証。 現在のファイルを確認するには、コマンドで%sを使用します。コマンドは安全に渡され、拡張やパイプなどのシェル機能は動作しません。

ほとんどlineinfileと同じですが、encoding辺りがWindowsだとキモになってきそうです。例によって行数指定などはできずに、検索した文字の前後に1行追加する、という形になります。

続いて記載例です。

# 2.3より前には、 'path'の代わりに 'dest'、 'destfile'または 'name'オプションを使用しました。
- win_lineinfile:
    path: C:\temp\example.conf
    regexp: '^name='
    line: 'name=JohnDoe'

- win_lineinfile:
    path: C:\temp\example.conf
    regexp: '^name='
    state: absent

- win_lineinfile:
    path: C:\temp\example.conf
    regexp: '^127\.0\.0\.1'
    line: '127.0.0.1 localhost'

- win_lineinfile:
    path: C:\temp\httpd.conf
    regexp: '^Listen '
    insertafter: '^#Listen '
    line: Listen 8080

- win_lineinfile:
    path: C:\temp\services
    regexp: '^# port for http'
    insertbefore: '^www.*80/tcp'
    line: '# port for http by default'

# 特定のエンコーディングで存在しない場合はファイルを作成する
- win_lineinfile:
    path: C:\temp\utf16.txt
    create: yes
    encoding: utf-16
    line: This is a utf-16 encoded file

# ファイルに行を追加し、結果のファイルがunix行区切り文字を使用していることを確認する
- win_lineinfile:
    path: C:\temp\testfile.txt
    line: Line added to file
    newline: unix

# backrefsを使用して行を更新する
- win_lineinfile:
    path: C:\temp\example.conf
    backrefs: yes
    regexp: '(^name=)'
    line: '$1JohnDoe'
Notes

以上です。本年のブログ更新はこれで終了となります。
半年間ブログを見てくださいました皆様、誠にありがとうございます。アクセス数をみてモチベーションを維持させていただいておりました。来年からも細々とですが記事は上げていきますので皆さま引き続き温かい目で見ていただけると幸いです。

それでは皆様よいお年を。