てくなべ (tekunabe)

ansible / network / automation

[Ansible][ACI] モジュールの冪等性と check モード(dry-run)の対応について

■ はじめに

Ansible の ACI モジュールの冪等性とcheck モード(dry-run)の対応について、簡単なサンプルをもとにご説明します。

  • 環境
    • Cisco DevNet Sandbox (APIC 4.1)
    • Ansible 2.9.0


■ 冪等性あり

すべて自分で検証したわけではないですが、APIC REST API の性質により、ACI モジュールには冪等性(idempotency)があるようです。

Cisco ACI Guide — Ansible Documentation

Because the APIC REST API is intrinsically idempotent and can report whether a change was made, the aci_rest module automatically inherits both capabilities and is a first-class solution for automating your ACI infrastructure.

ここでは aci_epg モジュールを利用して試してみます。

Playbook

tenant1 内の ap1 内に epg1 が存在する、という状態の Playbook を作成します。

---
- hosts: apic
  gather_facts: no
  
  tasks:
    - name: epg
      aci_epg:
        host: "{{ ansible_host }}"
        username: "{{ username }}"
        password: "{{ password }}"
        validate_certs: no
        tenant: tenant1
        ap: ap1
        epg: epg1
        state: present

実行(1回目)

f:id:akira6592:20191104225233p:plain:w400
epg1 はまだない
epg1 がまだない状態から、Playbook を初めて実行します。

$ ansible-playbook -i ../../inventory.ini epg_test.yml 

PLAY [apic] ************************************************************************

TASK [epg] *************************************************************************
changed: [apic01]

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

changed というステータスになり、無事に作成されました。

f:id:akira6592:20191104225255p:plain:w400
epg1 が作成された

実行(2回目)

先ほど epg1 が作られたあとに、もう一回実行します。

$ ansible-playbook -i ../../inventory.ini epg_test.yml 

PLAY [apic] ************************************************************************

TASK [epg] *************************************************************************
ok: [apic01]

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

今度は ok となり、特に設定変更が行われなかったことが分かります。


■ check モード(dry-run)も対応

ACI モジュールは、check モード(dry-run)にも対応しています。その Playbook の実行が、設定変更をもたらすのかどうかを、実際の設定変更をせずに知ることができます。ansible-plyaboo コマンドに --check オプションをつけます。

さきほど同じように aci_epg モジュールを利用して試してみます。

Playbook

tenant1 内の ap1 内に epg2 が存在する、という状態の Playbook を作成します。

---
- hosts: apic
  gather_facts: no
  
  tasks:
    - name: epg
      aci_epg:
        host: "{{ ansible_host }}"
        username: "{{ username }}"
        password: "{{ password }}"
        validate_certs: no
        tenant: tenant1
        ap: ap1
        epg: epg2
        state: present

実行(--check あり)

--check オプションを付けて、check モードで実行します。

$ ansible-playbook -i ../../inventory.ini epg_test.yml --check

PLAY [apic] ************************************************************************

TASK [epg] *************************************************************************
changed: [apic01]

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

画面でも確認できるように、実際には epg2 は作成されていません。

f:id:akira6592:20191104225349p:plain
epg2 はまだない

なお、もう一度 --check オプションを付けて実行しても結果は同じく changed です。

実行(--check なし)

念の為、--check なしにして、実際に設定変更します。

$ ansible-playbook -i ../../inventory.ini epg_test.yml

PLAY [apic] ************************************************************************

TASK [epg] *************************************************************************
changed: [apic01]

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

ログ上は 同じく changed でが、今度は通常実行なので、実際に epg2 が作成されました。

f:id:akira6592:20191104225430p:plain
epg2 が作成された

--diff オプションには非対応?

--diff オプションには対応していないようです。--diff オプションをつけてもログに変化はありませんでした。

注意点: check モード で changed でも通常実行時にエラーになることも

check モードは、現状の設定と、Playbook で指定した状態に差分があるかどうかを示すものです。 無事に check モードで changed になっても、いざ実際に通常実行するとエラーになることもありえます。

例で示します。以下の Plyabook では tenant1 内の ap9999 (存在しない Application Profile)内に epg1 がある、という状態を示しています。

---
- hosts: apic
  gather_facts: no

  tasks:
    - name: epg
      aci_epg:
        host: "{{ ansible_host }}"
        username: "{{ username }}"
        password: "{{ password }}"
        validate_certs: no
        tenant: tenant1
        ap: ap9999    # 存在しない AP
        epg: epg1
        state: present

check モードで実行すると、changed になります。

$ ansible-playbook -i ../../inventory.ini epg_test.yml --check
...(略)...
TASK [epg] $ ***********************************************************************
changed: [apic01]
...(略)...

次に、通常実行するとエラーになりますになります。EPG は、 Tenant > Apprication Profile > EPG というオブジェクト階層ですが、Playbook で指定した Apprication Profile の ap9999 が存在しないためです。

$ ansible-playbook -i ../../inventory.ini epg_test.yml 
...(略)...
TASK [epg] *********************************************************

fatal: [apic01]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "error": {"code": "102", "text": "configured object ((Dn0)) not found Dn0=uni/tn-tenant1/ap-ap9999/epg-epg1, "}, "msg": "APIC Error 102: configured object ((Dn0)) not found Dn0=uni/tn-tenant1/ap-ap9999/epg-epg1, "}
...(略)...


■ まとめ

Ansible の ACI モジュールの冪等性とcheck モード(dry-run)の対応について、簡単なサンプルをもとにご説明しました。

  • 冪等性あり
  • check モード対応