Ansible でリモートのファイルの内容を読み取る方法
はい。すいませんネタ切れですw 今回は小ネタも小ネタ、 Ansible の slurp モジュールについてです。 大して書くこともないので過去の Ansible の記事も貼っておきます。
innossh.hatenablog.com innossh.hatenablog.com innossh.hatenablog.com innossh.hatenablog.com
さて本題ですが、 Ansible を実行する際に対象のホスト上のファイルの内容を読み取って、その値を使って何か操作を行いたい時があります。例えば /var/log/message
内の特定のログを取得して、特定のサービスを再起動させたい、などでしょうか。
具体的な説明のために、今回は /etc/resolv.conf
の nameserver
を取得してみましょう。
何も考えずに playbook を書き始めるなら、単純に command, shell モジュールで grep を使うのがシンプルでしょうか。
tasks: - name: retrieve nameserver shell: "grep nameserver /etc/resolv.conf | cut -d' ' -f2" register: nameserver changed_when: False - name: print nameserver debug: var: nameserver.stdout
TASK [print nameserver] ***************************************************************************************************************************** ok: [ansible-sandbox_echo1_1] => { "nameserver.stdout": "127.0.0.11" }
ですが、もし専用のモジュールがあるなら command, shell モジュールを使うより良いですよね。 slurp モジュールというファイルの内容を読み取る機能があります。
slurp – Slurps a file from remote nodes — Ansible Documentation
slurp モジュールは次のように使います。
- name: slurp resolv.conf slurp: src: /etc/resolv.conf register: resolv_conf - name: set nameserver set_fact: nameserver: "{{ resolv_conf.content | b64decode }}"
content は base64 エンコードされているので、 decode してあげる必要があります。
上記のままではただファイルの内容を nameserver
の fact にセットしただけですので、 grep の時のように 127.0.0.11
をセットするには少しテクニックが必要です。
filter の regex_replace
を使うのですが、ファイルの内容に改行を含んでいると複数行を考慮した置換ができません。
そのため次のように、はじめに改行を置換してしまいましょう。
tasks: - name: slurp resolv.conf slurp: src: /etc/resolv.conf register: resolv_conf - name: set nameserver set_fact: nameserver: "{{ resolv_conf.content | b64decode | regex_replace('\n', ' ') | regex_replace('^.*nameserver ([^ ]+).*$', '\\1') }}" - name: print nameserver debug: var: nameserver
TASK [print nameserver] ***************************************************************************************************************************** ok: [ansible-sandbox_echo1_1] => { "nameserver": "127.0.0.11" }
今回は改行をスペースに置換しましたが、 slurp するファイルによります。 このようにして shell モジュールと grep を使用しなくても、ファイルの内容の特定の値を取得することができます。 以上あまり使い所がない小ネタでした。