📝
Ansibleを試してみた(jinja2編)
設定変更をするのにワンラインなんてことはないわけで複数の設定変更ってのを試してみた
cli_config
cli_configを使った複数設定変更
これは単純に1行ずつベタ書きするだけなのでAnsibleに詳しくなくても比較的容易にメンテ出来る
保守容易性ってのが優れていると言うのか
新たにset_ntp_jのroleを作ってやってみる
構成
ban@UoVb:~/ansible$ tree --charset=C
.
|-- after
|-- ansible.cfg
|-- before
|-- group_vars
|-- inventory.ini
|-- junos_config.yml
|-- log
`-- roles
|-- set_int_j
| |-- tasks
| | `-- main.yml
| `-- vars
| `-- main.yml
|-- set_ntp_j
| |-- tasks
| | `-- main.yml
| `-- vars
| `-- main.yml
|-- show_conf_j
| |-- tasks
| | `-- main.yml
| `-- vars
| `-- main.yml
`-- show_ver_j
|-- tasks
| `-- main.yml
`-- vars
`-- main.yml
17 directories, 11 files
ban@UoVb:~/ansible$
ファイルの中身
- roles/set_ntp_j/tasks/main.yml
- 複数行のコマンドを実行したい時は先頭に | (パイプ)を入れて繋げるとうまくいく
ban@UoVb:~/ansible$ cat roles/set_ntp_j/tasks/main.yml
---
- name: config interface
cli_config:
config: |
set system ntp server 1.1.1.1
set system ntp server 1.1.1.2
set system ntp server 1.1.1.3
backup: yes
backup_options:
filename: "{{ inventory_hostname }}_before_{{ lookup('pipe', 'date +%Y%m%d%H%M') }}"
dir_path: /home/ban/ansible/before
ban@UoVb:~/ansible$
- roles/set_ntp_j/vars/main.yml
ban@UoVb:~/ansible$ cat roles/set_ntp_j/vars/main.yml
---
ansible_become: true
ansible_become_method: enable
ansible_network_os: junos
ansible_password: ****
ansible_user: ban
ansible_connection: network_cli
ban@UoVb:~/ansible$
ansible実行前
ban@vsrx1> show configuration system ntp
ban@vsrx1>
ban@vsrx2> show configuration system ntp
ban@vsrx2>
ansible実行
ban@UoVb:~/ansible$ ansible-playbook -i inventory.ini junos_config.yml --tags set_ntp_j
PLAY [Junos Configure] ******************************************************************************************************************
TASK [set_ntp_j : config interface] *****************************************************************************************************
[WARNING]: To ensure idempotency and correct diff the input configuration lines should be similar to how they appear if present in the
running configuration on device including the indentation
changed: [vsrx2]
changed: [vsrx1]
PLAY RECAP ******************************************************************************************************************************
vsrx1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
vsrx2 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ban@UoVb:~/ansible$
ansible実行後
ban@vsrx1> show configuration system ntp
server 1.1.1.1;
server 1.1.1.2;
server 1.1.1.3;
ban@vsrx1>
ban@vsrx2> show configuration system ntp
server 1.1.1.1;
server 1.1.1.2;
server 1.1.1.3;
ban@vsrx2>
ただ、世のトレンドはjinja2らしいのでせっかくなのでやってみる
伝統的なコア-ディストリビューション-エッジよりもリーフ-スパインが主流になってるんでact/stnadbyではなくleaf/spineを想定してinventoryを↓に修正
- 修正前
ban@UoVb:~/ansible$ cat inventory.ini
[junos]
vsrx1 ansible_host=10.0.2.110
vsrx2 ansible_host=10.0.3.110
[junosact]
vsrx1 ansible_host=10.0.2.110
[junosstby]
vsrx2 ansible_host=10.0.3.110
[cisco]
cisco1 ansible_host=10.0.2.210
cisco2 ansible_host=10.0.3.210
ban@UoVb:~/ansible$
- 修正後
ban@UoVb:~/ansible$ cat inventory.ini
[junosall]
vsrx1 ansible_host=10.0.2.110
vsrx2 ansible_host=10.0.3.110
[junospine]
vsrx1 ansible_host=10.0.2.110
[junosleaf]
vsrx2 ansible_host=10.0.3.110
[cisco]
cisco1 ansible_host=10.0.2.210
cisco2 ansible_host=10.0.3.210
ban@UoVb:~/ansible$
jinja2
jinja2だとtemplatesディレクトリ作ってテンプレートを作成しておかなきゃいけないのと、テンプレートに埋め込むパラメータが必要になるのでこんな感じにしてみた
構成
ban@UoVb:~/ansible$ tree --charset=C
.
|-- after
|-- ansible.cfg
|-- before
|-- group_vars #こいつを新しく作った
| |-- junosleaf.yml #こいつを新しく作った
| `-- junosspine.yml #こいつを新しく作った
|-- inventory.ini #こいつは中身を編集した
|-- junos_config.yml
|-- log
`-- roles
|-- set_int_j
| |-- tasks
| | `-- main.yml #こいつは中身を編集した
| |-- templates #こいつを新しく作った
| | `-- config.j2 #こいつを新しく作った
| `-- vars
| `-- main.yml
|-- set_ntp_j
| |-- tasks
| | `-- main.yml
| |-- templates #こいつを新しく作った
| | `-- config.j2 #こいつを新しく作った
| `-- vars
| `-- main.yml
|-- show_conf_j
| |-- tasks
| | `-- main.yml
| `-- vars
| `-- main.yml
`-- show_ver_j
|-- tasks
| `-- main.yml
`-- vars
`-- main.yml
18 directories, 14 files
ban@UoVb:~/ansible$
編集したものたち
- inventory.ini
- グループ名を変更した
- 別にact/stbyのままでも良かったけれども・・・
ban@UoVb:~/ansible$ cat inventory.ini
[junosall]
vsrx1 ansible_host=10.0.2.110
vsrx2 ansible_host=10.0.3.110
[junosspine]
vsrx1 ansible_host=10.0.2.110
[junosleaf]
vsrx2 ansible_host=10.0.3.110
[cisco]
cisco1 ansible_host=10.0.2.210
cisco2 ansible_host=10.0.3.210
ban@UoVb:~/ansible$
- role/set_int_j/tasks/main.yml
- 1行ずつコマンドラインを打ち込む形式からjinja2テンプレートを参照する方式に変更
ban@UoVb:~/ansible$ cat roles/set_int_j/tasks/main.yml
---
- name: config template
cli_config:
config: "{{ lookup('template', '/home/ban/ansible/roles/set_int_j/templates/config.j2') }}"
backup: yes
backup_options:
filename: "{{ inventory_hostname }}_before_{{ lookup('pipe', 'date +%Y%m%d%H%M') }}"
dir_path: /home/ban/ansible/before
ban@UoVb:~/ansible$
新しくつくったものたち
- group_vars
- inventoryのグループごとにjinja2のパラメータをまとめている
- group_vars/junosspine.yml
- 基本的に後述のconfig.j2の変数と同じ名前にしてればおk
- 最後のパラメータのstatusは設定追加する時(junosではset)の時はadd、削除する時(junosではdelete)の時はdeleteとするとテンプレートから自動選択できるようにしたかっただけ
- #でコメントアウトしなくても毎回statusのパラメータをadd or deleteにすれば別に2行書かなくてもいいからそっちの方がばっちくないかも
ban@UoVb:~/ansible$ cat group_vars/junosspine.yml
---
set_int_j_conf:
# - { ifname: ge-0/0/3, desc: fromSPINEtoLEAF, status: add }
- { ifname: ge-0/0/3, desc: "", status: delete }
set_ntp_j_conf:
- { name: "", ipaddr: 1.1.1.1, status: add }
- { name: "", ipaddr: 1.1.1.2, status: add }
- { name: "", ipaddr: 1.1.1.3, status: add }
# - { name: "", ipaddr: 1.1.1.1, status: delete }
# - { name: "", ipaddr: 1.1.1.2, status: delete }
# - { name: "", ipaddr: 1.1.1.3, status: delete }
ban@UoVb:~/ansible$
- group_vars/junosleaf.yml
- junosspine.ymlと書き方は変わらない
- 今回はちゃんと別々のパラメータを読み込んでいるか(vsrx1はgroup/vars/junosspine.yml、vsrx2はgroup_vars/junosleaf.yml)確認するためにdescriptionの名前とntpサーバのアドレスを敢えて違うやつにしている
- spaineとleafで機能差分がありそうだったから分けただけ
- 例えば、spineの方にはL3の設定をすることが多ければjunosspine.ymlの方にL3の設定変更のパラメータばっかり書いておいて、leafの方にはL2の設定をすることが多ければjunosleaf.ymlの方にはL2の設定変更のパラメータばっかり書いておくとか
ban@UoVb:~/ansible$ cat group_vars/junosleaf.yml
---
set_int_j_conf:
- { ifname: ge-0/0/3, desc: fromLEAFtoSPINE, status: add }
# - { ifname: ge-0/0/3, desc: "", status: delete }
set_ntp_j_conf:
- { name: "", ipaddr: 1.1.2.1, status: add }
- { name: "", ipaddr: 1.1.2.2, status: add }
- { name: "", ipaddr: 1.1.2.3, status: add }
# - { name: "", ipaddr: 1.1.2.1, status: delete }
# - { name: "", ipaddr: 1.1.2.2, status: delete }
# - { name: "", ipaddr: 1.1.2.3, status: delete }
ban@UoVb:~/ansible$
- role/set_int_j/templates
- jinja2のテンプレートを格納しておくディレクトリ
- role/set_int_j/templates/config.j2
- テンプレートファイル
- junosへのコマンドラインを書いて可変部分に変数を設定するだけ
- if分が普通に使えるのでadd=set、delete=deleteにしている
ban@UoVb:~/ansible$ cat roles/set_int_j/templates/config.j2
{% for setint in set_int_j_conf %}
{% if setint.status == "add" %}
set interfaces {{ setint.ifname }} description {{ setint.desc }}
{% elif setint.status == "delete" %}
delete interfaces {{ setint.ifname }} description {{ setint.desc }}
{% endif %}
{% endfor %}
ban@UoVb:~/ansible$
- role/set_ntp_j/templates
- jinja2のテンプレートを格納しておくディレクトリ
- role/set_ntp_j/templates/config.j2
- テンプレートファイル
- junosへのコマンドラインを書いて可変部分に変数を設定するだけ
- if分が普通に使えるのでadd=set、delete=deleteにしている
ban@UoVb:~/ansible$ cat roles/set_ntp_j/templates/config.j2
{% for setint in set_ntp_j_conf %}
{% if setint.status == "add" %}
set system ntp server {{ setint.ipaddr }}
{% elif setint.status == "delete" %}
delete system ntp server {{ setint.ipaddr }}
{% endif %}
{% endfor %}
ban@UoVb:~/ansible$
jinja2でAnsibleを試してみた
実行してみる
実行前
- junos_config.yml
ban@UoVb:~/ansible$ cat junos_config.yml
---
- name: Junos Configure
hosts: junosall
strategy: free
gather_facts: no
roles:
- { role: show_conf_j, tags: show_conf_j }
- { role: show_ver_j, tags: show_ver_j }
- { role: set_int_j, tags: set_int_j }
- { role: set_ntp_j, tags: set_ntp_j}
ban@UoVb:~/ansible$
- vsrxたち
ban@vsrx1> show interfaces descriptions
ban@vsrx1>
ban@vsrx1> show configuration system ntp
ban@vsrx1>
ban@vsrx2> show interfaces descriptions
ban@vsrx2>
ban@vsrx2> show configuration system ntp
ban@vsrx2>
ansible実行
ban@UoVb:~/ansible$ ansible-playbook -i inventory.ini junos_config.yml --tags set_int_j,set_ntp_j
PLAY [Junos Configure] ******************************************************************************************************************************************
TASK [set_int_j : config template] ******************************************************************************************************************************
[WARNING]: To ensure idempotency and correct diff the input configuration lines should be similar to how they appear if present in the running configuration on
device including the indentation
changed: [vsrx2]
changed: [vsrx1]
TASK [set_ntp_j : config template] ******************************************************************************************************************************
changed: [vsrx2]
changed: [vsrx1]
PLAY RECAP ******************************************************************************************************************************************************
vsrx1 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
vsrx2 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ban@UoVb:~/ansible$
実行後
- ちゃんとvsrx1(junosspine)とvsrx2(junosleaf)で正しいパラメータを読み込みんでいる
ban@vsrx1> show interfaces descriptions
Interface Admin Link Description
ge-0/0/3 up up fromSPINEtoLEAF
ban@vsrx1>
ban@vsrx1> show configuration system ntp
server 1.1.1.1;
server 1.1.1.2;
server 1.1.1.3;
ban@vsrx1>
ban@vsrx2> show interfaces descriptions
Interface Admin Link Description
ge-0/0/3 up up fromLEAFtoSPINE
ban@vsrx2>
ban@vsrx2> show configuration system ntp
server 1.1.2.1;
server 1.1.2.2;
server 1.1.2.3;
ban@vsrx2>
Discussion