Ansible を利用して複数ノードを管理する場合、root アカウントで SSH ログインできるのはセキュリティ上好ましくないという理由から、他の一般ユーザでログインしてから become を使うことがあります。
私の場合は、以下のように example.yml ファイルと production ファイルを用意して、myadmin ユーザでログインし、ログイン後に sudo で root アカウントになって設定作業するようにしています。
- hosts: example_nodes
become: yes
become_user: root
roles:
- nvidia-driver
[example_nodes]
node01.example.jp
node02.example.jp
node03.example.jp
[example_nodes:vars]
ansible_ssh_user=myadmin
実際に実行するためのコマンドは、以下の通り。
$ ansible-playbook --ask-become-pass -i production example.yml
これはセキュリティ的に良いアプローチのはずなのですが、local_action と共存できない場合があります。以下のように、①NVidia のカーネルドライバをインストールする、②インストールされた場合は再起動する、③再起動の完了を待つ、という playbook を考えます。
- name: Install NVidia driver
apt: name=nvidia-driver state=latest
register: nvidia_driver_apt
- name: Reboot system to refresh NVidia driver
shell: sleep 2 && reboot
async: 1
poll: 0
when: nvidia_driver_apt.changed == True
- name: Wait system resume
local_action: wait_for host={{inventory_hostname}} port=22 delay=30
when: nvidia_driver_apt.changed == True
この playbook を実行すると、ステップ③の local_action では、手元の Ansible を実行中の端末で sudo を実行して root アカウントになろうとするので、以下のようなエラーになります。
TASK [nvidia-docker : Wait system resume] **************************************
skipping: [node01.example.jp]
skipping: [node02.example.jp]
fatal: [node03.example.jp -> localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "残念、また試してください。\n[sudo via ansible, key=sobbgsjtgollwvlmyeiyxugqpvpsskrw] password: \nsudo: 1 回パスワード試行を間違えました\n", "module_stdout": "", "msg": "MODULE FAILURE"}
この問題を回避するには、以下のように local_action を実行する時には become: False と設定しておく必要があります(末尾の行)。
- name: Install NVidia driver
apt: name=nvidia-driver state=latest
register: nvidia_driver_apt
- name: Reboot system to refresh NVidia driver
shell: sleep 2 && reboot
async: 1
poll: 0
when: nvidia_driver_apt.changed == True
- name: Wait system resume
local_action: wait_for host={{inventory_hostname}} port=22 delay=30
when: nvidia_driver_apt.changed == True
become: False
実際の使用例は、NVidia-Docker をインストールするための playbook にありますので、どうぞ参考にして下さい。