わけあって ansible を触るようになりました。ネットワーク機器の設定を自動更新できたら良い感じー。みたいな雰囲気で。
で、話のテンポはサササっと行くのですが、Cisco スイッチとかにアクセスする場合、 ssh ではなく今でも telnet を利用している人(会社)は多いかな?
エッジスイッチなんてのはグローバルアドレスが付いてないので外部から攻撃される心配ないし、パケットをキャプチャされることもないので『telnet でじゅーぶん。』みたいな。
そうなるといつまで経っても telnet を利用してしまうわけですが、 ansible が Cisco のネットワーク機器にアクセスするときには ios_command というモジュールを利用すると便利なのですが、こいつは ssh にしか対応してないので、それを使わず telnet モジュールでシコシコ tasks: を並べていく必要があるんですけども。
以下は telnet モジュールを利用した場合の標準的な playbooks の書き方です。
|
この通りにやっても動かないことが多々ある。debug: を指定して output の中を見てももーぐちゃぐちゃ。初めて ansible をテスト的に利用してみると
『ansible ってこんなダサいの? perl の Net::Telnet 使ったほうがよっぽどいーじゃん。』
とかになってしまうのであります。
ansible の telnet モジュールがまともに動かない。答えを先に書くと、その原因は “#” にあります。
以下、Cisco 機器のネットワークインターフェースの設定だとします。
|
description に “#” を使っていると telnet モジュールはプロンプトだと勘違いして処理がそこで止まります。
show interfaces status や show interfaces description ・ show running-config など何一つまともに動きません。
telnet モジュールの prompts: はプロンプトの “#” のみを見ているのでは無く Cisco ルータから出力された全ての “#” を見て動作しています。ヘボ過ぎる・・。 orz
telnet モジュールを利用した場合、出力された内容に “#” があるとまともに動作しません。ではどうやって対応するか? 以下は Cisco ルータの場合の対応策です。
|
prompts: に指定する文字が一文字だからダメで、二文字にマッチさせると何とか無事に動作するようになります。二文字でマッチできない場合はもう一文字追加で;-)。
上記の prompts: の設定では、本スト名が cisco の場合、プロンプトは以下になります。
|
つまり、ホスト名の最後の一文字と “#” を組み合わせた “o#” と、いう prompts: 、あと configure terminal 時にはプロンプトの前に “)” がつくので “)#” にマッチするように prompts: を記述します。
これで show running-config したときに設定中に “#” があっても無事に動作するようになります。
ansible で telnet モジュールを利用する場合には prompts: に設定した文字列に十分に注意しましょう。 prompts: に指定する文字は register: に出力される前に吸収されてしまいます。