てくなべ (tekunabe)

ansible / network automation / 学習メモ

CML-P (VIRL2) のインストールと基本機能

はじめに

2020/05/13 に、CML-Personal (VIRL2) のインストールと基本機能について、YouTube Live でお話させていただきました。

CML-Personal は、Cisco 公式のバーチャルラボ環境のソフトウェアで、仮想アプライアンス(.ova)として提供されます。IOSIOS XR、NX-OSなどの各種イメージもセットなので、「中古で買った機器のイメージを吸い上げて・・」といった作業も不要です。

前バージョンの VIRL 1.x よりもだいぶ使い勝手が良くなった感じだったので紹介させていただきました。

こちらのブログにも各種リソースを掲載します。

動画

www.youtube.com

  • 0:00 概要説明
  • 6:10 インストール
  • 8:43 セットアップ
  • 11:25 ラボ設定
  • 17:44 その他機能
    • パケットキャプチャ
    • ラボのダウンロード、インポート、
    • API
    • コンソールサーバー
    • Breakout tool

(音声がいまいちですみません・・。試行錯誤中です)

資料

www.slideshare.net

参考資料

参考資料の最後に掲載した参考資料を再掲します。

公式ドキュメント

説明動画

日本語ブログ

[Ansible] エスケープされた JSON を正しくディクショナリにする from_json フィルター

はじめに

Ansible では、結果が JSON になるタスクを実行すると、(少なくとも表示上は)エスケープされた JSON が返ってくることがあります。

この場合、構造化データのように見えて文字列なので、ディクショナリ(構造化データ)として正しく扱えません。

from_json フィルターをかけると、うまくいきます。

この記事では簡単なサンプルをもとに説明します。

  • 動作確認環境
    • Ansible 2.9.7


エスケープされた JSON とは?

以下は、nclu モジュールを利用して、Cumulus Linux に対して、show bgp summary json コマンドを実行した結果を、debug モジュールで表示した結果です。

msg 内に \ によるエスケープが入っています。JSON のように見えてただの文字列です。

TASK [debug show bgp summary] *************************************************************************
ok: [leaf01] => {
    "msg": {
        "changed": false,
        "failed": false,
        "msg": "{\n    \"ipv4 unicast\": {\n        \"as\": 65011, \n        \"bestPath\": {\n            \"multiPathRelax\": \"true\"\n        }, \n        \"dynamicPeers\": 0, \n        \"peerCount\": 2, \n        \"peerGroupCount\": 1, \n        \"peerGroupMemory\": 64, \n        \"peerMemory\": 42352, 
        ...(略)...
    }
}

このままでは、result.msg['ipv4 unicast'] のように、内部のキーを指定しても、'dict object' has no attribute 'ipv4 unicast' のような、キーの参照エラーになってしまいます。

ちょっとハマりやすいのは、上記例でいうと result.msg を参照したときは、以下のように、いかにも正しい JSON っぽく表示される点です。

TASK [debug show bgp summary] *************************************************************************
ok: [leaf01] => {
    "msg": {
        "ipv4 unicast": {
            "as": 65011,
            "bestPath": {
                "multiPathRelax": "true"
            },
            "dynamicPeers": 0,
            "peerCount": 2,
            ...(略)...

どう見てもディクショナリとして扱えそうですが、{{ result.msg | type_debug }} の結果は AnsibleUnsafeText です。どうして・・。


from_json フィルターでディクショナリに変換

正しくディクショナリとして扱うために、from_json フィルターをかけます。

"{{ result_bgp_summary_raw | from_json }}"

こでれで、JSON、ディクショナリになります。

TASK [debug show bgp summary] *************************************************************************
ok: [leaf01] => {
    "msg": {
        "ipv4 unicast": {
            "as": 65011,
            "bestPath": {
                "multiPathRelax": "true"
            },
            "dynamicPeers": 0,
            "peerCount": 2,
            ...(略)...

"{{ result_bgp_summary_raw.msg | from_json | type_debug }}" の結果は dict です。

ここまでくれば、通常のディクショナリと同じく、特定のキーを参照したりするだけです。

タスク例

    - name: debug show bgp summary
      debug:
        msg: "{{ bgp_summary['ipv4 unicast']['peerCount'] }}"
      vars:
        bgp_summary: "{{ result_bgp_summary_raw.msg | from_json }}"

(キーの指定を .ipv4 unicast ではなく ['ipv4 unicast'] としているのは、今回対象のデータに、たまたまスペース入りのキー名があったためです)

実行例

TASK [debug show bgp summary] *************************************************************************
ok: [leaf01] => {
    "msg": "2"
}


■ おわりに

エスケープされた JSON に、from_json フィルターをかけて、ディクショナリにする方法をご紹介しました。

私だけかもしれませんが、Ansible で構造化データの扱いで悩むことが結構あります。

あるはずのキーが has no attribute となってハマったときは、エスケープされてないか、type_debugの結果はどうなるか、などを確認するのがよさそうです。

[Ansible] nclu モジュールでエラー「Error in pending config. You may want to view `net pending` on this target.」発生時はbecomeを確認

はじめに

Ansible には Cumulus Linux のネットワーク管理コマンドツール nclu を扱う nclu モジュールがあります。

先日、試しに使ってみたところ以下のエラーになりました。

Error in pending config. You may want to view `net pending` on this target.

ピンとこなかったのですが、結果的には become: true のつけ忘れでした。

この記事では、発生したときのPlaybook、実行例、その対策を紹介します。

  • 動作確認環境
    • Ansible 2.9.7

発生の経緯

以下のような Playbook を利用しました。Plyabook 中には登場しませんが、利用するユーザーは vagrant という一般ユーザーです。

この記事ベースで環境を作成

---
- hosts: leaf01
  gather_facts: false

  tasks:
    - name: show bgp summary json
      nclu:
        commands:
          - show bgp summary json
      register: result_bgp_summary_raw

実行結果はこちら。

$ ansible-playbook -i intentory.ini assert_bgp.yml 

PLAY [leaf01] *************************************************************************************************************************

TASK [show bgp summary json] **********************************************************************************************************
fatal: [leaf01]: FAILED! => {"changed": false, "msg": "Error in pending config. You may want to view `net pending` on this target."}

PLAY RECAP ****************************************************************************************************************************
leaf01                     : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

対策(become: true 追加)

一般ユーザーで net show コマンドを実行すると

vagrant@leaf01:mgmt:~$ net show interface
ERROR: You do not have permission to execute that command.

のようなエラーになることを思い出したので、権限周りが原因だと思いました。

そこで以下のように become: true を追加したらうまくいきました、

---
- hosts: leaf01
  gather_facts: false
  become: true    # 追加

  tasks:
    - name: show bgp summary json
      nclu:
        commands:
          - show bgp summary json
      register: result_bgp_summary_raw

参考

[2020/05/03 追記]

Cumulus 側で、ユーザーをグループに追加する方法もあるようです。

[Ansible/AWX] 起動したジョブをあとから awx コマンドでモニターする(monitor サブコマンド)

はじめに

以前の記事で、awx コマンドでジョブの実行を終了までリアルタイムに見届ける --monitor オプションをご紹介しました。

tekunabe.hatenablog.jp

この --monitor オプションは、launch サブコマンドのオプションなので、起動とセットでした。

AWX 11.2.0 では、あらかめ GUIawx コマンドなどで起動したジョブを、あとからモニターできる monitor サブコマンドが追加されました。

この記事では、ジョブテンプレートとワークフロージョブテンプレートの monitor オプションを利用する例をご紹介します。

  • 動作検証環境
    • AWX 11.2.0

■ ジョブテンプレートの monitor

コマンド書式

ジョブテンプレートの実行ジョブのモニターは、以下のコマンド書式です。

awx jobs monitor [ジョブID]

実行例

まず、awx job_templates launch でジョブテンプレートを起動し(--monitor オプションなし)、あとから awx jobs monitor [ジョブID] でモニターします。

ログです。

$awx job_templates launch jt_01_show -f human     # 起動のみ(--monitor なし)
id   name       
==== ========== 
1220 jt_01_show           # ID が表示される
$
$ awx jobs monitor 1220   # 先程起動したワークフロージョブIDを指定してモニター
------Starting Standard Out Stream------  # ここから処理ををって徐々に表示される
SSH password: 

PLAY [ios] *********************************************************************

TASK [show ip route] ***********************************************************
ok: [ios1]

ASK [show ip route] ***********************************************************

...(略)....

ASK [debug ios_facts] *********************************************************
ok: [ios1] => {
    "ansible_facts.net_version": "16.11.01a"
}


LAY RECAP *********************************************************************
ios1                       : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

------End of Standard Out Stream--------  # 終了

$
$ awx jobs monitor 1220         # 終了したジョブなので、その旨のメッセージのみ表示
Unable to monitor finished job

(ところどころ、TASKASK のように 1文字目が欠けてるので微妙に気になります)


■ ワークフロージョブテンプレートの monitor

コマンド書式

ワークフロージョブテンプレートの実行ジョブのモニターは、以下のコマンド書式です。

awx workflow_jobs monitor [ジョブID]

実行例

まず、awx workflow_job_templates launch でワークフロージョブテンプレートを起動し(--monitor オプションなし)、あとから awx workflow_jobs monitor [ジョブID] でモニターします。

ログです。

$ awx workflow_job_templates launch  wf_01 -f human   # 起動のみ(--monitor なし)
id   name  
==== ===== 
1208 wf_01    # ID が表示される

$ awx workflow_jobs monitor 1208            # 先程起動したワークフロージョブIDを指定してモニター
------Starting Standard Out Stream------    # ここから処理ををって徐々に表示される
Launching wf_01...
 ↳ 1209 - jt_02_debug successful
 ↳ 1211 - jt_03_debug successful
------End of Standard Out Stream--------    # 終了
$
$ awx workflow_jobs monitor 1208            # 終了したジョブなので、その旨のメッセージのみ表示
Unable to monitor finished job  


おわりに

awx コマンドで、ジョブをあとからモニターできる monitor サブコマンドをご紹介しました。

今回は、awx コマンドで起動して awx コマンドでモニターする例でしたが、GUI で起動して awx コマンドでモニターするおような組み合わせもできます。 シチュエーションに応じて、使い分けできるようになって便利だと感じました。

参考

[Ansible/AWX] ジョブテンプレート・ワークフロージョブテンプレートのコピーではスケジュール、通知、パーミション設定はコピーされない

はじめに

Ansible Tower / AWX のジョブテンプレート、ワークフロージョブテンプレートにはコピー機能があります。

似たようなテンプレートを作成するときにとても便利です。

少し注意が必要なのは、スケジュール、通知、パーミションの設定はコピーされないという点です。

公式ドキュメントには以下のように記載されています。

16. Job Templates — Ansible Tower User Guide v3.6.4

If you choose to copy Job Template, it does not copy any associated schedule, notifications, or permissions.

19. Workflow Job Templates — Ansible Tower User Guide v3.6.4

If you choose to copy a workflow template, it does not copy any associated schedule, notifications, or permissions.

ということで、ワークフロージョブテンプレートで試してみます。

  • 動作確認環境
    • AWX 11.0.0

元になるワークフロージョブテンプレート

こんなワークフロージョブテンプレートで試します。

f:id:akira6592:20200427212823p:plain
元になるワークフロージョブテンプレート

1つのスケジュールがある状態です。

f:id:akira6592:20200427212855p:plain
スケジュール設定がある

失敗時に通知する設定がある状態です。

f:id:akira6592:20200427212913p:plain
通知設定がある

operator に実行権限がある状態です。

f:id:akira6592:20200427212938p:plain
権限設定が(デフォルト以外にも)ある

コピーの実行

テンプレート一覧画面で、コピーしたーテンプレートのコピーボタンを押すとコピーされてテンプレートができます。

f:id:akira6592:20200427213011p:plain
コピーボタンでコピーする

テンプレート名@コピー日時を含む名前になります。もちろん変更もできます。

コピーしたワークフロージョブテンプレート

どうなったか確認します。

スケジュールはコピーされません。

f:id:akira6592:20200427213044p:plain
スケジュール設定がない

通知の設定もコピーされません。

f:id:akira6592:20200427213105p:plain
通知設定がない

権限の設定も通知の設定もコピーされません。adminauditor の権限ははデフォルトであらゆるオブジェクトににつくので、ここにもついてます。

f:id:akira6592:20200427213125p:plain
権限設定が(デフォルト以外は)ない

おまけ

コピーすると、ワークフロー内のApproval Node の名前は copy が付きます。copy を削って元の名前に戻すこともできます。

f:id:akira6592:20200427214815p:plain
コピーすると cppy が自動でつく

おわりに

スケジュール、通知、パーミションもコピーされてほしいような、されてほしくないような、なんとも言えない感覚ですが、とりあえず覚えておきたいポイントです。

[Ansible] Junos に対して netconf ではなくSSH (network_cli) でコンフィグ投入する(cli_configモジュール)

はじめに

Ansible の Junos モジュール郡は、コネクションプラグイン(接続方式)として、netconfnetwork_cli (いわゆるSSH)に対応しています。

ただし、各モジュールごとに、利用できるコネクションプラグインが決まっています。

Junos OS Platform Options — Ansible Documentation

たとえば、設定変更コマンド(setdelete)などを投入できる、junos_config モジュールは、netconf のみに対応していて、network_cli には対応していません。

しかし、Junos 専用モジュールではなく、ベンダー抽象化した cli_configというモジュールであれば、Junos に対して network_cli (SSH) で、設定変更コマンドを投入できます。

この記事では、簡単なサンプルで説明します。

サンプルPlaybook

---
- hosts: vmx
  gather_facts: false
  
  vars:
    ansible_connection: network_cli
  
  tasks:
    - name: config test
      cli_config:
        config: set system ntp server 10.0.1.123

junos_config モジュールの lines オプション(複数形)のと違って、cli_config モジュールの config オプションは、リストではなく文字列の指定をする点にご注意ください。

そのため、複数行指定する場合は、以下のような改行入りの文字列として指定します。

    - name: config test
      config: |
        set system ntp server 10.0.1.123
        set system ntp server 10.0.2.123
        set system ntp server 10.0.3.123

file ルックアッププラグインconfig オプションを利用すれば、junos_configsrc オプションのように、コンフィグをファイルから読み込む事もできます。

実行

$ ansible-playbook -i ../inventory.ini config.yml 

PLAY [vmx] *********************************************************************************

TASK [config test] *************************************************************************
changed: [vmx]

PLAY RECAP *********************************************************************************
vmx                        : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0 
ignored=0   

一応、機器側の設定確認をします。

testuser@vMX-addr-0> show configuration system ntp | display set    
set system ntp server 10.0.1.123

無事に設定変更できました。

デフォルトで commit されます。commit オプションで無効にもできます。

他、junos_configcli_config は、どちらかが完全に勝っているというわけではありません。詳細は各モジュールのドキュメントを参照してください。

おわりに

このように、ベンダー専用モジュールでできなくても、cli_* モジュールならできる、ということを何度か経験しています。

あきらめる前に、一度 cli_commandcli_config モジュールの説明ページを確認してみることをおすすめします。

[Ansible/AWX] アドホック実行画面の追加変数欄では ansible_ で始まる変数名を指定できない

はじめに

Ansible Tower / AWX には、Playbook をジョブテンプレートとして実行する機能の他にも、アドホックansible コマンドを実行する機能もありま

-e オプションに相当する、追加変数の設定欄がありますが、指定できる変数が制限されています。

具体的には、ansible_ で始まる変数名が指定できません。(ジョブテンプレート画面など、他の画面では指定可能です)

  • 検証環境
    • AWX 11.0

検証

ここではアドホックコマンド実行画面で、以下の追加変数を指定して、起動します。

---
ansible: "I'm ok"
ansible_x: hello
ansible_port: 2222
ansible_network_os: junos

指定できない変数名がある

ansible_xansible_portansible_network_os が禁止という旨のエラーメッセージが表示されました。

参考: 知ったきっかけと調べた方法

もともとは、この画面で ansible_port 変数を利用して、ポートを変更した変数確認をしとうとしました。その際にエラーに遭遇しました。そこで、他になにが禁止されてるのだろうと思って調べることにしました。

ブラウザの言語設定を英語にすると、エラーメッセージは以下のようになります。

ansible_x, ansible_port, ansible_network_os are prohibited from use in ad hoc commands.

この are prohibited from use in ad hoc commands を頼りに、コードを検索すると、このあたりがヒットしました。

github.com

追っていくとここに行き着き、

github.com

def is_ansible_variable(key):
    return key.startswith('ansible_')

とあったので、ansible_ で始まる変数名が禁止されている、と判断しました。