Ansible Playbook の Python (JSNAPy) で Junos Snapshot Administrator を使用する
概要 Ansibleプレイブックの一部としてJSNAPyテストを実行し、Junosデバイスのランタイム環境のスナップショットをキャプチャして監査します。
PythonのJunos® Snapshot Administrator(JSNAPy)を使用すると、ネットワークのJunosデバイスのランタイム環境のスナップショットをキャプチャして監査できます。デバイスの設定と動作ステータスを取得して検証し、デバイスに対する変更を検証できます。ジュニパーネットワークスは、Ansibleプレイブックの一部として、Junosデバイスに対してJSNAPyテストを実行できるAnsibleモジュールを提供しています。 表 1 に、使用可能なモジュールの概要を示します。
コンテンツセット |
モジュール名 |
---|---|
モジュールを使用するには、Ansible制御ノードにPythonのJunosスナップショットアドミニストレータをインストールする必要があります。JSNAPy の設定ファイルとテスト ファイルの作成に関するインストール手順と情報については、 Python ドキュメントの Junos スナップショット アドミニストレータを参照してください。
リリース 2.0.0 以降 Juniper.junos
、 juniper_junos_jsnapy
モジュールはモジュールの機能を置き換えます junos_jsnapy
。
次のセクションでは、Ansible プレイブックでモジュールを使用する方法について説明します。
モジュールの概要
jsnapy
およびjuniper_junos_jsnapy
モジュールを使用すると、コマンドラインでJSNAPyを使用して実行できるのと同じJSNAPy機能の多くをAnsibleプレイブックから実行できます。
-
ランタイム環境のスナップショットのキャプチャーと保存
-
2 つのスナップショットの比較
-
スナップショットをキャプチャしてすぐに評価する
モジュールでは、action
引数と または test_files
引数のいずれかconfig_file
を指定する必要があります。引数はaction
、実行する JSNAPy アクションを指定します。表 2 に、有効なaction
値と同等の JSNAPy コマンドの概要を示します。
アクション値 |
形容 |
同等の JSNAPy コマンド |
---|---|---|
|
指定されたテスト ケースに基づいて 2 つの既存のスナップショットを比較するか、テスト ケースが指定されていない場合は、スナップショットをノードごとに比較します。 |
|
|
指定されたデバイスで変更を行った後、テスト ファイルで指定されたコマンドまたは RPC のスナップショットを取得します。 |
|
|
特定のデバイスに変更を加える前に、テスト ファイルで指定されたコマンドまたは RPC のスナップショットを取得します。 |
|
|
テストファイルで指定されたコマンドまたはRPCのスナップショットを取得し、テストケースの事前定義された基準に対してスナップショットを即座に評価します。 |
|
コマンド・ラインでJSNAPyを実行すると、JSNAPyは構成ファイルの hosts
セクションで指定されたホストに対して要求されたアクションを実行します。対照的に、Ansibleモジュールは、プレイブックで定義されたAnsibleインベントリグループ内のホストで要求されたアクションを実行します。その結果、モジュールはセクションを無視して hosts
構成ファイルを参照するか、1 つ以上のテスト ファイルを直接参照できます。
したがって、 および juniper_junos_jsnapy
モジュールは、action
引数に加えて、jsnapy
特定のアクションに使用するJSNAPy設定ファイルまたはJSNAPyテストファイルを指定するために、 または test_files
引数のいずれかを必要としますconfig_file
。 表 3 に、 config_file
および test_files
の引数の概要を示します。
モジュール引数 |
価値 |
詳細な情報 |
---|---|---|
|
JSNAPy 設定ファイルへの絶対または相対ファイル パス。 |
パスが相対パスの場合、モジュールは次の場所にある構成ファイルを指定された順序でチェックします。
構成ファイルが相対ファイル・パスを使用してテスト・ファイルを参照している場合、モジュールはまずプレイブック・ディレクトリー内のテスト・ファイルをチェックし、次にデフォルト |
|
JSNAPy テスト ファイルへの絶対または相対ファイル パス。これは、単一のファイルパスまたはファイルパスのリストにすることができます。 |
相対パスを指定するテスト ファイルごとに、モジュールは次の場所にあるファイルを指定された順序でチェックします。
|
引数test_files
と引数にはconfig_file
、絶対ファイル パスまたは相対ファイル パスを指定できます。相対ファイル パスを使用する場合は、オプションで module 引数を含めてdir
、ファイルが存在するディレクトリを指定できます。またはtest_files
引数がconfig_file
相対ファイルパスを使用する場合、モジュールは、引数が存在する場合でもdir
、最初にAnsibleプレイブックディレクトリの下のファイルをチェックします。ファイルが Playbook ディレクトリの下に存在しない場合、モジュールは引数ディレクトリが指定されている場合はその下dir
をチェックし、引数が省略されている場合は dir
/etc/jsnapy/testfiles ディレクトリの下をチェックします。ファイルが見つからない場合、プレイブックはエラー メッセージを生成します。
次のサンプル プレイブックは、snap_pre
configuration_interface_status.yaml 構成ファイルを使用してアクションを実行します。構成ファイルがプレイブックディレクトリに存在しない場合、モジュールはユーザーのホームディレクトリの jsnapy/testfiles サブディレクトリにあるファイルをチェックします。
--- - name: Junos Snapshot Administrator tests hosts: dc1a connection: local gather_facts: no tasks: - name: Take a pre-maintenance snapshot of the interfaces juniper.device.jsnapy: action: "snap_pre" dir: "~/jsnapy/testfiles" config_file: "configuration_interface_status.yaml"
Python リリース 1.3.0 の Junos Snapshot Administrator 以降、設定ファイルとテスト ファイルのデフォルトの場所は ~/jsnapy/testfiles です。ただし、仮想環境内またはそれ以前のリリースのデフォルトの場所は /etc/jsnapy/testfiles です。
モジュールは、セクションを含む hosts
構成ファイルを参照している場合でも、Ansibleプレイブックで指定されたホストで要求されたアクションを実行します。エラーが発生し、JSNAPy テストの実行に失敗した場合、モジュールは失敗を報告します。1つ以上のJSNAPyテストが失敗した場合、失敗は報告 されません 。JSNAPy テスト結果を確認するには、モジュールの応答を登録し、モジュールを使用して assert
応答で期待される結果を検証します。
Python の Junos Snapshot Administrator は、その操作に関する情報をデフォルトで /var/log/jsnapy/jsnapy.log ファイルに記録します。および juniper_junos_jsnapy
モジュールにはjsnapy
、オプションで、logfile
特定のタスクの情報が記録されるAnsible制御ノード上の書き込み可能ファイルへのパスを指定する 引数を含めることができます。ファイルに記録される情報のレベルは、Ansible の詳細レベルとデバッグ オプションによって決まります。デフォルトでは、重大度レベルが WARNING 以上のメッセージのみがログに記録されます。重大度レベル INFO または重大度レベル DEBUG 以上のメッセージをログに記録するには、それぞれ または -v
-vv
コマンドライン オプションを使用してプレイブックを実行します。
AnsibleプレイブックでJSNAPyテストを実行すると、コールバックプラグインを有効に jsnapy
して、失敗したJSNAPyテストの情報をキャプチャして要約できます。コールバックプラグインを有効にするには、 ステートメントをAnsible構成ファイルに追加します callback_whitelist = jsnapy
。詳細については、「 jsnapy コールバックプラグインを有効にする」を参照してください。
スナップショットの取得と比較
JSNAPyを使用すると、変更前と変更後のネットワークJunosデバイスのランタイム環境のスナップショットをキャプチャし、スナップショットを比較して、予想される変更を確認したり、予期しない問題を特定したりできます。および jsnapy
juniper_junos_jsnapy
Ansibleモジュールを使用すると、Ansibleプレイブックの一部としてJSNAPyスナップショットを取得して比較できます。モジュールは、各ホストの各スナップショットを、あらかじめ決められたファイル名を使用して、デフォルトのJSNAPyスナップショットディレクトリ内の個別のファイルに保存します。出力ファイルの詳細については、「 jsnapy および juniper_junos_jsnapy モジュール出力について」を参照してください。
変更を行う前に 1 つ以上のデバイスのベースライン スナップショットを取得するには、モジュールの引数snap_pre
を action
に設定し、構成ファイルまたは 1 つ以上のテスト ファイルを指定します。
次のプレイブックは、Ansibleインベントリグループ内の各デバイスのPREスナップショットを保存します。このタスクは、~/jsnapy/testfiles ディレクトリ内の configuration_interface_status.yaml 構成ファイルを参照し、プレイブック ディレクトリ内の jsnapy_tests.log ファイルにメッセージを記録します。
--- - name: Junos Snapshot Administrator tests hosts: dc1 connection: local gather_facts: no tasks: - name: Take a pre-maintenance snapshot of the interfaces juniper.device.jsnapy: action: "snap_pre" dir: "~/jsnapy/testfiles" config_file: "configuration_interface_status.yaml" logfile: "jsnapy_tests.log"
変更の実行後に 1 つ以上のデバイスのスナップショットを取得するには、モジュールの引数snap_post
を action
に設定し、構成ファイルまたは 1 つ以上のテスト ファイルを指定します。
次のプレイブックは、Ansibleインベントリグループ内の各デバイスのPOSTスナップショットを保存します。このタスクは、~/jsnapy/testfiles ディレクトリ内の同じ configuration_interface_status.yaml 構成ファイルを参照し、プレイブック ディレクトリ内の jsnapy_tests.log ファイルにメッセージを記録します。
--- - name: Junos Snapshot Administrator tests hosts: dc1 connection: local gather_facts: no tasks: - name: Take a post-maintenance snapshot of the interfaces juniper.device.jsnapy: action: "snap_post" dir: "~/jsnapy/testfiles" config_file: "configuration_interface_status.yaml" logfile: "jsnapy_tests.log"
またはjuniper_junos_jsnapy
モジュールがjsnapy
アクションまたはsnap_post
アクションを実行するとsnap_pre
、それぞれ「PRE」または「POST」タグを含む自動生成されたファイル名を使用して、各ホストの各スナップショットを個別のファイルに保存します。スナップショットとPOST
スナップショットを比較PRE
して更新をすばやく確認したり、変更によって発生した可能性のある問題を特定したりするには、モジュールの引数check
を action
に設定し、スナップショットの取得に使用したのと同じ構成ファイルまたはテスト ファイルを指定します。
モジュールがアクションを実行すると check
、各デバイスの各テストの既存の PRE スナップショットと POST スナップショットが比較され、テスト ファイルのセクションで定義された tests:
条件に対して評価されます。テスト・ファイルでテスト・ケースが定義されていない場合、JSNAPy はスナップショットをノードごとに比較します。テスト結果を確認するには、モジュールの応答を登録し、モジュールを使用して assert
応答で予想される結果を検証します。
次のプレイブックでは、Ansibleインベントリグループ内のすべてのデバイスに対して以前に実行された snap_pre
スナップショットと snap_post
アクションに対して取得されたスナップショットを比較します。結果は、構成ファイルで参照されているテスト ファイル内の条件を使用して評価されます。プレイブックは、モジュールの応答を 'test_result
' として登録し、モジュールを使用して assert
、指定されたデバイスですべてのテストに合格したことを確認します。
--- - name: Junos Snapshot Administrator tests hosts: dc1 connection: local gather_facts: no tasks: - name: Compare PRE and POST snapshots juniper.device.jsnapy: action: "check" dir: "~/jsnapy/testfiles" config_file: "configuration_interface_status.yaml" logfile: "jsnapy_tests.log" register: test_result - name: Verify JSNAPy tests passed assert: that: - "test_result.passPercentage == 100"
プレイブックを実行すると、アサーションによってテストに失敗したデバイスをすばやく特定できます。
user@host:~$ ansible-playbook jsnapy-interface-check.yaml PLAY [Junos Snapshot Administrator tests] ************************************* TASK [Compare PRE and POST snapshots] ***************************************** ok: [dc1a.example.net] ok: [dc1b.example.net] TASK [Verify JSNAPy tests passed] ********************************************* ok: [dc1b.example.net] => { "changed": false, "msg": "All assertions passed" } fatal: [dc1a.example.net]: FAILED! => { "assertion": "test_result.passPercentage == 100", "changed": false, "evaluated_to": false, "msg": "Assertion failed" } to retry, use: --limit @/home/user/jsnapy-interface-check.retry PLAY RECAP ******************************************************************** dc1b.example.net : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 dc1a.example.net : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
スナップチェック操作の実行
JSNAPyを使用すると、JSNAPyテストファイルで指定されたコマンドまたはRPCのスナップショットを取得し、テストケースで事前定義された基準に対してスナップショットを即座に評価できます。および jsnapy
juniper_junos_jsnapy
Ansibleモジュールを使用すると、Ansibleプレイブックの一部としてJSNAPyスナップチェック操作を実行できます。
スナップショットを取得し、テスト ファイルのセクションで事前に定義された一連の条件tests:
に基づいてすぐに評価するには、モジュールの引数snapcheck
を action
に設定し、構成ファイルまたは 1 つ以上のテスト ファイルを指定します。テスト結果を確認するには、モジュールの応答を登録し、モジュールを使用してassert
応答で予想される結果を検証します。
たとえば、次のプレイブックでは、Ansibleインベントリグループ内のデバイスごとに、コマンドまたはRPCごとに個別のスナップショットをテストファイルに保存し、モジュールの応答を登録し、assertモジュールを使用して、テストファイルで定義されているすべてのテストがそのデバイスで合格したことを確認します。
--- - name: Junos Snapshot Administrator tests hosts: dc1 connection: local gather_facts: no tasks: - name: Take a snapshot and immediately evaluate it juniper.device.jsnapy: action: "snapcheck" dir: "~/jsnapy/testfiles/" test_files: - "test_interface_status.yaml" - "test_bgp_neighbor.yaml" logfile: "jsnapy_tests.log" register: test_result - name: Verify JSNAPy tests passed assert: that: - "test_result.passPercentage == 100"
jsnapy と juniper_junos_jsnapy モジュール出力について
または juniper_junos_jsnapy
モジュールsnap_pre
が jsnapy
、 snap_post
、または snapcheck
のアクションを実行すると、スナップショットは JSNAPy snapshots ディレクトリに自動的に保存されます。モジュールは、別の場所を指定するようにJSNAPy設定ファイルを変更しない限り、デフォルトのJSNAPyディレクトリを使用します。このモジュールは、Ansibleインベントリ グループ内の各デバイスで実行されるコマンドまたはRPCごとに個別のファイルを作成します。表 4 に、引数の各値に対するスナップショット ファイルのファイル名の概要を示しますaction
。
Python リリース 1.3.0 の Junos Snapshot Administrator 以降、JSNAPy テスト ファイルとスナップショットのデフォルト ディレクトリは、それぞれ ~/jsnapy/testfiles と ~/jsnapy/snapshot です。ただし、仮想環境内またはそれ以前のリリースのデフォルトディレクトリは、 /etc/jsnapy/testfiles および /etc/jsnapy/snapshot です。
|
出力ファイル |
---|---|
|
hostname_プレ__hashcommand。format |
|
hostname_投稿_hash。commandformat |
|
hostname_snap_temp_hash_command。format |
どこ:
-
hostname- コマンドまたは RPC が実行されるデバイスのホスト名。
-
(プレ|投稿 |snap_temp) - アクションを識別するタグ。この操作では
snapcheck
、PRE
現在のリリースでは タグが使用されています。それ以前のリリースでは、snap_temp
というタグが使用されています。 -
hash- および
kwargs
キーを含むrpc
テスト ファイルから生成されたkwargs
ハッシュ。テストファイルが同じRPCを使用するが異なる引数を含み、RPCが同じホストで実行される場合、ハッシュはそのような場合に一意の出力ファイル名を保証します。テスト ファイルでキーが定義され
command
ている場合、またはテスト ファイルでキーが定義されrpc
ていてもキーが含まれていないkwargs
場合、ハッシュは省略されます。 -
command- 管理対象デバイスで実行されたコマンドまたは RPC。モジュールは、コマンドまたはRPC名の空白と特殊文字をアンダースコア(_)に置き換えます。
-
format- 出力の形式( xmlなど)。
およびjuniper_junos_jsnapy
モジュールはjsnapy
、ホスト名とコマンドまたはRPCに基づいて、特定のアクションのスナップショットファイル名のみを区別します。その結果、モジュールが同じコマンドまたはRPCを定義するテストファイルを使用して同じアクションに対して同じデバイス上でスナップショットを取得すると、モジュールは同じファイル名のスナップショットを生成し、新しいファイルが古いファイルを上書きします。
例えば、デバイス dc1a.example.net および dc1b.example.net で および コマンドを実行するshow chassis fpc
show interfaces terse
テストファイルをモジュールに含めaction: "snap_pre"
て参照する場合、結果ファイルは次のようになります。
user@ansible-cn:~$ ls jsnapy/snapshots dc1a.example.net_PRE_show_chassis_fpc.xml dc1a.example.net_PRE_show_interfaces_terse.xml dc1b.example.net_PRE_show_chassis_fpc.xml dc1b.example.net_PRE_show_interfaces_terse.xml
モジュールにデバイス dc1a.example.net の項目interface_name: lo0
を使用して kwargs
RPC を実行するget-interface-information
テスト ファイルが含まれaction: "snap_post"
、参照されている場合、結果のファイルは次のようになります。
dc1a.example.net_POST_r1w59I99HXxC3u0VXXshbw==_get_interface_information.xml
スナップショット ファイルの生成に加えて、 jsnapy
モジュール juniper_junos_jsnapy
とモジュールはモジュール応答で次のキーを返すこともできます。
-
action
- モジュールによって実行される JSNAPy アクション。 -
changed
- デバイスの状態が変化したかどうかを示します。JSNAPy は状態についてのみ報告するため、値は常にfalse
です。 -
failed
- プレイブック タスクが失敗したかどうかを示します。 -
msg
- JSNAPy テスト結果。
jsnapyコールバックプラグインを有効にする
Junosデバイスに対してJSNAPyテストを実行し、1つ以上のテストが失敗した場合、出力が広範囲に及ぶと、失敗したテストを特定して抽出することが困難な場合があります。コールバックプラグインを使用すると jsnapy
、失敗したJSNAPyテストの情報を簡単に抽出して要約できます。コールバックプラグインを有効に jsnapy
し、JSNAPyテストを含むプレイブックを実行すると、プラグインはプレイブック PLAY RECAP
の後に失敗したJSNAPyテストの情報を要約します。
コールバックプラグインは jsnapy
デフォルトでは有効になっていません。コールバックプラグインを有効にするには jsnapy
、 ステートメントをAnsible構成ファイルに追加します callback_whitelist = jsnapy
。
[defaults] callback_whitelist = jsnapy
コールバックプラグインを有効に jsnapy
してプレイブックを実行すると、プラグインは失敗したJSNAPyテストを人間が読める形式で要約します。例えば:
... PLAY RECAP **************************************************************** qfx10002-01 : ok=3 changed=0 unreachable=0 failed=1 qfx10002-02 : ok=3 changed=0 unreachable=0 failed=1 qfx5100-01 : ok=1 changed=0 unreachable=0 failed=1 JSNAPy Results for: qfx10002-01 ******************************************* Value of 'peer-state' not 'is-equal' at '//bgp-information/bgp-peer' with {"peer-as": "64502", "peer-state": "Active", "peer-address": "198.51.100.21"} Value of 'peer-state' not 'is-equal' at '//bgp-information/bgp-peer' with {"peer-as": "64510", "peer-state": "Idle", "peer-address": "192.168.0.1"} Value of 'oper-status' not 'is-equal' at '//interface-information/physical-interface[normalize-space(admin-status)='up' and logical-interface/address-family/address-family-name ]' with {"oper-status": "down", "name": "et-0/0/18"} JSNAPy Results for: qfx10002-02 ******************************************* Value of 'peer-state' not 'is-equal' at '//bgp-information/bgp-peer' with {"peer-as": "64502", "peer-state": "Active", "peer-address": "198.51.100.21"}
例:Ansible を使用した JSNAPy スナップチェック操作の実行
この jsnapy
モジュールを使用すると、Ansibleプレイブックの一部としてJunosデバイスに対してJSNAPyテストを実行できます。この例では、モジュールを使用して jsnapy
、 snapcheck
特定の設定変更を適用した後のJunosデバイスの動作状態を検証するアクションを実行します。
必要条件
この例では、以下のハードウェアとソフトウェアのコンポーネントを使用しています。
-
実行中のAnsible制御ノード:
-
Python 3.7 以降
-
コレクションがインストールされたAnsible2.10以降
juniper.device
-
Junos PyEZ リリース 2.6.0 以降
-
Python リリース 1.3.6 以降の Junos Snapshot Administrator
-
Ansibleプレイブックを実行する前に、以下が完了していることを確認してください。
-
SSH経由のNETCONFが有効で、適切な権限で設定されたユーザーアカウントを備えたJunosデバイス
-
Ansible制御ノードとJunosデバイスで適切なユーザーに対して構成されたSSH公開/秘密鍵のペア
-
必要なホストが定義されている既存のAnsibleインベントリ ファイル
概要
この例では、Ansibleプレイブックが3台のJunosデバイスでBGPピアリングセッションを設定し、モジュールを使用して jsnapy
各ネイバーアドレスに対してBGPセッションが確立されていることを確認します。プレイブックは、デバイスでセッションが確立されていることを検証すると、新しい構成のコミットを確認します。プレイブックでコミットが確認されない場合、Junos デバイスは自動的に以前にコミットされた設定にロールバックします。Ansibleプロジェクトでは、プレイブックのグループ変数とホスト変数をそれぞれとディレクトリで group_vars
定義します host_vars
。
プレイブックには 2 つのプレイがあります。最初のプレイである は、 Load and commit BGP configuration
設定を生成してアセンブルし、デバイスに設定を読み込み、コミット確認済みの操作を使用してコミットします。構成が更新されると、1 つのハンドラーに通知されます。このプレイでは、次のタスクが実行されます。
Remove build directory |
指定したデバイスの既存のビルド ディレクトリを削除します (存在する場合)。 |
Create build directory |
指定されたデバイスの新しい空のビルドディレクトリを作成します。 |
Build BGP configuration |
|
Assemble configuration parts |
この例では、BGP 構成ファイルのみが存在するため、結果の構成ファイルは前のタスクでレンダリングされた BGP 構成ファイルと同じです。後で新しいタスクを追加して他のテンプレートから追加の構成ファイルを生成すると、 |
Load and commit config, require confirmation |
設定を Junos デバイスに読み込み、コミットを恒久的なものにするには明示的な確認が必要な操作を使用して 要求された設定がデバイスにすでに存在する場合、 |
2つ目の再生では、 Verify BGP
は、JSNAPyテストファイル内のテストを使用して各デバイス上でJSNAPy snapcheck
操作を実行し、すべてのテストに合格した場合にコミットを確認します。このプレイでは、次のタスクが実行されます。
Execute snapcheck |
JSNAPy この例では、プレイブックは、引数を |
Confirm commit |
最初のプレイブック プレイで設定が更新され、すべての JSNAPy テストに合格した場合に、前のコミット操作を確認するコミット チェック操作を実行します。プレイブックで設定が更新されても、コミットが確認されない場合、Junos デバイスは自動的に設定を以前にコミットした設定にロールバックします。
手記:
前回のコミット操作 |
Verify BGP configuration |
(オプション)指定されたデバイスでのJSNAPyテストが成功したか失敗したかを明示的に示します。このタスクは特に必須ではありませんが、JSNAPy テストがいつどのデバイスで失敗したかをより簡単に識別できます。 |
構成
グループ変数の定義
手順
グループ変数を定義するには:
-
group_vars/all ファイルで、ビルド ディレクトリとコンフィギュレーション ファイルとログ ファイルのファイル名の変数を定義します。
build_dir: "{{ playbook_dir }}/build_conf/{{ inventory_hostname }}" junos_conf: "{{ build_dir }}/junos.conf" logfile: "junos.log"
Jinja2 テンプレートとホスト変数の定義
Jinja2 テンプレートの定義
BGP 設定の生成に使用する Jinja2 テンプレートを作成するには、次の手順に従います。
プロジェクトのプレイブックディレクトリに bgp-template.j2 という名前のファイルを作成します。
BGP 構成テンプレートをファイルに追加します。
interfaces { {% for neighbor in neighbors %} {{ neighbor.interface }} { unit 0 { description "{{ neighbor.name }}"; family inet { address {{ neighbor.local_ip }}/30; } } } {% endfor %} lo0 { unit 0 { family inet { address {{ loopback }}/32; } } } } protocols { bgp { group underlay { import bgp-in; export bgp-out; type external; local-as {{ local_asn }}; multipath multiple-as; {% for neighbor in neighbors %} neighbor {{ neighbor.peer_ip }} { peer-as {{ neighbor.asn }}; } {% endfor %} } } lldp { {% for neighbor in neighbors %} interface "{{ neighbor.interface }}"; {% endfor %} } } routing-options { router-id {{ loopback }}; forwarding-table { export bgp-ecmp; } } policy-options { policy-statement bgp-ecmp { then { load-balance per-packet; } } policy-statement bgp-in { then accept; } policy-statement bgp-out { then { next-hop self; accept; } } }
ホスト変数の定義
BGPコンフィギュレーションを生成するためにJinja2テンプレートで使用されるホスト変数を定義するには、以下のようにします。
プロジェクトの host_vars ディレクトリで、ホストごとに .yaml という名前のhostname個別のファイルを作成します。
r1.yaml ファイルでホスト r1 の変数を定義します。
--- loopback: 192.168.0.1 local_asn: 64521 neighbors: - interface: ge-0/0/0 name: to-r2 asn: 64522 peer_ip: 198.51.100.2 local_ip: 198.51.100.1 peer_loopback: 192.168.0.2 - interface: ge-0/0/1 name: to-r3 asn: 64523 peer_ip: 198.51.100.6 local_ip: 198.51.100.5 peer_loopback: 192.168.0.3
r2.yaml ファイルでホスト r2 の変数を定義します。
--- loopback: 192.168.0.2 local_asn: 64522 neighbors: - interface: ge-0/0/0 name: to-r1 asn: 64521 peer_ip: 198.51.100.1 local_ip: 198.51.100.2 peer_loopback: 192.168.0.1 - interface: ge-0/0/1 name: to-r3 asn: 64523 peer_ip: 198.51.100.10 local_ip: 198.51.100.9 peer_loopback: 192.168.0.3
r3.yaml ファイルでホスト r3 の変数を定義します。
--- loopback: 192.168.0.3 local_asn: 64523 neighbors: - interface: ge-0/0/0 name: to-r1 asn: 64521 peer_ip: 198.51.100.5 local_ip: 198.51.100.6 peer_loopback: 192.168.0.1 - interface: ge-0/0/1 name: to-r2 asn: 64522 peer_ip: 198.51.100.9 local_ip: 198.51.100.10 peer_loopback: 192.168.0.2
JSNAPyテストファイルの作成
手順
この jsnapy
モジュールは、 ~/jsnapy/testfiles ディレクトリー内の JSNAPy テスト・ファイルを参照します。JSNAPy テスト・ファイルを作成するには、次のようにします。
コマンドを実行し、
show bgp neighbor
BGP ピアの状態が確立されていることをテストする jsnapy_test_file_bgp_states.yaml ファイルを作成します。bgp_neighbor: - command: show bgp neighbor - ignore-null: True - iterate: xpath: '//bgp-peer' id: './peer-address' tests: # Check if peers are in the established state - is-equal: peer-state, Established err: "Test Failed!! peer <{{post['peer-address']}}> state is not Established, it is <{{post['peer-states']}}>" info: "Test succeeded!! peer <{{post['peer-address']}}> state is <{{post['peer-state']}}>"
コマンドを実行し、
show bgp summary
BGP ダウン ピア カウントが 0 でなければならないことをアサートする jsnapy_test_file_bgp_summary.yaml ファイルを作成します。bgp_summary: - command: show bgp summary - item: xpath: '/bgp-information' tests: - is-equal: down-peer-count, 0 err: "Test Failed!! down-peer-count is not equal to 0. It is equal to <{{post['down-peer-count']}}>" info: "Test succeeded!! down-peer-count is equal to <{{post['down-peer-count']}}>"
Ansibleプレイブックを作成する
デバイスを構成する最初のプレイを定義する
コンフィギュレーションをレンダリングし、それをデバイスにロードし、コミット確認済み操作としてコンフィギュレーションをコミットする最初のプレイを作成するには、以下を行います。
プレイブックの定型文と、モジュールをローカルで実行する最初のプレイを含めます。
--- - name: Load and commit BGP configuration hosts: bgp_routers connection: local gather_facts: no
既存のビルドディレクトリを空のディレクトリに置き換えるタスクを作成し、新しい設定ファイルを保存します。
tasks: - name: Remove build directory file: path: "{{ build_dir }}" state: absent - name: Create build directory file: path: "{{ build_dir }}" state: directory
Jinja2テンプレートファイルとホスト変数からBGP設定をレンダリングするタスクを作成し、そのホストのビルドディレクトリにある bgp.conf ファイルに保存します。
- name: Build BGP configuration template: src: "{{ playbook_dir }}/bgp-template.j2" dest: "{{ build_dir }}/bgp.conf"
ビルドディレクトリ内の設定ファイルを最終的な junos.conf 設定ファイルにアセンブルするタスクを作成します。
- name: Assemble configuration parts assemble: src: "{{ build_dir }}" dest: "{{ junos_conf }}"
デバイス上に設定を読み込み、確認が必要なコミット操作を実行し、設定が変更されていれば、指定されたハンドラに通知するタスクを作成します。
- name: Load and commit config, require confirmation juniper.device.config: load: "merge" format: "text" src: "{{ junos_conf }}" confirm: 5 comment: "config by Ansible" logfile: "{{ logfile }}" register: config_result # Notify handler, only if configuration changes. notify: - Waiting for BGP peers to establish connections
デバイスの構成が更新された場合にプレイブックの実行を一時停止するハンドラーを作成し、一時停止時間を環境に適した値に設定します。
handlers: - name: Waiting for BGP peers to establish connections pause: seconds=60
JSNAPy操作を実行するための2番目の再生を定義します
設定が変更され、JSNAPyテストに合格した場合、JSNAPy スナップチェック操作を実行し、コミットされた設定を確認する 2 つ目のプレイを作成するには、次の手順に従います。
モジュールをローカルで実行する2番目のプレイの定型文を含めます。
- name: Verify BGP hosts: bgp_routers connection: local gather_facts: no
指定されたJSNAPyテストファイルのテストに基づいてJSNAPyスナップチェック操作を実行するタスクを作成し、モジュールのレスポンスを登録します。
tasks: - name: Execute snapcheck juniper.device.jsnapy: action: "snapcheck" dir: "~/jsnapy/testfiles" test_files: - "jsnapy_test_file_bgp_states.yaml" - "jsnapy_test_file_bgp_summary.yaml" logfile: "{{ logfile }}" register: snapcheck_result
指定された条件が満たされた場合にコミットを確認するタスクを作成します。
# Confirm commit only if configuration changed and JSNAPy tests pass - name: Confirm commit juniper.device.config: check: true commit: false diff: false logfile: "{{ logfile }}" when: - config_result.changed - "snapcheck_result.passPercentage == 100"
(オプション)モジュールを使用して
assert
、JSNAPy テストに合格したことをアサートするタスクを作成します。- name: Verify BGP configuration assert: that: - "snapcheck_result.passPercentage == 100" msg: "JSNAPy test on {{ inventory_hostname }} failed"
業績
Ansibleコントロールノードで、完成したプレイブックを確認します。プレイブックに目的のコードが表示されない場合は、このセクションの手順を繰り返してプレイブックを修正します。
--- - name: Load and commit BGP configuration hosts: bgp_routers connection: local gather_facts: no tasks: - name: Remove build directory file: path: "{{ build_dir }}" state: absent - name: Create build directory file: path: "{{ build_dir }}" state: directory - name: Build BGP configuration template: src: "{{ playbook_dir }}/bgp-template.j2" dest: "{{ build_dir }}/bgp.conf" - name: Assemble configuration parts assemble: src: "{{ build_dir }}" dest: "{{ junos_conf }}" - name: Load and commit config, require confirmation juniper.device.config: load: "merge" format: "text" src: "{{ junos_conf }}" confirm: 5 comment: "config by Ansible" logfile: "{{ logfile }}" register: config_result # Notify handler, only if configuration changes. notify: - Waiting for BGP peers to establish connections handlers: - name: Waiting for BGP peers to establish connections pause: seconds=60 - name: Verify BGP hosts: bgp_routers connection: local gather_facts: no tasks: - name: Execute snapcheck juniper.device.jsnapy: action: "snapcheck" dir: "~/jsnapy/testfiles" test_files: - "jsnapy_test_file_bgp_states.yaml" - "jsnapy_test_file_bgp_summary.yaml" logfile: "{{ logfile }}" register: snapcheck_result # Confirm commit only if configuration changed and JSNAPy tests pass - name: Confirm commit juniper.device.config: check: true commit: false diff: false logfile: "{{ logfile }}" when: - config_result.changed - "snapcheck_result.passPercentage == 100" - name: Verify BGP configuration assert: that: - "snapcheck_result.passPercentage == 100" msg: "JSNAPy test on {{ inventory_hostname }} failed"
プレイブックの実行
プレイブックを実行するには:
-
ansible-playbook
制御ノードでコマンドを発行し、プレイブックのパスと必要なオプションを指定します。user@ansible-cn:~/ansible$ ansible-playbook ansible-pb-bgp-configuration.yaml PLAY [Load and commit BGP configuration] ************************************* TASK [Remove build directory] ************************************************ changed: [r1] changed: [r2] changed: [r3] TASK [Create build directory] ************************************************ changed: [r1] changed: [r2] changed: [r3] TASK [Build BGP configuration] *********************************************** changed: [r2] changed: [r1] changed: [r3] TASK [Assemble configuration parts] ****************************************** changed: [r3] changed: [r2] changed: [r1] TASK [Load and commit config, require confirmation] ************************** changed: [r2] changed: [r1] changed: [r3] RUNNING HANDLER [Waiting for BGP peers to establish connections] ************* Pausing for 60 seconds (ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort) ok: [r3]
PLAY [Verify BGP] ************************************************************ TASK [Execute snapcheck] ***************************************************** ok: [r2] ok: [r1] ok: [r3] TASK [Confirm commit] ******************************************************** ok: [r2] ok: [r1] ok: [r3] TASK [Verify BGP configuration] ********************************************** ok: [r1] => { "changed": false, "msg": "All assertions passed" } ok: [r2] => { "changed": false, "msg": "All assertions passed" } ok: [r3] => { "changed": false, "msg": "All assertions passed" } PLAY RECAP ******************************************************************* r1 : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 r2 : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 r3 : ok=9 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
検証
BGP ネイバーの検証
目的
各ネイバーアドレスに対してBGPセッションが確立されていることを確認します。
JSNAPy テストファイルは、BGP セッションが各ネイバーアドレスに対して確立されていること、およびダウンしているピアがないことをテストします。タスク出力により Verify BGP configuration
、指定されたデバイスがすべてのJSNAPyテストに合格したことをすばやく確認できます。JSNAPy passPercentage
が 100% の場合、タスクはタスク出力に含めます "msg": "All assertions passed"
。
アクション
Verify BGP configuration
タスクの出力を確認し、各デバイスがメッセージを返すAll assertions passed
ことを確認します。
TASK [Verify BGP configuration] ********************************************** ok: [r1] => { "changed": false, "msg": "All assertions passed" } ok: [r2] => { "changed": false, "msg": "All assertions passed" } ok: [r3] => { "changed": false, "msg": "All assertions passed" }
意味
この All assertions passed
メッセージは、デバイスで BGP セッションが正常に確立されたことを示します。
Ansibleプレイブックエラーのトラブルシューティング
設定読み込みエラーのトラブルシューティング
問題
Ansibleプレイブックは、 ConfigLoadError
構文エラーのためにデバイスに設定を読み込めなかったことを示すエラーを生成します。
fatal: [r1]: FAILED! => {"changed": false, "msg": "Failure loading the configuraton: ConfigLoadError(severity: error, bad_element: protocol, message: error: syntax error\nerror: error recovery ignores input until this point)"}
解決
このプレイブックは、Jinja2 テンプレートと、 host_vars ディレクトリでそのデバイス用に定義されたホスト変数を使用して、Junos OS 構成をレンダリングします。プレイブックは、Jinja2 テンプレートが無効な構成を生成すると、構文エラーを生成します。このエラーを修正するには、Jinja2 テンプレートを更新して、エラー メッセージ内のキーによって bad_element
識別される要素を修正します。
失敗したJSNAPyテストのトラブルシューティング
問題
タスクの出力は Verify BGP configuration
、JSNAPy passPercentage
が 100% に等しくなかったため、アサーションが失敗したことを示しています。
TASK [Verify BGP configuration] ************************************************************* fatal: [r1]: FAILED! => { "assertion": "snapcheck_result.passPercentage == 100", "changed": false, "evaluated_to": false, "msg": "JSNAPy test on r1 failed" }
デバイスがネイバーとのBGPセッションを確立していない場合、またはセッションがダウンした場合、アサーションは失敗します。アサーションが失敗し、そのデバイスの構成が最初の再生で更新された場合、プレイブックはデバイス上の新しい構成のコミットを確認せず、デバイスは構成を以前にコミットされた構成にロールバックします。
解決
ピアがセッションを確立する前に操作が行われた snapcheck
場合、またはBGPネイバーが正しく設定されていない場合、JSNAPyテストは失敗する可能性があります。プレイブックの出力に、構成が正常に読み込まれ、デバイスにコミットされたことが示されている場合は、ハンドラーの一時停止間隔を環境に適した値に増やし、プレイブックを再実行してみてください。
handlers: - name: Waiting for BGP peers to establish connections pause: seconds=75
それでもテストが失敗する場合は、Jinja2 テンプレートと各デバイスのホスト変数に正しいデータが含まれていること、および各デバイスの構成が正しいことを確認します。
失敗したコミット確認のトラブルシューティング
問題
1 つ以上のデバイスで構成が確認されませんでした。
TASK [Confirm commit] *********************************************************************** skipping: [r2] skipping: [r2] skipping: [r3]
解決
プレイブックは、設定が変更され、JSNAPy テストに合格した場合にのみ、設定を確認します。タスクの出力が Load and commit config, require confirmation
構成が変更されなかったことを示している場合、プレイブックはコミットを確認するタスクを実行しません。設定が変更されても確認されなかった場合、JSNAPyテストは失敗しています。BGPネイバーが正しく設定されていない場合、またはプレイブックがデバイスがBGPセッションを確立するのに十分な時間をプレイブックに提供しない場合、JSNAPyテストは失敗する可能性があります。詳細については、 失敗したJSNAPyテストのトラブルシューティングを参照してください。
変更履歴テーブル
機能のサポートは、使用しているプラットフォームとリリースによって決まります。 機能エクスプローラー を使用して、機能がプラットフォームでサポートされているかどうかを判断します。
Juniper.junos
、
juniper_junos_jsnapy
モジュールはモジュールの機能を置き換えます
junos_jsnapy
。