Reputation: 599
I've spent hours trying to template a .pgpass
file given a fairly complex variable structure. I think I need a nested "for" loop to access what I need, but I'm not sure how to drill down properly.
Here's the 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"
The .pgpass
file is of the format:
hostname:port:database:username:password
So, for each "client" under "clients", I need to iterate through and render the name
and pass
of each one. I've tried so many iterations of the jinja2 template, that it's probably not worth putting any down here, as none of them worked :) I'm open to restructuring the data in some way, but I feel that that's a fairly good way to structure it, as it may need to be read by multiple machines for other purposes (one to many?)
Any advice appreciated!
Upvotes: 1
Views: 947
Reputation: 6685
here is a playbook/template. please note some changes done in the variable structure. More specifically, the clients
is not a list variable anymore. added 2 more variables for db_name
and db_port
as well:
---
- 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 template:
{% 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 %}
result:
[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]#
hope it helps
Upvotes: 1
Reputation: 67984
Is this what you are looking for?
.
> 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
Upvotes: 1