File permissions unset or incorrect - ansible

I am using ansible copy module to copy a file. The linter tells me "File permissions unset or incorrect" and I don't understand the problem.
Here is the ansible task
- name: Ensure some.txt is there
copy:
src: some.txt
dest: "{{ some_path }}/some.txt"
force: false
mode: '644'
Where some.txt is a file that exists in the ansible/files directory.
I have also tried with mode: 0644 but no luck.
My ansible version:
$ ansible-lint --version
ansible-lint 5.0.7 using ansible 2.10.8
Restarting the editor fixed it, but that's not really an answer.
Any ideas?

risky-file-permissions
File permissions unset or incorrect
Missing or unsupported mode parameter can cause unexpected file permissions based on version of Ansible being used. Be explicit, like mode: 0644 to avoid hitting this rule. Special preserve value is accepted only by copy, template modules. See https://github.com/ansible/ansible/issues/71200
Reference: https://ansible-lint.readthedocs.io/en/latest/default_rules.html
If you're using some module who requires the usage of mode... Set the mode and the error will vanish.

You just need to specify mode: 0644 in your playbook and it will be all good.

Related

Head first program - ansible

I have installed ansible using following commands.
sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt install ansible
After i followed this Link. By using that i created a yml file called test.yml ( the code is shown below)
- name: test my new module
hosts: 127.0.1
tasks:
- name: run the new module
my_test:
name: 'hello'
new: true
register: testout
- name: dump test output
debug:
msg: '{{ testout }}'
Then i run ansible-playbook ./test.yml . I get following error.
I have no idea where i missed. Any idea is appreciated. Thank you so much.
sato:~/play_around_with_ansible$ ansible-playbook ./test.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note
that the implicit localhost does not match 'all'
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to be in '/home/ven/play_around_with_ansible/test.yml': line 4, column 5, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: run the new module
^ here
You are missing the inventory file. Create inventory file in current folder or in the directory of your choice and provide the inventory file path to the ansible-playbook command as below or you can mention the default location of your host file in ansible.cfg
inventory file contents (sample)
[127.0.1]
localhost ansible_connection=local
command
ansible-playbook -i inventory ./test.yml
In the above command inventory is the file name with path.
seems your 'yaml' file was not able to recognize the path for custom module. Even I am new to custom module development. As per the standards you should keep the .py file in "library" directory and create the .ymal file outside of library directory.
This will help your yaml file to look into ./library directory for modules.

How to get ansible to update PATH

is there a way to do:
export PATH=$PATH:/new/path/to/bin
in Ansible, if possible without using shell or command.
I've tried this
- name: Add another bin dir to system-wide $PATH.
copy:
dest: /etc/profile.d/custom-path.sh
content: 'PATH=$PATH:{{ my_custom_path_var }}'
That I got from:
https://www.jeffgeerling.com/comment/reply/2799
But it doesn't work as PATH results in:
\$PATH:/new/path/to/bin
Breaking the system's PATH.
Thanks!
Using shell or command would be:
- name: Add pm2 to PATH
shell: echo "PATH=$PATH:/new/path/to/bin" > /etc/environment
become: true
But I'd still prefer an option that doesn't use shell/command.
Solution without using shell module
instead of
content: 'PATH=$PATH:{{ my_custom_path_var }}'
Use
content: 'export PATH=$PATH:{{ my_custom_path_var }}'

Ansible: Copy contents of a directory to a location

I'm willing to transfer the contents of a folder unzipped from a source say myfolder to a location say dest_dir but apparently everything I try moves/copies/generates myfolder in the dest_dir location.
I tried
command: mv src dest_dir
I also tried unarchiving in the dest_dir location using,
unarchive:
src: /path/to/myfolder
dest: dest_dir
copy: no
become: yes
Apparently, for copy module, I found that remote_src does not support recursive copying yet.
What is the correct way to go about this?
Normally, in my system, I would do mv /path/to/myfolder/* dest_dir but wildcards throw an error with Ansible.
I'm using Ansible 2.3.2.
The reason you can't do it easily in Ansible is because Ansible was not designed to do it.
Just execute the command directly with shell module. Your requirement is not idempotent anyway:
- shell: mv /path/to/myfolder/* dest_dir
become: yes
Pay attention to mv defaults, you might want to add -f to prevent it from prompting for confirmation.
Otherwise play with synchronize module, but there's no value added for "move" operation. Just complexity.

Ansible copy module requires writable parent directory?

Need to set /proc/sys/net/ipv4/conf/all/forwarding to 1
That's can be easily done via command
- name: Enable IPv4 traffic forwarding
command: echo 1 > /proc/sys/net/ipv4/conf/all/forwarding
But that's bad practice - it will be always "changed" task.
So I tried the following:
- name: Enable IPv4 traffic forwarding
copy: content=1 dest="/proc/sys/net/ipv4/conf/all/forwarding" force=yes
Which failed with msg: "Destination /proc/sys/net/ipv4/conf/all not writable"
According to sources seems like copy always requires parent directory will be writable. But 1) I don't understand why 2) Any other "idiomatic" way to set destination file to required value?
While I still do not understand why copy needs to check parent directory permissions, thanks to #larsks:
sysctl module changes both sysctl.conf and /proc values
and this solves my task
- name: Enable IPv4 traffic forwarding
copy: content=1 dest="/proc/sys/net/ipv4/conf/all/forwarding" unsafe_writes=true
will disable Ansible's atomic write functionality, and instead write 1 to the file directly.
Atomic writes are good and useful because they mean you will never get a corrupted file that has the output of multiple processes interleaved, but /proc is a special magic thing. The classic Unix dance of writing to a temporary file until you're done, and then renaming it to the final filename you want breaks because /proc doesn't let you create random temporary files.
I found a workaround for this problem:
- name: Create temp copy of mongod.conf
copy:
src : /etc/mongod.conf
dest: /tmp/mongod.conf
remote_src: yes
diff: no
check_mode: no
changed_when: false
- name: Copy config file mongod.conf
copy:
src : "/source/of/your/mongod.conf"
dest: "/tmp/mongod.conf"
register: result
- name: Copy temp mongod.conf to /etc/mongod.conf
shell: "cp --force /tmp/mongod.conf /etc/mongod.conf"
when: result.changed == true

Permission change based on file extension using ansible

I want to change the permission of the file based on it's extension using ansible, for example I have directory test and within this directory I have a lot of shell script(.sh) and python(.py) files. I want to change the permission of shell script to 0700 and python files to 0644. Can you please help me that how I can achieve this. Thanks
There are many ways to do this. This should work. Tweak it to your needs.
- file: path={{item}} mode=0644
with_fileglob:
- <full_path>/*.py
- file: path={{item}} mode=0700
with_fileglob:
- <full_path>/*.sh
If the files are on remote, do this:
- shell: ls /test/*.py
register: py_files
- file: path={{item}} mode=0644
with_items: py_files.stdout_lines

Resources