The Inside Playbook

Ansible を使用してネットワークデバイスを再起動する

2019年12月20日、寄稿者: Sean Cavanaugh

Ansible を使用してネットワークデバイスを再起動する

11 月の Red Hat Ansible Automation Platform のリリースで、50 を超えるネットワークリソースのモジュールがリリースされました。これにより、ネットワークデバイスの自動化をより容易に、細かい設定なしで実施できるようになります。Andrius のブログ記事では、新しいリソースモジュールに加えて、ファクト収集の強化について紹介しています。この強化により、すべての新しいリソースモジュールでネットワークデバイスについてのより広範なファクトが得られるようになります。 このブログ記事では、目立たないけれど強力なもう 1 つの強化点を取り上げます。 その強化とは、ネットワークデバイスで wait_for_connection モジュールを使用できるようになったことです。デバイスの再起動やオフライン化の操作を含む Ansible Playbook を運用している場合、このモジュールを使うことで、Playbook での切断の処理をよりプログラマチックに行えるようになります。 wait_for_connection を活用すれば、ネットワーク自動化の Playbook を Linux ホストや Windows ホストの Playbook と同じような感覚で使えるようになります。

目次

wait_for と wait_for_connection の比較

プロンプトへの対応

reset_connection と組み合わせて使用する

wait_for と wait_for_connection の比較

wait_for と wait_for_connection の 2 つは、条件が満たされるまで処理を待機させられる便利なモジュールです。処理を停止させるモジュールには他に pause がありますが、このモジュールの使用はできるだけ避けることをお勧めします。Ansible Playbook の pause は、プログラミング言語の sleep と同じように扱うべきだと私は考えています。 デバイスがタスクを完了するのにかかる時間は一定ではありませんから、それに合わせてプログラマチックに処理を行える 2 つの wait_for モジュールは、処理をやみくもに一時停止させるよりも優れたソリューションだと思います。 pause モジュールには問題がもう 1 つあり、それはプロンプトへの応答を Ansible Tower の外で行わなければならないことです。 手動操作を絡めるのであれば、Ansible Tower ワークフローで承認ノードを使用するほうがはるかにいいやり方です。

wait_for モジュールは、ファイルシステム上に指定のパスが現れるか、ポートが再びアクティブになるまで待機します。これで、ポートがアップしてすぐにシステムにログインできない場合を除き、再起動を伴うほとんどのケースに対応できます。 wait_for_connection は、wait_for よりも一歩進んだ使い方ができます。wait_for_connection モジュールは、Ansible がデバイスに再度ログインして適切なプロンプトを受信できることを確認してからタスクを完了します。対象が Linux ホストや Windows ホストの場合、確認は ping モジュールまたは win_ping モジュールで行います。ネットワークデバイスの場合は、最後に使用した接続プラグインがデバイスに完全に接続できることを確認します (ただし、このブログ記事の執筆時点では、network_cli 接続プラグインが必須です)。つまり、これら 2 つのモジュールの違いは、wait_for はポートが開いていることを認識するだけなのに対して、wait_for_connection はタスクの完了後すぐに後続のタスクが意図した動作を開始できるということです。

プロンプトへの対応

ネットワークデバイスでは、再起動などの運用タスクを実行するときに、アクションを実行を確認するプロンプトが表示されることがよくあります。

たとえば Juniper vSRX デバイスでは、次のようなプロンプトが表示されます。

admin@rtr3> request system reboot
Reboot the system ? [yes,no] (no)

続行するには、ユーザーが再起動を承認する必要があります。cli_command の記事では取り上げませんでしたが、cli_command モジュールはプロンプトを処理することができます。 それも、1 つではなく複数のプロンプトを処理できます。この例は、保存されていない設定がある Cisco ルーターで reload コマンドを実行したところです。 このとき、Cisco ルーターはまずシステム設定が変更されていることを警告し、running-config の内容が失われる前に保存するかどうかを尋ねます。

rtr1#reload

System configuration has been modified. Save? [yes/no]:

yes または no で応答すると、2 番目のプロンプトが表示されます。

Proceed with reload? [confirm]

ここで必要なのは両方のプロンプトを処理できるタスクであり、cli_command モジュールを使えば作成できます。

---
- name: reboot ios device
  cli_command:
    command: reload
   prompt:
      - Save?
      - confirm
    answer:
     - y
     - y

上記のタスクでは、両方のプロンプトに yes と応答し、設定を保存してデバイスを再起動します。プロンプトのリストと応答のリストは一致し、同じ順序でなければなりません。 つまり、prompt[0] に対する応答は answer[0] でなければなりません。

複数のプロンプトを処理するさらに詳細な例は、Juniper vSRX デバイスでパスワードをリセットするサンプルをご覧ください。

reset_connection と組み合わせて使用する

cli_command を使用してデバイスを再起動する方法を理解していれば、それを wait_for_connection と組み合わせて、再利用可能な Ansible Playbook を作成できます。ただし、プログラマチックに動作させるにはもう 1 つ別のタスク (meta: reset_connection) を追加する必要があります。

Playbook では、再起動後にネットワークデバイスへのソケットを再確立できるよう、ネットワークデバイスへの現在の接続を閉じておく必要があります。接続が閉じられておらず、かつコマンドがタイムアウトになる前に再起動が完了した場合、残っていた接続が閉じられた SSH 接続を再利用しようとし、その結果「ソケットが開かれていません」というエラーが発生します。 これを適切に処理する Ansible Playbook は次のようになります。

- reboot task (this is a snippet, full task removed for brevity)

- name: reset the connection
  meta: reset_connection

- name: Wait for the network device to reload
  wait_for_connection:
    delay: 10

これで、再起動後にネットワークデバイスに再接続できる Ansible Playbook の完成です。上記の例の完全版は、こちらの Arista vEOS ネットワークデバイス向け reboot.yml Ansible Playbook を参照してください。

お問い合わせ・製品のご紹介

Red Hat Ansible Automationについてのお問い合わせは

ansible-jp@redhat.com

Red Hat Ansible Automation製品について

詳細はこちら