今回はAnsibleのios_configモジュールで「changed」が表示されてしまう事象について、対応策を見つけたのでまとめます。

個人的には大発見だったのですが、ちゃんと公式docs見てる方にとっては当たり前の事みたいです…

【目次】

スポンサーリンク




ios_configで「changed」が表示されてしまう

Ansibleは冪等性 (繰り返し実行しても結果が変わらないこと)を保証しています。
しかし、ios_configを利用した際、一部のコマンドで冪等性の検証が上手く出来ない場合がありました。

問題のPlaybook

---
- name: set loopback
  hosts: cisco
  gather_facts: no

  tasks:
    - name: set loopback
      ios_config:
        lines:
          - ip address 100.0.0.1 255.255.255.255
          - ip ospf 1 area 0
          - no shutdown
        parents: interface Loopback1

1回目の実行

$ ansible-playbook test.yml

PLAY [set loopback] ***************************************************************************

TASK [set loopback] ***************************************************************************
changed: [rtr1]

PLAY RECAP ***************************************************************************
rtr1                       : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

2回目の実行

$ ansible-playbook test.yml

PLAY [set loopback] ***************************************************************************

TASK [set loopback] ***************************************************************************
changed: [rtr1]

PLAY RECAP ***************************************************************************
rtr1                       : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

2回目も「changed=1」となってしまいました。これでは冪等性が確保できてるとは言えなさそうです…

「changed」が表示される原因と解決方法

結論から言うと、以下の2点に絞れます。
 ①show running-configの出力にコマンドが存在しない
 ②正確なコマンドを引き渡せていない

①show running-configの出力にコマンドが存在しない

Qiita:https://qiita.com/akira6592/items/92e6efc478978eb41eac

まず、こちらのQiitaを参考にさせていただき、ios_configの冪等性確保の仕組みについて把握しました。

どうやらios_configは、デフォルトでshow running-configの出力と投入するコマンドを比較して、設定済みかどうかを検証しているようです。

試しにshow running-configの出力を見てみます。

~~~~~出力省略~~~~~
!
interface Loopback1
 ip address 100.0.0.1 255.255.255.255
 ip ospf 1 area 0
!
~~~~~出力省略~~~~~

ここで、「no shutdown」が出力に含まれていないことがわかると思います。
これが「changed=1」と表示されてしまう原因みたいです。

対処方法

公式:https://docs.ansible.com/ansible/2.9/modules/ios_config_module.html

show running-config all であれば「no shutdown」も出力されます。
つまり、その結果を引き渡せれば冪等性のチェックも上手く行きそうです。

先ほどのQiitaの内容では、show running-config allの結果を取得し、それをモジュールに引き渡して解決していました。
現在はモジュールが更新されており、便利なオプションが追加されていたので、そちらを使用してみます。

defaults
 ・no (デフォルト) …事前configとしてshow running-configを取得
 ・yes …事前configとしてshow running-config allを取得

defaults: yes とすればこの問題は解決できそうです。

Playbook

---
- name: set loopback
  hosts: cisco
  gather_facts: no

  tasks:
    - name: set loopback
      ios_config:
        lines:
          - ip address 100.0.0.1 255.255.255.255
          - ip ospf 1 area 0
          - no shutdown
        parents: interface Loopback1
        defaults: yes

実行結果

PLAY [set loopback and get show ip route] ***************************************************************************

TASK [set loopback] ***************************************************************************
ok: [rtr1]

PLAY RECAP ***************************************************************************
rtr1                       : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

無事に「ok=1」が表示されました!

注意事項

IOSのバージョンによっては、show running-config allの出力に「no shutdown」が含まれない場合があります。
僕が観測した中だと、IOS ver 12系は含まれていませんでした。

この場合、defaults: yesを指定しても「changed=1」は表示され続けてしまいます。

②正確なコマンドを引き渡せていない

冪等性チェックを、show running-configの結果を基に行っていることが分かれば、これも納得です。

1つ注意なのは、”parents”の引数も正確なコマンドである必要があります。

おわりに

ios_configでchangedが表示されてしまう問題は、そういうもんだと割り切っていたのですが、ちゃんと対処方法があったみたいです。
公式docsのオプションはしっかり確認するべきですね…

あと、このスペースに「いかがでしたか?」を書くの辞めることにしました。
クールな技術ブログを目指していきます笑