jinja2 ansible-访问复杂变量

时间:2018-06-22 07:34:55

标签: ansible jinja2

我已经花了几个小时尝试给.pgpass文件加模板,因为它的结构相当复杂。我认为我需要一个嵌套的“ for”循环来访问所需的内容,但是我不确定如何正确地向下钻取。

这是var:

clients:
  - client1:
      postgres_users:
        - name: user1
          pass: mypassword1
        - name: user3
          pass: mypassword2
      postgres_user_priv_ssh_key: |   
        a
        multiline
        var
      postgres_user_pub_ssh_key: "ssh-rsa blahblahblah"
  - client2:
      postgres_users:
        - name: user3
          pass: mypassword3
        - name: user4
          pass: mypassword4
      postgres_user_priv_ssh_key: |   
        a.n.other
        multiline
        var
      postgres_user_pub_ssh_key: "ssh-rsa blahblahblahdeblah"

.pgpass文件的格式为:

hostname:port:database:username:password 

因此,对于“客户”下的每个“客户”,我需要遍历并渲染每个客户的namepass。我已经尝试了jinja2模板的如此多次迭代,可能不值得一试,因为它们都不起作用:)我愿意以某种方式重组数据,但是我觉得那是一种相当不错的方法对其进行结构化,因为可能需要多台机器将其读取以用于其他目的(一对多?)

任何建议表示赞赏!

2 个答案:

答案 0 :(得分:1)

这是您要寻找的吗?

> cat create-pgpass.yml
- hosts: localhost                                                                           
  become: yes                                                                                
  become_method: sudo                                                                        
  become_user: root                                                                          
  vars:                                                                                      
    pg_hostname: srv.example.com                                                             
    pg_port: 5432                                                                            
    pg_database: db001                                                                       
    pg_clients:                                                                              
      - client1:                                                                             
        postgres_users:                                                                      
          - name: user1                                                                      
            pass: mypassword1                                                                
          - name: user3                                                                      
            pass: mypassword2                                                                
        postgres_user_priv_ssh_key: |                                                        
            a                                                                                
            multiline                                                                        
            var                                                                              
        postgres_user_pub_ssh_key: "ssh-rsa blahblahblah"                                    
      - client2:                                                                             
        postgres_users:                                                                      
          - name: user3                                                                      
            pass: mypassword3                                                                
          - name: user4                                                                      
            pass: mypassword4                                                                
        postgres_user_priv_ssh_key: |                                                        
            a.n.other                                                                        
            multiline                                                                        
            var                                                                              
        postgres_user_pub_ssh_key: "ssh-rsa blahblahblahdeblah"                              
  tasks:                                                                                     
    - template:                                                                              
        src: /scratch/pgpass.j2                                                              
        dest: /scratch/.pgpass                                                               

> cat /scratch/pgpass.j2
{% for item in pg_clients %}
{% for user in item.postgres_users %}
{{ pg_hostname }}:{{ pg_port }}:{{ pg_database }}:{{ user.name }}:{{ user.pass }}
{% endfor %}
{% endfor %}

> ansible-playbook create-pgpass.yml
PLAY [localhost] 
****************************************************************************
TASK [Gathering Facts] 
**********************************************************************
ok: [localhost]
TASK [template] 
*****************************************************************************
ok: [localhost]
PLAY RECAP
*****************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

> cat /scratch/.pgpass 
srv.example.com:5432:db001:user1:mypassword1
srv.example.com:5432:db001:user3:mypassword2
srv.example.com:5432:db001:user3:mypassword3
srv.example.com:5432:db001:user4:mypassword4

答案 1 :(得分:1)

这是一部剧本/模板。请注意在变量结构中所做的一些更改。更具体地说,clients不再是列表变量。还为db_namedb_port添加了2个变量:

---
- name: test play
  hosts: localhost
  connection: local
  gather_facts: false
  become: yes
  vars:
    db_port: 5432
    db_name: "*"
    clients:
      client1:
        postgres_users:
          - name: user1
            pass: mypassword1
          - name: user3
            pass: mypassword2
        postgres_user_priv_ssh_key: |   
          a
          multiline
          var
        postgres_user_pub_ssh_key: "ssh-rsa blahblahblah"
      client2:
        postgres_users:
          - name: user3
            pass: mypassword3
          - name: user4
            pass: mypassword4
        postgres_user_priv_ssh_key: |   
          a.n.other
          multiline
          var
        postgres_user_pub_ssh_key: "ssh-rsa blahblahblahdeblah"

  tasks:
  - name: run the template
    template:
      src: templates/testt.j2
      dest: /tmp/testt.txt

jinja模板:

{% for db_client in lookup('dict', clients) %}
{% for user in clients[db_client.key].postgres_users %}
{{ db_client.key }}:{{ db_port }}:{{ db_name }}:{{ user.name }}:{{ user.pass }}
{% endfor %}
{% endfor %}

结果:

[root@optima-ansible ILIAS]# cat /tmp/testt.txt        
client1:5432:*:user1:mypassword1
client1:5432:*:user3:mypassword2
client2:5432:*:user3:mypassword3
client2:5432:*:user4:mypassword4
[root@optima-ansible ILIAS]# 

希望有帮助