Ansibleのios_configモジュールの parents オプションの使い道を考える

# 1. 事前調査
Cisco IOS機器の設定を管理する ios_config モジュールには parent 
というオプションがあります。[公式ドキュメント](https://docs.ansible.com/ansible/ios_config_module.html#options)では以下のように説明されています。
>
The ordered set of parents that uniquely identify the section the commands should be checked against. If the parents argument is omitted, the commands are checked against the set of top level or global commands.

階層を指定するようですね。なので例えば

```
interface GigabitEthernet1/0/1
 description hogehoge
```
のようなコンフィグを投入したい場合は、
parentsオプションに`interface GigabitEthernet1/0/1`を
linesオプションに`description hogehoge`を指定してあげればよさそうです。

ところが[【Ansible】AnsibleでCisco機器を制御してみる(サンプルコード2 port設定編)](http://qiita.com/onifinger/items/d40a68156c0a254a6e70)
で試されている方もいらっしゃいますが、linesオプションに両方してあげても
正常に処理は完了するようです。
★2016/07/07追記★
違いについて別途「[Ansibleのios_configモジュールでinterfaceコマンドはparentsに指定するのが良さそう（検証付き）](http://qiita.com/akira6592/items/5d993fcfae6e536bb65d)」にて検証しました。


# 2. 検討

では何のために parents オプションがあるのでしょうか。
モジュールのコードのほうは追えていないので正直まだ分かっていません。

ただ、parents、linesの2つのオプションに投入するコマンドが分かれているのであれば、
with_itemsなどのwith_*でparentsのループを回しているなかで、
都度linesで指定したコンフィグを流す、ということができそうです。

# 3. 複数インターフェースのdescription変更をparentsを使って変更する

普通に interface range コマンドを使おうよという話ですが、
ここはansibleの挙動を確認にするため、と割り切ります。

## 3.1. Playbookの作成
以下のPlaybookで試してみます。

```yaml
- hosts: cisco   # イベントファイルで 192.168.1.1を定義済み
  gather_facts: no
  connection: local

  tasks:
    - name: set description
      ios_config:
        parents:
         - "interface GigabitEthernet1/0/{{ item }}"  # itemにwith_sequenceの数字が入る
        lines:
         - "description No.{{ item }}" 
        provider: "{{ cli }}"
      register: result
      with_sequence: start=1 end=3   # シーケンスを定義 1,2,3
  vars:
    cli:   # 接続情報を辞書で定義（usernameとそれ以降はインベントリファイルから取得定義）
      host:     "{{ inventory_hostname }}"    # ホスト対象ホスト
      username: "{{ ansible_user }}"          # ログインユーザー
      password: "{{ ansible_password }}"      # ログインパスワード
      authorize: true                         # 特権モードに移行
      auth_pass: "{{ cisco_enable_secret }}"  # 特権パスワード
```

手動だと以下のコマンドを投入するのをイメージしています。

```
interface GigabitEthernet1/0/1
 description no.1

interface GigabitEthernet1/0/2
 description no.2

interface GigabitEthernet1/0/3
 description no.3

```

## 3.2. Playbookの実行
実行します。

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

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

TASK [set syslog] **************************************************************
changed: [192.168.1.1] => (item=1)
changed: [192.168.1.1] => (item=2)
changed: [192.168.1.1] => (item=3)

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

```
## 3.3 事後確認 
インターフェースのdescriptionを確認します。

```
foo#show interfaces status

Port      Name               Status       Vlan       Duplex  Speed Type
Gi1/0/1   no.1               connected    1          a-full a-1000 10/100/1000BaseTX
Gi1/0/2   no.2               notconnect   1            auto   auto 10/100/1000BaseTX
Gi1/0/3   no.3               notconnect   1            auto   auto 10/100/1000BaseTX
Gi1/0/4                      notconnect   1            auto   auto 10/100/1000BaseTX

（略）
```
無事変更されました。

# 4. 他にも使い道があるはず？
今夏思いついたのは with_* による繰り返しだけなのですが、
本当はほかにも使い道がある気はしています。
分かりましたらまた書きたいと思います。