2022年4月1日 星期五

ansible 在使用loop或with_items時加入條件when判斷

目前有一個使用情境

在管理多台主機的nginx設定時

要寫一個更新nginx config設定檔的腳本

因為是要套用在多台主機上

因為設定檔 都會以j2樣板方式寫好再套用各主機資料產生config檔案

所以會先準備好多個樣板

ex:

api.conf.j2 設定api相關

web.conf.j2 設定web相關

service.conf.j2 設定其他各式服務

socket.conf.js 設定 socket服務


但也因為各主機屬性不一樣

並不是所有的主機都會同時有這些設定檔案


因此在寫ansible控制腳本時就會需要使用迴圈

判斷如果樣板檔案存在就使用樣板產生設定檔案的功能


- name: check the nginx template config exist
  with_items:
    - src: '../../files/nginx/default.conf.j2'
      dest: '/etc/nginx/sites-available/default.conf'
    - src: '../../files/nginx/conf/web.conf.j2'
      dest: '/etc/nginx/sites-available/conf/web.conf'
    - src: '../../files/nginx/conf/api.conf.j2'
      dest: '/etc/nginx/sites-available/conf/api.conf'
  delegate_to: localhost
  stat:
    path: '{{item.src}}'
  register: stat_result
- name: build the nginx template config
  become: true
  with_items: '{{stat_result.results}}'
  template:
    src: '{{item.item.src}}'
    dest: '{{item.item.dest}}'
  when: item.stat.exists
- name: restart nginx
  service:
    name: nginx
    state: restarted

說明
以兩段工作來執行
第1段是檢查所有檔案是否存在
第2段是以上面檢查的結果判斷是否執行樣板render
第1段以stat來檢查檔案得到的回應stat_result
取得的 stat_result.results 為loop結果
{
  item: 即為with_items的一項,
  stat: {
    exists: true|false 是否存在
  }
}
第2段就可以以stat_result.results當作迴圈的內容
以when判斷是否執行
這樣 就不會因為檔案不存在由造成loop有錯誤

另外當執行loop發生錯誤
loop 內其他的正常項目還是都會作完
但下一段動作會因為錯誤而不執行
如同sample code內 如果loop出錯
那下一個重啟nginx的動作將不會被執行

這裡有一個特別注意的地方是
要檢查本機上的檔案是否存在
需要加上delegate_to: localhost
而且不可以使用root
也就是不可使用become:true

沒有留言: