てくなべ (tekunabe)

ansible / network automation / 学習メモ

StackStorm の Ansible Pack で利用するPythonパッケージの追加インストール方法

はじめに

StackStorm の Ansible Pack を利用して Junos のルーターに接続しようとしたところ、 ncclient is not installed というエラーになってしまいました。

このエラー自身はAnsible 単体で利用した時にも見かけたことがあったので対処方法を知っていました。

しかし、Ansible Pack の実行環境は virtualenv で隔離されおり、パッケージのインストール方法に少しだけコツがあったので、対処した方法をご紹介します。

結論としては、以下のコマンドを利用しました。

sudo /opt/stackstorm/virtualenvs/ansible/bin/pip install ncclient jxmlease


■ やりたかったこと

以下のような Playbook で Junos のバージョン情報を表示させる処理を試そうとしました。

- hosts: junos
  gather_facts: no
  connection: netconf

  tasks:
    - name: show
      junos_command:
        commands:
          - show version
      register: result

    - name: debug
      debug:
        msg: "{{ result.stdio_lines[0] }}"

  vars:
    ansible_network_os: junos
    ansible_user: testuser
    ansible_ssh_pass: testpass

■ 遭遇したエラー

ところが、以下のようなエラーになりました。

[ec2-user@ip-172-31-4-147 ~]$ st2 run ansible.playbook playbook=/home/ec2-user/junos_show.yml inventory_file=/home/ec2-user/inventory
.
id: 5b0011b76fb12304eceb1b8b
status: failed
parameters:
  cwd: /opt/stackstorm/packs/ansible
  inventory_file: /home/ec2-user/inventory
  playbook: /home/ec2-user/junos_show.yml
result:
  failed: true
  return_code: 2
  stderr: Executed command "/opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook --inventory-file=/home/ec2-user/inventory /home/ec2-user/junos_show.yml"
  stdout: "
PLAY [junos] *******************************************************************

TASK [show] ********************************************************************
fatal: [10.1.1.110]: FAILED! => {"msg": "ncclient is not installed"}
    to retry, use: --limit @/home/ec2-user/junos_show.retry

PLAY RECAP *********************************************************************
10.1.1.110               : ok=0    changed=0    unreachable=0    failed=1
"
  succeeded: false

ncclient というPythonパッケージが不足しているようです。


■ 対処

必要パッケージのインストール

Playbook 内で利用した、junos_commandモジュールのドキュメントを参照すると、ncclientjxmlease が必要とのことなのでこの2つをインストールすることにしました。

[ec2-user@ip-172-31-4-147 ~]$ sudo /opt/stackstorm/virtualenvs/ansible/bin/pip install ncclient jxmlease
(略)
Successfully installed jxmlease-1.0.1 ncclient-0.5.3

Ansible Pack を st2 pack install ansible でインストールした時に自動的に入った他のパッケージと site-packages 配下の権限を比較すると、以下のように異なります。

[ec2-user@ip-172-31-4-147 ~]$ ls -ls  /opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/
(略)
  4 drwxrwxr-x. 17 root st2packs   4096  5月 19 04:43 ansible
  0 drwxrwxr-x.  2 root st2packs    131  5月 19 04:43 ansible-2.5.3.dist-info
(略)
  0 drwxr-xr-x.  5 root root        243  5月 19 12:11 ncclient
  0 drwxr-xr-x.  2 root root        147  5月 19 12:11 ncclient-0.5.3.dist-info
(略)
  4 drwxrwxr-x.  2 root st2packs   4096  5月 19 04:43 paramiko
  0 drwxrwxr-x.  2 root st2packs    150  5月 19 04:43 paramiko-2.4.1.dist-info

補足

以下の方法でパッケージをインストールしても、Ansible Pack から ncclient は利用できませんでした。

# グローバル環境にインストールされ、Ansible Pack から利用できない
[ec2-user@ip-172-31-4-147 ~]$ pip install ncclient jxmlease
# 権限エラー
[ec2-user@ip-172-31-4-147 ~]$ source /opt/stackstorm/virtualenvs/ansible/bin/activate
(ansible) [ec2-user@ip-172-31-4-147 ~]$ pip install ncclient jxmlease
(略)
OSError: [Errno 13] 許可がありません: '/opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/ncclient'
# これもグローバル環境にインストールされてしまう
[ec2-user@ip-172-31-4-147 ~]$ source /opt/stackstorm/virtualenvs/ansible/bin/activate
(ansible) [ec2-user@ip-172-31-4-147 ~]$ sudo pip install ncclient jxmlease


■ 再実行

必要なパッケージをインストールしたので再実行します。

[ec2-user@ip-172-31-4-147 ~]$ st2 run ansible.playbook playbook=/home/ec2-user/junos_show.yml inventory_file=/home/ec2-user/inventory
........
id: 5b0014ee6fb12304eceb1b94
status: succeeded
parameters:
  cwd: /opt/stackstorm/packs/ansible
  inventory_file: /home/ec2-user/inventory
  playbook: /home/ec2-user/junos_show.yml
result:
  failed: false
  return_code: 0
  stderr: ''
  stdout: "
PLAY [junos] *******************************************************************

TASK [show] ********************************************************************
ok: [10.1.1.110]

TASK [debug] *******************************************************************
ok: [10.1.1.110] => {
    "msg": [
        "Hostname: ip-172-31-43-152",
        "Model: vmx",
        "Junos: 17.4R1-S2.2",
        "JUNOS OS Kernel 64-bit  [20180127.fdc8dfc_builder_stable_11]",
        "JUNOS OS libs [20180127.fdc8dfc_builder_stable_11]",
        "JUNOS OS runtime [20180127.fdc8dfc_builder_stable_11]",
(略)
    ]
}

PLAY RECAP *********************************************************************
10.1.1.110               : ok=2    changed=0    unreachable=0    failed=0
"
  succeeded: true

正常に実行でき、無事にJunosのバージョン情報が取得できました。


■ まとめ

StackStorm は Python で書かれているため、 virtualenv などのPythonの環境について意識する必要があると感じました。

公式ドキュメントに、この手の順が見つからなかったのですが、もしご存じの方がいらっしゃいましたら、コメントまたは twitter: @akira6592 へお知らせいただけるとうれしいです。