Where can I get a list of Ansible pre-defined variables? - ansible

I see that Ansible provide some pre-defined variables that we can use in playbooks and template files. For example, the host IP address is ansible_eth0.ipv4.address. Googleing and searching the docs I couldn't find a list of all available variables.
Would someone list them for me?

From the FAQ:
How do I see a list of all of the ansible_ variables?
Ansible by default gathers “facts” about the machines under management, and these facts can be accessed in playbooks and in templates. To see a list of all of the facts that are available about a machine, you can run the setup module as an ad hoc action:
ansible -m setup hostname
This will print out a dictionary of all of the facts that are available for that particular host. You might want to pipe the output to a pager.This does NOT include inventory variables or internal ‘magic’ variables. See the next question if you need more than just ‘facts’.
Here is the output for my vagrant virtual machine called scdev:
scdev | success >> {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"10.0.2.15",
"192.168.10.10"
],
"ansible_all_ipv6_addresses": [
"fe80::a00:27ff:fe12:9698",
"fe80::a00:27ff:fe74:1330"
],
"ansible_architecture": "i386",
"ansible_bios_date": "12/01/2006",
"ansible_bios_version": "VirtualBox",
"ansible_cmdline": {
"BOOT_IMAGE": "/vmlinuz-3.2.0-23-generic-pae",
"quiet": true,
"ro": true,
"root": "/dev/mapper/precise32-root"
},
"ansible_date_time": {
"date": "2013-09-17",
"day": "17",
"epoch": "1379378304",
"hour": "00",
"iso8601": "2013-09-17T00:38:24Z",
"iso8601_micro": "2013-09-17T00:38:24.425092Z",
"minute": "38",
"month": "09",
"second": "24",
"time": "00:38:24",
"tz": "UTC",
"year": "2013"
},
"ansible_default_ipv4": {
"address": "10.0.2.15",
"alias": "eth0",
"gateway": "10.0.2.2",
"interface": "eth0",
"macaddress": "08:00:27:12:96:98",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "10.0.2.0",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_devices": {
"sda": {
"holders": [],
"host": "SATA controller: Intel Corporation 82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [AHCI mode] (rev 02)",
"model": "VBOX HARDDISK",
"partitions": {
"sda1": {
"sectors": "497664",
"sectorsize": 512,
"size": "243.00 MB",
"start": "2048"
},
"sda2": {
"sectors": "2",
"sectorsize": 512,
"size": "1.00 KB",
"start": "501758"
},
},
"removable": "0",
"rotational": "1",
"scheduler_mode": "cfq",
"sectors": "167772160",
"sectorsize": "512",
"size": "80.00 GB",
"support_discard": "0",
"vendor": "ATA"
},
"sr0": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
"model": "CD-ROM",
"partitions": {},
"removable": "1",
"rotational": "1",
"scheduler_mode": "cfq",
"sectors": "2097151",
"sectorsize": "512",
"size": "1024.00 MB",
"support_discard": "0",
"vendor": "VBOX"
},
"sr1": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
"model": "CD-ROM",
"partitions": {},
"removable": "1",
"rotational": "1",
"scheduler_mode": "cfq",
"sectors": "2097151",
"sectorsize": "512",
"size": "1024.00 MB",
"support_discard": "0",
"vendor": "VBOX"
}
},
"ansible_distribution": "Ubuntu",
"ansible_distribution_release": "precise",
"ansible_distribution_version": "12.04",
"ansible_domain": "",
"ansible_eth0": {
"active": true,
"device": "eth0",
"ipv4": {
"address": "10.0.2.15",
"netmask": "255.255.255.0",
"network": "10.0.2.0"
},
"ipv6": [
{
"address": "fe80::a00:27ff:fe12:9698",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "08:00:27:12:96:98",
"module": "e1000",
"mtu": 1500,
"type": "ether"
},
"ansible_eth1": {
"active": true,
"device": "eth1",
"ipv4": {
"address": "192.168.10.10",
"netmask": "255.255.255.0",
"network": "192.168.10.0"
},
"ipv6": [
{
"address": "fe80::a00:27ff:fe74:1330",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "08:00:27:74:13:30",
"module": "e1000",
"mtu": 1500,
"type": "ether"
},
"ansible_form_factor": "Other",
"ansible_fqdn": "scdev",
"ansible_hostname": "scdev",
"ansible_interfaces": [
"lo",
"eth1",
"eth0"
],
"ansible_kernel": "3.2.0-23-generic-pae",
"ansible_lo": {
"active": true,
"device": "lo",
"ipv4": {
"address": "127.0.0.1",
"netmask": "255.0.0.0",
"network": "127.0.0.0"
},
"ipv6": [
{
"address": "::1",
"prefix": "128",
"scope": "host"
}
],
"mtu": 16436,
"type": "loopback"
},
"ansible_lsb": {
"codename": "precise",
"description": "Ubuntu 12.04 LTS",
"id": "Ubuntu",
"major_release": "12",
"release": "12.04"
},
"ansible_machine": "i686",
"ansible_memfree_mb": 23,
"ansible_memtotal_mb": 369,
"ansible_mounts": [
{
"device": "/dev/mapper/precise32-root",
"fstype": "ext4",
"mount": "/",
"options": "rw,errors=remount-ro",
"size_available": 77685088256,
"size_total": 84696281088
},
{
"device": "/dev/sda1",
"fstype": "ext2",
"mount": "/boot",
"options": "rw",
"size_available": 201044992,
"size_total": 238787584
},
{
"device": "/vagrant",
"fstype": "vboxsf",
"mount": "/vagrant",
"options": "uid=1000,gid=1000,rw",
"size_available": 42013151232,
"size_total": 484145360896
}
],
"ansible_os_family": "Debian",
"ansible_pkg_mgr": "apt",
"ansible_processor": [
"Pentium(R) Dual-Core CPU E5300 # 2.60GHz"
],
"ansible_processor_cores": "NA",
"ansible_processor_count": 1,
"ansible_product_name": "VirtualBox",
"ansible_product_serial": "NA",
"ansible_product_uuid": "NA",
"ansible_product_version": "1.2",
"ansible_python_version": "2.7.3",
"ansible_selinux": false,
"ansible_swapfree_mb": 766,
"ansible_swaptotal_mb": 767,
"ansible_system": "Linux",
"ansible_system_vendor": "innotek GmbH",
"ansible_user_id": "neves",
"ansible_userspace_architecture": "i386",
"ansible_userspace_bits": "32",
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "virtualbox"
},
"changed": false
}
The current documentation now has a complete chapter about Discovering variables: facts and magic variables.

ansible -m setup hostname
Only gets the facts gathered by the setup module.
Gilles Cornu posted a template trick to list all variables for a specific host.
Template (later called dump_variables):
HOSTVARS (ANSIBLE GATHERED, group_vars, host_vars) :
{{ hostvars[inventory_hostname] | to_yaml }}
PLAYBOOK VARS:
{{ vars | to_yaml }}
Playbook to use it:
- hosts: all
tasks:
- template:
src: templates/dump_variables
dest: /tmp/ansible_variables
- fetch:
src: /tmp/ansible_variables
dest: "{{inventory_hostname}}_ansible_variables"
After that you have a dump of all variables on every host, and a copy of each text dump file on your local workstation in your tmp folder. If you don't want local copies, you can remove the fetch statement.
This includes gathered facts, host variables and group variables.
Therefore you see ansible default variables like group_names, inventory_hostname, ansible_ssh_host and so on.

There are 3 sources of variables in Ansible:
Variables gathered from facts. You can get them by running command: ansible -m setup hostname
Built-in (pre-defined) Ansible variables (AKA 'magic' variables). They are documented in Ansible documentation: http://docs.ansible.com/playbooks_variables.html#magic-variables-and-how-to-access-information-about-other-hosts
Here is the list extracted from Ansible 1.9 documentation:
group_names
groups
inventory_hostname
ansible_hostname
inventory_hostname_short
play_hosts
delegate_to
inventory_dir
inventory_file
Variables passed to ansible via command line. But obviously you know what they are

I use this simple playbook:
---
# vars.yml
#
# Shows the value of all variables/facts.
#
# Example:
#
# ansible-playbook vars.yml -e 'hosts=localhost'
#
- hosts: localhost
tasks:
- fail: "You must specify a value for `hosts` variable - e.g.: ansible-playbook vars.yml -e 'hosts=localhost'"
when: hosts is not defined
- hosts: "{{ hosts }}"
tasks:
- debug: var=vars
- debug: var=hostvars[inventory_hostname]

There is lot of variables defined as Facts -- http://docs.ansible.com/ansible/playbooks_variables.html#information-discovered-from-systems-facts
"ansible_all_ipv4_addresses": [
"REDACTED IP ADDRESS"
],
"ansible_all_ipv6_addresses": [
"REDACTED IPV6 ADDRESS"
],
"ansible_architecture": "x86_64",
"ansible_bios_date": "09/20/2012",
"ansible_bios_version": "6.00",
"ansible_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-3.5.0-23-generic",
"quiet": true,
"ro": true,
"root": "UUID=4195bff4-e157-4e41-8701-e93f0aec9e22",
"splash": true
},
"ansible_date_time": {
"date": "2013-10-02",
"day": "02",
"epoch": "1380756810",
"hour": "19",
"iso8601": "2013-10-02T23:33:30Z",
"iso8601_micro": "2013-10-02T23:33:30.036070Z",
"minute": "33",
"month": "10",
"second": "30",
"time": "19:33:30",
"tz": "EDT",
"year": "2013"
},
"ansible_default_ipv4": {
"address": "REDACTED",
"alias": "eth0",
"gateway": "REDACTED",
"interface": "eth0",
"macaddress": "REDACTED",
"mtu": 1500,
"netmask": "255.255.255.0",
"network": "REDACTED",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_devices": {
"fd0": {
"holders": [],
"host": "",
"model": null,
"partitions": {},
"removable": "1",
"rotational": "1",
"scheduler_mode": "deadline",
"sectors": "0",
"sectorsize": "512",
"size": "0.00 Bytes",
"support_discard": "0",
"vendor": null
},
"sda": {
"holders": [],
"host": "SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)",
"model": "VMware Virtual S",
"partitions": {
"sda1": {
"sectors": "39843840",
"sectorsize": 512,
"size": "19.00 GB",
"start": "2048"
},
"sda2": {
"sectors": "2",
"sectorsize": 512,
"size": "1.00 KB",
"start": "39847934"
},
"sda5": {
"sectors": "2093056",
"sectorsize": 512,
"size": "1022.00 MB",
"start": "39847936"
}
},
"removable": "0",
"rotational": "1",
"scheduler_mode": "deadline",
"sectors": "41943040",
"sectorsize": "512",
"size": "20.00 GB",
"support_discard": "0",
"vendor": "VMware,"
},
"sr0": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
"model": "VMware IDE CDR10",
"partitions": {},
"removable": "1",
"rotational": "1",
"scheduler_mode": "deadline",
"sectors": "2097151",
"sectorsize": "512",
"size": "1024.00 MB",
"support_discard": "0",
"vendor": "NECVMWar"
}
},
"ansible_distribution": "Ubuntu",
"ansible_distribution_release": "precise",
"ansible_distribution_version": "12.04",
"ansible_domain": "",
"ansible_env": {
"COLORTERM": "gnome-terminal",
"DISPLAY": ":0",
"HOME": "/home/mdehaan",
"LANG": "C",
"LESSCLOSE": "/usr/bin/lesspipe %s %s",
"LESSOPEN": "| /usr/bin/lesspipe %s",
"LOGNAME": "root",
"LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:",
"MAIL": "/var/mail/root",
"OLDPWD": "/root/ansible/docsite",
"PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PWD": "/root/ansible",
"SHELL": "/bin/bash",
"SHLVL": "1",
"SUDO_COMMAND": "/bin/bash",
"SUDO_GID": "1000",
"SUDO_UID": "1000",
"SUDO_USER": "mdehaan",
"TERM": "xterm",
"USER": "root",
"USERNAME": "root",
"XAUTHORITY": "/home/mdehaan/.Xauthority",
"_": "/usr/local/bin/ansible"
},
"ansible_eth0": {
"active": true,
"device": "eth0",
"ipv4": {
"address": "REDACTED",
"netmask": "255.255.255.0",
"network": "REDACTED"
},
"ipv6": [
{
"address": "REDACTED",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "REDACTED",
"module": "e1000",
"mtu": 1500,
"type": "ether"
},
"ansible_form_factor": "Other",
"ansible_fqdn": "ubuntu2.example.com",
"ansible_hostname": "ubuntu2",
"ansible_interfaces": [
"lo",
"eth0"
],
"ansible_kernel": "3.5.0-23-generic",
"ansible_lo": {
"active": true,
"device": "lo",
"ipv4": {
"address": "127.0.0.1",
"netmask": "255.0.0.0",
"network": "127.0.0.0"
},
"ipv6": [
{
"address": "::1",
"prefix": "128",
"scope": "host"
}
],
"mtu": 16436,
"type": "loopback"
},
"ansible_lsb": {
"codename": "precise",
"description": "Ubuntu 12.04.2 LTS",
"id": "Ubuntu",
"major_release": "12",
"release": "12.04"
},
"ansible_machine": "x86_64",
"ansible_memfree_mb": 74,
"ansible_memtotal_mb": 991,
"ansible_mounts": [
{
"device": "/dev/sda1",
"fstype": "ext4",
"mount": "/",
"options": "rw,errors=remount-ro",
"size_available": 15032406016,
"size_total": 20079898624
}
],
"ansible_nodename": "ubuntu2.example.com",
"ansible_os_family": "Debian",
"ansible_pkg_mgr": "apt",
"ansible_processor": [
"Intel(R) Core(TM) i7 CPU 860 # 2.80GHz"
],
"ansible_processor_cores": 1,
"ansible_processor_count": 1,
"ansible_processor_threads_per_core": 1,
"ansible_processor_vcpus": 1,
"ansible_product_name": "VMware Virtual Platform",
"ansible_product_serial": "REDACTED",
"ansible_product_uuid": "REDACTED",
"ansible_product_version": "None",
"ansible_python_version": "2.7.3",
"ansible_selinux": false,
"ansible_ssh_host_key_dsa_public": "REDACTED KEY VALUE"
"ansible_ssh_host_key_ecdsa_public": "REDACTED KEY VALUE"
"ansible_ssh_host_key_rsa_public": "REDACTED KEY VALUE"
"ansible_swapfree_mb": 665,
"ansible_swaptotal_mb": 1021,
"ansible_system": "Linux",
"ansible_system_vendor": "VMware, Inc.",
"ansible_user_id": "root",
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "VMware"

The debug module can be used to analyze variables. Be careful running the following command. In our setup it generates 444709 lines with 16MB:
ansible -m debug -a 'var=hostvars' localhost
I am not sure but it might be necessary to enable facts caching.
If you need just one host use the host name as a key for the hostvars hash:
ansible -m debug -a 'var=hostvars.localhost' localhost
This command will display also group and host variables.

Note the official docs on connection configuration variables or "behavioral" variables - which aren't listed in host vars, appears to be List of Behavioral Inventory Parameters in the Inventory documentation.
P.S. The sudo option is undocumented there (yes its sudo not ansible_sudo as you'd expect ...) and probably a couple more aren't, but thats best doc I've found on em.

Some variables are not available on every host, e.g. ansible_domain and domain. If the situation needs to be debugged, I login to the server and issue:
user#server:~$ ansible -m setup localhost | grep domain
[WARNING]: provided hosts list is empty, only localhost is available
"ansible_domain": "prd.example.com",

I know this question has been answered already, but I feel like there are a whole other set of pre-defined variables not covered by the ansible_* facts. This documentation page covers the directives (variables that modify Ansible's behavior), which I was looking for when I came across this page.
This includes some common and some specific use-case directives:
become: Controls privilege escalation (sudo)
delegate_to: run task on another host (like running on localhost)
serial: allows you to run a play across a specific number/percentage of hosts before moving onto next set

https://github.com/f500/ansible-dumpall
FYI: this github project shows you how to list 90% of variables across all hosts. I find it more globally useful than single host commands. The README includes instructions for building a simple inventory report. It's even more valuable to run this at the end of a playbook to see all the Facts. To also debug Task behaviour use register:
The result is missing a few items:
- included YAML file variables
- extra-vars
- a number of the Ansible internal vars described here: Ansible Behavioural Params

Related

Jinja2 for loop doesn't follow original dictionary order

So I'm using a .j2 template file to generate a report regarding primary and secondary disk devices in a system.
I have to print the primary disk first and I'm covering only sd* and vd* device naming scheme.
Problem is the for loop always do a reverse lookup on the dictionary.
Here's the a ansible_devices variable on my system.
ansible1 | SUCCESS => {
"ansible_facts": {
"ansible_devices": {
"dm-0": {
"holders": [],
"host": "",
"links": {
"ids": [
"dm-name-rhel_rhel8-root",
"dm-uuid-LVM-DOufRu3rljRtRzbfEbU3jOt0XPsF4dTm8muvelhzXFaWdS0ivguPLcwB1EQaTdOj"
],
"labels": [],
"masters": [],
"uuids": [
"26028eb5-091e-41f5-993c-8639ded7c1c5"
]
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "",
"sectors": "146800640",
"sectorsize": "512",
"serial": "VB011d5a18",
"size": "70.00 GB",
"support_discard": "0",
"vendor": null,
"virtual": 1
},
"dm-1": {
"holders": [],
"host": "",
"links": {
"ids": [
"dm-name-rhel_rhel8-swap",
"dm-uuid-LVM-DOufRu3rljRtRzbfEbU3jOt0XPsF4dTmv7C9OKBjTw1x1xQ4VeF7G2iGYeCHi6Y2"
],
"labels": [],
"masters": [],
"uuids": [
"15cb7bae-eec8-421e-a324-5c8087b31b17"
]
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "",
"sectors": "4317184",
"sectorsize": "512",
"serial": "VB011d5a18",
"size": "2.06 GB",
"support_discard": "0",
"vendor": null,
"virtual": 1
},
"sda": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
"links": {
"ids": [
"ata-VBOX_HARDDISK_VB011d5a18-fc7b8d75",
"scsi-0ATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75",
"scsi-1ATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75",
"scsi-SATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75"
],
"labels": [],
"masters": [],
"uuids": []
},
"model": "VBOX HARDDISK",
"partitions": {
"sda1": {
"holders": [],
"links": {
"ids": [
"ata-VBOX_HARDDISK_VB011d5a18-fc7b8d75-part1",
"scsi-0ATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75-part1",
"scsi-1ATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75-part1",
"scsi-SATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75-part1"
],
"labels": [],
"masters": [],
"uuids": [
"7431a3cf-0ed2-4813-9df7-083f8ee4f6ae"
]
},
"sectors": "2097152",
"sectorsize": 512,
"size": "1.00 GB",
"start": "2048",
"uuid": "7431a3cf-0ed2-4813-9df7-083f8ee4f6ae"
},
"sda2": {
"holders": [
"rhel_rhel8-swap",
"rhel_rhel8-root"
],
"links": {
"ids": [
"ata-VBOX_HARDDISK_VB011d5a18-fc7b8d75-part2",
"lvm-pv-uuid-hBGpnr-FYc6-95QG-dsoT-qD3k-Imd0-0yoWzd",
"scsi-0ATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75-part2",
"scsi-1ATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75-part2",
"scsi-SATA_VBOX_HARDDISK_VB011d5a18-fc7b8d75-part2"
],
"labels": [],
"masters": [
"dm-0",
"dm-1"
],
"uuids": []
},
"sectors": "266336256",
"sectorsize": 512,
"size": "127.00 GB",
"start": "2099200",
"uuid": null
}
},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "mq-deadline",
"sectors": "268435456",
"sectorsize": "512",
"serial": "VB011d5a18",
"size": "128.00 GB",
"support_discard": "0",
"vendor": "ATA",
"virtual": 1
},
"sdb": {
"holders": [],
"host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)",
"links": {
"ids": [
"ata-VBOX_HARDDISK_VB6207845b-7aa2bea6",
"scsi-0ATA_VBOX_HARDDISK_VB6207845b-7aa2bea6",
"scsi-1ATA_VBOX_HARDDISK_VB6207845b-7aa2bea6",
"scsi-SATA_VBOX_HARDDISK_VB6207845b-7aa2bea6"
],
"labels": [],
"masters": [],
"uuids": []
},
"model": "VBOX HARDDISK",
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "mq-deadline",
"sectors": "10485760",
"sectorsize": "512",
"serial": "VB6207845b",
"size": "5.00 GB",
"support_discard": "0",
"vendor": "ATA",
"virtual": 1
}
},
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false
}
As it can be seen, the order is as;
dm-0
dm-1
sda
sdb
My template file is below;
{% for dev in ansible_devices %}
{% if dev == 'sda' %}
primary device {{ dev }} found on {{ ansible_hostname }}
{% endif %}
{% if dev == 'sdb' %}
second device {{ dev }} found on {{ ansible_hostname }}
{% endif %}
{% if dev == 'vda' %}
primary device {{ dev }} found on {{ ansible_hostname }}
{% endif %}
{% if dev == 'vdb' %}
second device {{ dev }} found on {{ ansible_hostname }}
{% endif %}
{% endfor %}
{% if ('sdb' not in ansible_devices) and ('vdb' not in ansible_devices) %}
no second device found on {{ ansible_hostname }}
{% endif %}
If I execute this within a playbook, the following content is generated;
--- before
+++ after: /home/ansible/.ansible/tmp/ansible-local 12580ell0d0oq/tmp1qs9mu2y/devices.j2
## -0,0 +1,2 ##
+primary device sda found on ansible3
+no second device found on ansible3
changed: [ansible3]
--- before
+++ after: /home/ansible/.ansible/tmp/ansible-local-12580ell0d0oq /tmpej185qb4/devices.j2
## -0,0 +1,2 ##
+second device sdb found on ansible2
+primary device sda found on ansible2
changed: [ansible2]
--- before
+++ after: /home/ansible/.ansible/tmp/ansible-local-12580ell0d0oq/tmpkbcmuhqa/devices.j2
## -0,0 +1,2 ##
+primary device sda found on ansible4
+no second device found on ansible4
changed: [ansible4]
--- before
+++ after: /home/ansible/.ansible/tmp/ansible-local-12580ell0d0oq/tmpvkm3uid6/devices.j2
## -0,0 +1,2 ##
+second device sdb found on ansible1
+primary device sda found on ansible1
changed: [ansible1]
Somehow, the iteration is going in reverse order, I've seen this in all the alternative tests for the given scenario.
Am I missing something here?

Getting a value out of registered variable in Ansible

So, I'm provisioning an EC2 instance using the ec2 module. At the end I'm using register: ec2info, so, I can later reference values inside, such as instance ID and Public DNS.
- name: Print the results
debug:
var: ec2info
Gets me
TASK [Print the results] ***********************************************************************************************************************
ok: [localhost] => {
"ec2info": {
"changed": true,
"deprecations": [
{
"collection_name": "amazon.aws",
"msg": "The 'ec2' module has been deprecated and replaced by the 'ec2_instance' module'",
"version": "4.0.0"
}
],
"failed": false,
"instance_ids": [
"i-0e9de15eb82eda3ad"
],
"instances": [
{
"ami_launch_index": "0",
"architecture": "x86_64",
"block_device_mapping": {
"/dev/sda1": {
"delete_on_termination": true,
"status": "attached",
"volume_id": "vol-066bb2dd4d14bdcac"
}
},
"dns_name": "ec2-35-173-126-60.compute-1.amazonaws.com",
"ebs_optimized": false,
"groups": {
"sg-0a732c6cbeb3f1025": "launch-wizard-39"
},
"hypervisor": "xen",
"id": "i-0e9de15eb82eda3ad",
"image_id": "ami-06644055bed38ebd9",
"instance_type": "t2.micro",
"kernel": null,
"key_name": "daro.io",
"launch_time": "2022-02-01T02:05:22.000Z",
"placement": "us-east-1c",
"private_dns_name": "ip-172-31-90-87.ec2.internal",
"private_ip": "172.31.90.87",
"public_dns_name": "ec2-35-173-126-60.compute-1.amazonaws.com",
"public_ip": "35.173.126.60",
"ramdisk": null,
"region": "us-east-1",
"root_device_name": "/dev/sda1",
"root_device_type": "ebs",
"state": "running",
"state_code": 16,
"tags": {
"Name": "new_demo_template"
},
"tenancy": "default",
"virtualization_type": "hvm"
}
],
"tagged_instances": []
}
}
I would like to get the value of Public DNS I have tried
- name: Print the results
debug:
var: ec2info.instances.public_dns_name
## AND
var: ec2info.instances['public_dns_name']
## AND
var: '{{ec2info.instances.public_dns_name}}'
If you could also point out to the part of the documentation that covers this?
So, I figured it out
var: ec2info.instances[0].public_dns_name

Remove double quotes from Ansible fact

There is a json output which I am trying to parse. I registered the output into variable named instance_ip.
Here is the json output:
{
"msg": {
"instances": [
{
"root_device_type": "ebs",
"private_dns_name": "",
"cpu_options": {
"core_count": 2,
"threads_per_core": 1
},
"security_groups": [],
"state_reason": {
"message": "Client.UserInitiatedShutdown: User initiated shutdown",
"code": "Client.UserInitiatedShutdown"
},
"monitoring": {
"state": "disabled"
},
"ebs_optimized": false,
"state": {
"code": 48,
"name": "terminated"
},
"client_token": "test-Logst-14O6L4IETB05E",
"virtualization_type": "hvm",
"architecture": "x86_64",
"tags": {
"sg:environment": "TST",
"Name": "logstash1",
"aws:cloudformation:logical-id": "Logstash1A1594E87",
"sg:owner": "Platforms#paparapa.com",
"aws:cloudformation:stack-name": "test-three-ec2-instances-elk-demo",
"elastic_role": "logstash",
"sg:function": "Storage"
},
"key_name": "AWS_key",
"image_id": "ami-09f765d333a8ebb4b",
"state_transition_reason": "User initiated (2021-01-31 09:46:23 GMT)",
"hibernation_options": {
"configured": false
},
"capacity_reservation_specification": {
"capacity_reservation_preference": "open"
},
"public_dns_name": "",
"block_device_mappings": [],
"metadata_options": {
"http_endpoint": "enabled",
"state": "pending",
"http_tokens": "optional",
"http_put_response_hop_limit": 1
},
"placement": {
"group_name": "",
"tenancy": "default",
"availability_zone": "ap-southeast-2a"
},
"enclave_options": {
"enabled": false
},
"ami_launch_index": 0,
"ena_support": true,
"network_interfaces": [],
"launch_time": "2021-01-31T09:44:51+00:00",
"instance_id": "i-0fa5dbb869833d7c6",
"instance_type": "t2.medium",
"root_device_name": "/dev/xvda",
"hypervisor": "xen",
"product_codes": []
},
{
"root_device_type": "ebs",
"private_dns_name": "ip-10-x-x-x.ap-southeast-2.compute.internal",
"cpu_options": {
"core_count": 2,
"threads_per_core": 1
},
"source_dest_check": true,
"monitoring": {
"state": "disabled"
},
"subnet_id": "subnet-0d5f856afab8f0eec",
"ebs_optimized": false,
"iam_instance_profile": {
"id": "AIPARWXXVHXJWC2FL4AI6",
"arn": "arn:aws:iam::instance-profile/test-three-ec2-instances-elk-demo-Logstash1InstanceProfileC3035819-1F2LI7JM16FVM"
},
"state": {
"code": 16,
"name": "running"
},
"security_groups": [
{
"group_id": "sg-0e5dffa834a036fab",
"group_name": "Ansible_sec_group"
}
],
"client_token": "test-Logst-8UF6RX33BH06",
"virtualization_type": "hvm",
"architecture": "x86_64",
"public_ip_address": "3.x.x.x",
"tags": {
"Name": "logstash1",
"aws:cloudformation:logical-id": "Logstash1A1594E87",
"srg:environment": "TST",
"aws:cloudformation:stack-id": "arn:aws:cloudformation:ap-southeast-2:117557247443:stack/test-three-ec2-instances-elk-demo/ca8ef2b0-63ad-11eb-805f-02630ffccc8c",
"sg:function": "Storage",
"aws:cloudformation:stack-name": "test-three-ec2-instances-elk-demo",
"elastic_role": "logstash",
"sg:owner": "Platforms#paparapa.com"
},
"key_name": "AWS_SRG_key",
"image_id": "ami-09f765d333a8ebb4b",
"ena_support": true,
"hibernation_options": {
"configured": false
},
"capacity_reservation_specification": {
"capacity_reservation_preference": "open"
},
"public_dns_name": "ec2-3-x-x-x.ap-southeast-2.compute.amazonaws.com",
"block_device_mappings": [
{
"device_name": "/dev/xvda",
"ebs": {
"status": "attached",
"delete_on_termination": true,
"attach_time": "2021-01-31T10:22:21+00:00",
"volume_id": "vol-058662934ffba3a68"
}
}
],
"metadata_options": {
"http_endpoint": "enabled",
"state": "applied",
"http_tokens": "optional",
"http_put_response_hop_limit": 1
},
"placement": {
"group_name": "",
"tenancy": "default",
"availability_zone": "ap-southeast-2a"
},
"enclave_options": {
"enabled": false
},
"ami_launch_index": 0,
"hypervisor": "xen",
"network_interfaces": [
{
"status": "in-use",
"description": "",
"subnet_id": "subnet-0d5f856afab8f0eec",
"source_dest_check": true,
"interface_type": "interface",
"ipv6_addresses": [],
"network_interface_id": "eni-09b045668ac59990c",
"private_dns_name": "ip-10-x-x-x.ap-southeast-2.compute.internal",
"attachment": {
"status": "attached",
"device_index": 0,
"attachment_id": "eni-attach-0700cd11dfb27e2dc",
"delete_on_termination": true,
"attach_time": "2021-01-31T10:22:20+00:00"
},
"private_ip_addresses": [
{
"private_ip_address": "10.x.x.x",
"private_dns_name": "ip-10-x-x-x.ap-southeast-2.compute.internal",
"association": {
"public_ip": "3.x.x.x",
"public_dns_name": "ec2-3-x-x-x.ap-southeast-2.compute.amazonaws.com",
"ip_owner_id": "amazon"
},
"primary": true
}
],
"mac_address": "02:d1:13:01:59:b2",
"private_ip_address": "10.x.x.x",
"vpc_id": "vpc-0016dcdf5abe4fef0",
"groups": [
{
"group_id": "sg-0e5dffa834a036fab",
"group_name": "Ansible_sec_group"
}
],
"association": {
"public_ip": "3.x.x.x",
"public_dns_name": "ec2-3-x-x-x.ap-southeast-2.compute.amazonaws.com",
"ip_owner_id": "amazon"
},
"owner_id": "117557247443"
}
],
"launch_time": "2021-01-31T10:22:20+00:00",
"instance_id": "i-0482bb8ca1bef6006",
"instance_type": "t2.medium",
"root_device_name": "/dev/xvda",
"state_transition_reason": "",
"private_ip_address": "10.x.x.x",
"vpc_id": "vpc-0016dcdf5abe4fef0",
"product_codes": []
}
],
"failed": false,
"changed": false
},
"_ansible_verbose_always": true,
"_ansible_no_log": false,
"changed": false
}
The goal is to get the private ip address and append the port number.
With the following task I got the list with node ip address ["10.x.x.x"]
- name: Getting EC2 instance ip address
set_fact:
instance_ip: "{{ logstash_instance | json_query('instances[*].network_interfaces[*].private_ip_address') | flatten }}"
With next task in a play I am trying to append the port number but I am keep getting
"['10.x.x.x:5044']"
- name: Get everything between quotes and append port 5044
set_fact:
logstash_hosts: "{{ instance_ip | map('regex_replace', '^(.*)$', '\\1:5044') | list }}"
Here is the template output:
# ------------------------------ Logstash Output -------------------------------
output.logstash:
hosts: "['10.x.x.x:5044']"
I need to get rid of the double quotes and pass the clean variable ['10.x.x.x:5044'] to my template file.
You can try creating a new list variable with the port number appended to each element, using this approach:
- set_fact:
logstash_hosts: "{{ logstash_hosts|default([]) + [ item ~ ':5044' ] }}"
with_items: "{{ instance_ip }}"
Then in template:
output.logstash:
hosts: {{ logstash_hosts|to_yaml }}
Also since the Logstash configuration is a YAML formatted file, you use YAML list syntax and directly use the instance_ip variable (and avoid set_fact). Then the template will look like this:
output.logstash:
hosts:
{% for ip in instance_ip %}
- {{ ip }}:5044
{% endfor %}

Registering Multiple Same-Host Services

I am using the Consul API to register a local web-service running on various ports on my local machine. My end-goal is to be able to run multiple backends and load balance against them on different ports.
I am running a local Consul server of one node for development in a Vagrant VM. I have registered the first instance of my service:
{
"Node": {
"ID": "49d3be4b-5ee5-5f0f-e145-dcb1782e5b4b",
"Node": "localhost",
"Address": "127.0.0.1",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "127.0.0.1",
"wan": "127.0.0.1"
},
"Meta": {
"consul-network-segment": ""
},
"CreateIndex": 5,
"ModifyIndex": 6
},
"Services": {
"consul": {
"ID": "consul",
"Service": "consul",
"Tags": [],
"Address": "",
"Port": 8300,
"EnableTagOverride": false,
"CreateIndex": 5,
"ModifyIndex": 5
},
"rusty": {
"ID": "rusty",
"Service": "rusty",
"Tags": [
"rusty",
"rust"
],
"Address": "127.0.0.1",
"Port": 8001,
"EnableTagOverride": false,
"CreateIndex": 247,
"ModifyIndex": 491
}
}
}
You can see my service, rusty, registered on port 8001. The strange thing is that when I register the same service on a different port, Consul supersedes port 8001 with the new service port.
Is there not a way to run multiple backends for a service on different ports on the same host?
Try to check that you are registering services with different IDs. For complete info see the parameters for /agent/service/register endpoint.
Here is an example with two rusty service instances with different IDs rusty1 and rusty2
{
"Node": {
"ID": "eff2fae3-6ee5-5de7-bf1a-c041992a1d6a",
"Node": "FB20160707",
"Address": "192.168.1.66",
"Datacenter": "dc1",
"TaggedAddresses": {
"lan": "192.168.1.66",
"wan": "192.168.1.66"
},
"Meta": {},
"CreateIndex": 5,
"ModifyIndex": 6
},
"Services": {
"consul": {
"ID": "consul",
"Service": "consul",
"Tags": [],
"Address": "",
"Port": 8300,
"EnableTagOverride": false,
"CreateIndex": 5,
"ModifyIndex": 5
},
"rusty1": {
"ID": "rusty1",
"Service": "rusty",
"Tags": [],
"Address": "10.10.10.10",
"Port": 8001,
"EnableTagOverride": false,
"CreateIndex": 16,
"ModifyIndex": 28
},
"rusty2": {
"ID": "rusty2",
"Service": "rusty",
"Tags": [],
"Address": "10.10.10.10",
"Port": 8002,
"EnableTagOverride": false,
"CreateIndex": 19,
"ModifyIndex": 29
}
}
}
As per my comment to #ruslan-sennov, if the services section looked like this (the ID for each instance of the rusty service is made unique by adding the port, but the name is kept as rusty):
"Services": {
"consul": {
"ID": "consul",
"Service": "consul",
"Tags": [],
"Address": "",
"Port": 8300,
"EnableTagOverride": false,
"CreateIndex": 5,
"ModifyIndex": 5
},
"rusty": {
"ID": "rusty:8001",
"Service": "rusty",
"Tags": [
"rusty",
"rust"
],
"Address": "127.0.0.1",
"Port": 8001,
"EnableTagOverride": false,
"CreateIndex": 247,
"ModifyIndex": 491
},
"rusty": {
"ID": "rusty:8002",
"Service": "rusty",
"Tags": [
"rusty",
"rust"
],
"Address": "127.0.0.1",
"Port": 8002,
"EnableTagOverride": false,
"CreateIndex": 247,
"ModifyIndex": 491
}
}
This then means you can query the rusty service with a SRV query and get detail on which ports are available:
dig #127.0.0.1 rusty.service.consul SRV
; <<>> DiG 9.11.3 <<>> rusty.service.consul SRV
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56091
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 52, AUTHORITY: 0, ADDITIONAL: 5
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;rusty.service.consul. IN SRV
;; ANSWER SECTION:
rusty.service.consul. 0 IN SRV 1 1 8001 FB20160707.node.dc1.consul.
rusty.service.consul. 0 IN SRV 1 1 8002 FB20160707.node.dc1.consul.
If you also change the names to be unique (rusty1 and rusty2 as suggested by Ruslan) you lose this querying ability.
I know this is late to answer this, but hope this would help someone.
As per Spring Cloud Consul docs, Add this to bootstrap.yml.
spring:
cloud:
consul:
discovery:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

Get a list of all Mac addresses using ansible

I know that module setup provides Mac addresses per interface, for example:
"ansible_eth0": {
"active": true,
"device": "eth0",
"ipv4": {
"address": "192.168.35.174",
"broadcast": "192.168.35.255",
"netmask": "255.255.255.0",
"network": "192.168.35.0"
},
"ipv6": [
{
"address": "fe80::250:56ff:fe91:a6c2",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "00:50:56:91:a6:c2",
"module": "vmxnet3",
"mtu": 1500,
"pciid": "0000:0b:00.0",
"promisc": false,
"speed": 10000,
"type": "ether"
Suppose the server has 10 interfaces and I want to gather all their mac's, separated with semicolon. How would I do that if I don't know how many interfaces server has and I don't know their names?
Take a look at this answer for complete description.
You may try this:
ansible_interfaces |
map('regex_replace','^','ansible_') |
map('extract',hostvars[inventory_hostname]) |
selectattr('macaddress','defined') |
map(attribute='macaddress') |
list
This expression is not tested, but the idea should be clear.

Resources