てくなべ (tekunabe)

ansible / network automation / 学習メモ

JANOG41.5 で「もっと気軽に始めるAnsible」という発表をしてきました

■ はじめに

2018/04/20 に開催された JANOG41.5 Interim Meeting で「もっと気軽に始めるAnsible」という発表をさせていただきました。

janog.connpass.com

Ansible はネットワーク機器にも対応しています。YAML形式の定義ファイル(Playbook)を書かずに、もっと気軽に始められる Ad-Hoc な Ansible の使い方をご紹介します。

今回は、Playbook もインベントリファイルも、設定ファイルも作らず、意地でもコマンドで済ませるというポリシーです。

この記事では、発表資料の共有とサンプルコマンドの再掲、感想をまとめます。


■ 資料

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

speakerdeck.com

■ 動画

Jストリーム様のご協力により発表の動画も公開されました。私の発表は 1:23:20 頃からです。

api01-platform.stream.co.jp

他の方の発表の分も JANOG41.5 connpass イベントページ に掲載されています。

コマンドサンプル

資料中に掲載されているサンプルコマンドをコピペしやすいように、以下に再掲します。

環境準備 (資料P22)

# Ansible のインストール
pip install ansible
# Junosモジュールで必要なpythonモジュールのインストール
pip install ncclient jxmlease

利用例1: コンフィグの取得

  • 準備 (資料P12)
# 実行結果を json にする
export ANSIBLE_STDOUT_CALLBACK=json
# ansible コマンドでも前述の設定を有効にする
export ANSIBLE_LOAD_CALLBACK_PLUGINS=True
# (オプション)接続対象ホストキーがAnsibleホストに未登録の場合は、ホストキーチェックを無効化
export ANSIBLE_HOST_KEY_CHECKING=False
  • 実行 (資料P13)
ansible -i 172.16.0.1, all \
   -m junos_command \
   -a "commands='show configuration'" \
   -c netconf -u root -k \
   -e ansible_network_os=junos \
   | jq -r ".plays[0].tasks[0].hosts[].stdout[0]" > config.txt

利用例2: 参照NTPサーバーの追加

  • 準備
# (オプション)接続対象ホストキーがAnsibleホストに未登録の場合は、ホストキーチェックを無効化
export ANSIBLE_HOST_KEY_CHECKING=False
  • 実行 (資料P16)
ansible -i 172.16.0.1,172.16.0.2 all \
   -m junos_config \
   -a "lines='set system ntp server 172.16.0.123'" \
   -c netconf -u user1 -k \
   -e ansible_network_os=junos

参考資料

資料中に掲載されているリンクをジャンプしやすいように、以下に再掲します。

  • 公式ドキュメント
    • ansible コマンドでネットワークモジュール を使う (Run Your First Network Ansible Command)

Run Your First Command and Playbook — Ansible Documentation


■ togetter まとめ

私の発表時のツイートは P13 の 18:23 あたりからです。

togetter.com


■ 感想など

発表の反応を拝見すると「ワンライナー的な使い方もアリだな」ですとか「Cisco IOSで試してみた」という方々がいらっしゃって嬉しかったです。

ネットワークエンジニアが Ansible を触ってみる入り口の一つとして、今回の発表が参考になったら幸いです。

さて、JANOG は前回のJANOG 41が初参加でした。ネットワーク運用自動化BoF内で発表もさせ頂いたので、2回連続で機会をいただきました。ありがとうございました。

次回 JANOG 42 は、2018/07/11-13 に三重で開催されます。次回も参加する予定です。

www.janog.gr.jp

「Safety‐1 & Safety‐2―安全マネジメントの過去と未来」という本を読みました

書籍「Safety‐1 & Safety‐2―安全マネジメントの過去と未来」

Safety‐1 & Safety‐2―安全マネジメントの過去と未来

Safety‐1 & Safety‐2―安全マネジメントの過去と未来

  • 作者: エリックホルナゲル,Eric Hollnagel,北村正晴,小松原明哲
  • 出版社/メーカー: 海文堂出版
  • 発売日: 2015/11/01
  • メディア: 単行本
  • この商品を含むブログを見る


Safety‐1 、Safety‐2 という考え方について

Safety-1 は、うまくいかない要因を排除しようという考え方の安全マネジメント。 Safety-2 は、うまくいく理由を理解して、うまくいくようにしようという考え方の安全マネジメント。Safety-2 の考え方に興味を持ったので読みました。

たとえば、インシデントのなぜなぜ分析は良くすると思いますが「うまくいったことのなぜなぜ分析」はしたことありますでしょうか?読みながらそんな問いかけを思い浮かべました。

うまくいったことは認識しずらく、測定もしずらい。けれど、そこと向き合うのが Safety-2。


個人的な気付きと解釈

  • Safety-1 は、プレッシャーを受けやすい。
  • Safety-2 は、モチベーションを保てる。
  • これら2つは排他関係ではなく、Safety-2 は Safety-1 を補完するような関係。
  • うまくいかないことの原因は、そもそも線形でたどれるほど単純ではない。要因特性図を思い浮かべればは分かる。
  • なのでうまくいかない原因らしきものを捉えても同じようなことは起こる。
  • それをよりもうまくいくことに真面目に向き合うべき。

難しく、飲み込みきれない部分も多いですが、考え方の枠が広がった気がします。 ほかの分野にも応用できる部分もありそうです。

『カイゼン・ジャーニー / 「一人から始める」を始める。』に参加してきました

■ はじめに

2018/04/04、書籍「カイゼン・ジャーニー」の第1部「一人から始める」をテーマにしたイベントに参加してきました。

  • イベント開催ページ

devlove.doorkeeper.jp

www.shoeisha.co.jp

著者の新井剛さん、市谷聡啓さんのぞれぞれの経験をもとにした発表と、事前のアンケートで寄せられたお題をもとにした座談会(5人程度のグループディスカッション)という構成でした。


■ 新井さんパート

speakerdeck.com

当たり前のことを当たり前にやった、ちょっと勇気を持ってやっているのかも、という点が印象的でした。 最近、当たり前のこと向き合う意味、難しさ、他の真似だけではだめ・・などなど考える事があったため、勇気をもらいました。


■ 市谷さんパート

www.slideshare.net

「これからはソロの時代」「所属から提供へ」という言葉が印象的でした。 私自身もちょっと人と違うことをすることを好んでしている節があるので、そういう意味では自ら進んでぼっちになっているのかもしれません。 ですが、それを誰かに伝えて表現することで、ひょっこり同じことしてくれる人が出てくるということを感じているので、こういうのも悪くないなと思っています。


■ 座談会パート

ぼっちからのはじめ方、巻き込み方、組織風土などをテーマにディスカッションしました。 他のグループや、著者への質疑応答含めて気になったものは以下です。

  • 物理的な本を人目につくところに置くとおくと話のきっかけになる。
  • 巻き込むときはアーリーアダプターにターゲットを絞ったほうが良いのでは。
  • 無理して巻き込まなくても、自分でどんどんやっちゃえば良い。新たな風景が見えてくる。そのうちついてくる。
  • アジャイルのプラクティスを導入するときは、プラクティス名を言わずに、課題に向き合って取り組むべき。プラクティス先行だと警戒される。


■ 気づき・まとめ

参加者含めて、非常に熱のある集まりだと感じました。 一方で、このような社外のコミュニティだけでなく、もっと身近な自社にも自分が知らないだけで、同じような思いの人がいるのではという問いかけを自分にしました。 偶然、翌日に似たようなテーマで同僚と話すこと機会があり、色々共感を得られたのがとても嬉しかったです。 今後は社内にも目を配ってみようと思いました。

ansible Ad-Hoc コマンドの callback plugin の指定時は bin_ansible_callbacks = True も必要

■ はじめに

Ansible には callback plugin という仕組みがあり、結果出力の形式を変更したりすることができます。

ansible-playbook コマンドでは、ansible.cfgstdout_callback の指定を、ansible コマンドではこれに加え bin_ansible_callbacks = True という指定が必要です。

この記事では、それぞれの例をご紹介します。


■ ansible-playbook コマンドの場合

例えば、 json という callback plugin を指定して ansible-playbook コマンド実行する例を見てみます。

設定ファイル(ansible.cfg)

stdout_callbackjson を指定します。

stdout_callback = json

なお、環境変数として設定する場合は export ANSIBLE_STDOUT_CALLBACK=json を実行します。

設定の確認

念のため ansible-config コマンドで設定を確認します。

[vagrant@centos7 vagrant]$ ansible-config dump | grep CALLBACK
DEFAULT_CALLBACK_PLUGIN_PATH(default) = [u'/home/vagrant/.ansible/plugins/callback', u'/usr/share/ansible/plugins/callback']
DEFAULT_CALLBACK_WHITELIST(default) = []
DEFAULT_LOAD_CALLBACK_PLUGINS(default) = False
DEFAULT_STDOUT_CALLBACK(/etc/ansible/ansible.cfg) = json    ← json になった

実行結果

ここでは junos_command モジュールで show version を実行する Playbook を実行します。

[vagrant@centos7 vagrant]$ ansible-playbook -i inventory junos_test.yml
{
    "plays": [
        {
            "play": {
                "id": "525400da-a710-c40b-4624-000000000008",
                "name": "junos"
            },
            "tasks": [
                {
                    "hosts": {
                        "172.16.0.1": {
                            "_ansible_no_log": false,
                            "_ansible_parsed": true,
                            "changed": false,
                            "invocation": {
                                (~略~)
                            },
                            "stdout": [
                                "Hostname: vsrx1\nModel: firefly-perimeter\nJUNOS Software Release [12.1X47-D15.4]"
                            ],
                            "stdout_lines": [
                                [
                                    "Hostname: vsrx1",
                                    "Model: firefly-perimeter",
                                    "JUNOS Software Release [12.1X47-D15.4]"
                                ]
                            ]
                        }
                    },
                    "task": {
                        "id": "525400da-a710-c40b-4624-00000000000a",
                        "name": "show version"
                    }
                }
            ]
        }
    ],
    "stats": {
        "172.16.0.1": {
            "changed": 0,
            "failures": 0,
            "ok": 1,
            "skipped": 0,
            "unreachable": 0
        }
    }
}

このように、JSON 形式で結果が出力されます。


■ ansible コマンドの場合

ansible コマンド(ad-hocコマンドとも呼ばれる) でも、callback plugin を指定する場合は、stdout_callback 以外にも bin_ansible_callbacks という設定も必要です。

設定ファイル(ansible.cfg)

stdout_callbackjson を指定するのに加え、 bin_ansible_callbacksTrue に指定します。

stdout_callback = json
bin_ansible_callbacks = True

なお、環境変数として設定する場合は export ANSIBLE_LOAD_CALLBACK_PLUGINS=True を実行します。

設定の確認

念のため ansible-config コマンドで設定を確認します。

[vagrant@centos7 vagrant]$ ansible-config dump | grep CALLBACK
DEFAULT_CALLBACK_PLUGIN_PATH(default) = [u'/home/vagrant/.ansible/plugins/callback', u'/usr/share/ansible/plugins/callback']
DEFAULT_CALLBACK_WHITELIST(default) = []
DEFAULT_LOAD_CALLBACK_PLUGINS(/etc/ansible/ansible.cfg) = True    ← True になった
DEFAULT_STDOUT_CALLBACK(/etc/ansible/ansible.cfg) = json

実行結果

ここでは junos_command モジュールで show version を実行する ansible コマンド を実行します。

[vagrant@centos7 vagrant]$ ansible -i 172.16.0.1, all -m junos_command -a "commands='show version'" -c netconf -u root
-k
SSH password:  (パスワードを入力)
{
    "plays": [
        {
            "play": {
                "id": "525400da-a710-ece8-5deb-000000000007",
                "name": "Ansible Ad-Hoc"
            },
            "tasks": [
                {
                    "hosts": {
                        "172.16.0.1": {
                            "_ansible_no_log": false,
                            "_ansible_parsed": true,
                            "changed": false,
                            "invocation": {
                                (~略~)
                            },
                            "stdout": [
                                "Hostname: vsrx1\nModel: firefly-perimeter\nJUNOS Software Release [12.1X47-D15.4]"
                            ],
                            "stdout_lines": [
                                [
                                    "Hostname: vsrx1",
                                    "Model: firefly-perimeter",
                                    "JUNOS Software Release [12.1X47-D15.4]"
                                ]
                            ]
                        }
                    },
                    "task": {
                        "id": "525400da-a710-ece8-5deb-000000000009",
                        "name": ""
                    }
                }
            ]
        }
    ],
    "stats": {
        "172.16.0.1": {
            "changed": 0,
            "failures": 0,
            "ok": 1,
            "skipped": 0,
            "unreachable": 0
        }
    }
}
[vagrant@centos7 vagrant]$

無事に ansible コマンドでも json 形式で出力できました。


■ まとめ

json callback plugin を利用する場合を例にまとめます。

ansible-playbook コマンド

  • ansible.cfg で設定する場合
[defaults]
stdout_callback = json
export ANSIBLE_STDOUT_CALLBACK=json

ansible コマンド

  • ansible.cfg で設定する場合
[defaults]
stdout_callback = json
bin_ansible_callbacks = True
export ANSIBLE_STDOUT_CALLBACK=json
export ANSIBLE_LOAD_CALLBACK_PLUGINS=True

Ansible の ios_command の出力結果でパスワードが ******** でマスクされる

■ はじめに

Ansible には Cisco IOSshow コマンドを実行できる ios_command モジュールが用意されています。 このモジュールは設計上、コマンド実行結果にパスワードで指定した文字列が含まれる場合、パスワードに関係ない箇所でも******** でマスクするという動作をします。(例外あり、後述。)

この記事では動作の確認と対応案をご紹介します。

  • 動作確認バージョン
    • Ansible 2.5.0
    • Ansible 2.4.3


■ 現象

詳細は以下の issue に記載されています。(設計上の動作のため closed )

github.com

例えば、cisco99 というパスワードを指定していいて、かつ、パスワードに関係ない箇所にも cisco99 という文字列が含まれているコンフィグ想定して、どのような時にどのようにマスクされるかを見ていきます。

  • 想定事前コンフィグ抜粋
interface Loopback0
 description hogehogecisco99hogehoge

以下のように、 ios_config モジュール内の providerpassword オプションでパスワードを指定すると、コマンド実行結果にそのパスワードと文字列が ******** でマスクされます。

Playbook

- hosts: ios
  gather_facts: no
  connection: local

  tasks:
    - name: show
      ios_command:
        commands:
          - show run
        provider:
          username: cisco
          password: cisco99        # パスワード
      register: result

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

出力結果例(抜粋)

パスワードと同じ文字列である cisco99 がマスクされます。

interface Loopback0
 description hogehoge********hogehoge

このように、パスワードが平文でコンフィグに書かれている場合にマスクすることを意図した設計のようですが、パスワードが同じ文字列が、description などパスワードと関係ない箇所に現れる場合でもマスクします。


■ 対応案

パスワードと同じ文字列をコンフィグに含めない

パスワード認証を利用する場合は、まずはこれが原則かと思います。

鍵を利用する

冒頭で紹介した issue のコメントでも提案されている方法です。鍵利用した認証に変更することで、そもそもPlaybookや変数でパスワードをしなくなるので上記のような現象は起こらなくなります。

ansible_ssh_pass 変数を利用する

ios_config モジュール内の providerpassword オプションでパスワードを指定するのではなく、どこかしらで ansible_ssh_pass で変数で指定するとマスクされません。

Playbook

- hosts: ios
  gather_facts: no
  connection: local

  # 今回は見通しが良いようにPlaybook内に変数定義
  vars:
    ansible_user: cisco
    ansible_ssh_pass: cisco99        # パスワード

  tasks:
    - name: show
      ios_command:
        commands:
          - show run
      register: result

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

出力結果例(抜粋)

パスワードと同じ文字列である cisco99 がマスクされず、そのまま出力されます。

interface Loopback0
 description hogehogecisco99hogehoge

Ansible 2.5 の場合

Ansible 2.5 では network_cli という新しいコネクションタイプの利用が推奨されています。netowrk_cli では、そもそもモジュール内の privider オプションで指定した認証情報は利用せず、ansible_useransible_ssh_pass などの変数を利用します。

Playbook

- hosts: ios
  gather_facts: no
  connection: network_cli

  # 今回は見通しが良いようにPlaybook内に変数定義
  vars:
    ansible_user: cisco
    ansible_ssh_pass: cisco99    # パスワード
    ansible_network_os: ios      # network_cli 固有の変数

  tasks:
    - name: show
      ios_command:
        commands:
          - show run
      register: result

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

出力結果例(抜粋)

パスワードと同じ文字列である cisco99 がマスクされず、そのまま出力されます。

interface Loopback0
 description hogehogecisco99hogehoge


■ まとめ

セキュリティを考慮した設計上の動作ではありますが、状況によっては副作用的な動きとなります。上記であげた対応案が参考になれば幸いです。

なお、本件は 2018/03/24 に参加させていただいた Ansible Workshop #3 2018 Spring で小耳に挟んだ話でした。気になったでので確認してみました。

Ansible ネットワークモジュールのプチ社内勉強会をしました

■ 目的

本日、社内でAnsibleのネットワークモジュールのプチ勉強会をしました。 本当にプチと言う感じで参加者は数人、資料もほとんど既存資料のリンク集でした。

初めての人には、実際にAnsibleを他人が動かしてるところを見たり、自分で動かしたりすることで、雰囲気を掴んでもらうことを狙いました。

すでに少しかじっている人には

  • 聞くまでもないけど地味に困っていることを聞ける
  • 操作を見せ合うことによって新しい発見を得る

という場になるように意識しました。

ペアプログラミング、モブプログラミングを少し参考にして、ハンズオンの時は操作端末は1つにしました。

利用した資料は以下の通りです。(機密情報なし)







本日の内容

  • Ansible 2.5 におけるネットワークモジュールのトピック(30分)
  • 仮想ネットワーク機器環境の準備の仕方(5分)
  • プチハンズオン&フリータイム(25分)

Ansible 2.5 におけるネットワークモジュールのトピック

仮想ネットワーク機器環境の作り方

プチハンズオン

  • junos
    • コンフィグバックアップ
      • 実行コマンドは show configuration
    • 設定変更
      • 実行コマンドは set system ntp server 10.0.0.1
  • ios
    • コンフィグバックアップ
      • 実行コマンドは show run
    • 設定変更
      • 実行コマンドは ntp server 10.0.0.1

参考資料


Ansible もくもく会 (第2回)に参加してきました #ansiblejp

f:id:akira6592:20180328180131j:plain

■ はじめに

Ansible ユーザー会主催の、Ansible もくもく会 (第2回)に参加してきました。 ブログ枠で参加したわけではないですが、せっかくなので、やったことや感じたことなどを簡単にまとめます。

ansible-users.connpass.com


■ やったこと

Ansible Lightbulb に沿って

Ansilbe Lightbulb というハンズオン資料の中の、Ansible Tower に関する箇所をハンズオンしました。

  • Ansible Tower の概要、用語を知る
  • Ansible Tower インストールする
  • Ansible Tower の各種設定、ジョブ実行する

利用したPlaybook(Apacheのデプロイ)は予め用意されたものを利用する手順になっていたため、特にPlaybookは自分で作成することなく、Ansible Towerの操作に集中できました。

ネットワーク機器にも

別途自分で用意した用意した、AWS上の Cisco IOS-XE インスタンスに対して show version コマンドを叩くことも試してみました。

作成したPlaybookは以下の通りです。

- hosts: all
  connection: local
  gather_facts: no
  
  tasks:
    - name: show
      ios_command:
        commands:
          - show version
      register: res
      
    - name: d
      debug:
        msg: "{{ res.stdout_lines[0] }}"

Ansible Tower からのジョブ実行結果は以下の通りです。 f:id:akira6592:20180328180555p:plain


■ 成果発表LT

私は成果発表LTという枠で、参加させていただきました。 LTといっても、特に資料の作成は必要はなく、やったことや気づきなどの振り返りを口頭で発表する感じで行いました。 一般枠は埋まりやすいですが、成果発表LT枠であれば登録しやすいので、参加登録に出遅れた場合は成果発表LT枠を検討してみてはいかがでしょうか。


■ 感じたこと

Ansible Tower には、Ansible Engine にはない、プロジェクト、テンプレートなどの概念があります。 それぞれがどういう役割のもので、どういう組み合わせで利用されるものなのかをきちんとおさえることが、最初に一歩だと思いました。


■ 他の参加者から

みんなで書き上げる Etherpad

Etherpad というツールを使って、各種案内やTips、Q&Aなどを講師、参加者みんなで書き上げていきました。 その内容は以下のQiitaの記事に転記していただいたようです。ありがとうございます。

qiita.com

参加ブログ

@Tocyuki さんの記事です。 tocyuki.hatenablog.jp

■ まとめ

レッドハットの方や、講師役の方がいらっしゃったので、不明な点はいつでも聞けるという点で心強かったです。 また、環境はAWS EC2 のインスタンスが各自に割り当てられていたので、大変助かりました。 まだまだ触り足りないので自分の環境でもハンズオンをやりつつ、次回もぜひ参加させていただきたいと思います。

(各種ノベルティもありがとうございました!)