てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] 「つまずき Ansible 【Part38】ネットワークモジュールを VS Code でデバッグしたい」ふりかえり

はじめに

2024/02/04 に、「つまずき Ansible【Part38】ネットワークモジュールを VS Codeデバッグしたい」という配信をしました。

tekunabe.connpass.com

cisco.ios コレクションのモジュールのような、ネットワーク機器に接続して操作するとき、Playbook で指定したオプションがどのように処理されるのか、を知りたいときがあって、VS Code でステップ実行とかできたらいいなーと思っていました。

あくまでも Playbook を起点にデバッグしたかったです。

いろいろ試行錯誤した結果できるようになり、ブログよりもデモ中心にお見せしたほうが伝わりやすいと思い、久々に配信をしました。


動画

youtu.be

前提条件

今回の方法が通用するのは、わかっている範囲でいくつか条件があります。

  • ネットワークモジュールであること
    • つまり、コントロールノードでモジュールのコードが動作する
  • Direct Execution (import_modules) が有効であること
    • ansible.netcommon コレクション 3.0.0 からデフォルトで有効
    • つまり、コントロールノードで「圧縮→コピー→解凍」というフェーズを介さずにモジュールのコードが動作する

また、私の環境ではまだ macOS でしかできていません。Remote SSH で接続した先の Linux ではうまくブレークポイントを有効にできませんでした(類似事象 issue)。

([2024/02/27 追記] issue がクローズされ、参考ドキュメトがアップされていました)

仕込み

デバッガの定義ファイルである .vscode/launch.json には以下の定義をしてあります。

今回は、ansible もコレクションも ${workspaceFolder}/.venv にインストールしています。

programで、そのなかの ansible-playbook を指定しているのが一番のポイントです。

{
  // IntelliSense を使用して利用可能な属性を学べます。
  // 既存の属性の説明をホバーして表示します。
  // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "ansible-playbook: 現在のファイル",
      "type": "debugpy",
      "request": "launch",
      "console": "integratedTerminal",
      "program": "${workspaceFolder}/.venv/bin/ansible-playbook",   // ポイント
      "args": [
        "${file}",   // 開いているファイル
        "-i",
        "${workspaceFolder}/inventory.yml",    // イベントリファイル
        "-vvvvv"   // お好み
      ],
      "env": {
        // "PYTHONPATH": "${workspaceFolder}/.venv/lib/python3.11/site-packages/", // 試行錯誤の残骸
        // "ANSIBLE_COLLECTIONS_PATHS": "hogehoge",  // 必要に応じて
        "ANSIBLE_PERSISTENT_CONNECT_TIMEOUT": "0" // 必要に応じて(デバッグ中に接続断しないように)
      },
      "justMyCode": false, // モジュールのコードにブレークポイントを張るため
      // "subProcess": false, // 試行錯誤の残骸
    }
  ]
}

cisco.ios.ios_command モジュールのデバッグ

以下のような、show コマンドを実行する Playbook をデバッグします。

---
- name: Test play
  hosts: ios
  gather_facts: false

  tasks:
    - name: Test ios
      cisco.ios.ios_command:
        commands:
          - show interfaces

動かしたいファイルを開いている状態で、統合ターミナルではなく 「実行とデバッグ」経由で、launch.json で定義した ansible-playbook: 現在のファイル" を選択します。

デバッガの起動

すると、あらかじめ設定したブレークポイントのところで止まってくれます。

モジュール内部のブレークポイントで止まっている

少し進めると、Playbook で指定した show コマンドが入っていることがわかります。

show interfaces

変数の値は参照だけでなく変更もできます。この状態で show ip route にコマンドを書き換えて処理を実行すると、show ip route が実行されます。

show ip route に変更

cisco.ios.ios_interfaces モジュールのデバッグ

続いて、インターフェースの基本設定をする cisco.ios.ios_interfaces モジュールのデバッグを試します。

---
- name: Test play
  hosts: ios
  gather_facts: false

  tasks:
    - name: Configure interface
      cisco.ios.ios_interfaces:
        config:
          - name: GigabitEthernet0/0
            description: sakana

今回は、モジュール本体から呼ばれている別のファイルのところにブレークポイントを設定しました。wantd という変数に、Playbook で指定した、こうなってほしいという設定値が入っているのがわかります。

ステップ実行中

一方 haved の中には、機器から取得したインターフェースの今の設定が入っているのがわかります。

haved の中身

今度はちょっと変わった例として、以下のような変なインターフェースの名前を Playbookで指定してデバッグします。

          - name: Giggegegegeggegerrjii0/0

処理を追っていくと、normalize_interface で、インターフェースの名前のノーマライズをしていることがわかります。ここでは、小文字に変換したうえで gi から始まれば、GigabitEthernet として扱う、ということがわかります。

github.com

ノーマライズ判定

おわりに

コードを読む力があれば、デバッグしなくても処理が理解できると思うのですが、私はこのようにステップ実行して見れると非常にありがたいです。

配信方法を急遽 YouTube Live から Zoom に切り替えたため、参加者の皆様にはお手数おかけしました・・。 それでもご視聴いただいた皆さん、ありがとうございました!

参考

VS Code の基本やデバッグについては、最近発売された「改訂新版 Visual Studio Code実践ガイド」がおすすめです。いろいろと新しい機能についても説明されています。