Trabajar con el inventario de Ansible

Ansible realiza un seguimiento de la configuración de los recursos conservando listas, denominadas listas del inventario, como archivos simples (también denominados archivo host). Estas listas de inventario pueden ser estáticas o dinámicas. Las listas dinámicas se pueden actualizar automáticamente cuando se agregan, suprimen o mueven recursos de inventario.

Como muchos recursos de la Oracle Cloud Infrastructure (OCI) se agregan y suprimen con el tiempo, las listas estáticas de inventario pueden quedar obsoletas fácilmente. Las herramientas como Terraform o los SDK de OCI también pueden afectar a sus recursos.

Oracle Cloud Infrastructure proporciona un plug-in de inventario dinámico para mantener el inventario preciso de Ansible.

Para obtener más información sobre los archivos de inventario de Ansible, consulte Trabajar con el inventario y Trabajar con el inventario dinámico.

Activación del plugin de inventario

Si tiene un archivo ansible.cfg existente y esa configuración ya habilita plugins mediante enable_plugins, debe activar el complemento de inventario de OCI agregándolo también. Por ejemplo:

[inventory]
enable_plugins = oracle.oci.oci

Si aún no tiene un archivo ansible.cfg que contenga enable_plugins, no necesita agregar el plugin de inventario de OCI a la configuración.

Configuración del plugin de inventario

El único requisito para utilizar el plugin del inventario de OCI después de activarlo es proporcionar un origen de inventario para los que cuente con permisos para analizar. Los orígenes de inventario se definen en un archivo de configuración YAML. Consulte Permisos de usuario para obtener más información.

Para empezar a utilizar el plugin de inventario con un origen de configuración YAML, cree un archivo con uno de los siguientes nombres de archivo aceptados:

  • <nombrearchivo>.oci.yml
  • <nombrearchivo>.oci.yaml

Agregue plugin: oracle.oci.oci al archivo de configuración YAML.

El archivo de origen de inventario mínimo necesario para ejecutar el plugin de inventario de OCI es similar al siguiente, por ejemplo:

# demo.oci.yml
plugin: oracle.oci.oci
 
# Optional fields to specify oci connection config:
config_file: ~/.oci/config
config_profile: DEFAULT

En este ejemplo se utilizan los parámetros config_file y config_profile para que el plugin pueda utilizar la información de autenticación que se describe en el archivo de configuración de SDK y CLI. Algunos parámetros también se pueden proporcionar como variables de entorno.

Para obtener una lista completa de los parámetros y las variables de entorno que soporta el plugin, consulte Plugin de inventario de OCI. Los escenarios de inventario incluyen muchos de los parámetros disponibles.

Importante

Por defecto, el plug-in de inventario de OCI solo detecta y muestra las instancias informáticas que tienen una dirección IP pública. Consulte Preferencias de formato de nombre de host para obtener más información.

Orden de prioridad

El plugin de inventario utiliza el siguiente orden de prioridad cuando se proporciona una opción en más de una ubicación:

  1. Configuración del archivo YAML.
  2. Variables de entorno.
  3. Configuración del profile seleccionado en el archivo de configuración del OCI.

Recuperación de hosts de base de datos

Por defecto, el plugin del inventario de OCI detecta y muestra solo las instancias informáticas. Los nodos de base de datos son servidores que ejecutan software de base de datos. Los nodos de base de datos se recuperan definiendo la opción fetch_db_hosts en true. Por ejemplo:

# demo.oci.yml

# DB Hosts
plugin: oracle.oci.oci
fetch_db_hosts: true

Uso del plugin de inventario

Los plugins de inventario de Ansible permiten definir los orígenes de datos que se utilizan para compilar un inventario de hosts que Ansible utiliza para las tareas de destino. Se accede a estos orígenes de datos mediante los parámetros -i /path/to/file o -i 'host1, host2' de la línea de comandos o desde otros orígenes de configuración.

Puede ejecutar el inventario con este comando, por ejemplo:

ansible-inventory -i <filename>.oci.yml --graph

Esto produce una salida similar a la siguiente:

@all:
  |--@oci:
  |  |--compute_instance1
  |  |--compute_instance2
  |–@ungrouped:
Importante

Por defecto, el inventario se genera para todos los compartimentos del arrendamiento. Debe tener el permiso COMPARTMENT_INSPECT en el compartimento raíz para que este script pueda acceder a todos los compartimentos. Sin embargo, cuando se especifica compartment_ocid, el inventario se genera solo para el compartimento específico, por lo que solo se necesita el permiso COMPARTMENT_INSPECT en el compartimento especificado. Para obtener más información, consulte Cómo funcionan las políticas.

Para recuperar todos los detalles de la instancia, también debe tener permiso para mostrar y leer las instancias y VNIC, así como leer las VCN y subredes. Consulte Permisos de usuario para obtener más información.

Puede agregar plugins de inventario a la ruta de acceso del plugin y definir la ruta del inventario por defecto para simplificar los comandos. Agregue la ruta de inventario por defecto a la sección [defaults] del archivo ansible.cfg, o utilice la variable ANSIBLE_INVENTORY de entorno para que apunte a los orígenes de inventario. A continuación, puede ejecutar el siguiente comando para generar la misma salida que cuando se transfieren los orígenes de configuración YAML directamente:

ansible-inventory --graph

Normalmente, los plugins de inventario solo se ejecutan al inicio de una ejecución, antes de que se carguen cuadernos de estrategias, reproducciones y roles. Puede 'volver a ejecutar' un plugin mediante la tarea meta: refresh_inventory, que borra el inventario existente y vuelve a crearlo.

Salida de inventario

La lista de inventario que genera el plugin de inventario se agrupa utilizando los siguientes atributos:

  • Región en la que reside la instancia informática
  • Nombre del compartimento al que pertenece la instancia informática
  • Dominio de disponibilidad en el que está la instancia informática
  • vcn_id de la VCN en la que está la instancia de Compute
  • subnet_id de la subred en la que está la instancia informática
  • security_list_ids de la subred en la que está la instancia informática
  • image_id de la imagen utilizada para iniciar la instancia informática
  • Forma de la instancia informática
  • Etiquetas de formato libre de la instancia informática, con el nombre de grupo definido en tag_<tag_name>=<tag_value>
  • Etiquetas definidas de la instancia informática, con el nombre de grupo definido en <tag_namespace>#<tag_name>=<tag_value>
  • Metadatos de instancia informática de OCI (pares de clave-valor), con el nombre de grupo definido en <metadata-key>=<metadata-value>
  • Metadatos extendidos de las instancias informáticas de OCI (pares de clave-valor), con el nombre de grupo definido en <metadata-key>=<metadata-value>

Preferencias de formato de nombre de host

El inventario generado por el plugin del inventario de OCI solo contiene instancias que tienen una dirección IP pública por defecto. Esto resulta útil en casos en los que el nodo de controlador de Ansible está fuera de la VCN, ya que Ansible solo puede acceder a instancias que tengan direcciones IP públicas.

Puede configurar inventory_hostname en private_ip o cualquier nombre de host personalizado mediante la transferencia de expresiones Jinja2 como una lista a la opción hostname_format_preferences. La opción hostname_format_preferences toma una lista de expresiones Jinja2 en orden de prioridad para componer inventory_hostname. El plugin de inventario ignora las expresiones si el resultado es una cadena vacía o un valor "Ninguno". La instancia se ignora si ninguna de las expresiones hostname_format_preferences da como resultado un valor no vacío.

En el siguiente ejemplo, se define inventory_hostname en "display_name+'.oci.com'", "private_ip" o "public_ip":

hostname_format_preferences:
  - "display_name+'.oci.com'"
  - "private_ip"
  - "public_ip"

Las expresiones se evalúan en host_vars de cada instancia. La evaluación respeta el orden de prioridad en la configuración para componer inventory_hostname. En el ejemplo anterior, "display_name+'.oci.com'" se evalúa antes que "private_ip" y "public_ip".

Filtrado de hosts

El plugins de inventario de OCI incluye varias opciones de filtrado para filtrar los hosts devueltos por el plugin.

Exclusión de hosts del inventario

Puede transferir una lista de expresiones condicionales Jinja2 al parámetro exclude_host_filters. Cada expresión de la lista se evalúa para cada host. Cuando la expresión es verdadera, el host se excluye del inventario. El parámetro exclude_host_filters tiene prioridad sobre las opciones include_host_filters y filters.

En el siguiente ejemplo se excluyen del inventario los hosts que no están en la región "iad":

exclude_host_filters:
  - "region not in ['iad']"

Exclusión de hosts con etiquetas de formato libre

Para excluir un host del inventario mediante etiquetas de formato libre, puede utilizar la siguiente sintaxis:

exclude_host_filters:
  # filter the hosts with freeform tag with key <tag_key> which has value <tag_value>
  - "'<tag_value>' == freeform_tags.<tag_key>"
  # filter the hosts which has <tag_key> freeform tag
  - "'<tag_key>' in freefrom_tags"

Por ejemplo:

exclude_host_filters:
  - "'operating_system' in freeform_tags"
  - "'linux' == freeform_tags.operating_system"

Exclusión de hosts con etiquetas definidas

Para excluir un host del inventario mediante etiquetas definidas, puede utilizar la siguiente sintaxis:

exclude_host_filters:
  #filter the hosts with defined tag in <namespace> with <tag_key> and <tag_value>
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  # filter the hosts with <tag_key> in the <namespace> in defined tags
  - "'<tag_key>' in defined_tags.<namespace>"

Por ejemplo:

exclude_host_filters:
  - "'ansible' == defined_tags.ansible_collections_tag_namespace.managed_by"
  - "'managed_by' in defined_tags.ansible_collections_tag_namespace"

Inclusión de hosts en el inventario

Puede transferir una lista de expresiones condicionales Jinja2 al parámetro include_host_filters. Cada expresión de la lista se evalúa para cada host. Cuando la expresión es verdadera, el host se incluye en el inventario.

En el siguiente ejemplo, solo se incluyen los hosts que tienen un display_name que termina con ".oci.com" en el inventario:

include_host_filters:
  - "display_name is match('.*.oci.com')"
Nota

Las opciones include_host_filters y filters no se pueden utilizar juntas.

Inclusión de hosts con etiquetas de formato libre

Para incluir un host del inventario mediante etiquetas de formato libre, puede utilizar la siguiente sintaxis:

include_host_filters:
  # filter the hosts with freeform tag with key <tag_key> which has value <tag_value>
  - "'<tag_value>' == freeform_tags.<tag_key>"
  # filter the hosts which has <tag_key> freeform tag
  - "'<tag_key>' in freefrom_tags"

Por ejemplo:

include_host_filters:
  - "'operating_system' in freeform_tags"
  - "'linux' == freeform_tags.operating_system"

Inclusión de hosts con etiquetas definidas

Para incluir un host del inventario mediante etiquetas definidas, puede utilizar la siguiente sintaxis:

include_host_filters:
  #filter the hosts with defined tag in <namespace> with <tag_key> and <tag_value>
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  # filter the hosts with <tag_key> in the <namespace> in defined tags
  - "'<tag_key>' in defined_tags.<namespace>"

Por ejemplo:

include_host_filters:
  -  "'ansible' == defined_tags.ansible_collections_tag_namespace.managed_by"
  -  "'managed_by' in defined_tags.ansible_collections_tag_namespace"

Activación de la caché

El almacenamiento en caché se puede activar para acelerar las consultas. Puede definir opciones de almacenamiento en caché para un origen de configuración YAML individual o para varios orígenes de inventario mediante variables de entorno o archivos de configuración de Ansible. Si activa el almacenamiento en caché de un plugin de inventario sin proporcionar opciones de almacenamiento en caché específicas del inventario, el plugin de inventario utiliza las opciones de almacenamiento en caché de hechos.

A continuación se muestra un ejemplo de activación de almacenamiento en caché para un archivo de configuración YAML individual:

# demo.oci.yml
plugin: oracle.oci.oci
cache: yes
cache_plugin: jsonfile
cache_timeout: 7200
cache_connection: /tmp/oci_inventory
cache_prefix: oci

Uso de grupos dinámicos

Puede crear grupos dinámicos utilizando variables de host con la opción keyed_groups construida. La opción groups también se puede utilizar para crear grupos, y para crear y modificar variables de host. A continuación se muestra la sintaxis para grupos con claves y grupos que utilizan etiquetas:

keyed_groups
- key: freeform_tags.<tag key>
  prefix: <my_prefix>
- key: defined_tags.<namespace>.<tag key>
  prefix: <my_prefix>
groups:
  <group_name>: "'<tag_value>' == freeform_tags.<tag_key>"
  <group_name>: "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  <group_name>: "'<tag_key>' in defined_tags.<namespace>"

Por ejemplo:

# demo.oci.yml
plugin: oracle.oci.oci
regions:
  - us-phoenix-1
  - us-ashburn-1
keyed_groups:
  # add hosts to tag_Name_value groups for each oci host's tags.Name variable
  - key: tags.Name
    prefix: tag_Name_
groups:
  # add hosts to the group development if any of the dictionary's keys or values is the word 'devel'
  development: "'devel' in (tags|list)"
  # add hosts with freefrom_tags that has 'operating_system' key and 'linux' value to 'linux' group
  linux: "'linux' == freeform_tags.operating_system"
  # add hosts with freefrom tags that has 'operating_system' key to os group
  os: "'operating_system' in freeform_tags"
  # add hosts with defined tags in the namespace 'ansible_collections_tag_namespace' with tag 'managed_by' and value 'ansible'
  ansible_managed: "'ansible' == defined_tags.ansible_collections_tag_namespace.managed_by"
  # add hosts with defined tags in the namespace 'ansible_collections_tag_namespace' with tag 'managed_by'
  cm_managed_hosts: "'managed_by' in defined_tags.ansible_collections_tag_namespace"

En este ejemplo, se produce un resultado similar al siguiente:

@all:
  |--@development:
  |  |--compute_instance1
  |  |--compute_instance2
  |--@linux:
  |  |--compute_instance1
  |--@os:
  |  |--compute_instance1
  |  |--compute_instance2
  |--@ansible_managed:
  |  |--compute_instance1
  |--@cm_managed_hosts:
  |  |--compute_instance2
  |--@ungrouped

Si un host no tiene las variables especificadas en la configuración, el host no se agrega a grupos que no sean los que crea el plugin de inventario y la variable de host ansible_host no se modifica.

Escenarios de inventario

En las siguientes secciones se incluyen ejemplos de configuración que abarcan escenarios de inventario comunes.

Recuperación de todos los hosts informáticos

Para recuperar todos los hosts, la configuración puede ser tan sencilla como el siguiente ejemplo:

plugin: oracle.oci.oci

Recuperación solo de hosts de base de datos

Para recuperar todos los nodos que alojan el software de base de datos al excluir hosts informáticos, la configuración sería similar al siguiente ejemplo:

plugin: oracle.oci.oci

# fetch databse hosts
fetch_db_hosts: true
# don't fetch Compute hosts
fetch_compute_hosts: False

Recuperación de hosts de regiones específicas

Para recuperar hosts solo en las regiones especificadas, la configuración sería similar al siguiente ejemplo:

plugin: oracle.oci.oci

# Fetch only the hosts in the regions us-ashburn-1, us-phoenix-1
regions:
  - us-ashburn-1
  - us-phoenix-1

Definición de nombre de host de inventario

Para definir el formato del nombre de host de inventario utilizado en el inventario, la configuración incluiría una sección similar al siguiente ejemplo:

plugin: oracle.oci.oci

# Sets the inventory_hostname to either "display_name+'.oci.com'", "public_ip", "private_ip", or "id" 
# "display_name+'.oci.com'" has more preference than "public_ip", "private_ip", "id".
hostname_format_preferences:
  - "display_name+'.oci.com'"
  - "public_ip"
  - "private_ip"
  - "id"

Consulte Preferencias de formato de nombre de host para obtener más información.

Exclusión de hosts del inventario

Para utilizar una expresión condicional Jinja2 para excluir hosts del inventario, la configuración incluiría una sección similar al siguiente ejemplo:

plugin: oracle.oci.oci

# Excludes hosts that are not in the region 'iad' from the inventory
exclude_host_filters:
  - "region not in ['iad']"

Consulte Filtrado de hosts para obtener más información.

Inclusión de hosts en el inventario

Para utilizar una expresión condicional Jinja2 para incluir hosts en el inventario, la configuración incluiría una sección similar al siguiente ejemplo:

plugin: oracle.oci.oci

# Includes only the hosts that have a display_name ending with '.oci.com' in the inventory
include_host_filters:
  - "display_name is match('.*.oci.com')"

Consulte Filtrado de hosts para obtener más información.

Nota

Las opciones include_host_filters y filters no se pueden utilizar juntas.

Recuperación de hosts de compartimentos específicos

En el siguiente ejemplo se muestra cómo recuperar todos los hosts de los compartimentos especificados:

# Fetch all hosts
plugin: oracle.oci.oci

# Select compartment by OCID or name
compartments:
  - compartment_ocid: <ocid1.compartment.oc1..exampleuniqueID>
    fetch_hosts_from_subcompartments: false

  - compartment_name: "<compartment_name>"
    parent_compartment_ocid: <ocid1.tenancy.oc1..exampleuniqueID>

Otras opciones

La siguiente configuración de ejemplo combina los escenarios anteriores con más opciones de configuración:

# Fetch all hosts
plugin: oracle.oci.oci

# Optional fields:
config_file: ~/.oci/config
config_profile: DEFAULT

# Example select regions
regions:
  - us-ashburn-1
  - us-phoenix-1

# Enable threads to speedup lookup
enable_parallel_processing: yes

# Select compartment by ocid or name
compartments:
  - compartment_ocid: <ocid1.compartment.oc1..exampleuniqueID>
    fetch_hosts_from_subcompartments: false

  - compartment_name: "<compartment_name>"
    parent_compartment_ocid: <ocid1.tenancy.oc1..exampleuniqueID>

# Sets the inventory_hostname. Each item is a Jinja2 expression and it gets evaluated on host_vars.
hostname_format_preferences:
  - "display_name+'.oci.com'"
  - "private_ip"
  - "public_ip"

# Excludes a host from the inventory when any of the Jinja2 expression evaluates to true.
exclude_host_filters:
  - "region not in ['iad']"
  - "'<tag_key>' in freeform_tags"
  - "'<tag_value>' == freeform_tags.<tag_key>"
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  - "'<tag_key>' in defined_tags.<namespace>"

# Includes a host in the inventory when any of the Jinja2 expression evaluates to true.
include_host_filters:
  - "display_name is match('.*.oci.com')"
  - "'<tag_key>' in freeform_tags"
  - "'<tag_value>' == freeform_tags.<tag_key>"
  - "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  - "'<tag_key>' in defined_tags.<namespace>"

# Example group results by key
keyed_groups
- key: freeform_tags.<tag key>
  prefix: <my_prefix>
- key: defined_tags.<namespace>.<tag key>
  prefix: <my_prefix>

groups:
  <group_name>: "'<tag_value>' == freeform_tags.<tag_key>"
  <group_name>: "'<tag_value>' == defined_tags.<namespace>.<tag_key>"
  <group_name>: "'<tag_key>' in defined_tags.<namespace>"

# Example to create and modify a host variable
compose:
  ansible_host: display_name+'.oracle.com'

# Example flag to turn on debug mode
debug: true

# Enable Cache
cache: yes
cache_plugin: jsonfile
cache_timeout: 7200
cache_connection: /tmp/oci-cache
cache_prefix: oci_

# DB Hosts
fetch_db_hosts: True

# Compute Hosts (bool type)
fetch_compute_hosts: True

# Process only the primary vnic of a compute instance
primary_vnic_only: True

Solución de problemas del plugin de inventario

Si la lista de inventario generada por el plugin del inventario de OCI no incluye todas las instancias informáticas de su arrendamiento, revise la siguiente información.

Permisos de usuario

Asegúrese de que el usuario tiene los siguientes permisos de política. El OCID del usuario se especifica mediante la variable de entorno OCI_USER o la sección profile del archivo de configuración de SDK y CLI.

Para ver una lista de permisos para operaciones de API, consulte Detalles de los servicios básicos.

El plugin de inventario realiza llamadas de API para las siguientes operaciones:

  • ListCompartments
  • GetCompartment
  • ListVNICAttachments
  • GetVNIC
  • GetSubnet
  • GetVLAN
  • GetVCN
  • ListInstances
  • GetInstance
  • ListDBNodes
  • ListDBSystems
  • ListRegionSubscriptions

Para obtener más información

La información detallada sobre el uso del plugin de inventario de OCI está disponible en docs.oracle.com y readthedocs.io.

También puede utilizar el siguiente comando para consultar la documentación del plugin:

ansible-doc -t inventory oracle.oci.oci

Consulte la documentación oficial de Ansible para obtener más información sobre los plugins de inventario.