I am trying to read csv in ansible and the file they are sending me has spaces in column names. Example:
User name
Password
Home phone number
sampleuser
fksdakfjdk
54545646
I have tried to read it using escape symbols and similar but keep getting error. Since i am new to ansible maybe its something obvious that escapes me.
any help is appreciated.
Edit:
this is something similar to what i need
- name: Read users from CSV file and return a dictionary
read_csv:
path: credentials.csv
register: users
delegate_to: localhost
- name: test
command: mkdir /home/{{ item.['User name'] }}
loop: users.list
I see two problems with your playbook.
The first is that you have:
loop: user.list
This is trying to iterate over the literal string value user.list, which is going to fail. You should have:
loop: "{{ user.list }}"
Secondly, you have written:
{{ item.['User name'] }}
This looks like an attempt to combine the dot-style notation (item.key) with the bracket style notation (item[key]). You should write:
{{ item['User name'] }}
To read a dict with ansible, 2 possibility
variable.key
variable['key']
Use the second
- ansible.builtin.debug:
var: variable['Home phone number']
Related
For example i have variable A and I want to write a file B with these value from variable A. The value from var A will be vary from the survey input.
- hosts: myhost
vars:
A: "{{ input }}"
The content of the file B that I needed:
A="{{ input }}"
I need to replace the input for the file from the input value in the variable. The input can be anything inserted in the ansible survey.
Is there a way to write the input values from var A to the file B?
Since your question and description are very vague
Is there a way to write the input values from var A to the file B?
the answer might not fit fully to your use case.
You may use the template_module.
First create a file
variable.file.j2
A={{ A }}
and than write it to the destination.
- name: Template a file to /tmp/B
ansible.builtin.template:
src: variable.file.j2
dest: /tmp/B
Thanks to
Write variable to a file in Ansible
Ansible - Save registered variable to file
Templating would indeed be better. The quick 'n dirty method would be:
---
- hosts: my_hosts
vars:
A: my_value
tasks:
- shell: "echo {{ A }} > /tmp/B"
register: the_echo
This way you'll see what's happening
I have an ansible playbook that has created a file (/tmp/values.txt) in each server with the following content
1.1.1.1
2.2.2.2
3.3.3.3
4.4.4.4
5.5.5.5
And I have a conf file named etcd.conf in the /tmp/etcd.conf with the following content
and I need to substitute the value of each line from /tmp/values.txt, so /tmp/etcd.conf will look like this:
SELF_IP=1.1.1.1
NODE_1_IP=2.2.2.2
NODE_2_IP=3.3.3.3
NODE_3_IP=4.4.4.4
NODE_4_IP=5.5.5.5
Is there a way I can do this? I used the following lookup method but it only works in the controll server
- name: Create etcd.conf
template:
src: etcd.conf.j2
dest: /tmp/etcd.conf
vars:
my_values: "{{ lookup('file', '/tmp/values.txt').split('\n') }}"
my_vars: [SELF_IP, NODE_1_IP, NODE_2_IP, NODE_3_IP, NODE_4_IP]
my_dict: "{{ dict(my_vars|zip(my_values)) }}"
You can use the slurp: task to grab the content for each machine, or use command: cat /tmp/values.txt and then examine the stdout_lines of its register:-ed variable to achieve that same .split("\n") behavior (I believe you'll still need to use that .split call after | b64decode if you use the slurp approach)
What will likely require some massaging is that you'll need to identify the group (which may very well include all) of inventory hostnames for which that command will produce content, and then grab the hostvar out of them to get all values
Conceptually, similar to [ hostvars[hv].tmp_values.stdout_lines for hv in groups[the_group] ] | join("\n"), but it'll be tedious to write out, so I'd only want to do that if you aren't able to get it to work on your own
I am trying to get the first part of my inventory_hostname.
server00122.linux.ca.domain.com
All I want is the server00122 part.
My Code:
hostName: "{{ inventory_hostname | basename }}"
I use the above code. However, it just gives me the same output.
There is an other magic variable called inventory_hostname_short.
Extract from the above link:
inventory_hostname_short:
The short version of inventory_hostname
If you want the short form of any hostname similar to what the Unix command hostname --short provides, you can do it with split() like this (of course the hard-coded hostname can be replaced with any variable):
- name: Print short host name
debug:
msg: "{{ 'server00122.linux.ca.domain.com'.split('.')[0] }}"
The above task returns:
msg: server00122
Instead of using the inventory_hostname use ansible_hostname.
That should give you want you need.
I have an ansible playbook in which one variable I am passing from the command. I am trying to append a windows folder path to it. One way I am able to find out is to add the path to another variable and then join the two variable. I would like to know if it is possible to avoid the variable and put the path like this:
"{{ variable2 }} \build\dist\package\ui.msi"
variable1 has value "d:\install"
var_build_file_name is entered by the user
variable2 is formed by combining variable1 and var_build_number.
This is the actual content in the playbook which works:
vars:
installerFolder: "{{ UploadFolder }}{{ var_build_file_name | regex_replace('(\\.zip)','\') }}"
packagePath: '\build\dist\package\UI.msi'
- name: Install new version.
debug:
msg: "{{ installerFolder }}{{ packagePath }}"
And this is the playbook command:
ansible-playbook Install.yml -i ../inventory/hosts.ini --extra-vars "target=servername var_build_file_name=16.3.0.zip UploadFolder=D:\Install\\"
The output I am getting is:
"msg": "D:\\Install\\16.3.0\\build\\dist\\package\\UI.msi"
In the above output, how come two backslashes are showing instead of one?
Is it possible to do
msg: "{{ installerFolder }} '\build\dist\package\UI.msi' "
I have tried many combinations but the backslashes are not getting properly escaped for above. If it is not possible then can someone enlighten on the reason.
Thanks.
"msg": "D:\\Install\\16.3.0\\build\\dist\\package\\UI.msi"
It is the output of debug module, which is a JSON string, so every \ is escaped.
The actual value of the msg here is D:\Install\16.3.0\build\dist\package\UI.msi, as you expect it.
And you can definitely use this syntax: msg: '{{ installerFolder }}\build\dist\package\UI.msi'
I am trying to read the contents of a file, store these in a variable and then insert them into another file if they don't already exist.
So, how I'm attempting to go about this is as follows:
# Create a variable that represents the path to the file that you want to read from
ssh_public_key_file: '../../jenkins_master/files/{{ hostvars[inventory_hostname]["environment"] }}/id_rsa.pub'
# Create a variable that represents the contents of this file:
ssh_public_key: "{{ lookup('file', '{{ ssh_public_key_file }}') }}"
I then use these variables in my Ansible playbook as follows:
- name: Install SSH authorized key
lineinfile: create=yes dest=~/.ssh/authorized_keys line=" {{ ssh_public_key }}" mode=0644
However, when I try and run the playbook, I get the following error message:
could not locate file in lookup: {{ ssh_public_key_file }}
Can anyone recommend a solution or suggest what I may have done wrong?
Thanks,
Seán
You have to change the line to:
# Create a variable that represents the contents of this file:
ssh_public_key: "{{ lookup('file', ssh_public_key_file) }}"
If you need to concatenate variables and strings you can do it like this:
# Example with two variables
ssh_public_key: "{{ lookup('file', var_1+var_2) }}"
# Example with string and variable
ssh_public_key: "{{ lookup('file', '~/config/'+var_1) }}"
. .
First I would make sure that your ssh_public_key_file variable is set up properly. If you add a task like the following what does it show?
- name: display variable
debug: var=ssh_public_key_file
If the output looks something like this then the variable isn't defined properly (eg. the "environment" fact doesn't exist for the host):
ok: [localhost] => {
"ssh_public_key_file": "../../jenkins_master/files/{{ hostvars[inventory_hostname][\"environment\"] }}/id_rsa.pub"
}
However if everything is defined properly then your output should show the variables replaced with their correct values:
ok: [localhost] => {
"ssh_public_key_file": "../../jenkins_master/files/foo/id_rsa.pub"
}
Once you've verified that then I would do the same thing with your ssh_public_key variable. Just output its value using the debug module. It should display as the contents of the public key file.
One other thing I would strongly suggest is to avoid using lineinfile altogether. Since you're working with SSH keys I would recommend you use the authorized_key module instead. It's a much cleaner way of managing authorized_keys files.