
Si usa Ansible, sabe que el inventario es uno de sus componentes fundamentales. Un inventario es solo una lista de máquinas y posibles variables en las que puede ejecutar su libro de jugadas de Ansible.
Los archivos de manifiesto se pueden escribir en formato YAML, JSON o INI de Windows y pueden describir grupos de máquinas. P.ej:
---
all:
children:
servers:
hosts:
macmini2:
raspberrypi:
vars:
description: Linux servers for the Nunez family
desktops:
hosts:
dmaf5:
mac-pro-1-1:
vars:
description: Desktops for the Nunez family
También puede confirmar que el archivo tiene la estructura correcta.Por ejemplo, puede filtrar solo desktops
patrón:
[josevnz@dmaf5 ExtendingAnsibleWithPython]$ ansible-inventory --yaml --inventory /home/josevnz/EnableSysadmin/BashHere/hosts.yaml --graph desktops
@desktops:
|--dmaf5
|--mac-pro-1-1
Tener un manifiesto YAML estático puede no ser del todo práctico por las siguientes razones:
- Su lista de alojamiento es extensa. Admítelo, tienes mejores cosas que hacer que editar archivos YAML, ¿verdad?
- Su archivo de manifiesto tiene un formato incompatible con Ansible YAML. Puede estar en una base de datos o en un archivo de texto sin formato.
- Los servidores que forman parte de su inventario son de hecho dinámicos. Puede crear máquinas en la nube privada según sea necesario y sus direcciones IP cambian con frecuencia. Alternativamente, su red doméstica puede tener muchos dispositivos itinerantes (tabletas y teléfonos). ¿Quieres mantenerlo manualmente?
Formas de administrar el inventario en Ansible
Hay muchas formas de administrar su inventario en Ansible. Aquí hay algunas posibilidades:
- Convierta el inventario del formato antiguo a Ansible.
- Use manifiestos dinámicos con complementos, especialmente Nmap.
- Escriba sus propios scripts de inventario para generar inventario dinámicamente.
- Escriba un complemento de inventario de Ansible.
Este artículo incluye los dos primeros elementos de esa lista, y los artículos posteriores explicarán los dos últimos. Recuerde, cualquiera que sea el método que utilice, debe seguir buenas prácticas para empaquetar herramientas, utilizar entornos virtuales y realizar pruebas unitarias de su código para realizar esta tarea.
No te repitas: primero comprueba si alguien te lo ha escrito
Lo más probable es que lo hicieran. Puede ver rápidamente si alguien ha escrito un complemento que puede generar inventario de diferentes fuentes como esta:
$ ansible-doc -t inventory -l
P.ej:
$ ansible-doc -t inventory -l
advanced_host_list Parses a 'host list' with ranges
auto Loads and executes an inventory plugin specified in a YAML config
aws_ec2 EC2 inventory source
aws_rds rds instance source
azure_rm Azure Resource Manager inventory plugin
cloudscale cloudscale.ch inventory source
constructed Uses Jinja2 to construct vars and groups based on existing inventory
docker_machine Docker Machine inventory source
docker_swarm Ansible dynamic inventory plugin for Docker swarm nodes
foreman foreman inventory source
gcp_compute Google Cloud Compute Engine inventory source
generator Uses Jinja2 to construct hosts and groups from patterns
gitlab_runners Ansible dynamic inventory plugin for GitLab runners
hcloud Ansible dynamic inventory plugin for the Hetzner Cloud
host_list Parses a 'host list' string
ini Uses an Ansible INI file as inventory source
k8s Kubernetes (K8s) inventory source
kubevirt KubeVirt inventory source
linode Ansible dynamic inventory plugin for Linode
netbox NetBox inventory source
nmap Uses nmap to find hosts to target
online Online inventory source
openshift OpenShift inventory source
openstack OpenStack inventory source
scaleway Scaleway inventory source
script Executes an inventory script that returns JSON
toml Uses a specific TOML file as an inventory source
tower Ansible dynamic inventory plugin for Ansible Tower
virtualbox virtualbox inventory source
vmware_vm_inventory VMware Guest inventory source
vultr Vultr inventory source
yaml Uses a specific YAML file as an inventory source
Usando el complemento host_list
Este es el complemento más simple. Pasa una lista de máquinas o direcciones IP y está listo para comenzar.
[ Need more on Ansible? Take a free technical overview course from Red Hat. Ansible Essentials: Simplicity in Automation Technical Overview. ]
Aquí hay un ejemplo usando el módulo de ping y un usuario remoto josevnz
:
$ cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.17 mac-pro-1-1
192.168.1.16 macmini2
192.168.1.11 raspberrypi
$ cat /etc/hosts| /bin/cut -f1 -d' '|/bin/grep -P '^[a-z1]'
127.0.0.1
192.168.1.17
192.168.1.16
192.168.1.11
$ ansible -u josevnz -i $(/bin/cat /etc/hosts| /bin/cut -f1 -d' '|/bin/grep -P '^[a-z1]'|/bin/xargs|/bin/sed 's# #,#g') -m ping all
127.0.0.1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.11 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.16 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.1.17 | SUCCESS => {
"changed": false,
"ping": "pong"
}
No hay sorpresas aquí. Pero como puede ver, esto no es muy conveniente porque tuve que escribir un pequeño script Bash para generar la lista de hosts.Además, el inventario es estacionario (En cierto sentido, proviene de /etc/host
documento).
Aquí hay un complemento más interesante que usa Nmap.
Usando el complemento Nmap
El complemento Nmap le permite crear su lista de inventario utilizando escáneres de red conocidos. Primero, explicaré cómo funciona Nmap cuando lo ejecuta manualmente.
[ Download a Bash shell scripting cheat sheet. ]
Curso intensivo de Nmap
Puede usar Nmap en la línea de comandos para obtener una buena visión general de las máquinas y los servicios en la red:
$ sudo nmap -v -n -p- -sT -sV -O --osscan-limit --max-os-tries 1 -oX $HOME/home_scan.xml 192.168.1.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2022-03-05 10:29 EST
NSE: Loaded 45 scripts for scanning.
Initiating ARP Ping Scan at 10:29
Scanning 254 hosts [1 port/host]
Completed ARP Ping Scan at 10:29, 5.10s elapsed (254 total hosts)
Nmap scan report for 192.168.1.0 [host down]
Nmap scan report for 192.168.1.2 [host down]
Initiating Connect Scan at 10:29
Scanning 4 hosts [65535 ports/host]
Discovered open port 443/tcp on 192.168.1.1
Discovered open port 8080/tcp on 192.168.1.1
Discovered open port 445/tcp on 192.168.1.1
Discovered open port 139/tcp on 192.168.1.1
Discovered open port 80/tcp on 192.168.1.1
Discovered open port 80/tcp on 192.168.1.4
Discovered open port 35387/tcp on 192.168.1.4
Recuerde que este escaneo es una operación que requiere mucho tiempo. Nmap comprueba todos los puertos y hosts de la red, por lo que esto puede tardar unos minutos. incluso horas Si no ajusta su consulta.
Con eso en mente, por favor mantenga estos enlaces útiles. Los usará para ajustar sus parámetros de Nmap:
Para este inventario, le interesan las máquinas en las que Ansible puede usar Secure Shell (SSH) y realizar operaciones. Restringir el número de puerto a TCP 22 acelerará considerablemente el escaneo:
# '-n': 'Never do DNS resolution',
# '-p-': 'All ports. Use -p22 to limit scan to port 22',
# '-sV': 'Probe open ports to determine service/version info',
# '-T4': 'Aggressive timing template',
# '-PE': 'Enable this echo request behavior. Good for internal networks',
# '--version-intensity 1': 'Set version scan intensity. Default is 7',
# '--disable-arp-ping': 'No ARP or ND Ping',
# '--max-hostgroup 100': 'Hostgroup (batch of hosts scanned concurrently) size',
# '--min-parallelism 20': 'Number of probes that may be outstanding for a host group',
# '--osscan-limit': 'Limit OS detection to promising targets',
# '--max-os-tries 1': 'Maximum number of OS detection tries against a target',
# '-oX -': 'Send XML output to STDOUT, avoid creating a temp file'
$ nmap -v -n -p22 -sT -sV --osscan-limit --max-os-tries 1 -oX $HOME/home_scan.xml 192.168.1.0/24
Starting Nmap 7.80 ( https://nmap.org ) at 2022-03-05 10:51 EST
NSE: Loaded 45 scripts for scanning.
Initiating Ping Scan at 10:51
Scanning 256 hosts [2 ports/host]
Completed Ping Scan at 10:51, 2.31s elapsed (256 total hosts)
Nmap scan report for 192.168.1.0 [host down]
Nmap scan report for 192.168.1.2 [host down]
Nmap scan report for 192.168.1.5 [host down]
Nmap scan report for 192.168.1.7 [host down]
...
Completed NSE at 10:51, 0.00s elapsed
Nmap scan report for 192.168.1.1
Host is up (0.0024s latency).
PORT STATE SERVICE VERSION
22/tcp closed ssh
Nmap scan report for 192.168.1.3
Host is up (0.070s latency).
...
Nmap scan report for 192.168.1.11
Host is up (0.00036s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
...
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 256 IP addresses (8 hosts up) scanned in 2.71 seconds
Pero si no le importa el escaneo de puertos, entonces reemplace -p22
y -sn
(escaneo de ping) bandera:
$ time nmap -v -n -sn --osscan-limit --max-os-tries 1 -oX $HOME/home_scan.xml 192.168.1.0/24
Read data files from: /usr/bin/../share/nmap
Nmap done: 256 IP addresses (8 hosts up) scanned in 2.52 seconds
Esta ligera diferencia podría ser un factor en una red más grande, pero este ejemplo mantiene el escaneo de puertos en el puerto 22.
Una cosa más: de ahora en adelante, no usaré -n
cambio. Si pasa, la resolución de nombres DNS se desactivará y no sabrá el nombre de la máquina que acaba de escanear.
¿Es posible extender Nmap? sí. Ansible tiene un buen complemento de código abierto que envuelve el programa de línea de comandos de Nmap y analiza los resultados. Para ilustrar cómo funciona, me gustaría compartir un script de Python llamado nmap_scan_rpt.py que correlaciona los servicios encontrados por Nmap con avisos de seguridad (esta es una de las formas en que puede ampliar la herramienta original):
$ git clone [email protected]:josevnz/home_nmap.git $HOME/home_nmap.git
pushd home_nmap/
python3 -m venv $HOME/virtualenv/home_nmap/
. ~/virtualenv/home_nmap/bin/activate
nmap_scan_rpt.py $HOME/home_scan.xml
Siéntete libre de jugar con el código. También puede ejecutar Nmap como un servicio web, pero por ahora volveré a Ansible con Nmap.
Complemento Nmap para Ansible
Ahora está listo para explorar el complemento Ansible Nmap:
# We do not want to do a port scan, only get the list of hosts dynamically
---
plugin: nmap
address: 192.168.1.0/24
strict: False
ipv4: yes
ports: no
groups:
appliance: "'Amazon' in hostname"
regular: "'host' in hostname"
Entonces pruébalo:
$ ansible-inventory -i ExtendingAnsibleWithPython/Inventories/home_nmap_inventory.yaml --lis
Esto produce un buen JSON para que lo consuma Ansible:
{
"_meta": {
"hostvars": {
"android-1c5660ab7065af69.home": {
"ip": "192.168.1.4",
"ports": []
},
"dmaf5.home": {
"ip": "192.168.1.26",
"ports": []
}
},
"all": {
"children": [
"ungrouped"
]
},
"ungrouped": {
"hosts": [
"android-1c5660ab7065af69.home",
"dmaf5.home",
"macmini2",
"new-host-2.home",
"new-host-6.home",
"raspberrypi"
]
}
}
}
Nota: No puedo hacer funcionar la característica de ‘grupos’ de jinja2. Su propósito es poner hosts en grupos dinámicos basados en sus nombres de host.
Inventario dinámico en Ansible
He cubierto mucho material, así que aquí hay un resumen rápido de lo que has hecho:
- introducido
host_list
plugin y vi algunas limitaciones obvias, especialmente cuando se usa una gran cantidad de hosts. - Aprendió rápidamente Nmap y cómo usarlo para escanear todos los hosts de la red. Usaste este escaneo para crear un inventario.
- Configure y ejecute la herramienta comunitaria Ansible Nmap y compare su funcionalidad con un escaneo manual de Nmap.
En el próximo artículo de esta serie, le mostraré cómo crear un script para su propio inventario dinámico y por qué esta podría ser una mejor opción que usar un complemento estándar.
Recuerda, puedes descargar el código y experimentar. La mejor manera de aprender es a través de la práctica y los errores.