Why does Ansible pre-task always skip? - ansible

I am trying to develop a playbook which could allow root to easily reset the password by running a playbook any time. But it alwasy skips the pretask which does the validation.
---
- hosts: localhost
remote_user: root
become: yes
become_method: sudo
vars_prompt:
- name: "root_password"
prompt: "Enter your new root password"
private: no
when: root_password is not defined
pre_tasks:
- name: fail the play if the user missed out root_password
fail: msg="root password should not be empty"
when: root_password is not defined
tasks:
- name: Change root password
user: name=root update_password=always password={{ root_password }}

The task is set to run when root_password is not defined and whatever value you enter, you do define it in the vars_prompt section. Hence the task is skipped.
Judging from the message you want to fail when it's empty, so the condition should be:
when: root_password == ""

Related

import_playbook pass variable but it doesn't work in when condition

I've main yml (select.yml) which reuse machine-id.yml.
Both has prompt to ask for host ip, so I can run machine-id.yml directly and it will ask for IP.
select.yml as main script has also prompt for asking IP. But because it reuse machine-id.yml, I don't want to ask twice for IP, because in future I will add another subscript with another prompt maybe.
Problem I faced is that machine-id.yml takes dynamic_hosts value from select.yml. And it works - I can run select.yml and it will ask me for IP twice. When I put IP1 as prompt value and IP2 as second one, I see tasks are run on both hosts.
but I cannot use when: to prevent prompt in machine-id.yml. It says variable is not defined in debug. Also did not react on condition dynamic_hosts is not defined
select.yml
- hosts: localhost
gather_facts: no
vars_prompt:
- name: target_host
prompt: "[M] please enter the target host IP"
private: no
tasks:
- add_host:
name: "{{ target_host }}"
groups: dynamic_hosts
- import_playbook: machine_id.yml
machine-id.yml:
- hosts: localhost
gather_facts: no
tasks:
- debug:
var: dynamic_hosts
- name: PROMPT
block:
- name: ask host
pause:
prompt: "Please enter target IP"
register: target_host
- name: add to dynamic_hosts
add_host:
name: "{{ target_host.user_input }}"
groups: dynamic_hosts2
when: dynamic_hosts is not defined
- hosts: dynamic_hosts
vars:
ansible_python_interpreter: /usr/bin/python3
become: yes
tasks:
- name: Reset machine-id
shell: rm /etc/machine-id && rm /var/lib/dbus/machine-id && dbus-uuidgen --ensure=/etc/machine-id && dbus-uuidgen --ensure
args:
warn: no
dynamic_hosts is not a variable, it's an element in the list of groups. You can debug that if you do a debug var=groups
You have to access it via groups.dynamic_hosts.
- hosts: localhost
gather_facts: no
tasks:
- debug:
var: groups.dynamic_hosts
- name: PROMPT
block:
- name: ask host
pause:
prompt: "Please enter target IP"
register: target_host
- name: add to dynamic_hosts
add_host:
name: "{{ target_host.user_input }}"
groups: dynamic_hosts2
when: groups.dynamic_hosts is not defined

vars_prompt not working in role - Ansible

I'm trying to automate hostname creation for 10x machines using ansible roles. What I want when executing playbook, as this wait for enter the user name manually.
I tried with vars_prompt module for satisfying the requirement. But here for a single *.yml file, I'm able to see the expected results
Without role - I can see the input is taken to variable host. but this works fine.
#host.yml .
---
- hosts: ubuntu
user: test
sudo: yes
vars_prompt:
- name: host
prompt: "Specify host name?"
private: no
tasks:
- debug:
msg: ' log as {{ host }}'
- name: Changing hostname
hostname:
name: '{{ host }}'
With role, < this is not working > { vars_prompt not working }
#role.yml
---
- hosts: ubuntu
user: test
sudo: yes
roles:
# - hostname
#hostname/tasks/main.yml
- name: testing prompt
vars_prompt:
- name: host
prompt: "Specify host name?"
- name: Ansible prompt example
debug:
msg: "{{ host }}"
#Changing hostname
- name: Changing hostname
hostname:
name: "{{ host }}"
Here I'm getting error as
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/root/roles/hostname/tasks/main.yml': line 1, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: testing prompt
^ here
My expectation is to set some parameters need to set manually as input while the execution of playbook. Need to work this vars_prompt module in role.
Run 1st play with serial: 1 and enter the hostnames. 2nd play (in the same playbook) will use the facts.
- hosts: ubuntu
serial: 1
user: test
sudo: yes
tasks:
- pause:
prompt: "Specify hostname for {{ inventory_hostname }}?"
echo: yes
register: result
- set_fact:
host: "{{ result.user_input }}"
- hosts: ubuntu
user: test
sudo: yes
roles:
- hostname

Struggling to switch to root user with Ansible

I'm a beginner with Ansible, and I need to run some basic tasks on a remote server.
The procedure is as follows:
I log as some user (osadmin)
I run su - to become root
I then do the tasks I need to.
So, I wrote my playbook as follows:
---
- name: Some tasks
become: yes
become_user: root
# become_method: su // Also tried with that.
template: src=repo.j2 dest=/etc/yum.repos.d/test.repo owner=root group=root
register: copy
Also, I have the following in vars/main.yml:
ansible_user: osadmin
ansible_password: password1
ansible_become_password: password2
[ some other values ]
However, when running my tasks, Ansible / the hosts returns me the following:
"Incorrect sudo password"
While I'm sure I gave it the right password. So, I guess I'm not doing this correctly.
What would be the correct way to switch to root via su?
Thank you in advance
From your question, I see that variable values are stored in vars/main.yml. Instead have the variables inside group_vars/all.yml and uncomment # become_method: su.
Modified code
---
- name: Some tasks
become: yes
become_user: root
become_method: su // Also tried with that.
template: src=repo.j2 dest=/etc/yum.repos.d/test.repo owner=root group=root
register: copy
have variables in group_vars/all.yml
ansible_user: osadmin
ansible_password: password1
ansible_become_password: password2
[ some other values ]
I tried this and it works for me.

Ansible vars_prompt for roles

I have a set of Ansible playbooks and the main yml file is like this
- hosts: all
roles:
- common
- install_nginx
I want to add the confirm message when I trigger the playbook. I tried this and did not work
- hosts: all
vars_prompt:
- name: CONFIRM
prompt: Just to confirm you will install stuff
tasks:
- fail: no deployment this time
when: CONFIRM != 'yes'
roles:
- common
- install_nginx
How can I use vars_prompt in this case without modify every role?
If you look at the output from running your playbook with the vars_prompt you'll see that the fail task runs after the other roles. This is also mentioned in the Ansible docs for playbooks and roles:
If the play still has a ‘tasks’ section, those tasks are executed
after roles are applied.
As the above docs also mention if you want to force a task to run before any roles then you can use pre_tasks.
So to have your confirmation style prompt you could simply do this:
- hosts: all
vars_prompt:
- name: CONFIRM
prompt: Just to confirm you will install stuff
pre_tasks:
- fail: no deployment this time
when: CONFIRM != 'yes'
roles:
- common
- install_nginx
I am not very sure, but the way this works is :
- hosts: all
vars_prompt:
- name: "confirm"
prompt: Just to confirm you will install stuff
private: no
default: "no"
tasks:
- name: Install Nginx
apt: name=nginx
sudo: true
when: confirm == "yes"
Now if we need to call each role based on a condition , i suppose we shoud be using tags.
How to use Ansible vars_prompt for roles
i got the solution to use vars_prompts in ansible role section
i have directly included vars_prompt in my main.yml playbook as like before
- hosts: "{{HOSTS}}"
gather_facts: yes
become: yes
roles:
- syslog
- splunk
- nmon
- trendmicro
- user-creation
- extened-history
vars_prompt:
- name: "user_password"
prompt: "Enter User Password"
private: yes
confirm: yes
==========================================================
Below is the ansible command to execute the playbook
# ansible-playbook ort-linux.yml -e "HOSTS=TESTSERVER"
Enter User Password:
confirm Enter User Password:
========================================================
Below is my roles playbook for user id creation
---
- name: "Task-1 create Linux Team user"
user:
name: "{{item}}"
comment: LINUX_UNIX_TEAM
group: LINUX_UNIX_TEAM
shell: /bin/bash
generate_ssh_key: yes
ssh_key_bits: 2048
ssh_key_file: .ssh/id_rsa
createhome: yes
password: "{{user_password|password_hash('sha512')}}"
loop:
- sam
- jack
- kumar
- ravi
tags: linuxuser

Set remote_user for set of tasks in Ansible playbook without repeating it per task

I am creating a playbook which first creates a new username. I then want to run "moretasks.yml" as that new user that I just created. Currently, I'm setting remote_user for every task. Is there a way I can set it for the entire set of tasks once? I couldn't seem to find examples of this, nor did any of my attempts to move remote_user around help.
Below is main.yml:
---
- name: Configure Instance(s)
hosts: all
remote_user: root
gather_facts: true
tags:
- config
- configure
tasks:
- include: createuser.yml new_user=username
- include: moretasks.yml new_user=username
- include: roottasks.yml #some tasks unrelated to username.
moretasks.yml:
---
- name: Task1
copy:
src: /vagrant/FILE
dest: ~/FILE
remote_user: "{{newuser}}"
- name: Task2
copy:
src: /vagrant/FILE
dest: ~/FILE
remote_user: "{{newuser}}"
First of all you surely want to use sudo_user (remote user is the one that logs in, sudo_user is the one who executes the task).
In your case you want to execute the task as another user (the one previously created) just set:
- include: moretasks.yml
sudo: yes
sudo_user: "{{ newuser }}"
and those tasks will be executed as {{ newuser }} (Don't forget the quotes)
Remark: In most cases you should consider remote_user as a host parameter. It is the user that is allowed to login on the machine and that has sufficient rights to do things. For operational stuff you should use sudo / sudo_user
You could split this up into to separate plays? (playbooks can contain multiple plays)
---
- name: PLAY 1
hosts: all
remote_user: root
gather_facts: true
tasks:
- include: createuser.yml new_user=username
- include: roottasks.yml #some tasks unrelated to username.
- name: PLAY 2
hosts: all
remote_user: username
gather_facts: false
tasks:
- include: moretasks.yml new_user=username
There is a gotcha using separate plays: you can't use variables set with register: or set_fact: in the first play to do things in the second play (this statement is not entirely true, the variables are available in hostvars, but I recommend not using variables between roles). Defined variables like in group_vars and host_vars work just fine.
Another tip I'd like to give is to look into using roles http://docs.ansible.com/playbooks_roles.html. While it might seem more complicated at first, it's much easier to re-use them (as you seem to be doing with the "createuser.yml"). Looking at the type of things you are trying to achieve, the 'include all the things' path won't last much longer.
Kind of inline with your issue. Hope it helps. While updating my playbooks for Ansible 2.5 support for Cisco IOS network_cli connection
Credential file created with ansible-vault: auth/secrets.yml
---
creds:
username: 'ansible'
password: 'user_password'
Playbook:
---
- hosts: ios
gather_facts: yes
connection: network_cli
become: yes
become_method: enable
ignore_errors: yes
tasks:
- name: obtain login credentials
include_vars: auth/secrets.yml
- name: Set Username/ Password
set_fact:
remote_user: "{{ creds['username'] }}"
ansible_ssh_pass: "{{ creds['password'] }}"
- name: Find info for "{{ inventory_hostname }}" via ios_facts
ios_facts:
gather_subset: all
register: hardware_fact
Running playbook without auth/secrets.yml creds:
ansible-playbook -u ansible -k playbook.yml -l inventory_hostname

Resources