Ansible Playbook で localhost でタスクを実行する方法

Ansible

Ansible Playbook ( ansible-playbook )で localhost (ローカル環境)でタスクを実行する方法についてです。 必要になる度に方法を調べている気がするので、ここにかんたんにまとめておきます。

環境

動作確認には以下のバージョンを使いました。

  • Python 3.9 (3.9.5)
  • Ansible 4.x (4.1.0)

Ansible 環境として以下のファイルを作成済みとします。

  • ansible.cfg
  • playbooks/show-term.yml

それぞれ中身は次のとおりです:

ansible.cfg:

[defaults]
stdout_callback = yaml
verbosity = 1

playbooks/show-term.yml:

- hosts: all
  gather_facts: no
  tasks:
    - ansible.builtin.command:
        cmd: echo $TERM

Ansible Playbook で localhost でタスクを実行する方法

いくつか方法があります。

  • 方法 A) コマンドラインオプションで指定する
  • 方法 B) インベントリ設定で指定する
  • 方法 C) プレイブックで指定する
  • 方法 D) タスクで指定する

方法 A) コマンドラインオプションで指定する

ansible-playbook コマンドのコマンドラインオプションで指定する方法です。

ansible-playbook \
  --connection=local \
  -i localhost, \
  --limit localhost \
  playbooks/show-term.yml 

オプションの --connection=local-i--inventory ) と --limit を使用します。 -i localhost, の末尾の , はタイポではありません。

手元の環境で実行すると次のような出力が出ました:

ansible-playbook --connection=local -i localhost, --limit localhost playbooks/show-term.yml 
Using /path/to/ansible-playbook-localhost-examples/ansible.cfg as config file

PLAY [all] **********************************************************************

TASK [ansible.builtin.command] **************************************************
[WARNING]: Platform darwin on host localhost is using the discovered Python
interpreter at /usr/bin/python, but future installation of another Python
interpreter could change the meaning of that path. See https://docs.ansible.com/
ansible/2.11/reference_appendices/interpreter_discovery.html for more
information.
changed: [localhost] => changed=true 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  cmd:
  - echo
  - $TERM
  delta: '0:00:00.007343'
  end: '2021-06-22 18:07:43.223739'
  rc: 0
  start: '2021-06-22 18:07:43.216396'
  stderr: ''
  stderr_lines: <omitted>
  stdout: xterm-256color
  stdout_lines: <omitted>

PLAY RECAP **********************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

localhost で実行されたことが確認できます。 Python インタプリタについての警告が出ますが、ここはあまり重要ではありません。

この A) の方法はかんたんなテスト・動作確認以外で使うことはまず無いものと思います。

方法 B) インベントリ設定で指定する

インベントリ( inventory )ファイルの設定で指定する方法です。

inventory/local.yml:

all:
  hosts:
    local:
      ansible_connection: local
      ansible_host: localhost
      # `ansible-playbook` を走らせている Python インタプリタをコマンドの実行にも使用する
      ansible_python_interpreter: '{{ ansible_playbook_python }}'

設定項目の ansible_connectionansible_host を使用します。 ansible_connection は A) のコマンドラインオプションの --connection に相当するもので、値は必ず local にする必要があります。

ansible_python_interpreter の行は ansible-playbook の実行に使用されている Python インタプリタをタスクの実行にも使いたい場合に使用します。

手元の環境で実行すると次のような出力が出ました:

ansible-playbook -i inventory/local.yml playbooks/show-term.yml Using /path/to/ansible-playbook-localhost-examples/ansible.cfg as config file

PLAY [all] **********************************************************************

TASK [ansible.builtin.command] **************************************************
changed: [local] => changed=true 
  cmd:
  - echo
  - $TERM
  delta: '0:00:00.004960'
  end: '2021-06-22 18:09:08.102457'
  rc: 0
  start: '2021-06-22 18:09:08.097497'
  stderr: ''
  stderr_lines: <omitted>
  stdout: xterm-256color
  stdout_lines: <omitted>

PLAY RECAP **********************************************************************
local                      : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

こちらの方法は複数のプレイブックを同時に実行する場合などに有用です。

方法 C) プレイブックで指定する

プレイブックの設定で指定する方法です。

playbooks/show-term-on-local.yml:

- hosts: localhost
  gather_facts: no
  connection: local
  tasks:
    - ansible.builtin.command:
        cmd: echo $TERM

hosts: localhostconnection: local を使用します。

ansible-playbook playbooks/show-term-on-local.yml

プレイブック内のすべてのタスクが localhost で実行されます。 出力は A) B) と同等のなので割愛します。

方法 D) タスクで指定する

プレイブックの中のタスクの設定で指定する方法です。

playbooks/show-term-on-local-task-only.yml:

- hosts: all
  gather_facts: no
  tasks:
    - ansible.builtin.command:
        cmd: echo $TERM
      delegate_to: localhost

こちらはタスクの設定で delegate_to: localhost を指定します。

こちらの方法の注意点として、有効なホストが 1 件以上無いと「 hosts: all に合致するものが無い」と判断されてプレイブックが実行されないので、ダミーのホストでもよいのでインベントリ・ホストの指定をしてあげる必要があります。

ansible-playbook -i xyz, playbooks/show-term-on-local-task-only.yml

こちらは指定されたタスクだけが localhost で実行されます。

こちらも出力は A) B) C) と同等のなので割愛します。

D) のタスクで指定する方法としては、 delegate_to の他にもうひとつ local_action を使った方法もあります。

- hosts: all
  gather_facts: no
  tasks:
    - local_action:
        module: ansible.builtin.command
        cmd: echo $TERM

以上です。 基本的には、ホスト適用の粒度を「インベントリ」「プレイブック」「タスク」のどれにしたいかで B) C) D) を使い分けることになるかと思います。

本記事のサンプルコードを GitHub のリポジトリに置いておいたので、実行してみたい方はご利用ください。

参考

公式ドキュメントです。

英語ですが、途中まで記事を書いた後に趣旨丸かぶりの記事を見つけてしまいました。


アバター
後藤隼人 ( ごとうはやと )

ソフトウェア開発やマーケティング支援などをしています。詳しくはこちら