How to do waiting elements in playbook - ansible

i have playbook which creating vm's. Me need to waiting when will appear network. How to do it if element don't exist?
Part my playbook:
- ovirt_nics_facts:
vm: "{{ vm }}"
auth: "{{ ovirt_auth }}"
register: nics_facts
until: (ovirt_nics[0].reported_devices[0].ips[0].address is search("10.10.20.")) or
(ovirt_nics[0].reported_devices[0].ips[0].address is search("192.168.250."))
retries: 20
delay: 60
Error:
fatal: [localhost]: FAILED! => {"msg": "The conditional check 'ovirt_nics[0].reported_devices[0].ips[0].address is defined' failed. The error was: error while evaluating conditional (ovirt_nics[0].reported_devices[0].ips[0].address is defined): list object has no element 0"}

I decided trouble:
- name: add vm to temporary inventory
block:
- ovirt_nics_facts:
vm: "{{ vm }}"
auth: "{{ ovirt_auth }}"
register: nics_facts
until: ovirt_nics[0].reported_devices|length > 0
retries: 20
delay: 60

Related

Loop through the children host group ansible is failing

My inventory file is having below host groups:
[uat1]
123.11.23.22 ansible_user="xxx"
[OS_uat2]
123.45.6.7 ansible_user="yyy"
[uat1_childs:children]
uat1
OS_uat2
I am having the vars file which is having param for below hosts. I am running a playbook to run a shell command. I am passing some parameters with the playbook. I am passing deployment_environment as uat1_childs. This is giving me error. Playbook is:
- name: play to ping test
gather_facts: false
hosts: "{{ deployment_environment }}"
ignore_unreachable: yes
vars_files:
- r_params.yml
vars:
package: "{{ package }}"
tasks:
- set_fact:
env_param: "{{ deployment_environment }}"
- name: ping test
ping:
data: pong
- name: Deploy Services on "{{ deployment_environment }}"
shell: cd "{{ env_select[env_param].script_path }}"; sh "{{ env_select[env_param].script_path }}/deploy.sh" "param1" "param2" "{{ env_select[env_param].repo }}" "{{ artifact_version }}" "{{ env_select[env_param].ENV }}" "{{ arti_username }}" "{{ arti_pass }}" "{{ deployer }}" "{{ package }}" "{{ env_select[env_param].deployment_path }}"
when: (package == "abc")
with_items: "{{ groups[{{ 'deployment_environment' }}] }}"
This is giving me error as:
fatal: [123.11.23.22]: FAILED! =>
{
"msg": "'dict object' has no attribute 'deployment_environment'"
}
fatal: [123.45.6.7]: FAILED! =>
{
"msg": "'dict object' has no attribute 'deployment_environment'"
}
I tried removing apostrophe in with items, still it is giving me error. Cant identify how to run the task in all children host group.

How to stop VM and Validate that VM is stoped using Ansible?

For my Project, I need to create an Ansible script that does the following:
Shut down VM
Checks that vm are not reachable
Create messages that say what VM is still up and what vm is still down.
I wrote the following script for this:
---
# tasks file for start-stop-vm
- name: Stop all VM
community.general.shutdown:
# delay: 60
when: ('webservers' in group_names)
- name: check what vm is still up
ansible.builtin.ping:
register: result
# - name: Output result
# debug:
# var: result
- name: Return the vm that still running
debug:
msg: "Following VM are still up {{ inventory_hostname }}"
when: (result.failed == false)
- name: Return the vm that still running
debug:
msg: "Following VM are down {{ inventory_hostname }}"
when: (result.failed != false)
My question is, is there any better way to do this?
Is this a VMware-based VM? if that's the case, you can use the vmware modules:
- name: "Shuting down using guest tools"
vmware_guest_powerstate:
hostname: "{{ vcenter_ip }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
uuid: "{{ vm_facts.instance.hw_product_uuid }}"
state: shutdown-guest
state_change_timeout: 240
force: yes
delegate_to: "localhost"
register: newState
ignore_errors: yes
when: vm_facts.instance.guest_tools_status == "guestToolsRunning"
- name: "Power off from vCenter"
vmware_guest_powerstate:
hostname: "{{ vcenter_ip }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password }}"
validate_certs: False
uuid: "{{ vm_facts.instance.hw_product_uuid }}"
state: powered-off
force: yes
delegate_to: "localhost"
ignore_errors: yes
register: newState
First task tries to poweroff the VM using guest tools
Second task tries to poweroff the VM using the poweroff option from VMWare.
After this two steps, you can get current status for the VM to confirm that the actual state is powered off.

Launching oVirt Template cannot find data_center

So far I believe I am very close to getting Ansible to launch a VM template in oVirt. I'm able to authenticate without an issue, I believe specify the quota but even though it's launching a template it cannot find its data_center. No examples that I can find define data_center in the ovirt_vm module, this is what I have:
---
# tasks file for ovirt-template-launch
- name: Login to oVirt
ovirt_auth:
hostname: "{{ ovirt_hostname }}"
url: "{{ ovirt_ind_url }}"
username: "{{ ovirt_login_username }}"
password: "{{ ovirt_login_password }}"
insecure: true
- name: Create persistent SSO token
ovirt_vm:
auth: "{{ ovirt_auth }}"
state: absent
name: myvm
# Gather quota/datacenter
- ovirt_quota_info:
data_center: "{{ ovirt_datacenter }}"
name: "{{ ovirt_quota }}"
auth: "{{ ovirt_auth }}"
register: result
- name: Run VM with cloud init
ovirt_vm:
name: "{{ vmname }}"
template: centos7-template1
cluster: Default
memory: 2GiB
high_availability: true
high_availability_priority: 50
disks:
- size: 10GiB
name: data
storage_domain: mydomain
interface: virtio
auth: "{{ ovirt_auth }}"
quota_id: "{{ ovirt_quota_id }}"
cloud_init:
nic_boot_protocol: static
nic_ip_address: 10.0.1.5
nic_netmask: 255.255.254.0
nic_gateway: 10.0.1.1
nic_name: eth0
nic_on_boot: true
host_name: testdomain.com
custom_script: |
write_files:
- content: |
Hello, world!
path: /tmp/greeting.txt
permissions: '0644'
Error is:
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AttributeError: 'NoneType' object has no attribute 'data_center'
fatal: [localhost]: FAILED! => {"changed": false, "msg": "'NoneType' object has no attribute 'data_center'"}

when condition does not match with "ansible_host" Ansible 2.10?

I try something very simple but it does not work:
I want to execute a task only, if two strings are the same:
hostname=1-Europe-ECV-Site2
ansible_host=1-Europe-ECV-Site2
This is the playbook:
- debug: var=hostname
- debug: var=ansible_host
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
when: ansible_host == hostname
I got this result, even if I can see by debugging, that both values are equal:
PLAY [Configure vyOS BGP LAN Router] *****************************************************************************************************************************************************
TASK [get_ip_vsphere : debug] ************************************************************************************************************************************************************
ok: [1-Europe-ECV-Site2] =>
hostname: 1-Europe-ECV-Site2
ok: [1-Europe-ECV-Site3] =>
hostname: 1-Europe-ECV-Site3
ok: [1-Europe-ECV-Site1-1] =>
hostname: 1-Europe-ECV-Site1-1
ok: [1-Europe-ECV-Site1-2] =>
hostname: 1-Europe-ECV-Site1-2
TASK [get_ip_vsphere : debug] ************************************************************************************************************************************************************
ok: [1-Europe-ECV-Site2] =>
ansible_host: 1-Europe-ECV-Site2
ok: [1-Europe-ECV-Site3] =>
ansible_host: 1-Europe-ECV-Site3
ok: [1-Europe-ECV-Site1-1] =>
ansible_host: 1-Europe-ECV-Site1-1
ok: [1-Europe-ECV-Site1-2] =>
ansible_host: 1-Europe-ECV-Site1-2
TASK [get_ip_vsphere : Gather a virtual machine info] ************************************************************************************************************************************
skipping: [1-Europe-ECV-Site2]
skipping: [1-Europe-ECV-Site3]
skipping: [1-Europe-ECV-Site1-1]
skipping: [1-Europe-ECV-Site1-2]
TASK [get_ip_vsphere : Gather a virtual machine info] ************************************************************************************************************************************
skipping: [1-Europe-ECV-Site2]
skipping: [1-Europe-ECV-Site3]
skipping: [1-Europe-ECV-Site1-1]
skipping: [1-Europe-ECV-Site1-2]
Question:
Why this condition does not match? Do I need to do something special if I want to use the build in variable ansible_host I use Ansible 2.10
EDIT:
The purpose of this playbook is to write only the discovered IP address into the inventory YAML file under host_vars, if it is not already defined. As you can see in my example, the ansible_host is equal to the hostname of the VM, if no IP address was detected.
For this I have to check if ansible_host == hostname and only then IP must be fetched and written into the YAML inventory file.
Another solution is to check if 192.168. is not included in "ansbile_host" and then execute the task:
when: "'192.168' in ansible_host"
But this also does not work!
What do I miss?
I don't think issue is with the ansible_host variable. It is because you are trying to match hostname with ansible_host, which should ideally match every time (looking at the debug output).
For example, when the task vmware_guest_info runs on 1-Europe-ECV-Site3:
hostname == ansible_host
Will be:
"1-Europe-ECV-Site3" == "1-Europe-ECV-Site3"
#=> True
Which is not what you want, even if it runs. If you want the task to run only when ansible_hostname matches 1-Europe-ECV-Site2, then the condition should be:
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
when: ansible_hostname == "1-Europe-ECV-Site2"
This solution works, I don't know why the other conditions does not fit:
---
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
when: "'192.168' not in ansible_host"
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress != "0.0.0.0"
register: gather_vm_info
delegate_to: localhost
when: "'192.168' not in ansible_host"
- debug: var=gather_vm_info.instance.guest.ipAddress
- name: Update IP
block:
- name: Add ansible_host IP to the YAML inventory file
delegate_to: localhost
lineinfile:
path: host_vars/{{ hostname }}.yml
line: " ansible_host: {{ gather_vm_info.instance.guest.ipAddress }}"
- name: Update dynamic ansible_host with new IP Address
set_fact:
ansible_host: "{{ gather_vm_info.instance.guest.ipAddress }}"
ansible_hostname: "{{ hostname }}"
when: "'192.168' not in ansible_host"
If you use IP address in when condition, it works. Hostname resolution did not happen in my case.
when: ansible_host == "xx.xx.xx.xx"

How to parallize the execution by hostgroup in ansible

I am dynamically creating the hostgroup by site and it did well with below recipe.
- name: "generate batches from batch_processor"
batch_processor:
inventory: "{{ inventory_url }}"
ignore_applist: "{{ ignore_applist | default('None') }}"
ignore_podlist: "{{ ignore_podlist | default('None') }}"
register: batch_output
- name: "Creating batches by site"
include: batch_formatter.yml hostkey="{{ 'batch_' + item.key }}" hostlist="{{ item.value | list | join(',') }}"
with_dict: "{{ batch_output.result['assignments'] }}"
In my playbook, i have like this
- hosts: batch_*
serial: 10
gather_facts: False
tasks:
- include: roles/deployment/tasks/dotask.yml
I initially had strategy: free but in some reason it didn't pickup parallel. Currently i am using all batch hosts 10 at time to deploy.
I am thinking of below items
batch_site1 - 10 in parallel
batch_site2 - 10 in parallel
batch_site3 - 10 in parallel
But in the playbook, i don't want to specify the hostgroup execution by site as they are dynamic. Sometime, we will have siteX and sometime it wont be there. Please suggest the best approach.
- hosts: batch_*
gather_facts: False
strategy: free
tasks:
- include: roles/deployment/tasks/dotask.yml
when: "'batch_site1' not in group_names"
async: 600
poll: 0
register: job1
- name: Wait for asynchronous job to end
async_status:
jid: '{{ job1.ansible_job_id }}'
register: job_result1
until: job_result1.finished
retries: 30
- include: roles/deployment/tasks/dotask.yml
when: "'batch_site2' not in group_names"
register: job2
async: 600
poll: 0
- name: Wait for asynchronous job to end
async_status:
jid: '{{ job2.ansible_job_id }}'
register: job_result2
until: job_result2.finished
retries: 30
- include: roles/deployment/tasks/dotask.yml
when: "'batch_site3' not in group_names"
register: job3
async: 600
poll: 0
- name: Wait for asynchronous job to end
async_status:
jid: '{{ job3.ansible_job_id }}'
register: job_result3
until: job_result3.finished
retries: 30
This config slightly working on my purpose, however i couldn't pull the async_status to show better results in screen.
{"msg": "The task includes an option with an undefined variable. The error was: 'job1' is undefined\n\nThe error appears to have been in '/../../../../play.yml': line 12, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Wait for asynchronous job to end\n ^ here\n"}
not sure why ?

Resources