てくなべ (tekunabe)

ansible / network automation / 学習メモ

【Ansible】 junos モジュール使用時にエラー "'NoneType' object has no attribute 'startswith'" になる場合の対処

■ 現象

junos_command や junos_config モジュールを netconf 接続で使用時に、Playbook などの書き方の不備により

fatal: [172.16.0.1]: FAILED! => {"msg": "'NoneType' object has no attribute 'startswith'"}

というエラーになってしまうことがあります。 (Ansible 2.6.1/ 2.6.2 で確認)

  • playbook
- hosts: junos
  gather_facts: no

  tasks:
    - name: test
      junos_config:
        lines:
          - set system ntp server 10.0.0.123

  vars:
    ansible_connection: netconf
    ansible_user: testuser
    ansible_ssh_pass: testpass
  • インベントリファイル
[junos]
172.16.0.1
  • 実行結果(エラー)
(ansible262) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory junos_26.yml

PLAY [junos] *******************************************************************************

TASK [command test] ************************************************************************
fatal: [172.16.0.1]: FAILED! => {"msg": "'NoneType' object has no attribute 'startswith'"}
        to retry, use: --limit @/vagrant/junos_26.retry

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


■ 対処 (ansible_network_os: junos を指定)

公式ドキュメントに記載があるようにansible_network_os という変数に junos をセットします。

  • Playbook
- hosts: junos
  gather_facts: no

  tasks:
    - name: test
      junos_config:
        lines:
          - set system ntp server 10.0.0.123

  vars:
    ansible_connection: netconf
    ansible_network_os: junos     # 追加
    ansible_user: testuser
    ansible_ssh_pass: testpass

一方、junos_command モジュールと network_cli コネクションタイプ(netconfではなく)の組み合わせで、この ansible_network_os 変数の指定を忘れると

fatal: [172.16.0.1]: FAILED! => {"msg": "Unable to automatically determine host network os. Please manually configure ansible_network_os value for this host"}

という親切なエラーメッセージが表示されるので、エラーハンドリングが甘めになっているのかも知れません。

なお、現在開発中の Ansible 2.7 で ansible_network_os を指定せずに junos_config モジュールを試した場合、親切なエラーメッセージが表示され・・るのではなく、正常に設定変更できてしまいました。(本エントリ執筆時点)

Ansible 2.7 で導入予定のネットワークモジュール cli_command を試す

■ はじめに

現在開発中の Ansible 2.7 (develブランチ) で、ネットワーク機器への 参照系コマンドを実行するモジュール cli_command が登場したことを知りました。

Ansible 2.7 の ROADMAP を眺めていたときにモジュール名だけは見たことがあったのですが、実際に devel にマージされたようなので、Junos と IOS で試した結果を記載します。

なお、同じく Ansible 2.7 で開発中の 設定系 コマンドを投入するモジュール cli_config については「Ansible 2.7 で導入予定のネットワークモジュール cli_configを試す」をご参照ください。

基本情報

cli_command モジュール 公式ドキュメント

cli_command - Run a cli command on cli-based network devices — Ansible Documentation

対応プルリク

github.com

コード (cli_command.py)

ansible/cli_command.py at devel · ansible/ansible · GitHub

※現在(2018/8/7)開発中のため、仕様が変わる可能性があります。後日確認時点で、リストで指定する commands オプションから、文字列で指定する command オプションに変更されています。詳細は、公式ドキュメントをご参照ください。


■ 準備(開発版 Ansible のインストール)

pip install git+https://github.com/ansible/ansible.git@devel

現在、これで開発中の Ansible 2.7 がインストールされます。



■ Juniper Junos で試す

インベントリファイル

以下のインベントリファイルを用意します。今回は各変数は Playbook 内で定義することにします。

[junos]
172.16.0.1

Playbook

今回は、show version コマンドの結果を画面に表示するだけの、以下の Playbook を用意します。 ポイントは、コネクションタイプに network_cli を指定するところです。通常の、Junos に対しては、netconf を指定して、NETCONF で接続することが多いかと思いますが、 cli_command モジュールは netconf には対応していません。 他、ansible_network_os 変数も(私が)忘れがちですが、指定します。

- hosts: junos
  gather_facts: no

  tasks:
    - name: command test
      cli_command:
        commands:
          - show version
      register: result

    - name: debug 
      debug:
        msg: "{{ result.stdout_lines[0] }}"

  vars:
    ansible_connection: network_cli
    ansible_network_os: junos
    ansible_user: testuser
    ansible_ssh_pass: testuserpsss

実行

無事に実行され、 show version の結果が表示されました。

(ansible27) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory junos_27.yml

PLAY [junos] ***************************************************************************

TASK [command test] ********************************************************************
ok: [172.16.0.1]

TASK [debug] ***************************************************************************
ok: [172.16.0.1] => {
    "msg": [
        "Hostname: vsrx1",
        "Model: firefly-perimeter",
        "JUNOS Software Release [12.1X47-D15.4]"
    ]
}

PLAY RECAP *****************************************************************************
172.16.0.1                 : ok=2    changed=0    unreachable=0    failed=0

なお、ansible_connection: netconf を指定した場合は、以下のエラーになります。

connection type netconf is not valid forthis module



Cisco IOS で試す

インベントリファイル

Junosのときと同様、変数は Playbook 内で定義することにします。

[ios]
172.16.0.2

Playbook

- hosts: ios
  gather_facts: no

  tasks:
    - name: command test
      cli_command:
        commands:
          - show version
      register: result

    - name: debug 
      debug:
        msg: "{{ result.stdout_lines[0] }}"

  vars:
    ansible_connection: network_cli
    ansible_network_os: ios
    ansible_user: testuser
    ansible_ssh_pass: testuserpass

実行

無事に実行され、 show version の結果が表示されました。

(ansible27) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory ios_27.yml

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

TASK [command test] **********************************************************************************************************
ok: [172.16.0.2]

TASK [debug] *****************************************************************************************************************
ok: [172.16.0.2] => {
    "msg": [
        "Cisco IOS XE Software, Version 16.08.01a",
        "Cisco IOS Software [Fuji], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.8.1a, RELEASE SOFTWARE (fc1)",
        "Technical Support: http://www.cisco.com/techsupport",
        "Copyright (c) 1986-2018 by Cisco Systems, Inc.",
        "Compiled Tue 03-Apr-18 18:43 by mcpre",
        (...略...)
    ]
}

PLAY RECAP *******************************************************************************************************************
172.16.0.2             : ok=2    changed=0    unreachable=0    failed=0



■ Junos も IOS もまとめて試す

お気づきかもしれませんが、前述の Junos 向け Playbook と、IOS 向け Playbook の差分は、 hostsansible_network_os しかありません。そのため、変数定義の方法を工夫することで、Playbook は1つにまとめる事ができます。

準備するファイルは、インベントリファイル、変数ファイル、Playbook です。

イベントリファイル

[junos]
172.16.0.1

[ios]
172.16.0.2

変数ファイル

  • group_vars/junos.yml
ansible_connection: network_cli
ansible_network_os: junos
ansible_user: testuser
ansible_ssh_pass: testuserpass
  • group_vars/ios.yml
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: testuser
ansible_ssh_pass: testuserpass

もっと工夫の余地がありますが、あまりファイル数が増えてもサンプルとして見通しが悪くなるため、この辺にしておきます。

Playboook

前述のプラットフォーム別の Playbook との違いは hosts: all にしたことと、変数定義をしなくなったことです。 これでプラットフォーム固有の記述はなくなりました。

- hosts: all
  gather_facts: no

  tasks:
    - name: command test
      cli_command:
        commands:
          - show version
      register: result

    - name: debug 
      debug:
        msg: "{{ result.stdout_lines[0] }}"

実行

1つの Playbook で Junos、IOS の両方の show version コマンドの結果を表示することができました。

(ansible27) [vagrant@centos7 vagrant]$ ansible-playbook -i inventory all_27.yml

PLAY [all] ************************************************************************************

TASK [command test] ***************************************************************************
ok: [172.16.0.1]
ok: [172.16.0.2]

TASK [debug] **********************************************************************************
ok: [172.16.0.2] => {
    "msg": [
        "Cisco IOS XE Software, Version 16.08.01a",
        "Cisco IOS Software [Fuji], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 16.8.1a, RELEASE SOFTWARE (fc1)",
        "Technical Support: http://www.cisco.com/techsupport",
        "Copyright (c) 1986-2018 by Cisco Systems, Inc.",
        "Compiled Tue 03-Apr-18 18:43 by mcpre",
        (...略...)
    ]
}
ok: [172.16.0.1] => {
    "msg": [
        "Hostname: vsrx1",
        "Model: firefly-perimeter",
        "JUNOS Software Release [12.1X47-D15.4]"
    ]
}

PLAY RECAP *********************************************************************************
172.16.0.1                 : ok=2    changed=0    unreachable=0    failed=0
172.16.0.2                 : ok=2    changed=0    unreachable=0    failed=0


■ まとめ

簡単ですが、 cli_command モジュールの動作を確認しました。 最近のネットワークモジュールは、プラットフォームに依存しないタイプ(内部で ansible_network_os変数を見てプラットフォーム固有モジュールを呼ぶ?)も増えてきており、 cli_command モジュールもその流れだと思います。

社内技術イベントで「無料で仮想Junos環境を手元に作ろう」という発表をしました

はじめに

弊社では年に数回、AP Tech Fest という社内向けの技術イベントを開催しています。(参考:2017年11月開催分

大体毎回何かしらの発表しているのですが、2018/07/18 開催分では「無料で仮想Junos環境を手元に作ろう」という発表をしました。

資料

最初から資料を社外公開できる内容で作っているので、資料を公開します。

www.slideshare.net

以下のエントリの内容をベースにしています。

tekunabe.hatenablog.jp

発表しようと思った経緯

4月からの新人研修で Cisco IOS を使ってCCNAや実機研修をされているところは多いと思いますが、実際業務についたら IOS以外を扱うことも多いです。例えば Juniper(Junos) を業務で使うことになって、自分でも勉強したいけど環境をどう作ったらよいか悩んでいる人向けに発表しました。時期としてもちょうどよいと思いましたので。

参考

www.ap-com.co.jp

Ansible Night in Fukuoka 2018.08 で「Ansibleではじめるネットワーク自動化」という発表をしてきました

f:id:akira6592:20180805164638p:plain:w400

■ はじめに

【祝】初福岡開催!

Ansible Nitght (旧Meetup)は2017年までは東京でのみの開催でしたが、2018年は他の場所でも開催されています。 7月には大阪で、そして8月3日には福岡で Ansible Night in Fukuoka 2018.08 が開催されました。

ansible-users.connpass.com

今回、ありがたいことにお話をいただきまして「Ansibleではじめるネットワーク自動化」をいう発表をさせていただきました。


■ 資料

私が発表に使用した資料はこちらです。

www.slideshare.net

時間の都合で紹介しきれなかったものを含め、サンプル(デモ動画あり)を6つ入れています。 内容的には、JANOG42 で発表した Ansibleネットワーク自動化チュートリアルの後半をベースにして、最後の方に「ハマりどころ」というセクションを追加しました。

■ togetter まとめ

@morita92hiro さんがまとめてくださりました。ありがとうございます。

togetter.com


■ 他の方の資料まとめ

他の方の資料は以下のページにアップされています。

https://ansible-users.connpass.com/event/93620/presentation/


■ ブロガー枠の方のレポート記事

ブロガー枠で参加された ambasad さんのレポート記事です。

dev.classmethod.jp

■ おまけ

会場の下にはクラスメソッドさんの福岡オフィス

今回の会場は博多駅から徒歩圏内の「福岡県Rubyコンテンツ産業振興センター」の5Fのセミナールームでした。 一つ下のフロアには2017年に開所されたクラスメソッドさん福岡オフィスさんがあると伺い、連れて行っていただきました。

classmethod.jp

2次元社員めそ子ちゃんのステッカーなどもいただきました。ありがとうございました! f:id:akira6592:20180805162447p:plain:w300

Ansible飯

Ansible飯という名の懇親会にも参加させていただきました。 地元の方に地元のメニューを選んでいただいたところに、優しさを感じました。ありがとうございました。


■ 感想など

当初どのくらいの人に来ていただけるか少々不安だったのですが、結果的には30人ほどの方にご参加いただけたようです。 これからも福岡、九州でコミュニティが盛り上がることを願っております。

それでも SlideShare を使う理由

■ はじめに

私は普段、発表資料を SlideShare へアップロードしています。

www.slideshare.net

しかし、2017年に SlideShareスライドが差し替えができない仕様に変わってしまいました。

私の観測範囲ではこの頃から Speaker Deck へ移行する方がちらほら見受けられました。 私自身もこれは厳しいと思い、移行先として Sperker Deck を試したりはしたのですが、また SlideShare に戻ってきました。 この記事ではその理由についてまとめたいと思います。


■ 1. 自動リンク機能があるから

f:id:akira6592:20180805150502p:plain

SlideShare はリンクが有効なドキュメントをアップロードすると、有効なままになってくれます。 よく、一次情報となる公式ドキュメントへのリンクなどをはったりするので、この機能は閲覧者にとって便利かなと思います。

Speaker Deck にはこの機能はないようです。


■ 2. YouTube動画差し込み機能があるから(現在は廃止)

f:id:akira6592:20180805150156p:plain

YouTube にアップロードした動画のURLを、スライドの任意の位置に差し込む事ができます。 私はなにかのデモ動画をスライドに差し込みたいときにこの機能を利用します。 スライド本体とは違って、差し込みは追加も変更も削除もできます。

動画が差し込まれているスライドは、左上に印が付きます。 以下、動画を差し込んだスライドの例です。P23、P29などに差し込んでいます。

www.slideshare.net

※ 2019/04/23 追記: 動画差し込み機能ですが、どうもできなくなってしまったようです。ツイッターを確認する限り複数の方が同様のことをコメントしていました。

f:id:akira6592:20190423151909p:plain
Edit YouTube Video タブがない
※ 2019/07/16 追記: 廃止の旨、公式案内がありました。

Adding YouTube Videos to a SlideShare Presentation – No Longer Available | SlideShare Help


■ 3. タイトルを変更してもURLが変わらないから

あとからタイトルを修正したり、「2018年度版」とか付けたりしたい時があるので、タイトルを変更したときにURLが変わらないのは助かります。twitter で流したあとにURL変わってしまうのは忍びないので。

SlideShare ではサイトにスライドをアップロードする際のタイトルを元にURLを生成しますが、日本語タイトルだと、URLがいまいちな感じになります。 そのため私は場合は、最初のアップロードの際は英語でタイトルを付けてそれらしいURLにした後に、日本語タイトルに直します。

なお、Speaker Deck はタイトルを変更するとURLが変わってしまいます。 ただ、以下の記事のようにスラッシュ区切りで英語タイトルを指定すれば、前半の日本語タイトル部分を変更してもURLは変わりません。

kakakakakku.hatenablog.com


■ まとめ

どのようなスライド共有サービスが良い方は、使い方と考え方次第だと思います。 私の場合は「自分がスライドを差し替えられない不便さの解消」より「閲覧者がリンクをクリックできる便利さ」を選びました。

Ansible もくもく会 (第4回)にメンターとして参加してきました #ansiblejp

Ansible ユーザー会主催の、Ansible もくもく会 (第3回)にメンター参加してきました。 ブログ枠で参加したわけではないですが、メンターって意外とハードル低いですよ、という感じを共有したく思います。

ansible-users.connpass.com

Ansibleもくもく会への参加は今回で3回目なので、そろそろと思っていました。 (第2回で成果共有枠で参加したときの記事

メンターは、参加者から質問があった時に答えたり、答えられなくても一緒に悩んだりするのが役割です。 メンター自体複数人いますし、他にもレッドハット社員の方もサポートしてくれたので、そんなに大変ではありませんでした。

当日の質問は、口頭やEtherPadというリアルタイムにみんなで書き込めるメモ帳のようなサービス上でやり取りしました。 以下のページでやり取りが残されています。

qiita.com

Ansibleもくもく会は今後も開催されますが、一般枠は倍率が高く当選しにくいです。 ある程度Ansibleの知識がある人は、まず「次回メンター枠」で参加して、様子を見た後に、次回「メンター枠」で参加されることをオススメします。

参考(参加された方のブログ)

tips-reports.blogspot.com

iryond.hatenablog.com

【JANOG42】私にとっての「つなぐ、つたえる、つみあげる」

f:id:akira6592:20180718183110j:plain

■ はじめに

2018/07/11 - 13 に三重県津市で開催された JANOG42 Meeting in Mie(ホスト:株式会社ZTV様)に参加してきました。

今回のテーマは開催地である津(つ)市にちなんで「つなぐ、つたえる、つみあげる」でした。 そこで、それぞれの点で簡単に振り返ってみたいと思います。


■ 「つなぐ」

f:id:akira6592:20180718182759j:plain 今回は、弊社の新人も一緒に参加しました。もちろん業界未経験ですし、このようなイベントにもはじめての参加です。 なので、私の知り合いのエンジニアにまざってもらって(前回のJANOG41のテーマは"かきまぜる"でしたね)、社外エンジニアと弊社新人をつなぐことができました。 お相手したくださったエンジニアのみなさん、ありがとうございました。


■ 「つたえる」

f:id:akira6592:20180718174324j:plain 以下の記事通り「Ansible ネットワーク自動化チュートリアル」という発表をさせていただきました。

tekunabe.hatenablog.jp

はじめてAnsibleを知るネットワークエンジニアに、Ansibleがどんなものか、どんなことができるか、などをデモ動画も交えておつたえしました。


■ 「つみあげる」

f:id:akira6592:20180720145618p:plain

アーカイブ配信動画より)

IPv6アドレスの番号計画、どうしてますか。〜 あれっ、みんなどうしてんだろう 〜」というセッションの質疑応答の時間で、質問をさせていただきました。JANOGの参加は今回が2回目なのですが、質問のマイクに立つのはこれが初めてでした。小さなことですが、私にとっては新しい経験をつみあげるかたちとなりました。

goto_ipv6 さん、ツイートありがとうございます。