Ansible Symbolic Link Task Role Failure - ansible

I am new to ansible and executing the following ansible task:
- name: Create symbolic links
file:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ jboss_usr }}"
group: "{{ jboss_grp }}"
state: link
with_items:
- { src: "/apps/etc/jboss", dest: "/etc/jboss" }
- { src: "/apps/var/log/jboss", dest: "/var/log/jboss" }
And I got the following error:
2018-12-21 21:27:23,469 p=15185 u=ex_sam | failed: [hostname.x] (item={u'dest': u'/etc/jboss', u'src': u'/apps/etc/jboss'}) => {
"changed": false,
"invocation": {
"module_args": {
"attributes": null,
"backup": null,
"content": null,
"delimiter": null,
"dest": "/etc/jboss",
"diff_peek": null,
"directory_mode": null,
"follow": true,
"force": true,
"group": "jboss",
"mode": null,
"original_basename": null,
"owner": "jboss",
"path": "/etc/jboss",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": "/apps/etc/jboss",
"state": "link",
"unsafe_writes": null,
"validate": null
}
},
"item": {
"dest": "/etc/jboss-as",
"src": "/apps/etc/jboss"
},
"msg": "Error while linking: [Errno 13] Permission denied",
"path": "/etc/jboss-as",
"state": "absent"
}
I am trying to find out why the symbolic link creation failed.
I read the following:
https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#id6
I says the "changed" attribute is a boolean indicating if the task had to make changes.
But, there are lots of null parameters in the invocation:module_args elements of the json
Does that mean the values are really “null” or they are being set to a default value?
I have looked into the ansible documentation and I am not sure if the invocation:module_args null values are representative of the outcome of the trying to create the symbolic link i.e. are the null input or output of executing the tasks.
I think some of the nulls are defaults, but will appreciate some helpful comments on the possible relation between the json returned in my ansible error log and the actual "Error while linking: [Errno 13] Permission denied".
Thanks all for you anticipated help.

I think, is the permissions on /etc. So probably you need to add the option:
become: true
To your task.

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.

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

Is there a way to capture the failure output of lineinfile in Ansible

I have a playbook with lineinfile. I need to capture the failure.
When I use register the failed ones of lineinfile are not being capture also the success one does not have enough information like a general register values. (Eg. there is no rc code, stdout or anything)
I need to capture the hosts on which the lineinfile task failed.
Please let me know if there is any method to achieve the requirement.
lineinfile:
path: /test
regexp: "^host"
line: "host myhost 127.0.0.1"
state: present
register: result
I am trying capture this message that is displayed in the verbose but unable to capture it with a register so that I can use the when condition and say when rc == 257 it is to be marked as failed.
fatal: [examplehost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"attributes": null,
"backrefs": false,
"backup": true,
"content": null,
"create": false,
"delimiter": null,
"directory_mode": null,
"firstmatch": false,
"follow": false,
"force": null,
"group": null,
"insertafter": null,
"insertbefore": null,
"line": "HOST example.something 127.0.0.1",
"mode": null,
"owner": null,
"path": "/test/my",
"regexp": "^HOST",
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "present",
"unsafe_writes": null,
"validate": null
}
},
"msg": "Destination /test/my does not exist !",
"rc": 257
I don't understand your complaint; lineinfile: is going to ensure that line appears in the target file, and will only use the regexp: bit to assist it in placing the line. If the file does not have a line that starts with host, then lineinfile: will just append the line: to the bottom of the file, and cheerfully report that it did so in result.msg:
changed: [host0] => {"backup": "", "changed": true, "msg": "line added"}
changed: [host1] => {"backup": "", "changed": true, "msg": "line replaced"}

Removing files except for some in ansible [duplicate]

This question already has answers here:
How to use Ansible's with_item with a variable?
(2 answers)
Closed 5 years ago.
I have the following files in my tmp directory
root#ansible:/tmp/test$ ls /tmp/test/
file1 file2 file3
I also have the following playbook which is modeled after this
vars:
exclude_files: file1
tasks:
- name: check files
shell: ls -l /tmp/test
register: capture
- name: remove files
file: path=/tmp/test/{{item}} state=absent
with_items: capture.stdout_lines
when: item not in exclude_files
- name: debug variable
debug: msg={{exclude_files}}
Unfortunately the second task isn't removing file2,file3. Instead it's treating the registered variable as a file.
ok: [172.16.2.3] => (item=capture.stdout_lines) => {
"changed": false,
"invocation": {
"module_args": {
"attributes": null,
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": null,
"mode": null,
"original_basename": null,
"owner": null,
"path": "/tmp/test/capture.stdout_lines",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "absent",
"unsafe_writes": null,
"validate": null
}
},
"item": "capture.stdout_lines",
"path": "/tmp/test/capture.stdout_lines",
"state": "absent"
Any idea why this code isn't working? I am using ansible 2.3.
with_items: capture.stdout_lines should be with_items: "{{capture.stdout_lines}}"
Bare variables in with_... are deprecated long ago.

How to create a directory with particular SE Linux context on it

Here is what I have:
- name: Create directories that will be used as persistent volumes
become: yes
become_method: sudo
file:
path: /tmp/pv-{{ item }}
state: directory
mode: "g=rwx"
group: "root"
selevel: _default
seuser: _default
serole: _default
setype: svirt_sandbox_file_t
with_items:
- cassandra
- services
The two directories are correctly created, group a rights are ok. But the SE Linux context is wrong.
$ ll -dZ /tmp/pv-cassandra
drwxrwxr-x. 2 jkremser root unconfined_u:object_r:user_tmp_t:s0 40 Mar 9 15:19 /tmp/pv-cassandra
This is the part of the debugging output:
ok: [localhost] => (item=cassandra) => {
"changed": false,
"diff": {
"after": {
"path": "/tmp/pv-cassandra"
},
"before": {
"path": "/tmp/pv-cassandra"
}
},
"gid": 0,
"group": "root",
"invocation": {
"module_args": {
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": "root",
"mode": "g=rwx",
"original_basename": null,
"owner": null,
"path": "/tmp/pv-cassandra",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": "_default",
"serole": "_default",
"setype": "svirt_sandbox_file_t",
"seuser": "_default",
"src": null,
"state": "directory",
"unsafe_writes": null,
"validate": null
},
"module_name": "file"
},
"item": "cassandra",
"mode": "0775",
"owner": "root",
"path": "/tmp/pv-cassandra",
"size": 80,
"state": "directory",
"uid": 0
}
What am I doing wrong? My OS is Fedora 25.
If I use the copy module, instead of the file, that has almost the same parameters, it throws this error:
Aborting, target uses selinux but python bindings (libselinux-python) aren't installed
After installing the libselinux-python package, it works! So it looks like the file module silently swallows the error and does what it can do :( I can't depend on the fact that user has the libselinux-python package installed.
I'll probably call the chcon myself as a shell command or add the package as a prerequisite:
- name: Install the libselinux-python package
package:
name: libselinux-python
state: present

Resources