ときどきAnsible日記

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

AnsibleのModule:lineinfile

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

今回はファイルを編集するlineinfileについて記述します。実は初期構築とか運用と化しているとかなりの確率でファイルを変更することがあります。そのときに主に使うことになるのがこちらかと思います。

説明文は下記になります。
このモジュールは、ファイルを検索して、行が存在するかどうかを確認します。
これは、ファイル内の1行だけを変更したい場合に、主に有効です。 複数の類似した行を変更する場合は、replaceモジュールを参照するか、ファイル内に行のブロックを挿入/更新/削除する場合はblockinfileをチェックしてください。 それ以外の場合は、コピーモジュールまたはテンプレートモジュールを参照してください。


使ってみるとわかりますが、普通にファイルを編集しようとするとかなり苦労します。。。しかしながらこのモジュールが一番細かい指示が出せるので、これでダメったらshellなりcommandなりでLinuxコマンドで直接編集する、という事が必要となります。

実はAnsibleでファイルを編集するModuleはlineinfile、replace、blockinfileの3つだけなのですが、すべてのモジュールで致命的な欠点があると思っています。それは編集対象行が指定できない、というところです。編集対象についてはあくまで対象になる文字列を検索して、その前後に挿入する指定しか出来ません。これがかなり辛い状況です。(詳細はAnsibleでファイル編集を行いたい - ときどきAnsible日記をご参照ください)


パラメータは以下です。

パラメータ 必須 デフォルト 選択肢 備考
attributes no None ファイルまたはディレクトリに必要な属性。 サポートされているフラグを取得するには、ターゲットシステムの chattr のマニュアルページを参照してください。 この文字列には、 lsattr で表示されているものと同じ順序で属性を含める必要があります。aliases: attr
backrefs no no yes or no state = present で使用されます。 設定されている場合は、 regexp が一致した場合に入力されるバックリファレンス(定位置と名前付きの両方)を行に含めることができます。 このフラグは、モジュールの動作を少し変更します。 insertbefore と insertafter は無視され、 regexp がファイルのどこにも一致しない場合、ファイルは変更されません。
backup no no yes or no タイムスタンプ情報を含むバックアップファイルを作成して、何らかの形で誤って元のファイルを戻すことができます。
create no no yes or no state = present で使用されます。 指定した場合、ファイルはまだ作成されていない場合に作成されます。 デフォルトでは、ファイルが見つからない場合は失敗します。
group no chownに供給されるような、ファイル/ディレクトリを所有すべきグループの名前。
insertafter no EOF EOF or *regex* state = present で使用されます。 指定すると、指定された正規表現の最後の一致の後に行が挿入されます。 特別な値があります。 ファイルの最後に行を挿入する EOF 。 指定した正規表現にマッチがない場合は、代わりにEOFが使用されます。 backrefs では使用できません。
insertbefore no BOF or *regex* state = present で使用されます。 指定すると、指定された正規表現の最後の一致の前に行が挿入されます。 値は利用可能です。 ファイルの先頭に行を挿入する BOF 。 指定された正規表現に一致するものがない場合、その行はファイルの最後に挿入されます。 backrefs では使用できません。
line no state = present に必須です。 ファイルに挿入/置換する行。 backrefs が設定されている場合、正規表現が一致すると regexp キャプチャグループで展開される後方参照を含むことがあります。
mode no ファイルまたはディレクトリをモードにする必要があります。 / usr / bin / chmod でモードが実際には0644のような8進数であることを覚えている人のために。 先行ゼロを離れると、予期しない結果が生じる可能性があります。 バージョン1.8では、モードはシンボリックモード(たとえば、 u + rwx または u = rw、g = r、o = r )として指定できます。
others no ファイルモジュールで受け入れられるすべての引数もここで動作します。
owner no chown に供給されるファイル/ディレクトリを所有するユーザーの名前。
path yes 変更するファイル。
regexp no ファイルのすべての行を検索する正規表現。 state = presentの場合、見つかった場合に置換するパターン。見つかった最後の行だけが置換されます。 state = absentの場合、削除する行のパターン。 Python正規表現を使用します。 http://docs.python.org/2/library/re.htmlを参照してください。
selevel no s0 SELinuxファイルコンテキストのレベル部分。 これは、MLS / MCS属性であり、 range と呼ばれることもあります。 _default 機能は seuser のように機能します。
serole no SELinuxファイルコンテキストの役割部分、 _default 機能は seuser のように機能します。
setype no SELinuxファイルコンテキストのタイプ部分、 _default 機能は seuser のように機能します。
seuser no SELinuxファイルコンテキストのユーザ部分。 該当する場合、システムポリシーをデフォルトにします。 _default に設定されている場合、利用可能であれば、ポリシーの user 部分が使用されます。
state no present present or absent 行が存在するかどうか。
unsafe_writes no 通常、このモジュールでは、アトミック操作を使用してデータの破損やターゲットファイルからの一貫性のない読み込みを防止しています。 1つの例は、ドッカーがマウントしたファイルです。アトミックに更新することはできず、安全でない方法でのみ実行できます。このブーリアンオプションは、tのファイルを更新する安全でない方法にフォールバックすることを可能にします。
validate no None 場所にコピーする前に実行する検証コマンド。 検証するファイルへのパスは、以下の例のように存在しなければならない '%s'経由で渡されます。 コマンドは安全に渡され、拡張やパイプなどのシェル機能は機能しません。


例文はこちら

# 2.3より前には、'path'の代わりに 'dest'、'destfile'または'name'オプションを使用しました。
- lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: 'SELINUX=enforcing'

- lineinfile:
    path: /etc/sudoers
    state: absent
    regexp: '^%wheel'

- lineinfile:
    path: /etc/hosts
    regexp: '^127\.0\.0\.1'
    line: '127.0.0.1 localhost'
    owner: root
    group: root
    mode: 0644

- lineinfile:
    path: /etc/httpd/conf/httpd.conf
    regexp: '^Listen '
    insertafter: '^#Listen '
    line: 'Listen 8080'

- lineinfile:
    path: /etc/services
    regexp: '^# port for http'
    insertbefore: '^www.*80/tcp'
    line: '# port for http by default'

# 正規表現を渡さずにファイルが存在しない場合は、ファイルに行を追加する
- lineinfile:
    path: /tmp/testfile
    line: '192.168.1.99 foo.lab.net foo'

# wheel行のコメント削除 YAMLドキュメントのGotchasを参照してください。
- lineinfile:
    path: /etc/sudoers
    state: present
    regexp: '^%wheel\s'
    line: '%wheel ALL=(ALL) NOPASSWD: ALL'

# Yamlはバックスラッシュを二重引用符でエスケープする必要がありますが、一重引用符ではエスケープする必要はありません
- lineinfile:
    path: /opt/jboss-as/bin/standalone.conf
    regexp: '^(.*)Xms(\\d+)m(.*)$'
    line: '\1Xms${xms}m\3'
    backrefs: yes

# 保存する前にsudoersファイルを検証する
- lineinfile:
    path: /etc/sudoers
    state: present
    regexp: '^%ADMIN ALL='
    line: '%ADMIN ALL=(ALL) NOPASSWD: ALL'
    validate: 'visudo -cf %s'


lineinfileについては一旦これで終了です。お疲れ様でした。