やりたかったこと: Networkmanagerで存在する接続名しらべて根こそぎipv4.methodをmanualにしてOS再起動でNICの設定がやりなおしになるのを防ぐ。

なんかnmcliモジュールでmethod指定ansible2.4だと見当たらなかったので以下のようにshellモジュールなどで頑張ってみた次第。
(たぶんバージョン上がったらそのうちオプション増えそうだけど需要によるのかな。)

# Networkmanager(nmcli)でipv4methodをautoからmanualに変更
- name: set var of string for network device names
  shell: /bin/nmcli --fields NAME con show|grep -e .*[0-9]
  register: check_network_devices

# see: http://docs.ansible.com/ansible/latest/playbooks_loops.html#using-register-with-a-loop
- name: check ipv4 connection method
  shell: /bin/nmcli connection show "{{ item_device }}"|grep ipv4.method|awk '{print $2}'
  register: check_ipv4_conn_method
  with_items: "{{ check_network_devices.stdout_lines }}"
  loop_control:
    loop_var: item_device
  ignore_errors: yes

- name: update ipv4 connection method
  command: /bin/nmcli connection modify "{{ chkcon4.item_device }}" ipv4.method manual
  with_items: "{{ check_ipv4_conn_method.results }}"
  when: chkcon4.stdout != 'manual'
  loop_control:
    loop_var: chkcon4
  ignore_errors: yes

私が解説書くよりマニュアル見たほうがよっぽど早い気がしますが一応備忘録として書きますと、
ループ処理でregister登録した変数がres1とすると、res1.resultsの下に配列でデータが入りまして、
それをそのままwith_itemsなどに指定すると"{{ item.stdout }}"などのように配列の中身のdict(mapとかhashともいう)オブジェクトにキー(stdoutのぶぶん)指定でアクセスできる、という話になるようでございますです。
Networkmanagerを有効化しない方向もそれはそれでいい気がします。
あと、stdout_linesは標準出力結果が入った変数(改行区切り)を1行ずつを配列の1要素に変換してくれるやつです。
(showで取り出したNICごとに複数行の戻り値を配列に入れてwith_itemsで指定してmethodの確認につかう)

今回はむやみにググるよりマニュアルガン見したほうがよかったかなあと思いましたがテスト方法は以下が参考になりました。
https://qiita.com/tbuchi888/items/031c918ce9e542a37cc4

json_queryフィルタとか使わなきゃならんのかと勘違いしたけどそんな必要はなくてよかったです。

ただ、IPアドレスが事前にNetworkmanager的に設定されていないとmethodをmanualにできないエラーがでてたので、
そっちはshellではなくてnmcliモジュール使って設定するのがよさそうかなと思いました。
http://docs.ansible.com/ansible/devel/modules/nmcli_module.html

- name: set ipv4 address(for change method to manual)
  nmcli:
    type: ethernet
    conn_name: "{{ setif.conn_name }}"
    state: present
    ip4: "{{ setif.ip4 }}"
    dns4: 8.8.8.8
  with_items: "{{ nmcli_ethernet }}"
  when: not setif.conn_name | search("__omit_")
  ignore_errors: yes
  loop_control:
    loop_var: setif
  tags: set-ipv4-addr,nmcli

変数の中身が無かったらスキップするomitは指定したらその瞬間にdefinedとかになるらしくwhenとかのconditional的にis definedだとエラーになるのでsearch関数でomitじゃなかったらみたいなのをpython詳しい人に教えてもらったけど、ほんとはリストの長さlenとかで数えてその分だけ読ませるようなのが理想とも聞きました。

あと、set_factつかうとloopのタスクでregisterに登録してresultsに入ってる内容の任意のdictオブジェクトをキー指定で取り出してlistに変換できるようです(以下の例のようなのでマニュアルにも載ってる)

~略~
    - name: set fact interfacefiles
      set_fact:
        ifdests: "{{ cp_nwif_res.results | map(attribute='dest') | list }}"  #★これ
    - name: debug ifdest setfact
      debug: var=ifdests
~略~

上記はloopしてるcopyモジュールのregisterのresultsをdest(コピー先)だけ取り出してるやつ。
モジュール毎に戻り値(registerに入る値)がマニュアルに書いてあるようでした。

参考:
http://docs.ansible.com/ansible/latest/playbooks_loops.html#using-register-with-a-loop
http://docs.ansible.com/ansible/latest/playbooks_filters.html
ansible-doc nmcli
http://www.neko-no-me.net/2015/05/09/956/
http://docs.ansible.com/ansible/latest/set_fact_module.html
http://docs.ansible.com/ansible/latest/copy_module.html#return-values

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.