Ansible copy module with {{ item }} - copy

I have a yml file for variables which goes like this.
- newHosts
- hostIP: 192.168.1.22
filename: file1
- hostIP: 192.168.1.23
filename: file2
I am using add_host: {{ item.hostIP }} with_items {{ newHosts }}.
I want to copy respective file to respective hosts with something like {{ item.filename }} but it copies all files to each host. How I just copy only the corresponding file to the node. How can I do that?

You can use conditionals that are applied at each iteration of the loop for example:
- hosts: all
tasks:
- name: copy file to appropriate server
copy: src={{item.filename}} dest=/var/foo/{{item.filename}}
with_items: newHosts
when: item.hostIP == ansible_ssh_host

Related

Merging two Dictionaries in Helm

I am using Helm 3. I have two values.yaml files. In common/values.yaml I have defined:
deployment:
ports:
- name: http
protocol: TCP
The common is of the type library. In my-app, which is of the type application, the common is added as a dependency. In my-app/values.yaml I have added:
deployment:
ports:
- containerPort: 8081
I have defined a template _deployment.yaml in common/templates. In this file I am trying to merge these two deployment dictionaries into one by using:
{{- $deployment := merge .Values.common.deployment .Values.deployment -}}
When I am printing {{ $deployment }}, it is giving output:
map[ports:[map[containerPort:8080 name:http protocol:TCP]]]
And if I do:
{{- $deployment := merge .Values.deployment .Values.common.deployment -}}
The output of {{ $deployment }} is:
map[ports:[map[containerPort:8081]]]
Moreover the output of {{ .Values.common.deployment }} is:
map[ports:[map[name:http protocol:TCP]]]
And the output of {{ .Values.deployment }} is:
map[ports:[map[containerPort:8081]]]
What I would like to have after merging is:
deployment:
ports:
- name: http
protocol: TCP
containerPort: 8081
Any advice you could give would be much appreciated.
Looks like the merge operation does not work as expected on lists (it's a common problem, as the merge operation is ambiguous on list: should a list be appended or replaced when merging ?)
Anyway, I would suggest to merge the ports data with:
{{- $ports := merge .Values.deployment.ports[0] .Values.common.deployment.ports[0] -}}
and render the result with:
deployment:
ports:
- {{- toJson $ports }}
HTH

How to identify the hosts in my playbook from a variable file?

on my hosts file, I have like 10 different groups that each has devices in it. each customer deployment, should go to a specific region and I want to specify that in a customer config file.
In my playbook, I tried to use a variable in front of hosts and my plan was to specify the hosts group in the config file.
master_playbook.yml
hosts: "{{ target_region }}"
vars:
custom_config_file: "./app_deployment/customer_config_files/xx_app_prod.yml"
xx_app_prod.yml
customer: test1
env: prod
app_port: 25073
target_region: dev
Error message I get:
ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'target_region' is undefined
To determine a HOST(who is not the running host) in which groups he is in u have to use a little helper:
Create a script:
#!/usr/bin/env ansible-playbook
#call like: ./showgroups -i develop -l jessie.fritz.box
- hosts: all
gather_facts: no
tasks:
- name: show the groups the host(s) are in
debug:
msg: "{{group_names}}"
After that u can run a Playbook Like:
- name: "get group memberships of host"
shell: "{{ role_path }}/files/scripts/show_groups -i {{ fullinventorypath }} -l {{ hostname }}"
register: groups
- name: "create empty list of group memberships"
set_fact:
memberships: []
- name: "fill list"
set_fact:
memberships: "{{ memberships + item }}"
with_items: groups.stdout.lines

Ansible - How to add/modify PATH variable in CentOS?

I'm trying to add /usr/pgsql-10/bin to $PATH, since I want everybody who uses the machine, to be able to run the psql command.
Tried to follow this example:
- name: add {{extra_path}} to path
lineinfile:
dest: /etc/environment
state: present
backrefs: yes
regexp: 'PATH=(["]*)((?!.*?{{extra_path}}).*?)(["]*)$'
line: "PATH=\1\2:{{extra_path}}\3"
First of all, I don't quite understand how should I exactly modify this.
Should I replace just the extra_path or the whole {{extra_path}} with my path (/usr/pgsql-10/bin).
I tried either way and I get different errors.
To makes matters worse, my /etc/environment doesn't even contain PATH.
Declare additional path only
vars:
extra_path: /usr/pgsql-10/bin
The tasks below are based on the idea from Response to updating PATH with ansible - system wide
If the file is at the controller test the local file
- name: 'Add {{ extra_path }} if PATH does not exist'
lineinfile:
path: /etc/environment
line: 'PATH="{{ extra_path }}"'
insertafter: EOF
when: lookup('file', '/etc/environment') is not search('^\s*PATH\s*=')
- name: 'Add {{ extra_path }} to PATH'
lineinfile:
path: /etc/environment
regexp: 'PATH=(["])((?!.*?{{ extra_path }}).*?)(["])$'
line: 'PATH=\1\2:{{ extra_path }}\3'
backrefs: yes
If the files are on the remote hosts fetch them first. To make the play idempotent don't report changes on fetching. Fit the destination to your needs
- name: 'Fetch /etc/environment to {{ playbook_dir }}/environments'
fetch:
src: /etc/environment
dest: "{{ playbook_dir }}/environments"
changed_when: false
- name: 'Add {{ extra_path }} if PATH does not exist'
lineinfile:
path: /etc/environment
line: 'PATH="{{ extra_path }}"'
insertafter: EOF
when: lookup('file', path) is not search('^\s*PATH\s*=')
vars:
path: "{{ path_items|path_join }}"
path_items:
- "{{ playbook_dir }}"
- environments
- "{{ inventory_hostname }}"
- etc/environment
- name: 'Add {{ extra_path }} to PATH'
lineinfile:
path: /etc/environment
regexp: 'PATH=(["])((?!.*?{{ extra_path }}).*?)(["])$'
line: 'PATH=\1\2:{{ extra_path }}\3'
backrefs: yes
See Python regex.

How do I access the current user in a helm chart template

I have a helm chart template, and I would like to use the result of whoami as a template variable. How do I do this?
So if my values.yaml file has:
env:
uniqueId: {{ whoami? }}
how might I do this?
note: I am on os x, so whoami I believe assumes a linux environment, however, in the spirit of this being deployment agnostic I presume there is a non-unix way of doing this.
The Helm Chart's "values.yaml" file is typically for default values. Anything that you'd like to override should be done at time of install/upgrade of the chart.
The Helm docs show a lot of different ways in which values can be used: https://github.com/kubernetes/helm/blob/master/docs/charts.md
In this case, one option is to set the value on the command line:
helm install -set env.whoami=$(id -un) ./your-chart.tgz
You could then have a value.yaml file like:
env:
whoami: "default"
Finally, you can use it in a template like:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Chart.Version }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: WHOAMI
value: {{ .Values.env.whoami }}
Obviously your template will vary, the above is just a snippet.

Ansible - Append variable for same precedence

I'd like to append my variable for a set_fact in the same precedence. See this link: http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
The naming of the variable has to be the same in both yml files.
In group_vars/all.yml I have defined:
my_var:
- value
- another
And in group_vars/hostgroup.yml I have defined
my_var:
- win
What I expect my_var is:
{{ value }}{{ another }}{{ win }}
What it actually is:
{{ win }}
How do I ensure my set_fact appends both variables.
There is no way to merge lists with default inventory plugins.
Your only option is to merge them in runtime with set_fact:
- set_fact:
my_var: "{{ my_var + ['win'] }}"