I have a playbook which creates a virtual machine in vCenter. During creation the VM mounts iso image and installs OS automatically. After installation VM gets its IP address. I want to continue running playbook, but using the IP.
I read about wait_for, but I don't understand how to use it. Or maybe there is another way do it?
Playbook below:
- hosts: localhost
gather_facts: false
connection: local
user: ansible
become: true
vars_files:
- ../roles/vm-create/vars/default.yml
vars_prompt:
- name: "name_VM"
prompt: "VM name:"
private: no
default: "vm001"
- name: "vcenter_user"
prompt: "vCenter user"
private: no
default: "root"
- name: "vcenter_pass"
prompt: "Enter password vCenter"
private: yes
roles:
- vm-create
# waiting for the installation and gets ip (Do-Until Loops or wait_for)
- name: setting VM
become: true
hosts: '{{ get_ip }}'
roles:
- { role: ldap-client, tags: [ 'ldap' ] }
You don't show how you assign the get_ip variable, so I assume you can reference it. It's not straightforward, because you would have to either access it with hostvars['localhost']['get_ip]` or you should create a dynamic inventory.
Then you just need to use a very basic wait_for task, but because you want to assign a role to the machine, you need to define the task in the pre_tasks section.
Your second play should be:
- name: setting VM
become: true
hosts: '{{ get_ip }}'
pre_tasks:
- name: Ensure machine at {{ get_ip }} SSH port is listening
wait_for:
host: "{{ get_ip }}"
port: 22 # SSH port
delay: 60 # wait 1 minute before trying
roles:
- { role: ldap-client, tags: [ 'ldap' ] }
Related
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"
I have this simple playbook named delete.yml
- hosts: all
become: false
tasks:
- pause:
prompt: "Are you sure you want to delete \" EVERYTHING \"? Please confirm with \"yes\". Abort with \"no\" or Ctrl+c and then \"a\""
register: confirm_delete
- set_fact:
confirm_delete_fact: "{{ confirm_delete.user_input | bool }}"
- hosts: all
become: false
roles:
- {role: destroy when: confirm_delete_fact }
my inventory is
[my_group]
192.168.10.10
192.168.10.11
192.168.10.12
so I run the playbook with
ansible-playbook delete.yml -i inventoryfile -l my_group
Everything works but only for one host, the others in my_group are skipped because of the conditional check
What is wrong?
you could try that:
- hosts: all
become: false
tasks:
- pause:
prompt: "Are you sure you want to delete \" EVERYTHING \"? Please confirm with \"yes\". Abort with \"no\" or Ctrl+c and then \"a\""
register: confirm_delete
- name: Register dummy host with variable
add_host:
name: "DUMMY_HOST"
confirm_delete_fact: "{{ confirm_delete.user_input | bool }}"
- hosts: all
become: false
vars:
confirm_delete_fact: "{{ hostvars['DUMMY_HOST']['confirm_delete_fact'] }}"
roles:
- {role: destroy when: confirm_delete_fact }
if you dont want error on DUMMY_HOST (try to connect ssh), just do
- hosts: all,!DUMMY_HOST
explanations:
if you put your prompt in task, it will be used one time and belongs to hostvars of the first host, so i create a new dummy host and pass variable to other playbook.
you could avoid that:
by putting the prompt over the tasks and testing the variable hostvars:
- hosts: all
become: false
vars_prompt:
- name: confirm_delete
prompt: "Are you sure you want to delete \" EVERYTHING \"? Please confirm with \"yes\". Abort with \"no\" or Ctrl+c and then \"a\""
private: no
default: no
tasks:
- set_fact:
confirm_delete_fact: "{{ confirm_delete | bool }}"
- hosts: all
become: false
roles:
- {role: destroy when: hostvars[inventory_hostname]['confirm_delete_fact'] }
you could use the second solution because, you have the same hosts in both playbook. If different, i suggest you to use the first solution.
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"
}
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.
I want to set variables and use them as parameters later on. This is the code I have
---
- hosts: localhost
connection: local
vars:
vcenter_hostname: hellothere.hey.com
user: root
pass: ohheytherehowareyou
vars_prompt:
- name: 'vm_task_action'
prompt: 'Enter vm action to execute (none, delete)'
default: 'none'
private: no
- name: 'guest_vm'
prompt: "Enter the guest vm you want to delete"
default: 'none'
private: no
when: vm_task_action == "delete"
tasks:
- name: deleting VMs
vsphere_guest:
vcenter_hostname: vcenter_hostname
username: user
password: pass
guest: "{{ guest_vm }}"
state: absent
force: yes
when: vm_task_action == 'delete'
What is wrong with this code and how do I fix it. Any help would be greatly appreciated.
The Error says for itself:
'pass' is not a valid variable name
pass is a special keyword, so it can't be used as variable.
Use mypass: ohheytherehowareyou, for example.
P.S. also note that when: can't be used in vars_prompt section.