Red Hatのさいとうです。 前回のAnsible2.8の新機能1 - Interpreter Discoveryから、だいぶ時間がたってしまいましたが、Ansible 2.8で実装された新機能2をお届けします。単に忙しかっただけで書くのを忘れてたわけじゃないんですよ。
今回ご紹介するのは Become Pluginです。
Become機能のプラグイン化
Ansible v2.8以前は、sudoやsuなどのコマンドを利用してrootなどの特定のユーザ権限でPlaybookを実行する機能は、コア機能が利用するライブラリ内で定義されており、利用者が独自に改変したり、拡張したりすることができませんでした。 Ansible v2.8以降では、この機能をプラグイン化してコア機能から切り離すことで、利用者が必要に応じて拡張できるようになりました。
この記事では、必要最低限の機能を実装した独自のbecome pluginを作成して、ansible-playbookコマンド実行時に利用する方法を紹介します。
Becomeプラグインの実装
ここでは、以下のように、sudo su -c <コマンド>
を実行する以下のスクリプト(sudosu)をターゲットホストの/usr/bin/sudosuとして配置して、Playbook実行時にbecome methodとして利用します。
#!/bin/sh sudo su "$@" # # [EOF] #
これをターゲットホストに/usr/bin/sudosu
として配置したら、実行権を与えておきます。
# chmod +x /usr/bin/sudosu
続いて、become pluginであるsudosu.py
を作成します。DOCUMENTATION
に ansible_become_user
, ansible_become_exe
, ansible_become_password
を記述するのを忘れないでください。この記述がないと、becomeパラメータとして必要なパスワードなどの情報をプラグインに引き渡すことができません:
# -*- coding: utf-8 -*- from __future__ import (absolute_import, division, print_function) __metaclass__ = type from ansible.module_utils.six.moves import shlex_quote from ansible.plugins.become import BecomeBase DOCUMENTATION = """ become: sudosu description: - Testing for custom become_plugin options: become_user: description: User you 'become' to execute the task default: root vars: - name: ansible_become_user become_exe: description: sudosu executable default: sudosu vars: - name: ansible_become_exe become_pass: description: Password to pass to sudo required: False vars: - name: ansible_become_password """ class BecomeModule(BecomeBase): name = 'sudosu' def build_become_command(self, cmd, shell): self.prompt = '[sudo] password for ' command = self.get_option('become_exe') or self.name success_cmd = self._build_success_command(cmd, shell) return '%s -c %s' % (command, shlex_quote(success_cmd)) # # [EOF] #
self.prompt
にパスワードインタラクション用のプロンプトを設定します。それ以降の記述は、現状ドキュメントが存在していないため、su.py
や sudo.py
などを参考にしてBecomeBaseクラスを読み解きつつ実装してみました(もちろんちゃんと動作します)。
このプラグインを、以下のようにPlaybookのbecome_pluginディレクトリに配置します:
. ├── become_plugins │ └── sudosu.py ├── inventory └── test.yml
このプラグインを利用するtest.yml
は、以下のように記述しています:
--- - hosts: all gather_facts: no tasks: - yum: name: wget state: latest become: yes become_method: sudosu become_user: root
最後に、このPlaybookを実行してみます。--ask-become-pass
でsudo su
の実行時に聞かれるパスワードを渡すのをお忘れなく。-vvv
オプションを付与して実行すると、タスクの実行にsudosu
が使われているのが確認できます。
$ ansible-playbook -i inventory test.yml --ask-become-pass -vvv ansible-playbook 2.8.1 config file = /etc/ansible/ansible.cfg configured module search path = [u'/home/hsaito/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /home/hsaito/.pyenv/versions/2.7.16/envs/ansible-2.8.1-py27/lib/python2.7/site-packages/ansible executable location = /home/hsaito/.pyenv/versions/ansible-2.8.1-py27/bin/ansible-playbook python version = 2.7.16 (default, May 7 2019, 14:18:00) [GCC 9.0.1 20190312 (Red Hat 9.0.1-0.10)] Using /etc/ansible/ansible.cfg as config file BECOME password: ******** ... <test00> SSH: EXEC sshpass -d8 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="hsaito"' -o ConnectTimeout=10 -o ControlPath=/home/hsaito/.ansible/cp/22ce55f06b -tt test00 '/bin/sh -c '"'"'sudosu -c '"'"'"'"'"'"'"'"'/usr/bin/python /home/hsaito/.ansible/tmp/ansible-tmp-1561363694.88-125525749171244/AnsiballZ_yum.py'"'"'"'"'"'"'"'"' && sleep 0'"'"'' ...
まとめ
become plugin(だけじゃないけど)は開発者向けのドキュメントが存在していません。バンドルされているsudoなどのプラグインを読み解いて、がんばって実装するしかありませんが、sudoやsuなどのようにバンドルされているプラグイン以外の権限昇格コマンドを利用したいような場合は、become pluginとして独自に実装できるようになりました。また、プラグイン化されたことで、アップストリームへの機能拡張のリクエストもしやすくなるというメリットもありますので、今後の拡張に期待したいところです(もう世にある権限昇格系のコマンドは既に実装されている気もしますが)。