Adding new sudo user using ansible - "password": "NOT_LOGGING_PASSWORD" message - vagrant

I'm using Vagrant (Virtual Box provider) to setup a local Virtual Machine. I'm also using ansible and more specific ansible_local (Vagrant plugin) to deploy some tools into the VM.
Initially I'm trying to create a new user following the ansible documentation.
---
- name: Master Node
hosts: 127.0.0.1
connection: local
user: root
vars_files:
- vars/vars.yml
vars:
username: nikolas
tasks:
- name: Adding user
user: name={{username}} shell=/bin/bash groups=root append=yes password={{pass}}
sudo: yes
- name: Placing RSA key
authorized_key: user={{username}} key="{{ lookup('file', 'id_rsa.pub') }}"
sudo: yes
When I run the playbook, I get this message:
PLAY [Master Node] ************************************************************
GATHERING FACTS ***************************************************************
ok: [127.0.0.1]
TASK: [Adding user] **************************************************
changed: [127.0.0.1] => {"changed": true, "comment": "", "createhome": >true, "group": 1001, "groups": "root", "home": "/home/nikolas", "name": >"nikolas", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", >"state": "present", "system": false, "uid": 1001}
TASK: [Placing RSA key] *******************************************************
changed: [127.0.0.1] => {"changed": true, "key": "ssh-rsa >AAAAB3N....public_rsa_key", "key_options": null, >"keyfile": "/home/desmotes/.ssh/authorized_keys", "manage_dir": true, >"path": null, "state": "present", "unique": false, "user": "nikolas"}
PLAY RECAP ********************************************************************
127.0.0.1 : ok=4 changed=2 unreachable=0 >failed=0
"password": "NOT_LOGGING_PASSWORD"
As a result, when i am trying to logged in as nikolas in the VM to get authentication error.
Do you know where is my mistake ?
Thank you

I think you need to modified your user creation task like this:
- name: Adding user
user: name={{username}} shell=/bin/bash groups=root append=yes password={{ pass | password_hash('sha512') }}
sudo: yes
Hope that help you.

Related

Ansible variable in dictionary key

I am trying to execute a playbook for setting up Dell servers and I have some problems with a dictionary in module idrac_redfish_config. I need to enable SOL for a specific user, but for this I want to use a key in the dictionary with a variable because ID of user can be different from server to server.
How I try to add a variable to a dictionary key like this:
- name: Store id test-user
set_fact:
ID: "{{ result.redfish_facts.user.entries | json_query(\"[?UserName=='test-user'].Id\") }}"
- name: Enable SOL for test-user
community.general.idrac_redfish_config:
category: Manager
command: SetManagerAttributes
resource_id: iDRAC.Embedded.1
manager_attributes:
Users.{{ ID[0] }}.SolEnable: "Enabled" <---
Users.{{ ID[0] }}.IpmiLanPrivilege: "Administrator" <---
baseuri: "testhost"
username: "admin"
password: "admin"
I get this error:
TASK [Store id test-user] **************************************************************************************************************************************************************************************
ok: [localhost] => {
"ansible_facts": {
"ID": [
"8"
]
},
"changed": false
}
TASK [Enable SOL for test-user] ********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"baseuri": "testhost",
"category": "Manager",
"command": [
"SetManagerAttributes"
],
"manager_attribute_name": null,
"manager_attribute_value": null,
"manager_attributes": {
"Users.{{ ID[0] }}.IpmiLanPrivilege": "Administrator",
"Users.{{ ID[0] }}.SolEnable": "Enabled"
},
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"resource_id": "iDRAC.Embedded.1",
"timeout": 10,
"username": "admin"
}
},
"msg": "SetManagerAttributes: Manager attribute Users.{{ ID[0] }}.SolEnable not found"
}
If I do this:
manager_attributes: "{
'Users.{{ ID[0] }}.SolEnable': Enabled
'Users.{{ ID[0] }}.IpmiLanPrivilege': Administrator
}"
I get:
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"baseuri": "testhost",
"category": "Manager",
"command": [
"SetManagerAttributes"
],
"manager_attributes": "{ 'Users.8.SolEnable': Enabled 'Users.8.IpmiLanPrivilege': Administrator }",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"resource_id": "iDRAC.Embedded.1",
"timeout": 10,
"username": "admin"
}
},
"msg": "argument manager_attributes is of type <class 'str'> and we were unable to convert to dict: unable to evaluate string as dictionary"
}
I didn't find in Ansible documentation how to do this correctly.
According to documentation, manager_attributes should be a dict of key/value pairs to set on your device. The keys have dots in their names and you cannot "statically" create dynamic key names as you tried above (i.e. "prefix{{ dynamic_value }}suffix": "some content" does not work as you experienced by yourself since the key name does not go through jinja2 templating).
Below is a solution. It's far from being the only one but that's the first that came to my mind and I could setup an example for you quickly. In this case, I create a list of {key: X, value: Y} dicts with your dynamic names as keys and use the items2dict filter to transform this back to a dict itself.
I don't have a network device to play this against so I could not verify that the final result is actually accepted by the module. My example simply uses a debug with your input data to illustrate and outputs a dictionary as the module expects. You will have to tune the exact key names if they are wrong but at least you should be able to move forward.
- name: Dynamic dict
hosts: localhost
gather_facts: false
vars:
ID:
- "8"
my_attributes:
- key: "Users.{{ ID[0] }}.IpmiLandPrivilege"
value: Administrator
- key: "Users.{{ ID[0] }}.SolEnable"
value: Enabled
tasks:
- name: construct a dynamic dict and debug
vars:
manager_attributes: "{{ my_attributes | items2dict }}"
debug:
var: manager_attributes
Which gives:
PLAY [Dynamic dict demo] ***************************************************************************************************************************************************************************************************************
TASK [construct a dynamic dict and debug] **********************************************************************************************************************************************************************************************
ok: [localhost] => {
"manager_attributes": {
"Users.8.IpmiLandPrivilege": "Administrator",
"Users.8.SolEnable": "Enabled"
}
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Edit: An additional (out of many others) example to achieve the same goal. The output is exactly the same as above:
- name: Dynamic dict
hosts: localhost
gather_facts: false
vars:
ID:
- "8"
manager_attributes: "{{
{
'Users.' + ID[0] + '.IpmiLandPrivilege': 'Administrator',
'Users.' + ID[0] + '.SolEnable': 'Enabled'
}
}}"
tasks:
- name: construct a dynamic dict and debug
debug:
var: manager_attributes

Accessing hosts in metagroup children from Ansible Playbook

I'm trying sort out my inventory.yaml file to arrange hosts by groups and then call them in an Ansible playbook.
The inventory.yaml file looks like this:
---
all:
hosts:
children:
MY_Lab:
Ubuntu_18:
hosts:
BWT_BKP_A:
ansible_host: "10.2.8.19"
BWT_BKP_B:
ansible_host: "10.2.8.22"
BWT_BKP_C:
ansible_host: "10.2.9.12"
vars:
ansible_connection: ssh
ansible_user: administrator
ansible_ssh_pass: P#ssword
ansible_sudo_pass: P#ssword
From my Ansible playbook I'd like to access hosts on Ubuntu_18 section, but I can't:
name: Test connectivity
hosts: BWT_BKP_A
vars:
ansible_python_interpreter: /usr/bin/python3
tasks:
- name: Ping test
ping:
I get the following error:
ansible-playbook ping-test.yaml -i inventory.yaml
[WARNING]: Could not match supplied host pattern, ignoring: BWT_BKP_A
PLAY [Test connectivity] *****************************************************************************************************
skipping: no hosts matched
If I try the whole group, like :
hosts: Ubuntu_18
I get the same error.
Not sure what I'm missing. I'm using ansible 2.9.12
You have an error in your inventory file. The children key should be a peer of hosts, not a child, and every time you are trying to create a "subgroup" you need another children: key.
Using this as my test inventory:
---
all:
children:
MY_Lab:
children:
Ubuntu_18:
hosts:
BWT_BKP_A:
ansible_host: "127.0.0.1"
BWT_BKP_B:
ansible_host: "127.0.0.1"
BWT_BKP_C:
ansible_host: "127.0.0.1"
I can run:
$ ansible -i hosts.yml -m ping MY_Lab
BWT_BKP_B | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
BWT_BKP_A | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
BWT_BKP_C | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
Or:
$ ansible -i hosts.yml -m ping BWT_BKP_A
BWT_BKP_A | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
Etc.

I'm trying find datasore of vm guest with ansible

I'm trying to extract value of vm datastore with ansible snippet:
- name: Gather disk facts from virtual machine using name
vmware_guest_disk_facts:
hostname: "{{ vcenter_server }}"
username: "{{ vcenter_user }}"
password: "{{ vcenter_pass }}"
datacenter: "{{ datacenter }}"
validate_certs: no
name: "{{ item }}"
delegate_to: localhost
register: disk_facts
with_items: "{{ vm_list }}"
- name: Get disk info
debug:
var: disk_facts.results.guest_disk_facts.backing_datastore
Output:
[root#sysmgttl1 lvm]# ansible-playbook -i hosts vmfacts.yml -e vcenter_server=vmimgtpw002 -e vm_list=sndprfql8
PLAY [sndprfql8] ***********************************************************************************************************************************************************
TASK [Gathering Facts] *****************************************************************************************************************************************************
ok: [sndprfql8]
TASK [Gather disk facts from virtual machine using name] *******************************************************************************************************************
ok: [sndprfql8 -> localhost] => (item=sndprfql8)
TASK [Get disk info] *******************************************************************************************************************************************************
ok: [sndprfql8] => {
"disk_facts.results.guest_disk_facts.backing_datastore": "VARIABLE IS NOT DEFINED!"
}
PLAY RECAP *****************************************************************************************************************************************************************
sndprfql8 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
This is what my disk_facts looks like.
ok: [sndprfql8] => {
"disk_facts": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"guest_disk_facts": {
"0": {
"backing_datastore": "QADEV07",
"backing_eagerlyscrub": false,
"backing_filename": "[QADEV07] sndprfql8/sndprfql8.vmdk",
"backing_thinprovisioned": true,
"backing_type": "FlatVer2",
"backing_uuid": "6000C292-7716-6296-de04-69bac9186661",
"backing_writethrough": false,
"capacity_in_bytes": 68719476736,
"capacity_in_kb": 67108864,
"controller_key": 1000,
"key": 2000,
"label": "Hard disk 1",
"summary": "67,108,864 KB",
"unit_number": 0
}
},
"invocation": {
"module_args": {
"datacenter": "RDC",
"folder": null,
"hostname": "vmimgtpw002",
"name": "sndprfql8",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"port": 443,
"use_instance_uuid": false,
"username": "svcvread#chop.edu",
"uuid": null,
"validate_certs": false
}
},
"item": "sndprfql8"
}
]
}
}
If this is really for a one shot use, the following should do:
- name: Get disk info
debug:
var: disk_facts.results[0].guest_disk_facts['0'].backing_datastore
If you goal is to get all values for a list of vms in the result possibly having several disks, the following will give you a flattened list (that you can de-duplicate with the unique filter if needed)
- debug:
msg: "{{ disk_facts | json_query('results[].guest_disk_facts.*[].backing_datastore') }}"

ansible - copy key to authorized keys file

I have created a user using ansible and now would like to copy the .ssh/id_rsa.pub file to the authorized_keys file.
I checked the authorized_keys module but that is used to copy the keys from the host machine to the guest.
Wondering what would the right approach.
- name: Adding user - {{ user }}
user: name={{ user }}
group={{ group }}
shell=/bin/bash
password=${password}
groups=sudo
append=yes
generate_ssh_key=yes
ssh_key_bits=2048
ssh_key_file=.ssh/id_rsa
The generated key is returned by the user module, so you can register the result and then use the key in a subsequent authorized_key task. That is, if I have a playbook like this:
- hosts: localhost
tasks:
- name: add user
user:
name: testuser
shell: /bin/bash
password: secret
append: yes
generate_ssh_key: yes
ssh_key_bits: 2048
register: newuser
- debug:
var: newuser
I will see as output something like:
TASK [debug] *******************************************************************
ok: [localhost] => {
"newuser": {
"append": true,
"changed": true,
"comment": "",
"group": 21946,
"home": "/home/testuser",
"move_home": false,
"name": "testuser",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"ssh_fingerprint": "2048 SHA256:Tn6UOl/WYToJCaW3QUnLMWgEfthILIsoCP+534qWzfw ansible-generated on lkellogg-pc0dzzve (RSA)",
"ssh_key_file": "/home/testuser/.ssh/id_rsa",
"ssh_public_key": "ssh-rsa ... ansible-generated on examplehost",
"state": "present",
"uid": 21940
}
}
So you can add a task like this:
- authorized_key:
user: root
state: present
key: "{{ newuser.ssh_public_key }}"

Ansible: approach to loop through a complex variable in order to access different layers under the same task

What would be the correct approach to loop through a complex dictionary variable in an Ansible play in order to be able to call items from different layers of the variable in the same module/task?
The variable in question looks like this (but it could be any number of layers down, so far I only have about 3 layers down):
installation:
v10:
installs: yes
das_username: dasusr
das_group: dasadm
package_name: v10.tar.gz
binaries_folder: binaries
install_path: /opt/V10
instances:
inst1:
enabled: yes
username: inst1
group: dbiadm
port: 50000
databases:
jts:
name: 'JTS'
state: present
pagesize: 32768
rtc:
name: 'CCM'
state: absent
pagesize: 16384
rqm:
name: 'QM'
state: absent
pagesize: 32768
inst2:
enabled: no
username: inst2
group: dbiadm
port: 50005
databases:
warehouse:
name: 'DW'
state: present
pagesize: 32768
v9:
installs: no
instances:
inst3:
enabled: no
databases:
rqm:
name: 'RM'
state: absent
pagesize: 32768
lqe:
name: 'LQE'
state: absent
pagesize: 16384
Tasks include creating databases using the install_path (layer 1) and databases parameters (layer 3) under the same shell module or in a template.
For example (the task should look something like this) but with the correct method of looping:
- name: Creating the databases
become_user: "{{ item.0.instances.username }}"
shell: "./db2 create database {{ item.1.name }} using pagesize {{ item.1.pagesize }}"
args:
chdir: "{{ item.0.install_path }}/bin"
with_subelements:
- "{{ installation }}"
- instances.databases.clm
Thank you!
It's not a trivial feat to do such thing in ansible, becase loops in ansible are one-dimensional. There is a hackish way though, you can use nested includes with loop control. So let's say i put all of your variables inside vars.yml and have a following files:
playbook-nested.yml
- hosts: localhost
tasks:
- name: pass version forward
include: instances.yml v="{{ version_item }}"
with_items: "{{ installation }}"
loop_control:
loop_var: version_item
instances.yml
- name: Pass instance forward
include: databases.yml i={{ instance_item }}
with_items: "{{ installation[v].instances }}"
loop_control:
loop_var: instance_item
databases.yml
- name: echo command
debug: msg="./db2 create database {{ item.name }} using pagesize {{ item.pagesize }}"
with_items: "{{ installation[v].instances[i].databases.clm }}"
when: installation[v].instances[i].databases.clm is defined
So the output of command ansible-playbook playbook-nested.yml -e #vars.yml will be:
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [pass version forward] ****************************************************
included: /home/user/instances.yml for localhost
included: /home/user/instances.yml for localhost
TASK [Pass instance forward] ***************************************************
included: /home/user/databases.yml for localhost
TASK [echo command] ************************************************************
ok: [localhost] => (item={u'state': u'absent', u'name': u'RQM', u'pagesize': 32768}) => {
"item": {
"name": "RQM",
"pagesize": 32768,
"state": "absent"
},
"msg": "./db2 create database RQM using pagesize 32768"
}
ok: [localhost] => (item={u'state': u'absent', u'name': u'LQE', u'pagesize': 16384}) => {
"item": {
"name": "LQE",
"pagesize": 16384,
"state": "absent"
},
"msg": "./db2 create database LQE using pagesize 16384"
}
TASK [Pass instance forward] ***************************************************
included: /home/user/databases.yml for localhost
included: /home/user/databases.yml for localhost
TASK [echo command] ************************************************************
ok: [localhost] => (item={u'state': u'present', u'name': u'JTS', u'pagesize': 32768}) => {
"item": {
"name": "JTS",
"pagesize": 32768,
"state": "present"
},
"msg": "./db2 create database JTS using pagesize 32768"
}
ok: [localhost] => (item={u'state': u'absent', u'name': u'CCM', u'pagesize': 16384}) => {
"item": {
"name": "CCM",
"pagesize": 16384,
"state": "absent"
},
"msg": "./db2 create database CCM using pagesize 16384"
}
ok: [localhost] => (item={u'state': u'absent', u'name': u'QM', u'pagesize': 32768}) => {
"item": {
"name": "QM",
"pagesize": 32768,
"state": "absent"
},
"msg": "./db2 create database QM using pagesize 32768"
}
TASK [echo command] ************************************************************
skipping: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=8 changed=0 unreachable=0 failed=0
I'm not sure what does clm mean and do i have to loop over databases as well, but i think the concept is clear to you now.
You can also use the nested_loops on the lower level i guess.

Resources