てくなべ (tekunabe)

ansible / network / automation / StackStorm

Software Design 2018年12月号の Ansible 特集に寄稿しました(ウラ話など)

gihyo.jp

はじめに

Software Design 2018年12月号の Ansible 特集の中の「第3章:Ansibleでネットワーク作業も自動化」という章を寄稿させていただきました。個人的には貴重な経験だったので、経緯や気づきなどを書きたいと思います。

f:id:akira6592:20181116160011j:plain:w300


きっかけは継続したアウトプットから

もともとは、技術評論社さんとレッドハットさんの間で、企画がうまれました。

そこから、Ansible ユーザー会というコミュティで開催しているイベントへの参加や登壇、Ansible 関連のブログ投稿などをしていた私に「ネットワークの章を書いてみないか」とお声がけいただきました。

紙の媒体へのアウトプットは自信が無かったのですが、せっかくありがたく頂いた機会だったので、やってみようと思いました。


過去資料をベースにネタ検討

Ansible とネットワーク組み合わせの資料はいくつか作ってので、それらを参考にして内容を構成しようと考えました。

ベースとなるネタはあったとしても、どのような読者を想定するか、何ページ設けられるかなどの要素を考ええると、アウトラインを決めるまで検討することは少なくなかったです。

結果としては、シンプルな内容するため以下の内容に絞りました。

  • 概要
  • 情報取得サンプル(show コマンドの結果出力)
  • 設定変更サンプル(SNMPコミュニティ名の設定)

Playbook で指定するコマンドは、あえてすべてべた書きにしました。 テンプレートや変数を利用してもよかったのですが、なるべく簡単にしようと思って避けました。

自分の中で、記事の設計のようなものができるのは時間がかかってしまいましたが、そこからは意外と順調でした。(ただし、書きすぎ。後述)


文章の書き方に四苦八苦、ツールの力もお借りして

そもそも、文章を書くのが得意ではなく、このブログも文章を書く練習を兼ねて書いています。 そのため、正しい日本語書くための資料をいくつか読みました。とくに以下の点に気を付けました。

  • 文章は短く
    • 長くしない。適度に区切って、必要に応じて接続詞を挟む。
  • 主語と述語は合わせる
    • 主語と述語がねじれてしまわないようにする。
  • 「~することができる」は「~できる」にする
    • 不思議なクセでよく書いてしまうが、多くの場合は短くできる
  • 印刷してチェックする
    • ディスプレイでいくらチェックしても気づけないミスに気付ける

初期段階の原稿は、Visual Studio Codeテキスト校正くん という拡張を利用してチェックしながら書きました。自分の悪いクセを指摘してくれる先生のような存在で、非常に助かりました。

また、スライド資料であれば箇条書きと口頭で説明できる内容でも、いざ文章にしようとすると、文章の組み立て方に迷って苦戦しました。


後輩にレビューを依頼

原稿がある程度できたところで、後輩のネットワークエンジニアにレビューをお願いしました。分かりにくかった箇所などを指摘してもらい、修正しました。迷いながら書いた箇所が思いっきりバレました。


ブログとも専門書籍とも違う

やはり、ブログを書くのと違って、気軽に修正できないという点で、気を使う場面が多くありました。 原稿のボリュームのコントロールも難しかったです。当初、張り切って書いたら長すぎてしまいました。。どこをどう削るかは悩みました。紙媒体固有の難しさを感じました。

また、雑誌の中のひとつの特集ですから Ansible 専門書と違って、読者は Ansible 目的で読んでいるとは限りません。その中でちょっとでも興味を持ってもらうためには、淡々と紹介するのではなく、見出し、とくに導入部分に気を遣いました。


おわりに

中島さん(@irix_jp)、齊藤さん(@saito_hideki)というスーパーなエンジニアのみなさんと一緒に特集を作り上げることができて、とてもうれしかったです。

また、技術評論社Software Designご担当のみなさんにもお世話になりました。 gihyo.jp

編集さんもデザイナーさんもみなさんプロフェッショナルですね!

特集全体としては、入門、ネットワーク、GUIツールのAWX、CIの組み立て方などをカバーしてます。Ansible を始めたり、もっと知るきっかけになったら、とてもうれしいです。

今回は機会をいただきありがとうございました!




おまけ:リンク集

記事中に登場するリンクを以下に掲載します。

[Batfish] 重複したインターフェースのIPアドレスを検出する

ネットワーク機器のコンフィグ解析ツール Batfish には、重複したインターフェースのIPアドレスを検出する機能があります。 Batfish の Python ライブラリpybatfish でいう ipOwners() に、パラメータ duplicatesOnly=True を与えたときの動作です。

以下に、試した Junipter Notebook を貼り付けます。

Check_Duplicate_IP_Addresses

なお、あくまでもインターフェースのIPアドレスをチェックしますので、 それ以外、例えば ntp server 10.0.0.123 のような設定が複数のコンフィグにあっても重複にはなりません。

関連エントリ

tekunabe.hatenablog.jp

[Batfish] SRX(Junos)上の評価されないポリシーを検出する

はじめに

ネットワーク機器のコンフィグ解析ツール Batfish には、読み込んだコンフィグのルーターACLや、ファイアウォールのポリシーの中から、評価されないポリシーを検出する機能があります。 Batfish の Python ライブラリpybatfish でいう filterLineReachabilityです。

評価されないポリシーとは

ポリシーは、通常上から順番に評価され、条件にマッチした時点でそれ以降のポリシーは評価しません。そのため、例えば(極端な例ですが)1行目に IP を利用したすべての通信を許可するポリシーがある場合、2行目に HTTP を許可するポリシーが定義してあっても評価されません。

ポリシーの追加、変更が繰り返されるとポリシーが複雑化し、意図せずこのような評価されないポリシーができてしまうこともあるかもしれません。 ポリシーの数が多い場合、人間の判断による検出が難しいので、機械的に実現したいところです。

SRX (Junos)で試しました

試した Jupyter Notebook の .ipynb ファイルを以下の Gist にアップしましたので貼り付けます。

gist3bf4a03265db735977dbec7625169d96

なお、上記の例には含まれていませんが、ICMP の type や code までは判断していないようです。 具体的に試したのは、junos-icmp-all 許可と junos-icmp-ping 許可 の組み合わせです。

junos-icmp-ping 許可 → junos-icmp-all 許可というポリシーの順番であれば、後者の junos-icmp-all も評価されるはずです。ですが、batfish 上では、評価されないポリシーとして検出されました。

そのため、batfish 上では2つのポリシーとも type や code までは判断せず、単にICMP 許可という定義として扱われ、重複、後ろにあるポリシーは評価されないと判断された、と考えました。

Cisco IOSACL での例は公式 Notebook に

Cisco IOSACL での利用されないエントリを検出する例は、公式 Jupyter Notebook の Analyzing ACLs and firewall rules with Batfish 内の filterLineReachability: Analyzing reachability of filter lines にあります。

参考

tekunabe.hatenablog.jp

[Batfish] 単体の Docker イメージと pybatfish の環境構築方法

■ Batfish 公式の 2つの Docker イメージ

Batfish には公式 Docker イメージが2つあります。

  • イメージ1: batfish/batfish
    • batfish 本体の イメージ
  • イメージ2: batfish/allinone
    • batfish 本体と かんたんにお試しできる Jupyter Notebook とサンプルコンフィグ入りイメージ

以前の Batfish 概要をお伝えした記事では、簡単に試すの目的だったため、batfish/allinone を利用しましたが、イメージサイズが少々大きめです。 Batfish 本体だけで良ければ、イメージサイズが小さめの batfish/batfish のほうが適しています。

この記事では、以下の点についてまとめます。

  • Docker イメージ batfish/batfish を利用したコンテナの起動
  • ホスト側に pybatfish をインストールして、コンテナ内の batfish にアクセスする

概要図

f:id:akira6592:20181026185106p:plain


■ コンテナの起動

手順は docker/batfish.md at master · batfish/docker Batfish service docker container に記載されています。

mkdir -p data
docker run -v $(pwd)/data:/data -p 9997:9997 -p 9996:9996 batfish/batfish

コンテナから見た /data には、機器構成情報をまとめたスナップショットなどのデータが保存されます。 これらのデータを、ホスト側のデータとして永続的に保持するために、-v オプションでマウントを指定しています。 権限の都合上 --privileged が必要な場合もあります。


■ ホストへの pybatfish のインストール

主な手順は batfish/pybatfish: Python client for Batfish に記載されています。

# pybatfish リポジトリの clone
git clone https://github.com/batfish/pybatfish.git
cd pybatfish

# pybatfish のインストール
pip install .

現状は直接 pip install pybatfish でインストールできませんが、いずれできるようになるかもしれません。


■ 動作確認

手順は pybatfish のドキュメントの Getting started に記載されているコードを参考にします。

あらかじめ python インタープリタを起動しておきます。

各種 import

from pybatfish.client.commands import *
from pybatfish.question.question import load_questions, list_questions
from pybatfish.question import bfq

エスチョンのロード

load_questions()

スナップショットの初期化

bf_init_snapshot('jupyter_notebooks/networks/example') 

jupyter_notebooks/networks/example は、pybatfish リポジトリを clone した中に含まれる、サンプルのネットワーク機器のコンフィグなどが含まれています。 単なる動作確認目的のため、こちらを利用しています。

ログ

status: TRYINGTOASSIGN
.... no task information
status: ASSIGNED
.... Fri Oct 26 08:51:18 2018 UTC Parse configurations 0 / 13
status: ASSIGNED
.... Fri Oct 26 08:51:18 2018 UTC Parse configurations 0 / 13
status: ASSIGNED
.... Fri Oct 26 08:51:18 2018 UTC Parse configurations 0 / 13
status: ASSIGNED
.... Fri Oct 26 08:51:18 2018 UTC Parse configurations 0 / 13
status: ASSIGNED
.... Fri Oct 26 08:51:18 2018 UTC Parse configurations 2 / 13
status: ASSIGNED
.... Fri Oct 26 08:51:18 2018 UTC Parse configurations 8 / 13 Elapsed 00:00:05
status: ASSIGNED
.... Fri Oct 26 08:51:18 2018 UTC Reading, unpacking, and deserializing files containing 'org.batfish.datamodel.GenericConfigObject' instances 10 / 15
status: TERMINATEDNORMALLY
.... Fri Oct 26 08:51:18 2018 UTC Deserializing objects of type 'org.batfish.datamodel.Configuration' from files 15 / 15
Default snapshot is now set to ss_b10132b4-75db-4544-a2ba-8dc82f1706d2
'ss_b10132b4-75db-4544-a2ba-8dc82f1706d2'

IPアドレスの取得

ip_owners_ans = bfq.ipOwners().answer()

取得したIPアドレスの表示

ip_owners_ans.frame().head()

ログ

         Node      VRF           Interface          IP  Mask  Active
0    as2dist2  default           Loopback0     2.1.3.2    32    True
1    as2dist1  default           Loopback0     2.1.3.1    32    True
2    as2dept1  default  GigabitEthernet1/0  2.34.201.4    24    True
3    as2dept1  default           Loopback0     2.1.1.2    32    True
4  as3border2  default  GigabitEthernet1/0     3.0.2.1    24    True

as1border1 の GigabitEthernet0/0 の情報を取得、表示

iface_ans = bfq.interfaceProperties(nodes='as1border1', interfaces='GigabitEthernet0/0', properties='all-prefixes').answer()
iface_ans

ログ

                       Interface
0  as1border1:GigabitEthernet0/0


■ まとめ

Batfish 単体のコンテナの起動と pybatfish の環境構築方法をご紹介しました。 このあとは、Python でコードを書いたり、Junypter Notebook を準備するなどして、実現したいことを実装していくことになります。

https://www.batfish.org/

[Batfish] ネットワーク機器のコンフィグを読み込んでルーティングなどの様々な検証ができるツール「Batfish」の紹介

■ Batfish とは: 実機に接続することなくコンフィグを検証

f:id:akira6592:20181025150354p:plain

Batfish は、ネットワーク機器のコンフィグの様々な検証ができるツールです。 実機に接続する必要はありません。 準備したコンフィグファイルを読み込んでパースし、解析して内部でネットワーク機器が動作するようなイメージです。

本体は Java で書かれていて、Python から扱うためのクライアントである pybatfishもあります。 設定変更のコンフィグの妥当性を、あらかじめ Batfish で確認してから実機に投入する、というようなことが実現できるのではないかと、最近興味を持ちました。

この記事では、Batfish でできることなどの概要や、Docker、Jupyter Notebook を利用した試し方をご紹介します。

Cisco、Arista、Juniper、Palo Alto などの機器に対応

Batfish が対応している機器の一覧はこちらです。これらの機器の形式のコンフィグファイルを読み込むことができます。 https://github.com/batfish/batfish#what-configuration-formats-does-batfish-support

Cisco、Arista、Juniper、Palo Alto などの機器に対応しています。

情報ソース(デモ動画・プレゼン資料)

Batfish 公式サイトのトップにもリンク掲載されていますが、デモ動画やプレゼン資料などがあります。

チュートリアル動画

今後も Batfish の YouTube チャンネルで動画が増えるかもしれません。

プレゼン動画・資料

ブログ


■ Allinone の Docker イメージ でかんたんにお試しできる

Batfish には 2 つの公式 Docker イメージがあります。

イメージ1: batfish/batfish

batfish 本体の イメージです。 f:id:akira6592:20181026160249p:plain (数字はTCPポート番号)

イメージ2: batfish/allinone  ←今回はこちらを利用

batfish と かんたんにお試しできる Jupyter Notebook とサンプルコンフィグ入りイメージです f:id:akira6592:20181026230814p:plain

利用方法は、Dockerfile が管理されているリポジトリ batfish/dockerREADME.md に記載されています。 ここでは、batfish/allinone を利用して、簡単に動作を確認する方法をご紹介します。

もし、Docker コンテナを動かす環境が用意できない場合は、batfish/pybatfish リポジトリにある Jupyter Notebook の .ipynb ファイル で雰囲気がつかめます。 Play with Docker のような、ブラウザだけで Docker 環境を一定時間利用できるサービスを利用するという手段もあります。

コンテナの起動と Junipter Notebook へのログイン

docker run -p 8888:8888 batfish/allinone

コンテナ側で Jupyter Notebook が 8888/TCP ポートを空けているので、ホスト側からも 8888/TCP でアクセスできるようにポートマッピングしています。

コンテナが起動すると、以下のようなログが表示されます。

  • ログ
[root@centos7 ~]# docker run -p 8888:8888 batfish/allinone
[I 04:30:16.094 NotebookApp] Writing notebook server cookie secret to /data/.local/share/jupyter/runtime/notebook_cookie_secret
[I 04:30:16.779 NotebookApp] Serving notebooks from local directory: /notebooks
[I 04:30:16.779 NotebookApp] The Jupyter Notebook is running at:
[I 04:30:16.779 NotebookApp] http://(0320725b43c3 or 127.0.0.1):8888/?token=abcdef123456xxxx
[I 04:30:16.779 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[W 04:30:16.780 NotebookApp] No web browser found: could not locate runnable browser.
[C 04:30:16.780 NotebookApp]

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://(0320725b43c3 or 127.0.0.1):8888/?token=abcdef123456xxxx

上記のログの例では token=abcdef123456xxxx が Jupyter Notebook へログインするトークン情報です。この場合、以下のような URL で Jupyter Notebook へログインします。

http://localhost:8888/?token=abcdef123456xxxx

Notebook の選択

Jupyter Notebook にログインすると、以下の Notebook の一覧が表示されます。

f:id:akira6592:20181025150132p:plain

ここでは、一番初歩的そうな「Getting started with Batfish.ipynb」を選択して説明します。

なお、同じディレクトリにある networks ディレクトリの配下には、example-filtersexamples ディレクトリがあります。これらの 2つのディレクトリの中には、ネットワーク機器のコンフィグやホストの定義ファイルが含まれています。Batfish でこれらのディレクトリを指定すると、コンフィグなどを読み込んで、解析できる状態になります。

Getting started with Batfish

この Notebook は、大まかには以下の流れです。

  • networks/example ディレクトリに含まれる、ネットワーク機器(Cisco IOS)のコンフィグや、ホストの定義などを読み込み、スナップショットを作成する
  • 設定の抽出や、traceroute、ルーティングテーブルなどを検証する。

見出しだけ翻訳して、一部 "※" で注釈をつけた .ipynb ファイルを作成したので、以下に貼り付けます。

Getting started with Batfish (Japanese)

自身で準備したコンフィグで試すには

上記の例では SNAPSHOT_PATH = "networks/example"という指定で、 networks/example ディレクトリ配下のネットワーク機器のコンフィグやホスト定義ファイルを読み込んでいます。自身で準備したコンフィグなどを読み込ませたい場合は、以下のようなファイル、ディレクトリの配置にした上で、読み込むパスを変更します。

networks/mynet
|-- configs      # ネットワーク機器のコンフィグを格納
|   |-- router1.cfg 
|   `-- router2.cfg
|-- hosts         # ホスト定義ファイルを格納(batfish固有使仕様)(任意)
|   |-- host1.json
|   `-- host2.json
`-- iptables     # ホストに適用する iptables 定義ファイル(任意)
   |-- host1.iptables
   `-- host2.iptables

詳細は Packaging snapshots for analysis を参照してください。


■ まとめ

ネットワーク機器のコンフィグを読み込んでルーティングなどの様々な検証ができるツール「Batfish」で、どんな事ができるかなど、雰囲気が伝わりましたでしょうか。 完全に実機と同じものとみなして検証することは難しいですが、補助的な検証には利用できるのではないでしょうか。 また、実機に接続する必要がなく、コンフィグだけ用意すればよい点も魅力的です。

私自身はまだ調べ始めたばかりです。また何か新しいことが分かったり試したりしたら、このブログに投稿したいしと思います。

参考

Ansible と Batfish を組み合わせた話の Webinar があるようです。

[2018/11/12 追記] 動画と資料がアップされました。

www.ansible.com

https://www.ansible.com/hubfs/2018_Content/Ansible-Intentionet-Webinar-Slides.pdf

【Ansible】ios_config モジュールでべき等性を考慮せずにコンフィグを投入する方法(match: none)

■ match オプション を none にするとべき等性を考慮しない

Ansible には、Cisco IOS 機器にコンフィグ投入などができる ios_config というモジュールがあります。 このモジュールはデフォルトで、べき等性を保とうとする仕様になっています。 大まかな流れとしては以下の通りです。

  1. 事前に現状のコンフィグを取得
  2. オプションで指定されたコンフィグとの差分を確認
  3. 差分コンフィグのみを投入

なんらかの事情で、べき等性を考慮せずに無条件でコンフィグを投入したい場合は match オプションに none を指定します。

  • ios_config モジュールの match オプションの none の説明

    if match is set to none, the module will not attempt to compare the source configuration with the running configuration on the remote device.


■ 検証

簡単な例で検証した結果を記載します。

環境: Ansbile 2.7.0

match: no を指定しない場合(デフォルト)

Playbook
- hosts: iosal
  gather_facts: no

  tasks:
    - name: set ntp
      ios_config:
        lines:
          - ntp server 10.0.0.123
初回実行 (changed=1)
TASK [set ntp] *************************************************************
changed: [iosal1]

PLAY RECAP *****************************************************************
iosal1                     : ok=1    changed=1    unreachable=0    failed=0

今までなかっコンフィグを指定したため、実際に投入され、changed になりました。

再実行 (changed=0: べき等性を考慮した結果)

同じ Playbook を使用してもう一度実行します。

TASK [set ntp] *************************************************************
ok: [iosal1]

PLAY RECAP *****************************************************************
iosal1                     : ok=1    changed=0    unreachable=0    failed=0

タスクは changed にならず、べき等性を考慮した結果となりました。

match: none を指定する場合

先の検証で投入したコンフィグはいったん削除し、match: none を指定した Playbook で検証します。

Playbook
- hosts: iosal
  gather_facts: no

  tasks:
    - name: set ntp
      ios_config:
        lines:
          - ntp server 10.0.0.123
        match: none          # 追加
初回実行 (changed=1)
TASK [set ntp] *************************************************************
changed: [iosal1]

PLAY RECAP *****************************************************************
iosal1                     : ok=1    changed=1    unreachable=0    failed=0

今までなかっコンフィグを指定したため、実際に投入され、changed になりました。

再実行 (changed=1: べき等性を考慮しなかった結果)

同じ Playbook を使用してもう一度実行します。

TASK [set ntp] *************************************************************
changed: [iosal1]

PLAY RECAP *****************************************************************
iosal1                     : ok=1    changed=1    unreachable=0    failed=0

また changed になり、べき等性を考慮しなかった結果となりました。

【Ansible】ios_config モジュールで特権ユーザーにもかかわらず operation requires privilege escalation が発生する不具合について(2.7.1で修正)

■ 現象: 特権ユーザーにもかかわらずエラーに

特定条件下で、Ansible の ios_config モジュール使用時に、特権ユーザーを利用しているにもかかわらず、operation requires privilege escalation というエラーが表示され、Playbook の処理が中断されてしまう不具合があります。

github.com

通常であれば、operation requires privilege escalation というエラーは、コンフィグ投入などの特権が必要な操作を、特権でない状態で実行しようとしたときに表示されるエラーです。この不具合では、特権ユーザーであってもこのエラーが表示されてしまいます。

この不具合は数ヶ月見守っていたのですが、ここ最近で修正の動きがあったため、記事にまとめました。


■ 発生条件

私が試したり、調べたりした範囲では、以下のような発生条件となりました。

  • コマンド実行結果の取得に時間がかかり、コマンド実行結果に > が含まれる

検証環境は Ansible 2.7.0 です。 どうやら、処理に時間がかかるとプロンプト以外に > が含まれている場合、それをユーザー(非特権)EXEC モードのプロンプトの一部として解釈してしまい「権限がないのでこのコマンドは実行できない」という判断になってしまうようです。

  • (参考)プロンプトの例
iso1>          # ユーザーEXECモードの例
ios1> enable
ios1#          # 特権EXECモードの例

プロンプト以外に > が含まれる可能性があるのは、インターフェースの description や、SNMP コミュニティ名、ACL名などです。

対象バージョンの範囲は、こちらのコメント

The root cause of the issue is in the fix made in PR #39063 (from 2.5.2 onwards) to handle the ios device on which \r\n characters are not prefixed before prompt

を含めて考えると以下のようになると思います。 (2.7.0以外未検証)

  • 2.5 系: 2.5.2 以降
  • 2.6 系: 2.6.0 以降
  • 2.7 系: 2.7.0 (現状本バージョンのみ)


■ 対策見込み

修正分が Ansible 2.7.1 としてリリースされる予定です。 このリリースでは、 network_cli コネクションプラグインのパラメーターとして、 persistent_buffer_read_timeout が追加される予定です。このパラメーターで、プロンプトを解釈するタイミングを調整して対策することになります。デフォルトは 0.1 秒です。

なお現状、2.7.1はリリースされていませんが、

pip install git+https://github.com/ansible/ansible.git@stable-2.7

でインストールできるバージョン「ansible 2.7.0.post0」で確認したところ、エラーは出なくなりました。 場合に読もると思いますが、persistent_buffer_read_timeout は調整不要でした。

[2018/10/26 追記] Ansible 2.7.1 がリリースされました。 https://github.com/ansible/ansible/blob/stable-2.7/changelogs/CHANGELOG-v2.7.rst#v2-7-1

Fix prompt mismatch issue for ios (https://github.com/ansible/ansible/issues/47004)


■(参考)検証内容詳細

私が検証した方法を記載します。

コンフィグテンプレートの準備

現象を再現するための仕込みのコンフィグとして、以下を準備します。

{% for i in range(200) %}
snmp-server community com{{ i }} RO h>oge
{% endfor %}

コマンドの最後のオプション(ACL名)であるh>oge> を含めているのがポイントです。

この Jinja2 テンプレートは、以下のようなコマンドを生成します。

snmp-server community com0 RO h>oge
snmp-server community com1 RO h>oge
snmp-server community com2 RO h>oge
...(略)...
snmp-server community com198 RO h>oge
snmp-server community com199 RO h>oge

Playbook の準備

- hosts: iosprg
  gather_facts: no

  tasks:
    - name: set snmp
     ios_config:
        src: snmp.j2

  vars:
    ansible_command_timeout: 300  # 投入に時間がかかるためデフォルト 10 秒より伸ばす

コンフィグの仕込み

準備したコンフィグテンプレートをいったん流し込みます。

$ ansible-playbook -i inventory.ini insert.yml

これで準備が整いました。

再現試行

対象機器が、

  • コマンド実行結果の取得に時間がかかり、コマンド実行結果に > が含まれる

という状態になったところで、もう一度同じ Playbook を実行します。通常であれば、変更なしで正常終了するはずです。

$ ansible-playbook -i inventory.ini set_snmp.yml

PLAY [iosprg] *******************************************************************************************************************

TASK [set snmp] ***************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible.module_utils.connection.ConnectionError: operation requires privilege escalation
fatal: [iosprg1]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n  File \"/home/vagrant/.ansible/tmp/ansible-local-6780JjM2oM/ansible-tmp-1540298326.36-234692567510359/AnsiballZ_ios_config.py\", line 113, in <module>\n _ansiballz_main()\n  File \"/home/vagrant/.ansible/tmp/ansible-local-6780JjM2oM/ansible-tmp-1540298326.36-234692567510359/AnsiballZ_ios_config.py\", line 105, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/vagrant/.ansible/tmp/ansible-local-6780JjM2oM/ansible-tmp-1540298326.36-234692567510359/AnsiballZ_ios_config.py\", line 48, in invoke_module\n    imp.load_module('__main__', mod, module, MOD_DESC)\n  File \"/tmp/ansible_ios_config_payload_4kli5Q/__main__.py\",line 536, in <module>\n  File \"/tmp/ansible_ios_config_payload_4kli5Q/__main__.py\", line 467, in main\n  File \"/tmp/ansible_ios_config_payload_4kli5Q/__main__.py\", line 328, in edit_config_or_macro\n  File \"/tmp/ansible_ios_config_payload_4kli5Q/ansible_ios_config_payload.zip/ansible/module_utils/connection.py\", line 173, in __rpc__\nansible.module_utils.connection.ConnectionError: operation requires privilege escalation\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
        to retry, use: --limit @/vagrant/demo/insert.retry

PLAY RECAP **********************************************************************************************************************
iosprg1                    : ok=0    changed=0    unreachable=0    failed=1

operation requires privilege escalation というエラーが発生しました。 ios_config モジュールは、指定されたコンフィグ投入前の事前コンフィグを取得処理があるため、その際に > が引っかかってしまったのではないかと思います。

なお、ACL名のところを変えていくつかのパターンで試したところ、以下のような結果になりました。

  • エラー発生
    • h>oge
    • hoge>
  • 正常
    • hoge


■ 関連 issue / PR