not able call more than one roles by using include_role - ansible

needed help to see what is wrong with this include_role.
This work without any problem:
#US East (N. Virginia)
- hosts: localhost
gather_facts: false
connection: local
vars:
region_services:
- "us-east-1"
tasks:
- name: 3 run - should loop and print dynamic var
include_role: name=nginx
when: aws_region_name == "us-east-1"
with_items:
- "{{ region_services }}"
This doesn't work by calling any extra roles:
#US East (N. Virginia)
- hosts: localhost
gather_facts: false
connection: local
vars:
region_services:
- "us-east-1"
tasks:
- name: 3 run - should loop and print dynamic var
include_role: name=nginx
- name: 4 run - should loop and print dynamic var
include_role: name=nginx
when: aws_region_name == "us-east-1"
with_items:
- "{{ region_services }}"
error I get like this
'item' is undefined\n\nThe error appears to have been in

You can also include roles in your playbook like this.
# US East (N. Virginia)
- hosts: localhost
gather_facts: false
connection: local
vars:
region_services:
- "us-east-1"
roles:
- {role: ../roles/nginx}
- {role: ../roles/other}
...

Related

Ansible vars_prompt for host list into Import_playbook

I want to use a specific host / host list for an imported playbook which I get from a vars_prompt input. How can I do this? So far I wasn´t able to get this running.
I have two playbooks which I need to run separately and ios_check_routerports.yaml is the parent playbook:
ios_check_routerports.yaml
---
- hosts: '{{ branch_number }}'
connection: network_cli
gather_facts: False
any_errors_fatal: no
throttle: 75
vars_prompt:
- name: "branch_number"
prompt: "Which branch do you want to check?"
default: all
private: no
tasks:
- name: Check facts
ios_facts:
gather_subset: hardware
- name: Create directory
file:
path: /root/ansible/pb-outputs/ios_check_routerports/
state: directory
delegate_to: 127.0.0.1
- name: Run playbook
import_playbook: ios_check_routerports_main.yaml
ios_check_routerports_main.yaml
---
- hosts: '{{ branch_number }}'
connection: network_cli
gather_facts: False
any_errors_fatal: no
throttle: 75
tasks:
- name: Check default-gateway
ios_command:
commands: sh run | i default-gateway
register: default_gateway
I tried to set a fact for the var {{ branch_number }} like this:
ios_check_routerports.yaml
- set_fact:
devices: "{{ branch_number }}"
ios_check_routerports_main.yaml
---
- hosts: '{{ devices }}'
connection: network_cli
The playbook always runs into an error because the hosts var is not defined. What am I doing wrong here?
try this: no need to create a new variable devices but a dummy host
in ios_check_routerports.yaml add a task:
- name: Register dummy host with variable
add_host:
name: "DUMMY_HOST"
DEVICES: "{{ branch_number }}"
then :
- hosts: "{{ hostvars['DUMMY_HOST']['DEVICES'] }}"
connection: network_cli
as you create a new host, i suggest you to delete it if you havent need the variable branch_number so remove_host doesnt exit:
either you do a first task - meta: refresh_inventory
or you modify your host like this:
- hosts: "{{ hostvars['DUMMY_HOST']['DEVICES'] }},!DUMMY_HOST"

How to use variables defined through vars_prompt of one host in another host vars?

I am having 2 plays in a playbook. One of them prompts for input from user and I want to use that variable in another play. Please suggest me how to do that
---
- hosts: workers
gather_facts: false
sudo: true
vars_prompt:
- name: "server_ip"
prompt: "Enter the Server IP"
private: no
roles:
- client-setup-worker
- hosts: master
gather_facts: false
sudo: true
vars:
server: "{{ hostvars['workers']['server_ip'] }}"
roles:
- client-setup-master
In the above playbook I want to use server_ip defined in workers hosts to be used in master hosts.
I am facing the error "The error was: \"hostvars['workers']\" is undefined" while doing so
I am facing the error "The error was: \"hostvars['workers']\" is undefined" while doing so
That's because workers is evidently a group, and not a host, which is the only thing one will find declared in hostvars
You'll need to grab one of the hosts at random from the workers group, and then extract its fact; I believe this will do that:
update after seeing the mostly correct answer by #VladimirBotka
- hosts: workers
vars_prompt:
# as before ...
pre_tasks:
- name: re-export the vars_prompt for cross playbook visibility
set_fact:
server_ip: '{{ server_ip }}'
roles:
# as before
- hosts: masters
vars:
server: '{{ hostvars[(groups.workers|first)].server_ip }}'
The scope of variables declared in vars_prompt is the play.
Such variable may be put into the hostvars by set_facts "to use that variable in another play". For example the play below
- hosts: test_01
gather_facts: false
vars_prompt:
- name: "server_ip"
prompt: "Enter the Server IP"
private: no
tasks:
- set_fact:
stored_server_ip: "{{ server_ip }}"
- debug:
var: stored_server_ip
- hosts: test_02
gather_facts: false
vars:
server: "{{ hostvars.test_01.stored_server_ip }}"
tasks:
- debug:
var: server
gives (abridged):
ok: [test_01] => {
"stored_server_ip": "10.1.0.10"
}
ok: [test_02] => {
"server": "10.1.0.10"
}

ansible does not read in variables when connected to another host

I have a playbook which reads in a list of variables:
vars_files:
- vars/myvariables.yml
tasks:
- name: Debug Variable List
debug:
msg: "An item: {{item}}"
with_list: "{{ myvariables }}"
This prints out the list of "myvariables" from a file variables.yml, which contains:
---
myvariables:
- variable1
- variable2
I get the following as expected.
"msg": "An item: variable1"
"msg": "An item: variable2"
However, when I connect to another host, and run the same Debug statement, it throws an error:
vars_files:
- vars/myvariables.yml
tasks:
- name: Configure instance(s)
hosts: launched
become: True
remote_user: ubuntu
port: 22
gather_facts: False
tasks:
- name: Wait for SSH to come up
delegate_to: ***
remote_user: ubuntu
connection: ssh
register: item
- name: Debug Variable List
debug:
msg: "An item: {{item}}"
with_list: "{{ myvariables }}"
OUTPUT:
"msg": "'myvariables' is undefined"
How do I define the variables file when connecting to another host that is not localhost?
Any help on this would be greatly appreciated.
With "hosts: launched" you started new playbook. Put the vars_files: into the scope of this playbook (see below).
- name: Configure instance(s)
hosts: launched
become: True
remote_user: ubuntu
port: 22
gather_facts: False
vars_files:
- vars/myvariables.yml
tasks:
Review the Scoping variables.

Ansible-Execute a last mandatory role in the playbook even though any previous roles in the execution flow fails

I have ansible playbook something like this
---
- hosts: localhost
connection: local
tasks:
- set_fact:
build_date_time: "{{ ansible_date_time }}"
- hosts: localhost
connection: local
gather_facts: false
vars:
role: Appvariables
base_image_tag: Base
roles:
- role: begin-building-ami
- hosts: just_created
remote_user: "{{ default_user }}"
vars:
role: AppName
roles:
- { role: role1, become: yes }
- role: role2
- { role: role3, become: yes }
- { role: role4, become: yes }
- { role: role5, become: yes }
- hosts: localhost
connection: local
gather_facts: false
vars:
role: Appname
ansible_date_time: "{{ build_date_time }}"
roles:
- finish-building-ami
Here in this case we have a situation to execute the finish-building-ami role where we terminate the instance after baking the ami. If any reason any of the previous role1-role5 fails in the flow fails It stops the playbook and we have the failed instance which we needed to terminate automatically.Right now we are going and terminating it manually if it fails.
So needed to run finish-building-ami(mandatory role where we stop the instance and take ami and terminate the instance at last ) if even any of the role1-role5 fails in the above mentioned playbook.
You can rewrite your existing play to use import_role or include_role tasks instead of the roles section. This allows you to use blocks:
---
- hosts: localhost
gather_facts: false
tasks:
- block:
- import_role:
name: role1
- import_role:
name: role2
become: true
- import_role:
name: role3
rescue:
- set_fact:
role_failed: true
- hosts: localhost
gather_facts: false
tasks:
- debug:
msg: This task runs after our roles.

Ansible Five random hosts from /etc/ansible/hosts

I have this playbook, it work using max_index but always takes the first 3 hosts from /etc/ansible/hosts , i need to take 3 random (and not repeated) hosts from that file.
playbook.yml
---
- hosts: ciscos
connection: local
gather_facts: false
tasks:
- group_by: key=limited_selection
when: play_hosts.index(inventory_hostname) < max_index | int
- hosts: limited_selection
gather_facts: no
/etc/ansible/hosts
[ciscos]
stagin ansible_host=10.xx.xx.1
stagin2 ansible_host=10.xx.xx.1
stagin3 ansible_host=10.xx.xx.1
stagin4 ansible_host=10.xx.xx.1
stagin5 ansible_host=10.xx.xx.1
Solution
You need to shuffle the elements of the group and choose three first. The Jinja2 expression for that is:
(groups['ciscos'] | shuffle)[0:3]
Implementation which should work, but has problems
You should be able to simply filter the group in the hosts declaration:
- hosts: "{{ (groups['ciscos'] | shuffle)[0:3] }}"
gather_facts: no
tasks:
- debug:
However the results are undeterministic - although the play shows as running against three randomly chosen hosts, the tasks are sometimes executed on 1, 2, 3, or 0:
PLAY [[u'stagin2', u'stagin4', u'stagin5']] *******************************************************************************
TASK [debug] **************************************************************************************************************
ok: [stagin2] => {
"msg": "Hello world!"
}
ok: [stagin5] => {
"msg": "Hello world!"
}
Workaround (implementation which works)
Use add_host module to create a filtered group:
- hosts: localhost
connection: local
gather_facts: no
tasks:
- add_host:
name: "{{ item }}"
groups: limited_selection
loop: "{{ (groups['ciscos'] | shuffle)[0:3] }}"
- hosts: limited_selection
gather_facts: no
tasks:
- debug:
What about something like this?
---
- hosts: ciscos
gather_facts: False
connection: local
tasks:
- name: Fact My Inventory
set_fact:
myinventory: "{{ ansible_play_batch | shuffle }}"
run_once: True
delegate_to: localhost
- name: Fact limited_selection
set_fact:
limited_selection: "{{ myinventory[0:max_index|int] }}"
run_once: True
delegate_to: localhost
- name: Create Inventory
add_host:
name: '{{ item }}'
groups: limited_selection
with_items: "{{ limited_selection }}"
delegate_to: localhost
- hosts: limited_selection
gather_facts: no
tasks:
- name: Debug
debug:
msg: "I'm in the limited selection group!"
Be careful with play_hosts as it is deprecated.
Note: I have kept the playbook with connection:ciscos instead of localhost for learning purposes and showing the ansible_play_batch and max_index variables. It is better to have a localhost play with groups instead of delegate_to:localhost

Resources