お疲れ様です。たそ(@taso_int)です。
来週初任給がもらえるのでワクワクしてます。
初任給で椅子を買いたいですね。
あと親にも何かあげたいです。 何かおススメありますかね。
今回も続きをやっていきたいと思います。
前回の内容について知りたい方はこちらへ
前回の出来なかったところから行っていきます。
1.構成図
以前の構成から192.168.1.2→192.168.1.254に変更します。
しかし、AnsiblleホストとSSH接続しており、playbookで変更すると
止まってしまうので手動で設定変更をします。
そこでstartup-configとrunnig-configの設定ファイルを保存して
変更部分を比較するplaybookを書きたいと思います。
2.動作設計
今回のplaybookの動作手順を考えたいと思います。
1.実際にコマンドをそれぞれ実行する。
2.実行結果をファイルで保存をする。 ←(ここまではできた)
3.ファイルを比較する。
4.比較結果をplaybook実行中に表示させる。
5.write memoryをするかを問い合わせる。
2番以降まで出来たので、3番以降を行っていきたいと思います。
3.手順
比較する方法でshellモジュールを使って直接diffするパターンと
diffモジュールをつかう方法があります。
(横地さん教えていただきありがとうございます。)
3-1.shellモジュールver
まずはshellを使って直接diffを行う方法から見てきます。
tasks: - name: show startup ios_command: commands: show startup-config register: result - name: diff show debug: var: result.stdout_lines
shellモジュールを使ってdiffをAnsiblleホストで直接実行するように指示を出してます。
(ルータ内ではない)
shellモジュールを利用するとなぜかエラー(赤文字)出力がされ
playbookが停止してしまいます。
これはコマンド結果のリターンコードが0以外になって、
shell モジュールがエラーと判定してしまっているとのことです。
この解決策をしてfailed_when:falseを設定することで
常に成功状態にさせる方法を取りました。
またfailed_when: result.rc not in [0, 1]と設定することで、
出力なしが0 出力ありが1 エラーが2と分類できるので、
本来のエラーを漏らさないようになるためこちらの方がいいと思います。
出力方法はdebugモジュールを利用し、var: result.stdout_linesを指定することで、
1行づつ出力されます。
3-2.diffモジュールver
diffモジュールを使用した場合です。
ansible.utils.fact_diff というモジュールを利用して行うことができます。
ただしansible 2.9 や ansible 2.10ではansible.utils というcollectionを
ansible-galaxy collection install ansible.utils でインストールする必要があります。
またshowコマンドで格納した変数を利用しているので、変数を分ける必要があります。
今回は変数を分けてcopyコマンドでファイル出力し、
その変数をdiffに再利用する形を取ります。
(jinja2 のうまい書き方がわからないのです)
tasks: - name: show startup ios_command: commands: show startup-config | begin version register: result1 - name: file make startupconf copy: content: "{{ result1.stdout[0] }}" dest: "startconf_{{ inventory_hostname }}" - name: show running ios_command: commands: show running-config | begin version register: result2 - name: file make runningconf copy: content: "{{ result2.stdout[0] }}" dest: "runconf_{{ inventory_hostname }}" - name: diff ansible.utils.fact_diff: before: "{{ result1 }}" after: "{{ result2 }}"
こちらはdiffのモジュールなので出力も見やすく行ってくれます。
やはり、shellやcommandモジュールは奥の手らしいですね。
(どうやって皆さんモジュール見つけてるんだろうか…)
3-3.保存方法
本来なら確認を取りたいのですが、分岐するのは難しいなと感じました。
そこで処理を一時的に停止させることのできるpauseモジュールがあるとのこと
(金魚の方本当に情報ありがとうございます。)
pauseで確認→OKならenter→そのままplaybookを実行
pauseで確認→NOならctrl+c→playbookを停止終了
pauseよりも上のtaskはconfigを保存してもしなくても行いたいのでこれでいいですね。
debugに入れて表示してもよかったですがnameにいれる荒技をしました。
こんな感じになりました。
- name: running-configをstartup-configに保存します。 enterで実行 Ctrl+cで停止します pause: #enterで下のタスクが実行 ctrl+c後 aで下のタスクを実行せず停止 - name: write memory ios_config: save_when: modified tags: - save
4.確認
最終的にはこのような感じになりました。
shell ver
--- - hosts: ios gather_facts: false tasks: - name: show startup ios_command: commands: show startup-config | begin version register: result - name: file make start template: src: ios_log.j2 dest: "startconf_{{ inventory_hostname }}" - name: show running ios_command: commands: show running-config | begin version register: result - name: file make run template: src: ios_log.j2 dest: "runconf_{{ inventory_hostname }}" - name: diff shell: diff -u startconf_{{ inventory_hostname }} runconf_{{ inventory_hostname }} register: result failed_when: false - name: diff show debug: var: result.stdout_lines - name: running-configをstartup-configに保存します。 enterで実行 Ctrl+cで停止します pause: - name: write memory ios_config: save_when: modified tags: - save
diff ver
--- - hosts: ios gather_facts: false tasks: - name: show startup ios_command: commands: show startup-config | begin version register: result1 - name: file make startupconf copy: content: "{{ result1.stdout[0] }}" dest: "startconf_{{ inventory_hostname }}" - name: show running ios_command: commands: show running-config | begin version register: result2 - name: file make runningconf copy: content: "{{ result2.stdout[0] }}" dest: "runconf_{{ inventory_hostname }}" - name: running-configをstartup-configに保存します。 enterで実行 Ctrl+cで停止します pause: - name: diff ansible.utils.fact_diff: before: "{{ result1 }}" after: "{{ result2 }}"
設定変更後、試しにshellバージョンでそのまま実行してみます。
いい感じに出来てます。
ちなみにpauseで停止させるとこんな感じに
いいですね
以上で完成になります。やったね!
来週は基本情報勉強のためお休みします。
ここまで読んでいただきありがとうございました。