Ansible SHA1 encrypt variable - ansible

how can I encode a given string using ansible?
I'm trying to do this:
echo -n "mypassword" | sha1sum

Q: "Encode a given string."
A: Use hash filter. For example, the command and the filter
- shell: echo -n "mypassword" | sha1sum
register: result
- debug:
var: result.stdout
- set_fact:
pswd: "{{ 'mypassword' | hash('sha1') }}"
- debug:
var: pswd
give the same results
"result.stdout": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2 -"
"pswd": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2"
Q: "Insert the output string into a file."
A: For example, use the template
shell> cat templates/pswd.j2.txt
pswd: {{ pswd }}
- template:
src: pswd.j2.txt
dest: pswd.txt
give
shell> cat pswd.txt
pswd: 91dfd9ddb4198affc5c194cd8ce6d338fde470e2

Related

Regex match for key in jinja2 selectattr()

Given the data:
"serverName", [
serverData: [
{
"internal_ip": "10.1.1.100",
"external_ip": "172.16.1.10",
"name": "dns-1"
},
],
]
This extracts the name value dns-1 when the internal_ip matches the equalto. So far, so good.
- debug:
msg: "{{ mydict | selectattr('internal_ip', 'equalto', '10.1.1.100') |
map(attribute='name') | list }}"
In the real problem, I do not know which type of *_ip will the ip address I'm searching for will reside. It could be under internal_ip, it could be under external_ip and for all I know, there could be even more options, the only thing that will always be there - is the actual IP address I'm searching for: '10.1.1.100`.
So I need to regex match like so:
- debug:
msg: "{{ mydict | selectattr('^.*$', 'equalto', '10.1.1.100') |
map(attribute='name') | list }}"
I'm not sure if this is possible, but it seems to be one of the ways out of this jam.
For example, the playbook
shell> cat playbook.yml
- hosts: localhost
vars:
mylist:
- {internal_ip: 10.1.1.101, external_ip: 172.16.1.10, name: dns-1}
- {internal_ip: 10.1.1.102, external_ip: 172.16.1.10, name: dns-2}
- {internal_ip: 10.1.1.103, external_ip: 172.16.1.10, name: dns-3}
tasks:
- set_fact:
sel: "{{ sel|default([]) + [item.name] }}"
loop: "{{ mylist }}"
when: sel_ip|default('') in item.values()|list
- debug:
var: sel
gives
shell> ansible-playbook playbook.yml -e sel_ip=172.16.1.10
...
sel:
- dns-1
- dns-2
- dns-3
shell> ansible-playbook playbook.yml -e sel_ip=10.1.1.103
...
sel:
- dns-3

How to format strings with jinja/ansible?

Friends,
I am learning Ansible here and trying to apply what I am learning to one of my simple projects. I got stuck trying to format some strings. I getting the following error:
fatal: [localhost]: FAILED! => {"changed": false, "msg":
"AnsibleError: template error while templating string:
**unexpected ']', expected ')'**.
String:
cluster_name = \"{{ terraform['%s' | format(env)].cluster_name }}\"
\ncredentials = \"{{ terraform['%s' | format(env)].credentials }}\"
\ninitial_node_count = \"{{ terraform['%s' | format(env]].initial_node_count }}
\format(env)].project }}\""}
...
This is how my jinja2 file looks like:
cluster_name = "{{ terraform['%s' | format(env)].cluster_name }}"
credentials = "{{ terraform['%s' | format(env)].credentials }}"
initial_node_count = "{{ terraform['%s' | format(env]].initial_node_count }}"
...
I want to generate strings like this terraform['testing'].credentials when I run ansible-playbook site.yaml -e env=testingand write them to a file. I can't figure out another way to get this done. Any Idea?
you want to use this syntax:
cluster_name = "{{ terraform[env].cluster_name }}"
With terraform.env, ansible will get the env key of the terraform env, but with terraform[env]
, ansible will resolve env to 'testing' and get the 'testing' key of the terraform var.
Q: "Generate strings like this terraform['testing'].credentials"
shell> ansible-playbook site.yaml -e env=testing
A: The playbook below
shell> cat site.yml
- hosts: localhost
tasks:
- set_fact:
cluster_name: "{{ begin }}{{ env }}{{ end }}"
vars:
begin: "terraform['"
end: "'].credentials"
- debug:
var: cluster_name
gives
cluster_name: terraform['testing'].credentials

User password creation in ansible playbook

I want to create a user and set a password for him.
First password line and second one in user module doesnt work. Tried to pass it via hash variable, but no luck :)
If I run
and place value into the password line - it works just fine, still i'd like to use my password variable. Can you kindly show the way how i can send its value into this command?
"password | password_hash('sha512', 'mysecretsalt') }}"
.
---
- name: create ssh keys and distribute ssh public key for user
hosts: clients
become: yes
vars:
uname : Jim
create_user : False
password : imuser
tasks:
- name: creating password
set_fact:
hash : "{{ 'password' | password_hash('sha512', 'mysecretsalt') }}"
- debug:
msg : "hashed password is {{ hash }}"
- name: create user if necessary
user:
name: "{{ uname }}"
state: present
password : "password | password_hash('sha512', 'mysecretsalt') }}"
# password : "{{ hash }}"
# password: $6$mysecretsalt$ZfUPIwkf1o9u8P04aJuQCgMfSZoIAeCoZpkbNKKn7LtiI.nQl8UWRIhO.rStaZzM8u0Bja3/9bzgOjagM5whY.
shell : /bin/bash
when: create_user == "True"
- name: get etc/passwd
shell: cat /etc/passwd
register: passwd
- block:
- debug:
var: passwd.stdout
- debug:
var: uname
when: inventory_hostname == "ansible_client1"
- name: create ssh key for user
user:
name: "{{ uname }}"
generate_ssh_key : yes
ssh_key_file : '{{ uname }}_id_rsa'
when: '"uname" in passwd.stdout'
register: create_key
- debug:
var: create_key
And the second question is:
Somehow task "create ssh key for user" is being skipped on ansible_client1 each run after i have deleted the user with userdel and his homedir with rm -rf since it looked weird at first runs of playbook. It works perfectly on 2nd host.
If i check /etc/passwd - user exist for both servers:
[admin#ansible_client1 ~]$ cat /etc/passwd | grep Jim
Jim:x:1004:1005::/home/Jim:/bin/bash
[admin#ansible_client2 Jim]$ cat /etc/passwd | grep Jim
Jim:x:1007:1008::/home/Jim:/bin/bash
User is being created each time on ansible_client1 and homedir is there, still task is being skipped and it looks like uname cannot be found in passwd.stdout somehow.
So... what's might be going on here i wonder
in the second task you have "password | password_hash('sha512', 'mysecretsalt') }}" it must be "{{ password | password_hash('sha512', 'mysecretsalt') }}" to use use te var password or "{{ 'password' | password_hash('sha512', 'mysecretsalt') }}" to use the word password as password.

How to extract the exact output from stdout.lines in ansible

My Ansible Playbook:
#Tag --> B.6 -->
- name: Change the Security Realm to CustomRealm from ManagementRealm
command: /jboss-as-7.1.1.Final/bin/jboss-cli.sh --connect--command="/core-service=management/management-interface=http-interface:read-attribute(name=security-realm)"
register: Realm
- debug:
msg: "{{ Realm.stdout_lines }}"
The output for the above command in the message is as follows:
ok: [342f2f7bed8e] => {
"msg": [
"{",
" \"outcome\" => \"success\","
" \"result\" => \"ManagementRealm\"",
"}"
]
}
is there a way to just exact \"result\" => \"ManagementRealm\"".
I tried using the
Realm.stdout_lines.find('result')
but that fails, AWk & grep commands doesn't seem to be working here.
Any thoughts is greatly appreciated.
Thak you
I think there are a few ways you could handle this.
1) Grep the output before it gets to Ansible:
# Note the change of 'command' to 'shell'
- name: Change the Security Realm to CustomRealm from ManagementRealm
shell: /jboss-as-7.1.1.Final/bin/jboss-cli.sh --connect--command="/core-service=management/management-interface=http-interface:read-attribute(name=security-realm)" | grep -o 'result.*'
register: Realm
2) If the output from the source script is always 4 lines long, you can just grab the 3rd line:
# List indexes start at 0
- debug:
msg: "{{ Realm.stdout_lines[2] | regex_replace('^ *(.*$)', '\\1') }}"
3) The nicest way if you have an option to modify jboss-cli.sh, would be to get the jboss-cli.sh to output valid JSON which can then be parsed by Ansible:
# Assuming jboss-cli.sh produces {"outcome": "success", "result": "ManagementRealm"}
- set_fact:
jboss_data: "{{ Realm.stdout | from_json }}"
- debug:
var: jboss_data.result

Ansible parses strings as lists if the format is compatible, how to escape?

Using ansible, I need to put a list of hosts in line in a file like so:
["127.0.0.1", "127.0.0.2", "127.0.0.3"]
But whenever I achieve this format, ansible interprets it as a list and the content of the file is this pythonic version:
['127.0.0.1', '127.0.0.2', '127.0.0.3']
Here's my attempts to get it out thus far:
---
- hosts: all
gather_facts: False
tasks:
- set_fact:
myhosts:
- 127.0.0.1
- 127.0.0.2
- 127.0.0.3
# This comes out as a list, I need a string
- set_fact:
var: "[ \"{{ myhosts | join('\", \"')}}\" ]"
- debug: var=var
# This comes out as a string, but I need no underscore on it
- set_fact:
var: "_[ \"{{ myhosts | join('\", \"')}}\" ]"
- debug: var=var
# This also comes out as a list
- set_fact:
var: >
[ "{{ myhosts | join('", "')}}" ]
- debug: var=var
# Also parsed as a list
- set_fact:
var: "{{ myhosts | to_json }}"
- debug: var=var
# ansible-playbook -i "localhost," this_file.yml
There are some filters that prevent Ansible template engine from doing string evaluation.
This list of filters is stored in STRING_TYPE_FILTERS setting.
In Ansible 2.1 it contains: string, to_json, to_nice_json, to_yaml, ppretty, json.
So, you can do this:
- lineinfile: line="{{ myhosts | to_json }}" dest=output.txt
This will add ["127.0.0.1", "127.0.0.2", "127.0.0.3"] line to the file.
And don't believe debug's output when dealing with exact string formatting.
Always use copy: content="{{ string_output_to_test | string }}" dest=test.txt and check file contents to be sure.
debug: var=myvar will always template with evaluation, so your string will always be printed as a list.
debug: msg="{{ myvar | string }}" will print myvar as JSON encoded string.

Resources