template task: write to root owned directory - ansible

I want to copy a template generated file to /etc/init.d folder. But template task doesn't seem to support sudo parameter.
What is the recommended way to handle this? should I copy it to temporary directory and then move file with with sudo?
The playbook task looks like as shown below. Ansible version 1.8.2
- name: copy init script
template: src=template/optimus_api_service.sh dest=/etc/init.d/optimus-api mode=0755 force=yes owner=root group=root

I have tested the following playbook and it works.
My setup:
The User vagrant on the machine vm is allowed to execute commands password-free with sudo.
I created a simple template and installed it with the following playbook:
---
- name: Test template
hosts: vm
gather_facts: no
remote_user: vagrant
vars:
bla: blub # some variable used in the template
tasks:
- name: copy init script
sudo: yes # << you have to activate sudo
sudo_user: root # << and provide the user
template: src=template/test.j2 dest=/opt/test mode=0755 force=yes owner=root group=root

Related

Creating a directory with Ansible results in file ownership change in /usr/lib/python3.7

Using Ubuntu 19.04 and Python 3.7
When I create a directory with Ansible, file ownership is changed in /usr/lib/python3.7
Obviously this should not happen and it breaks Python for the whole of Ubuntu, until the permissions are corrected.
The problem only happens when recurse=yes is used.
Here is a video showing the problem:
https://youtu.be/d3hj255pW9w
Here is the code/Ansible playbook:
ubuntu#ubuntu-GB-BXi3-5010:~/ansible$ cat ~/ansible/renderworker/ffmpegconverter/ansible/test.yml
---
- hosts: renderworkerhosts
become: yes
tasks:
# for some reason, recurse=yes results in owner & permissions changing in /usr/lib/python3.7
# which breaks Python on Ubuntu
- name: Create directory
file:
path=/opt/ffmpegconverter
state=directory
owner=root
group=ffmpeguser
mode=u=rwx,g=rwx,o=
recurse=yes
ubuntu#ubuntu-GB-BXi3-5010:~/ansible$
You should use a colon instead of the equal sign for delimiter between keys and values:
path: /etc/foo.conf

Ansible role with shared python virtual environment

I have ansible role which have task delegated to localhost:
- name: Test role
hosts: my_hosts
gather_facts: no
tasks:
- name: Register remote hosts
include_role: name=register_remote_hosts
delegate_to: localhost
The Role register_remote_systems must work for every host in my_hosts, but must be ran from the box where Ansible is invoked, that is why there is delegate_to.
The role register_remote_hosts checks for a specific application on localhost and if one is not installed it creates virtual environment and then installs it:
- name: Check if my_app is installed system-wide
shell: |
my_app --version >/dev/null 2>&1
register: my_app_cmd
failed_when: my_app_cmd.rc not in [0, 127]
- name: Install My App
block:
- name: Create temporary directory for my_app
tempfile:
state: directory
suffix: my_app
register: my_app_temp
- name: Create virtual environment
command: virtualenv "{{ my_app_temp.path }}"
- name: Install my_app
pip:
name: my_app
state: latest
virtualenv: "{{ my_app_temp.path }}"
virtualenv_site_packages: yes
- name: Set Virtual Environment variable
set_fact:
venv_activate: "source {{ my_app_temp.path }}/bin/activate"
when: my_app_cmd.rc != 0
- name: Use my_app
shell: |
{{ venv_activate | default('echo "Using my_app from system path"') }}
my_app --version
Everything works great, but if there are many hosts in my_hosts then a lot of venvs are being created.
What would be the best approach to create role which is reusing same venv with my_app installed. Note that role is included in many different playbooks and I do not want to write additional role included in every playbook where "Register remote hosts" included role is used. There is of course concurrency problem of creating venv prior to using that in other playbooks.
Above solution works and I can live with it, but maybe there are nicer design patterns for such problems in Ansible.
Solution is to put run_once (thanks #ssbarnea):
when: my_app_cmd.rc != 0
run_once: yes

Ansible: editing a config file as sudo (CoreOS)

I'm an ansible newbie.
I'm using ansible 2.3.0.0
I have the playbook below to bootstrap nodes for a k8s cluster in openstack:
- name: bootstrap
hosts: coreos
become_user: root
become_method: su
gather_facts: False
roles:
- defunctzombie.coreos-bootstrap
tasks:
- lineinfile:
path: /etc/coreos/update.conf
state: present
regexp: '^REBOOT_STRATEGY'
line: 'REBOOT_STRATEGY=off'
I want to turn off auto-reboots on coreos because our openstack installation has a problem with reboots not coming back up properly and having coreos reboot often is causing instance to have to be manually shut down and restarted.
Anyway, the playbook above doesn't work. I get this error:
"The destination directory (/etc/coreos) is not writable by the current user. Error was: [Errno 13] Permission denied: '/etc/coreos/.ansible_tmppQCJrCupdate.conf'"
So my syntax is wrong (I've tried a few different combinations with no luck).
Could someone point me in the right direction? And feel free to make a suggestion on anything about this playbook.
Thanks!
Instead of execute playbook as root user, use different user with sudo access.
Please try this:
- name: bootstrap
hosts: coreos
user: <user_name>
become_method: sudo
gather_facts: False
roles:
- defunctzombie.coreos-bootstrap
tasks:
- lineinfile:
path: /etc/coreos/update.conf
state: present
regexp: '^REBOOT_STRATEGY'
line: 'REBOOT_STRATEGY=off'
Replace <user_name> with your user.
Run your playbook as ansible-playbook <playbook_name> --ask-sudo-pass

How to delete local directory with ansible

I have to make delete some directory and create them on local before copy to the remote. Is there anyway to delete and create locally?
Currently I'm using 'command'
command: rm -r directory
But warning shows as
Consider using file module with state=absent rather than running rm
Is there any options we can use for local folder changes?
You can use diffrent delegation methods or use the local_action:
- local_action: file path=directory state=absent
If you're running this in a playbook, you can use a section of the playbook that uses a local connection to make changes on the command machine, then copies files to the remote:
---
- hosts: 127.0.0.1
connection: local
tasks:
- name: Delete local directory
file: path=/directory state=absent
- hosts: myhosts
tasks:
copy: src=/directory dest=/foo/directory
Update:
Current Ansible (2.10) does not like - local_action: , instead use delegate_to:
- name: Remove directory 'dir1'
file:
path: "path/to/dir1"
state: absent
delegate_to: localhost

how to define login user and become root in playbook

my loginuser is user1 and i want to execute the playbook with root. how can i do this. if i use in cmdline it does not work like this
ansible-playbook main.yaml -i hosts --user=git -k --become-user=root --ask-become-pass --become-method=su
Please tell me how to implement this.
name: Install and Configure IEM
hosts: rhel
ansible_become: yes
ansible_become_method: su
ansible_become_user: root
ansible_become_pass: passw0rd
tasks:
- name: Creating masthead file path
file: path=/etc/opt/BESClient state=directory
- name: Creating install directory
I use :
deploy.yml
- name: Todo something
hosts: all
become: yes
become_user: root
become_method: su
When you execute the playbook pass the password as an extra var.
--extra-vars='ansible_become_pass=password'
From Ansible docs:
you can set those in the playbook as #Raul-Hugo, with become_user and become_user;
alternatively, it can also be done in the inventory, which allows setting per host or group. But then the variables get "ansible_" prefix: ansible_become_user, ansible_become_user, etc. That's why the playbook you gave in your question did not work: it used variable names that are used in the inventory.
You can become root like below and install the packages
tasks:
- name: install apache package
become: yes
become_user: root
yum:
name: httpd
state: present
- name: ensure apache is running
become: yes
become_user: root
service:
name: httpd
state: started
All the above answers caused Ansible to try to login as root from the beginning. but in this case, the user you request is git so the below example worked for me:
- name: Install and Configure IEM
hosts: rhel
tasks:
- name: Creating masthead file path
file: path=/etc/opt/BESClient state=directory
remote_user: git
become: yes # when not specifying `become_user` it's "root"
This will cause it to login as git and after the login - switch to root

Resources