Jupyter Ansible Kernel 0.8.0でPythonコードが実行できるようになったので試してみた

Jupyter Ansible Kernelを使う事でJupyter notebookのセルに直接Ansibleのインベントリーやタスク、テンプレートなどが書けて実行することができます。
色々使って試していたら開発者のBen Thomassonさんから0.8.0からPythonコードをAnsible Kernelで実行できるようになってregister変数もPythonコードに引き継げるという情報を頂きました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Registered variables from ansible tasks show up in the python scope. <a href="https://twitter.com/hashtag/task?src=hash&amp;ref_src=twsrc%5Etfw">#task</a><br>shell: ls /<br>register: output<a href="https://twitter.com/hashtag/python?src=hash&amp;ref_src=twsrc%5Etfw">#python</a><br>print(output)</p>&mdash; Ben Thomasson (@benthomasson) <a href="https://twitter.com/benthomasson/status/1032709735420710912?ref_src=twsrc%5Etfw">2018年8月23日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

そこで、色々試して観た結果を書いていきたいと思います :)

# 1. Pythonのコードが実行できるかの確認

ここでは、Ansibleで実行した結果をPythonコードに持っていけるか確認してみます。
Ansibleで `shellモジュール` を使って `echo` 結果をregister変数に入れてPythonで表示してみます。

![スクリーンショット 2018-09-09 17.53.03.png](https://qiita-image-store.s3.amazonaws.com/0/180118/6bfa60a0-4784-e9c5-3c46-37c895cc1145.png)

想定通りpythonで表示することができました。

# 2. 使い方応用編

registerに入っているAnsible実行結果をPythonコードで操作できるのはとても便利そうだと思ったので、試しにAnsibleで取得したVMwareのVM情報一覧をPythonで整形しテーブルで表示してみました。

作成したnotebookファイルは以下にアップしてあります。
[https://github.com/sky-joker/ansible-vmware-learning-materials/blob/master/docs/jupyter/Ansible-Kernel/example/Ansibleで取得した結果をテーブルで表示する例.ipynb](https://github.com/sky-joker/ansible-vmware-learning-materials/blob/master/docs/jupyter/Ansible-Kernel/example/Ansibleで取得した結果をテーブルで表示する例.ipynb)

![ansible_kernel_table_display_test.gif](https://qiita-image-store.s3.amazonaws.com/0/180118/1e8574b1-bfc1-01f4-d6b4-a89dbee93023.gif)

これは、使い方次第ではかなり便利になりそうです :)

# 3. 出来ないパターン

## 3-1. register以外

registerで格納した変数以外は、今の所Pythonコードに引き継げないようです。

![スクリーンショット 2018-09-09 17.58.51.png](https://qiita-image-store.s3.amazonaws.com/0/180118/3ca46b38-124a-c93c-1a10-5db2e7bdf7b4.png)

やはり一度registerに入れる必要があります。

![スクリーンショット 2018-09-09 18.01.40.png](https://qiita-image-store.s3.amazonaws.com/0/180118/bc359961-7a87-3538-100d-f518c7b364db.png)


## 3-2. pythonの変数はAnsible側へ引き継げるか

Pythonコードに `msg` 変数を定義してAnsibleの `debugモジュール` で表示してみます。

![スクリーンショット 2018-09-09 18.03.43.png](https://qiita-image-store.s3.amazonaws.com/0/180118/0664c8fa-22c7-35d8-5add-c4255e413e42.png)

これも出来ません。
register以外は現在のバージョンでは対応していないようです。
issueを確認したらバグとして報告されていました。

[Python variable not accessible in a Ansible task #67](https://github.com/ansible/ansible-jupyter-kernel/issues/67)

# 4. Python3でエラーが発生する

以下のエラーが発生する場合は [Ansible Kernel 0.8.0 did not work with Python3 #65](https://github.com/ansible/ansible-jupyter-kernel/issues/65) を参照してください。

```python
Traceback (most recent call last):
  File "/usr/lib64/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/jupyter/venv/lib64/python3.6/site-packages/ansible_kernel/__main__.py", line 6, in <module>
    IPKernelApp.launch_instance(kernel_class=AnsibleKernel)
  File "/home/jupyter/venv/lib64/python3.6/site-packages/traitlets/config/application.py", line 658, in launch_instance
    app.start()
  File "/home/jupyter/venv/lib64/python3.6/site-packages/ipykernel/kernelapp.py", line 483, in start
    self.kernel.start()
  File "/home/jupyter/venv/lib64/python3.6/site-packages/ipykernel/kernelbase.py", line 290, in start
    self._publish_status('starting')
  File "/home/jupyter/venv/lib64/python3.6/site-packages/ipykernel/kernelbase.py", line 327, in _publish_status
    ident=self._topic('status'),
  File "/home/jupyter/venv/lib64/python3.6/site-packages/jupyter_client/session.py", line 748, in send
    stream.send_multipart(to_send, copy=copy)
  File "/home/jupyter/venv/lib64/python3.6/site-packages/ansible_kernel/kernel.py", line 68, in send_multipart
    result = channel.send_multipart(msg, *args, **kwargs)
  File "/home/jupyter/venv/lib64/python3.6/site-packages/ansible_kernel/kernel.py", line 1173, in send_multipart
    if msg0.startswith("comm"):
TypeError: startswith first arg must be bytes or a tuple of bytes, not str
```