Csv

我需要使用 jinja2 和 ansible 中的 csv 文件生成 ansible-playbook

  • July 23, 2020

我需要創建 jinja 模板來生成 ansible playbook 我需要從 csv 文件中讀取數據

csv 文件類似於下面(文件名 ansi.csv)

aaa,bbb,ccc,ddd
aa01,ansi,directory,yes
aa02,jinj,directory,yes
aa01,play,direvtory,yes
aa02,tem,directory,yes

我生成模板的劇本是


---
- hosts: localhost
 vars: 
   csvfile: "{{ lookup('file', 'csv_files/ansi.csv')}}"
 tasks:
 - name: generate template
   template:
      src: template.j2
      dest: playbook.yml

我已經創建瞭如下模板

---
{% for item in csvfile.split("\n") %}
{% if loop.index != 1 %}
{%   set list = item.split(",") %}
- name: 'make directory'
 hosts: {{ list[0]|trim()}}
 become: {{ list[3]}}
 tasks:
 - name: {{ list[1] }}
   file:
     path: {{list[1]}}
     state: {{ list[2] }}
{%  endif %}
{% endfor %}

我得到的輸出劇本更簡單

---
- name: 'make directory'
 hosts: aa01
 become: yes
 tasks:
 - name: ansi
   file:
     path: ansi
     state: directory
- name: make directory
 hosts: aa02
 become: yes
 tasks:
 - name: jinj
   file:
     path: jinj
     state: directory
- name: make directory
 hosts: aa01
 become: yes
 tasks:
 - name: play
   file:
     path: play
     state: directory
- name: make directory
 hosts: aa01
 become: yes
 tasks:
 - name: tem
   file:
     path: tem
     state: directory

但需要得到像下面這樣的劇本


---
- name: 'make directory'
 hosts: aa01
 become: yes
 tasks:
 - name: ansi
   file:
     path: ansi
     state: directory

 - name: play
   file:
     path: play
     state: directory

- name: make directory
 hosts: aa02
 become: yes
 tasks:
 - name: jinj
   file:
     path: jinj
     state: directory

 - name: tem
   file:
     path: tem
     state: directory

在上面的劇本中,我的期望是按第一列分組,只有我必須重複任務部分(如果主機相同),有人可以幫助我實現這一目標嗎?提前致謝

使用模組read_csv讀取 csv 文件並使用過濾器groupby。例如下面的劇本和模板

shell> cat playbook.yml
- hosts: localhost
 tasks:
   - read_csv:
       path: ansi.csv
     register: data
   - template:
       src: template.j2
       dest: playbook.yml
shell> cat template.j2
---
{% for host in data.list|groupby('aaa') %}
- name: 'make directory'
 hosts: {{ host.0 }}
 become: yes
 tasks:
{% for task in host.1 %}
   - name: {{ task.bbb }}
     file:
       path: {{ task.bbb }}
       state: {{ task.ccc }}

{% endfor %}
{% endfor %}

shell> cat playbook.yml 
---
- name: 'make directory'
 hosts: aa01
 become: yes
 tasks:
   - name: ansi
     file:
       path: ansi
       state: directory

   - name: play
     file:
       path: play
       state: direvtory

- name: 'make directory'
 hosts: aa02
 become: yes
 tasks:
   - name: jinj
     file:
       path: jinj
       state: directory

   - name: tem
     file:
       path: ten
       state: directory

引用自:https://unix.stackexchange.com/questions/599898