Unable to create directory using ansible playbook - ansible

Steps to reproduce-
Ensure you have a VM running in VirtualBox (RHEL8)
Create a ansible galaxy collection
ansible-galaxy collection init myorg.mycollection
Navigate into the Roles Directory and execute following command
ansible-galaxy role init myrole
Add following code in main.yml inside the roles/myrole/tasks/main.yml
---
# tasks file for myrole
- name: Create /home/{{username}}/.ssh, if not exist
file:
path: "/home/{{username}}/.ssh"
state: directory
Create a play.yml file with following content
---
- name: Configure Development Workstation
hosts: my_user_name-rhel8
connection: local
debugger: on_failed
gather_facts: no
become_user: my_user_name
vars:
uname: "my_user_name"
roles:
- role: myorg.mycollection.myrole
username: "{{ uname }}"
build your collection with following command
ansible-galaxy collection build myorg/mycollection
install your collection with following command
ansible-galaxy collection install ./myorg-mycollection-1.0.0.tar.gz --force
run ansible playbook with following command
ansible-playbook play.yml -i my_user_name-rhel8, --ask-become-pass -vvv
Expected Result: The /home/username/.ssh folder should be created successfully.
Actual Result: The ansible fails with following result
[WARNING]: Platform darwin on host my_user_name-rhel8 is using the discovered Python interpreter at /usr/bin/python, but future
installation of another Python interpreter could change the meaning of that path. See
https://docs.ansible.com/ansible/2.11/reference_appendices/interpreter_discovery.html for more information.
fatal: [my_user_name-rhel8]: FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"invocation": {
"module_args": {
"_diff_peek": null,
"_original_basename": null,
"access_time": null,
"access_time_format": "%Y%m%d%H%M.%S",
"attributes": null,
"follow": true,
"force": false,
"group": null,
"mode": null,
"modification_time": null,
"modification_time_format": "%Y%m%d%H%M.%S",
"owner": null,
"path": "/home/my_user_name/.ssh",
"recurse": false,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "directory",
"unsafe_writes": false
}
},
"msg": "There was an issue creating /home/anchavan as requested: [Errno 45] Operation not supported: '/home/my_user_name'",
"path": "/home/my_user_name/.ssh"
}

Related

Ansible: Accessing standard user home path while being logged in as root

I am trying to copy a file using ansible as sudo from remote user home directory ~/bin to usr/local.
This works:
- name: Copy Folder Working
become_user: "{{ ansible_facts.env.SUDO_USER }}"
become: yes
command: sudo mv ~/bin /usr/local/bin
But this doesn't:
- name: Copy Folder Permission Error
become_user: "{{ ansible_facts.env.SUDO_USER }}"
become: yes
copy:
remote_src: yes
src: ~/bin
dest: /usr/share
So even though I use become: yes ansible apparently doesn't copy using sudo. I do get the same permission error as if I would try to copy the file manually without using sudo. The paths seem to be correct. How can I avoid that or is sticking to the first self implemented solution the way to go?
Additional Info
This is part of a playbook that is executed on a server. That server can have ubuntu as its default user, but also any other default user of a Linux distribution is possible. Therefore the default user needs to be read from ansible_facts as I try to do by using "{{ ansible_facts.env.SUDO_USER }}". While SUDO_USER sounds odd this seems to work as I get the expected permission error:
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"_original_basename": null,
"attributes": null,
"backup": false,
"checksum": null,
"content": null,
"dest": "/usr/share",
"directory_mode": null,
"follow": false,
"force": true,
"group": null,
"local_follow": null,
"mode": null,
"owner": null,
"remote_src": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": "/home/ubuntu/bin",
"unsafe_writes": false,
"validate": null
}
},
"msg": "Destination /usr/share not writable"
}
There's also the issue I need to fix that it merges instead of copying, but there are multiple possible solutions for that which I feel are unrelated (for example copying the files from ~/bin/* instead and deleting the folder.

Unable to get product version. How to set CLASSPATH using ansible

I can get the weblogic version by doing this on the command prompt in unix.
$ . /app/wlserv*/server/bin/setWLSEnv.sh
$ java weblogic.version
I wish to grab the weblogic version using ansible on remote hosts so I wrote this playbook:
---
- hosts: dest_nodes
tasks:
- name: Get weblogic version
shell: "/app/wlserv*/server/bin/setWLSEnv.sh;java weblogic.version"
register: wlsversion
- debug:
msg: "{{ wlsversion }}"
However, I get this error:
fatal: [10.0.0.91]: FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"cmd": "/app/wlserv*/server/bin/setWLSEnv.sh;java weblogic.version",
"delta": "0:00:00.271434",
"end": "2020-05-15 16:31:44.209506",
"invocation": {
"module_args": {
"_raw_params": "/app/wlserv*/server/bin/setWLSEnv.sh;java weblogic.version",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"msg": "non-zero return code",
"rc": 1,
"start": "2020-05-15 16:31:43.938072",
"stderr": "Error: Could not find or load main class weblogic.version",
"stderr_lines": [
"Error: Could not find or load main class weblogic.version"
],
"stdout": "CLASSPATH=/usr/java/jdk1.8.0_192-amd64/lib/tools.jar:/app/wlserver/modules/features/wlst.wls.classpath.jar:\n\nPATH=/app/wlserver/server/bin:/app/wlserver/../oracle_common/modules/thirdparty/org.apache.ant/1.9.8.0.0/apache-ant-1.9.8/bin:/usr/java/jdk1.8.0_192-amd64/jre/bin:/usr/java/jdk1.8.0_192-amd64/bin:/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/app/wlserver/../oracle_common/modules/org.apache.maven_3.2.5/bin\n\nYour environment has been set.",
"stdout_lines": [
"CLASSPATH=/usr/java/jdk1.8.0_192-amd64/lib/tools.jar:/app/wlserver/modules/features/wlst.wls.classpath.jar:",
"",
"PATH=/app/wlserver/server/bin:/app/wlserver/../oracle_common/modules/thirdparty/org.apache.ant/1.9.8.0.0/apache-ant-1.9.8/bin:/usr/java/jdk1.8.0_192-amd64/jre/bin:/usr/java/jdk1.8.0_192-amd64/bin:/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/app/wlserver/../oracle_common/modules/org.apache.maven_3.2.5/bin",
"",
"Your environment has been set."
]
}
From the output, I see that the classpath did get set but java weblogic.version command failed on the remote host.
Can you please suggest how can i get the Weblogic version registered to wlsversion variable ?
Wow, I found the solution after some efforts. Posting the solution here. I'm sure many face this issue.
---
- hosts: dest_nodes
tasks:
- name: Get weblogic CLASSPATH
shell: "/app/wlserv*/server/bin/setWLSEnv.sh"
register: wlsenv
- name: Get weblogic Version
shell: "java weblogic.version"
environment:
CLASSPATH: "{{ wlsenv.stdout }}"
register: wlsversion
- debug:
msg: "{{ wlsversion }}"

maven_artifact comman of ansible is not working in Rundeck

Objective:
Download the artifact jar from nexus to a Target server. I have already tried an attempt to download the jar via URL and not via maven_artifact, which was successful anyway. But wanted to try with maven_artifact command
Code in playbook:
---
- name: TestOfMavenArtifactCommand
hosts: Target_Server_Where_the_Jar_needs_to_be_downloaded
tasks:
- maven_artifact:
group_id: ab.cdef.group
artifact_id: artifact_name
repository_url: 'https://nexusUrl/repository/maven-snapshots'
dest: /folder/artifact_name.jar
username: user
state: present
mode: 0755
When I run the Rundeck job, it fails. The error is like:
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible-playbook
python version = 2.7.5 (default, Jun 11 2019, 12:19:05) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
Using /etc/ansible/ansible.cfg as config file
Parsed /var/lib/rundeck/work/zxcv-folder-services/scpr-inventory_dev/dev/hosts.yml inventory source with ini plugin
[WARNING]: Ignoring invalid attribute: username
[WARNING]: Ignoring invalid attribute: artifact_id
[WARNING]: Ignoring invalid attribute: dest
[WARNING]: Ignoring invalid attribute: state
[WARNING]: Ignoring invalid attribute: mode
[WARNING]: Ignoring invalid attribute: repository_url
[WARNING]: Ignoring invalid attribute: group_id
PLAYBOOK: main.yml *************************************************************
1 plays in main.yml
fatal: [server00.companyxxx.dev ]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"artifact_id": null,
"attributes": null,
"backup": null,
"classifier": "",
"content": null,
"delimiter": null,
"dest": null,
"directory_mode": null,
"extension": "jar",
"follow": false,
"force": null,
"group": null,
"group_id": null,
"keep_name": false,
"mode": null,
"owner": null,
"password": null,
"regexp": null,
"remote_src": null,
"repository_url": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "devsent",
"timeout": 10,
"unsafe_writes": null,
"username": null,
"validate_certs": true,
"version": "latest"
}
},
"msg": "group_id must be set"
}
to retry, use: --limit #/var/lib/rundeck/work/abcd-batch-services/scpr-servers-operations_dev/deploy-servers/tasks/main.retry
Followed the reference of this:
https://docs.ansible.com/ansible/latest/modules/maven_artifact_module.html
This appears to be just an indentation error. Try:
tasks:
- maven_artifact:
group_id: ab.cdef.group
artifact_id: artifact_name
repository_url: 'https://nexusUrl/repository/maven-snapshots'
dest: /folder/artifact_name.jar
username: user
state: present
mode: 0755

ansible module os_keypair never returns the value of private_key

I would like to use the ansible module os_keypair to generate a ssh keypair with openstack. To do so I use the following code:
- name: create openstack ssh key pair
os_keypair:
name: my-key
auth: my authentication parameters
auth_type: password
state: present
register: key
When running that code starting from scratch i.e. no key previously generated, it works in the sense that the key is generated and uploaded in openstack.
However, I would need the private key in order to perform subsequent actions through ansible (e.g. local_action for copying the private key to a file). The module documentation says that the private key is available as one of the return value. When checking my return values I get the following:
"key": {
"created_at": null,
"fingerprint": null,
"id": null,
"is_deleted": null,
"location": null,
"name": null,
"private_key": null,
"public_key": null,
"type": "ssh",
"user_id": null
}
which looks kind of puzzling to me. Is that normal behavior or is there something wrong with that module ?
[UPDATE]
Here is a complete playbook that reproduces that behavior:
---
- hosts: localhost
become_user: ansible
become: True
tasks:
- name: create openstack ssh key pair
os_keypair:
name: my-key
auth:
auth_url: http://cloudsrv1.ill.fr:5000/v3
username: ansible-test
password: 1234
project_name: k8s
project_domain_name: default
user_domain_name: default
auth_type: password
state: present
register: key
- debug:
var: key
Playbook executed with python3 as python interpreter.
Output:
TASK [debug] ********************************************************************************************************************
ok: [localhost] => {
"key": {
"changed": true,
"failed": false,
"id": "my-key",
"key": {
"created_at": null,
"fingerprint": null,
"id": null,
"is_deleted": null,
"location": null,
"name": null,
"private_key": null,
"public_key": null,
"type": "ssh",
"user_id": null
}
}
}
and however the key is generated as can be seen from the openstack snapshot.
The problem was solved by pip installing the newest openstacksdk package (0.36).

Ansible inventory: replace issues

I have an inventory like this:
[all:vars]
env_cidr_prefix='172.25'
antother_var="foo"
[VPN_SERVER]
vpn-server ansible_host="{{ env_cidr_prefix}}.0.1"
During ansible playbook, the inventory holds only private ip address.
I wan't to replace the content of "ansible_host=" with the public ip
Example of a playbook:
- name: grab the vpn public_ip
set_fact: PUBLIC_IP="{{ instance_eip.public_ip }}"
when: inventory_hostname |search("vpn-server")
- name: update inventory with the vpn public ip
replace:
path: "{{ inventory_file }}"
regexp: "{{ ansible_host }}"
replace: "{{ PUBLIC_IP }}"
when: inventory_hostname |search("vpn-server")
if
ansible_host="172.25.0.1"
the replace module will work correctly.
but this fails
ansible_host="{{ env_cidr_prefix}}.0.1"
debug output:
ok: [vpn-server] => {
"changed": false,
"invocation": {
"module_args": {
"after": null,
"attributes": null,
"backup": false,
"before": null,
"content": null,
"delimiter": null,
"directory_mode": null,
"encoding": "utf-8",
"follow": false,
"force": null,
"group": null,
"mode": null,
"owner": null,
"path": "/home/toluna/ansible/openvpn/env.properties",
"regexp": "172.25.0.11",
"remote_src": null,
"replace": "1.1.1.1",
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"unsafe_writes": null,
"validate": null
}
},
"msg": ""
}
Note, I cant use the add_host module since the playbooks are running in different stages
Is there a better way to do it ?
Thanks
OK, after testing it I guess I understand what are you trying to achieve.
Several parts here:
The inventory file is like this:
vpn-server ansible_host="{{ env_cidr_prefix}}.0.1"
And you are trying to replace 172.25.0.1 literal which doesn't exist in your file. You have "{{ env_cidr_prefix}}.0.1" and not 172.25.0.1.
Options:
If you want to replace that way, you can use a Jinja2 file in your role, replace the variable and the inventory file the same way you are trying.
Override the /etc/hosts file of your Jenkins (I really don't like too much) and play with the host name.
Play with your hosts variable in the playbook like:
Hosts Playbooks:
- name : Test
hosts: "{{ variable_vpn_ip | default('vpn-server') }}"
And call it reading from a variable that you will change ad-hoc or:
ansible-playbook play.yml -e "variable_vpn_ip=172.25.0.1"

Resources