Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

動態載入多個 yaml file 作為 vars #49

Open
changchichung opened this issue Feb 15, 2020 · 1 comment
Open

動態載入多個 yaml file 作為 vars #49

changchichung opened this issue Feb 15, 2020 · 1 comment

Comments

@changchichung
Copy link

我有一個目錄底下放了許多的 yaml files
然後我需要這些 yaml files 裡面的某個屬性的值,來協助判斷要不要執行某些 tasks
一開始的想法有兩個

  1. 動態載入所有 yaml file ,賦予名稱,然後跑loop 取值
  2. 把所有 yaml file 組成一個大的 yaml file ,然後取值
    第二個作法暫時還沒有想法,雖然用python 好像很好做..

動態載入yaml files 沒有問題,但是在取值的時候卻不知道該怎麼做
後來在 ansible google groups 和stackoverflow 找到了解答
就順手分享一下

首先,用shell module 取得所有的yaml file 檔案名稱

- name: get users data from yaml files
  shell:  find /home/yaml -path '*user*' |grep -Ev 'delete|user$'|awk -F "/" '{print $6}'|awk -F "." '{print $1}'
  delegate_to: localhost
  register: pcusers

然後透過include_vars 把每個 yaml file 都載入,並且依照檔名賦予名稱

- name: load yaml
  include_vars:
    name: "{{ item }}"
    file: "/home/yaml/abc.com/user/{{ item }}.yml"
  with_items: "{{ pcusers.stdout_lines }}"
  register: "{{ item }}"

假設在該路徑底下有 aa.yaml bb.yaml ....zz.yaml
那這時候,在ansible 中,我就會有 aa bb 一直到 zz 這些 vars

用 debug 看一下是否正確

- name: debug users yaml file
  tags: loadomdata
  debug:
    var: "{{ item }}"
  with_items: "{{ pcusers.stdout_lines }}"

正確的話,應該會看到類似這樣的輸出

 [pc099.abc.com] => (item=tuo) => {
    "tuo": "{u'comment': u'Tao Un On', u'home_postal_code': 115, u'gender': u'M', u'symbol': 2016090102, u'marital_status': u'S', u'work_phone_number': u'02-2543-2391 6203', u'computer_user': True, u'birth_date': datetime.date(1992, 1, 19), u'uid': 20193, u'start_date': datetime.date(2015, 9, 1), u'name': u'tuo'}", 
    "item": "tuo"

本來的想法是既然已經有個 item 叫 tuo
那我就用 with_items 來做

with_items: 
  - "{{ pcusers.stdout_lines }}"
  - "{{ item }}"

不過呢,想也知道,事情沒有這麼簡單,這樣子做當然會發生錯誤!
後來又改用類似這樣的作法

- name: debug
  debug:
    msg: "{{ item }}.name" 
  with_items: 
    - "{{ pcusers.stdout_lines }}"

這樣子雖然可以執行,但是會看到執行的結果不是我想要的 "tuo" 而是跑出了 'tuo.name"
後來翻了一下 dynamic loading vars
在這篇找到了解答

https://stackoverflow.com/questions/41875645/evaluate-dynamic-variable-name-in-ansible

其實 ansible 文件裡面也有
https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#how-do-i-access-a-variable-name-programmatically

所以我改成這樣寫

- name: create users
  user:
    name: "{{ hostvars[inventory_hostname][item].name}}"
    comment: "{{ hostvars[inventory_hostname][item].comment}}"
    uid: "{{ hostvars[inventory_hostname][item].uid}}"
    password:  passwd|hostvars[inventory_hostname][item].name 
    shell: "/bin/bash"
    update_password: "on_create"
    state: present
    remove: yes
  when: hostvars[inventory_hostname][item].computer_user           
  with_items: "{{ pcusers.stdout_lines }}"

Bingo ! 可以順利跑完了!

後來又看到再簡潔一點的解法,於是又改成這樣

- name: create users
  user:
    name: "{{ vars[item]['name'] }}"
    comment: "{{ vars[item]['comment'] }}"
    uid: "{{ vars[item]['uid'] }}"
    password: passwd|vars[item]['name']
    shell: "/bin/bash"
    update_password: "on_create"
    state: present
    remove: yes
  when: vars[item]['computer_user']
  with_items: "{{ pcusers.stdout_lines }}"

這樣子就可以順利跑完,而且也比較好閱讀,算是又學到了一課..

@chusiang
Copy link
Member

先給讚 👍 ,晚點忙完再來詳讀了! <[_ _]>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants