ネットワークリソースモジュールを有効活用したい
ansible v2.9で追加されたネットワークリソースモジュールですが、いままでろくに使ったことがありませんでした。 少し時間ができたので、いろいろと試してみました。
ネットワークリソースモジュールとは
さまざまなネットワークデバイスの管理方法を簡素化および標準化
しているらしい
特徴としては下記のstateがあります、それぞれの説明は割愛させていただきます。
- merged
- replaced
- overridden
- deleted
- gathered
- rendered
- parsed
詳しいことは公式ドキュメントにお任せ docs.ansible.com
個人的にパッと見た時に特徴的だったのはreplacedでした。 今までのios_configでは設定の置き換えができなかった思いますので「これは、始まったか」と心の中でつぶやきました(嘘)
どう使うか
個人的にNW機器の構成管理をする際にPlaybook(もしくは変数ファイル)をあるべき状態に定義すればよい状態を目指しています ネットワークリソースモジュールを使って状態を目指します。
そもそもあるべき状態を定義すればよいってどんな状態なの?
今回はIOSのStaticRouteのAnsibleで設定していきます。
あるべき状態、つまり設定値は変数ファイル(static_route.yml)として host_vars配下に配置してあります
-- inventory |-- group_vars | `-- ios.yml |-- host_vars | `-- ios01 | `-- static_route.yml `-- ios1.ini
中身は以下にようになっています(インデントが若干おかしいのはいったん見逃してください)。
static_route: - address_families: - afi: ipv4 routes: - dest: 0.0.0.0/0 next_hops: - forward_router_address: 10.10.20.254 interface: GigabitEthernet1 - afi: ipv4 routes: - dest: 10.17.253.101/32 next_hops: - forward_router_address: 192.168.253.45 - afi: ipv4 routes: - dest: 8.8.8.8/32 next_hops: - forward_router_address: 10.10.20.254
この変数ファイルに定義してあるroute=機器に設定されているrouteとしたいわけです。 追加削除もこの変数ファイルをいじるだけでOKにし、Config投入時は差分の箇所のみ変更をかけてもらいたい。 冪等性も担保したい、もし手動で設定してしまってもなんとかしたい。
さっそく考えてみる
今回はCiscoDevNetで常時開放しているIOSXEを利用します。
すでにStaticRouteが何本も入っている状態です。
まず変数ファイルを用意する必要があるんですが、手で書き起こすのはさすがにやりたくない。。
そこでネットワークリソースモジュールの出番です。
gatheredを使う
gatheredはfactsに似ています、機器の設定を取得し決まった形に変換してくれます。
こんなPlaybookを作成し実行してみました。
--- - hosts: ios01 gather_facts: False tasks: - name: gathered cisco.ios.ios_static_routes: state: gathered register: gather_result - name: Write the Static Route configuration to a file copy: content: "{{ {'static_route': gather_result['gathered'] } | to_nice_yaml }}" dest: "{{ inventory_dir }}/host_vars/{{ inventory_hostname }}/static_route.yml" delegate_to: localhost
staticrouteの設定を取得し、parseし格納されます。
これで、実機から設定を変数ファイルに書き起こすことができました。(上に張っていたstatic_route.ymlです) (nice_to_yamlだと-のあとに余計にスペースはいったりちょっと変なんですよねぇ)
変数ファイルに追加や削除してみる
さて、先ほど出力したファイルをいじってみましょう。
設定追加
static_route.ymlに8.8.8.9/32のルートを追加してみます。 8.8.8.8/8を参考にコピペで作ります。
static_route: - address_families: - afi: ipv4 routes: - dest: 0.0.0.0/0 next_hops: - forward_router_address: 10.10.20.254 interface: GigabitEthernet1 - afi: ipv4 routes: - dest: 10.17.253.101/32 next_hops: - forward_router_address: 192.168.253.45 - afi: ipv4 routes: - dest: 8.8.8.8/32 next_hops: - forward_router_address: 10.10.20.254 - afi: ipv4 routes: - dest: 8.8.8.9/32 next_hops: - forward_router_address: 10.10.20.254
完成したので、設定だ!!
と、そのまえに
想定通りか確認してみる
投入するルートが想定通りか、どんなconfigを投入するのか?どんな結果になるのか?を確認したくなったので先に確認しましょう。
確認用のPlaybookを作成しました。 こちらはgatheredとrenderedの合わせ技になります。
renderedは設定時のconfigを出力してくれるstateになり、実機にログインしないでも利用可能です(Localで使える)
gatheredで取得した設定からrenderedした結果とstatic_route.ymlからrenderedした結果をdiffしてみます
diffにはfact_diffを利用しました。
--- - hosts: ios01 gather_facts: False tasks: - name: gathered cisco.ios.ios_static_routes: state: gathered register: gather_result - name: current config rendered cisco.ios.ios_static_routes: config: "{{ gather_result['gathered'] }}" state: rendered register: current_config - name: asumed config rendered cisco.ios.ios_static_routes: config: "{{ static_route }}" state: rendered register: assumed_config - name: fact_diff ansible.utils.fact_diff: before: "{{ current_config.rendered }}" after: "{{ assumed_config.rendered }}"
実行してみましょう
追加予定routeのip route 8.8.8.9 255.255.255.255 10.10.20.254
が+で見えました。
これは見やすい(よね?)
今度こそ実行
それでは設定変更を実施しましょう
用意したPlaybookがこちら
--- - hosts: ios01 gather_facts: False tasks: - name: replaced cisco.ios.ios_static_routes: config: "{{ static_route }}" state: replaced
ポイントはstate: replacedですね
さて実行、どーーーーん!
設定後の確認をしてみる
設定後の確認をしましょう、今回はconfigが想定通り設定されたか?の観点に絞って確認をします。
こちらは先ほど作成したPlaybookを再度実施することで簡単にできます。
変更なし=gatheredで取得した設定からrenderedした結果とstatic_route.ymlからrenderedした結果に差分なし
ということで想定通りに設定ができました。Ansible最高
おまけで削除
さて、DevnetのIOSXEにゴミをいれてしまったので最後は削除といきましょう。
まずは変数ファイルからいらないrouteを削除します
static_route: - address_families: - afi: ipv4 routes: - dest: 0.0.0.0/0 next_hops: - forward_router_address: 10.10.20.254 interface: GigabitEthernet1 - afi: ipv4 routes: - dest: 10.17.253.101/32 next_hops: - forward_router_address: 192.168.253.45
8.8.8.8/32と8.8.8.9/32のルートですね、こいつは私が足したので削除します。
追加時と同じように設定前の確認をします。
削除対象は赤色で出てきます(わかりやすい!)
ではreplaceを実行
え?なんでOK?
replacedの動きがよくわからない。。
overriddenが適切なのかも、、(自分の検証機じゃないのでoverriddenはスキップさせてください(´;ω;`))
ソースコードを読む気になれずでここでタイムアップ
まとめ
実際に動かすことが重要だと再認識しました。。。。
最後の削除で想定通り動かず不完全燃焼ですが、ネットワークリソースモジュールについて少し理解が深まってよかったです。
gatheredやrenderedなどの機能も便利に使えそうで妄想が膨らみますね。 今回想定と違ったoverridden/replaceの動きについてはリトライして勉強しようと思います。 (そもそもreplaceって文字だけでこんな挙動かなって勝手に想定していました、よくないですね)
変数ファイルをいじくるだけで設定を変更できるならGitとの相性もよりよくなるかも?とか、CIで投入予定のconfigまで出しておいて承認待ちで止めとくとかすればみんなの恐怖減るかな?とかいろいろと考えたら楽しくなりました。