LoginSignup
8
7

More than 5 years have passed since last update.

Ansibleのios_configモジュールでinterfaceコマンドはparentsに指定するのが良さそう(検証付き)

Last updated at Posted at 2016-07-09

●はじめに

Ansibleの Cisco IOS の設定変更に対応するモジュール「ios_config」にはコンフィグを指定するオプションが複数あります。
linesはメイン処理、parentsは「interface Gi1/0/1」などの階層指定、beforeは事前処理、afterは事後処理といった具合です。

このうち、linesparentsについて
linesにinterfaceコマンド指定しても特に困らなそうだけど、parentsとどう使い分けたらよいのだろう」
という疑問があったため動作検証して挙動を探りました。環境はansible 2.1です。(一部はモジュールのソースも確認)

個人的な結論としては「interfaceコマンドのような階層指定ははフルスペルでparentsに指定するのが良い」と思っています。

●パターン別検証

以下の条件を組み合わせて4パターン検証しました。

  • interfaceコマンドをparentsに指定するか、linesに指定するか
  • interfaceコマンドを「interface」のようにフルスペルで指定するか、「int」のように省略するか

事前のコンフィグは以下の通りです。

interface GigabitEthernet1/0/1
 switchport access vlan 192
 switchport mode access
end

このインターフェースに対してlinesでdescription を指定し、Playbookを2回実行して冪等性含めて検証します。

【パターン1】parents にフルスペルで指定する

Playbookの内容

pattern01.yml
---
- hosts: cisco    # インベントリファイルで 192.168.1.1(とりあえず1台)を[cisco]グループで定義済み
  gather_facts: no
  connection: local

  tasks:
    - name : set description
      ios_config:
        parents:    # parents にフルスペルで指定
          - int interface GigabitEthernet1/0/1
        lines:
          - description TESTTESTTEST
        provider: "{{ cli }}"
      notify: save config           # 変更があったら以下で定義するhandler「save config」を呼び出す
      register: result

    - name: DEBUG   # debug表示
      debug: var=result

  handlers:
    - name: save config             # コンフィグを保存する
      ios_command:
        commands:
          - write memory
        provider: "{{ cli }}"
      register: result

    - name: DEBUG   # debug表示
      debug: var=result

  vars:
    cli:   # 認証情報を定義しておく
      host:     "{{ inventory_hostname }}"
      username: "{{ ansible_user }}"
      password: "{{ ansible_password }}"
      authorize: true
      auth_pass: "{{ cisco_enable_secret }}"

Plyaybooの実行(1回目)

user@ubuntu-vm:/etc/ansible$ ansible-playbook cat_int.yml

PLAY [cisco] *******************************************************************

TASK [set description] *********************************************************
changed: [192.168.1.1]

TASK [DEBUG] *******************************************************************
ok: [192.168.1.1] => {
    "result": {
        "changed": true,
        "responses": [
            "",
            ""
        ],
        "updates": [
            "interface GigabitEthernet1/0/1",
            "description TESTTESTTEST"
        ]
    }
}

RUNNING HANDLER [save config] **************************************************
ok: [192.168.1.1]

PLAY RECAP *********************************************************************
192.168.1.1               : ok=3    changed=1    unreachable=0    failed=0

無事にdescriptionが設定されました。

コンフィグ
interface GigabitEthernet1/0/1
 description TESTTESTTEST
 switchport access vlan 192
 switchport mode access
end

Plyaybookの実行(2回目)

user@ubuntu-vm:/etc/ansible$ ansible-playbook cat_int.yml

PLAY [cisco] *******************************************************************

TASK [set description] *********************************************************
ok: [192.168.1.1]

TASK [DEBUG] *******************************************************************
ok: [192.168.1.1] => {
    "result": {
        "changed": false,
        "updates": []
    }
}

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

2貝目は変更なしとみなされ、descriptionコマンドは実行されなかったかたちとなります。
冪等性があるといえます。

【パターン2】parents に省略して指定する

Playbookの内容

抜粋です。他はパターン1と同じです。

pattern02.yml
      ios_config:
        parents:    # parents に省略して指定
          - int gi1/0/1
        lines:
          - description TESTTESTTEST

Plyaybooの実行(1回目)

user@ubuntu-vm:/etc/ansible$ ansible-playbook cat_int.yml

PLAY [cisco] *******************************************************************

TASK [set description] *********************************************************
changed: [192.168.1.1]

TASK [DEBUG] *******************************************************************
ok: [192.168.1.1] => {
    "result": {
        "changed": true,
        "responses": [
            "",
            ""
        ],
        "updates": [
            "int gi1/0/1",
            "description TESTTESTTEST"
        ]
    }
}

RUNNING HANDLER [save config] **************************************************
ok: [192.168.1.1]

PLAY RECAP *********************************************************************
192.168.1.1               : ok=3    changed=1    unreachable=0    failed=0

無事にdescriptionが設定されました。

コンフィグ
interface GigabitEthernet1/0/1
 description TESTTESTTEST
 switchport access vlan 192
 switchport mode access
end

Plyaybookの実行(2回目)

user@ubuntu-vm:/etc/ansible$ ansible-playbook cat_int.yml

PLAY [cisco] *******************************************************************

TASK [set description] *********************************************************
changed: [192.168.1.1]

TASK [DEBUG] *******************************************************************
ok: [192.168.1.1] => {
    "result": {
        "changed": true,
        "responses": [
            "",
            ""
        ],
        "updates": [
            "int gi1/0/1",
            "description TESTTESTTEST"
        ]
    }
}

RUNNING HANDLER [save config] **************************************************
ok: [192.168.1.1]

PLAY RECAP *********************************************************************
192.168.1.1               : ok=3    changed=1    unreachable=0    failed=0

おっと、変更ありとみなされ、descpriptionコマンドがまた実行されてしまいました。
これは、lines に指定した「description TESTTESTTEST」を投入しようとして、
現状コンフィグの「description TESTTESTTEST」の親階層のコンフィグである
「interface GigabitEthernet1/0/1」がparentsに指定した「gi1/0/1」と
文字列的に一致しないため、「実行すべきコマンド」と判断され

 configure terminal
 int gi1/0/1
 description TESTTESTTEST

が実行されたかたちとなります。冪等性がないといえます。

【パターン3】lines にフルスペル指定する

Playbookの内容

抜粋です。他はパターン1と同じです。

pattern03.yml
      ios_config:
        lines:
          - interface GigabitEthernet1/0/1
          - description TESTTESTTEST

Plyaybooの実行(1回目)

user@ubuntu-vm:/etc/ansible$ ansible-playbook cat_int.yml

PLAY [cisco] *******************************************************************

TASK [set description] *********************************************************
fatal: [192.168.1.1]: FAILED! => {"changed": false, "commands": ["configure terminal", "description TESTTESTTEST"], "failed": true, "msg": "matched error in response: description TESTTESTTEST\r\n                ^\r\n% Invalid input detected at '^' marker.\r\n\r\nSW104(config)#"}


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

おっと、エラーになってしまい、description コマンドが実行されませんでした。

このパターンでは「interface GigabitEthernet1/0/1」を linesで指定しているため
現状コンフィグに「interface GigabitEthernet1/0/1」自身がある場合は省略されてしまいます。
その結果、debug結果にあるように、

 configure terminal
 description TESTTESTTEST

の2行のみを実行しようます。
グローバルコンフィグレーションモードに description コマンドはありませんので
エラーとなっています。

このパターンは使用できないことが分かりました。

【パターン4】lines に省略して指定する

Playbookの内容

抜粋です。他はパターン1と同じです。

pattern04.yml
      ios_config:
        lines:
          - int gi1/0/1
          - description TESTTESTTEST

Plyaybookの実行(1回目)

user@ubuntu-vm:/etc/ansible$ ansible-playbook cat_int.yml

PLAY [cisco] *******************************************************************

TASK [set description] *********************************************************
changed: [192.168.1.1]

TASK [DEBUG] *******************************************************************
ok: [192.168.1.1] => {
    "result": {
        "changed": true,
        "responses": [
            "",
            ""
        ],
        "updates": [
            "int gi1/0/1",
            "description TESTTESTTEST"
        ]
    }
}

RUNNING HANDLER [save config] **************************************************
ok: [192.168.1.1]

PLAY RECAP *********************************************************************
192.168.1.1               : ok=3    changed=1    unreachable=0    failed=0

無事にdescriptionが設定されました。

コンフィグ
interface GigabitEthernet1/0/1
 description TESTTESTTEST
 switchport access vlan 192
 switchport mode access
end

Plyaybookの実行(2回目)

user@ubuntu-vm:/etc/ansible$ ansible-playbook cat_int.yml

PLAY [cisco] *******************************************************************

TASK [set description] *********************************************************
changed: [192.168.1.1]

TASK [DEBUG] *******************************************************************
ok: [192.168.1.1] => {
    "result": {
        "changed": true,
        "responses": [
            "",
            ""
        ],
        "updates": [
            "int gi1/0/1",
            "description TESTTESTTEST"
        ]
    }
}

RUNNING HANDLER [save config] **************************************************
ok: [192.168.1.1]

PLAY RECAP *********************************************************************
192.168.1.1               : ok=3    changed=1    unreachable=0    failed=0

おっと、パターン2と同様に2回目も description コマンドが実行されてしまいました。
これは、linesで指定した「int gi1/0/1」を投入しようとして、
現状コンフィグの「interface GigabitEthernet1/0/1」と一致しないため、「実行すべきコマンド」と判断され

 configure terminal
 int gi1/0/1
 description TESTTESTTEST

が実行されたかたちとなります。冪等性がないといえます。

●まとめ

4パターンの検証結果から以下のことが分かりました。

パターンNo. 階層コンフィグ指定場所 コマンド 正常実行 冪等性
【パターン1】 parents フルスペル(interface)
【パターン2】 parents 省略(int) ×
【パターン3】 lines フルスペル(interface) × -
【パターン4】 lines 省略(int) ×

これらの結果から、interfaceのような階層指定のコンフィグは
parentsにフルスペルで指定するのが良い、という個人的なまとめとなりました。

8
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7