Save list in key/value pair in Consul - ansible

I suppose this could be for any key/value storage type but I'm mainly using Consul for storage. I need a way to save a list in the value of a key. However, the quotes around the elements are stripped.
I've tried them all, the problem is I need them to return as a valid list so that i can run it through Ansible w/ with_flattened
curl -X PUT -d '['ui','dashboard']' http://localhost:8500/v1/kv/deploylist
curl -X PUT -d '[\'ui\',\'dashboard']' http://localhost:8500/v1/kv/deploylist
Ansible tasks:
- debug: msg="{{ deploylist_vars.value | map(attribute='Value') | first }}"
register: module_id
# Output
"msg": "[ui,dashboard]"
I need to loop through the list and perform further actions. However, I can't seem to parse the elements correctly.
- debug: msg="{{ item }}"
with_flattened:
- "{{ module_id }}"

Neither of those quotings looks quite right. I expect you want something JSON-like to be PUT, probably ["ui","dashboard"]. The following should get bash/zsh to pass that through:
curl -X PUT -d '["ui","dashboard"]' http://localhost:8500/v1/kv/deploylist
You could further do some backslash-escaping inside the single quotes, but don’t add more single quotes without some care.

Related

Is it possible to select an item within a list with a regex?

I am trying to create a script which is only selecting an item within a list, with a regex.
In my case, based on a certain condition which should be triggered wheter a specific character set is present of not within the name, then just select that item.
So far, I have produced the following code within an ansible Role:
- name: "Set_initial_regex"
set_fact:
name_regex: ".*((-a)+(\\d)?)\\..*\\.company\\..+"
# This regex should select any FQDN with "-a" followed by an optional number within its name (e.g. fqdn-test-a1.test.company.local)
- name: "Debug"
debug:
msg: "{{ name | split(',') | regex_search(name_regex) }}"
The name variable is provided with --extra-vars and could be multiple, but usually there are only two of them. They are separated by a comma - hence the split.
The code above works fine with | first and | last instead of regex_search, but I am looking for something more custom.
At the moment, the returned output is (for example):
"msg": [
"fqdn-test-a1.test.company.local",
"fqdn-test-b1.test.company.local"
]
And the desired output should -in this case- be just
"msg": [
"fqdn-test-a1.test.company.local"
]
Thanks in advance for any help or insights you might provide.
I found out the way to do this; the following code works fine for this purpose:
- name: "Debug"
debug:
msg: "{{ name | split(',') | select('search', name_regex) }}"
vars:
name_regex: ".*((-a)+(\\d)?)\\..*\\.company\\..+"
This returns the desired output mentioned above.
With select(), this works fine, as it should create a subset of a list, which is what I needed in this case.

Ansible read csv that has spaces in column names

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']

How to provide tab space for ansible variables

I have a task and i am writing the task result to the file. While writing to the file I need to give indentation.
I have tried the below command but it is indenting only the first line of the variable. But, I need the entire lines in the variable need to be indent. Is there anyway to do that?
- name: task
shell: some command
register: result
- shell: 'echo -e \\t{{result.stdout | to_json}} >>file.txt'
As stated in #Seshadri comment, your shell output lines are available either globally in stdout or in a list containing one element for each line in stdout_lines.
You can use the latest to treat each line separately. You don't really have to loop in this case. There are functions to apply the same filter to each element of a list. The following should do the trick to add a tab to each line element:
result.stdout_lines | map('regex_replace', '(.*)', '\\t\\g<1>')
You simply have to join the resulting list with new lines to get your content as expected.
You should use the existing tools in ansible when they exist rather than using shell whenever possible. One reason is that modules will very often handle idempotence for you (e.g. write the file only when content actually changed). In this case, the copy module using the content option (rather than src) is probably the best solution. So your final solution would look like:
- name: Write my result file
copy:
dest: file.txt
content: "{{ result.stdout_lines
| map('regex_replace', '(.*)', '\\t\\g<1>') | join('\n') }}"

Ansible: to get specific lines from stdout_lines of ansible playbook

I would like to print specific lines form stdout_lines from ansible playbook with string e.g "systemd". Could you please someone help me on this ?
The select filter is a way of applying an existing test, such as the search test to a list of items, allowing through only those items which pass the test's criteria; thus:
- shell: |
for i in alpha system beta; do
echo "${i}d"
done
register: bob
- debug:
msg: '{{ bob.stdout_lines | select("search", "systemd") | list }}'
You need that final | list on the end because select and its map friend produce python generators, and thus need a terminating operation, either first or list or length to cause them to actually do work

Can a value in a variable and a string with backslashes be combined in ansible?

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'

Resources