Ansible vars_prompt for roles - ansible

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

Related

set ansible_user for specific task in role

I am stumbling over setting the ansible_user (or remote_user) for a specific task in a role.
What works fine is to set the ansible_user in host or group vars and the role and tasks are using this user for ssh into the server.
What I want to achieve is to set an remote user for a specific task in a role.
So I have a main.yml where different tasks are included.
For one if them I want to set the ansible_user: user2
But I tried different variants, every time I execute the play with this role the ansible_user, defined in group or host vars will be used:
- name: "include user_create.yml"
include_tasks:
file: "user_create.yml"
apply:
become: yes
remote_user: user2
vars:
- become: yes
- remote_user: user2
- ansible_user: user2
tags:
- user_create
I tried almost all variants of the above settings but no luck.
Does anyone has an idea?
UPDATE:
This should work according to Zeitounator but did not work for me either:
- name: "include user_create.yml"
include_tasks:
file: "user_create.yml"
apply:
ansible_user: user2
tags:
- user_create
UPDATE2:
So i was able to set a different user to a task like this:
- name: "include user_create.yml"
include_tasks:
file: "user_create.yml"
#apply:
# become: yes
vars:
ansible_user: user2
tags:
- user_create
but only if there is no ansibl_user defined in all.yml.
So from my understanding a block or task var should overwrite a group var (all.yml is a group var from my understanding).
remote_user is a play level stanza. The variable to use elsewhere is ansible_user. I suspect what you want exactly is:
- name: "include user_create.yml"
include_tasks:
file: "user_create.yml"
apply:
become: yes
ansible_user: user2
tags:
- user_create
tags:
- always

How to Execute Role Inside the Ansible Blocks

I have written a ansible playbook which do a deployment on the remote machines
- name: Deployment part of the script
vars:
hostName:
build_num:
hosts: "{{hostName}}"
become: true
serial: 1
tasks: this does deployment
after this I want to execute the util which is on localhost from where this playbook will be executed.
Now I have written a roles which does this for me if I execute them separately as a playbook
- name: Roles Demo
hosts: 127.0.0.1
connection: local
vars:
var1: "sometextvalue"
var2: "sometextvalue"
var3: "someurl"
roles:
- demorole #role which I created
Now I want to integrate the role in my main playbook mentioned at the top but I am getting
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
although its the same snippet which is working fine when run individually
Also I wanted to execute this using "Ansible blocks" like when a certain condition is matched execute a certain role but for that also I am getting the same above error just to summarize what I want to achieve using the blocks is as below
- name: Deployment part of the script
vars:
hostName:
build_num:
hosts: "{{hostName}}"
become: true
serial: 1
tasks: this does deployment complete
- name: Task for Doing some check
hosts: 127.0.0.1
connection: local
vars:
var1: "dakdkadadakdhkahdkahkdh
var2: "jdjaldjlaj"
var3: "djasjdlajdlajdljadljaldjlaj"
block:
- name: Doing Check for some1
roles:
- role1
when: x == "somevalue1"
- block:
- name: Doing check for some2
roles:
- role2
when: x == "somevalue2"
.
.
.
assuming the vars value are same
so I am not sure if this could be achieved
Using a block outside of the tasks section is not valid.
You can however execute roles from within the tasks section, which will allow you to use blocks and when conditionals however you choose.
Example:
- name: Task for Doing some check
hosts: 127.0.0.1
connection: local
vars:
var1: "dakdkadadakdhkahdkahkdh
var2: "jdjaldjlaj"
var3: "djasjdlajdlajdljadljaldjlaj"
tasks:
- name: Doing Check for some1
import_role:
name: role1
when: x == "somevalue1"
You will need to decide whether to use import_role or include_role. Take a look at https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse.html#dynamic-vs-static for an explanation of the differences.

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

Why does Ansible pre-task always skip?

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 == ""

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