Oracle Cloud Infrastructure Documentation

Using the Dynamic Inventory Script

Ansible tracks configuration resources by preserving lists, called inventory lists, as simple list files (also sometimes called a hostfile). These inventory files can be either simple static lists, or they can be dynamic lists that automatically update when inventory resources are added, deleted, or moved. For more information about Ansible inventory files, see Working with Inventory. See also, Working with Dynamic Inventory.

When using Ansible to work with hosts that you have provisioned in Oracle Cloud Infrastructure, static inventory lists can cause problems because Compute instances are added and deleted over time. They can also be affected by external tools such as Terraform, or by the Oracle Cloud Infrastructure SDKs.

Having up-to-date and accurate inventory lists is essential for running Ansible playbooks. Oracle Cloud Infrastructure provides you with a script that you can download and run to ensure that your instance inventory list is always up-to-date. The script ensures that you always have the current set of Oracle Cloud Infrastructure compute instances available to your playbooks.

Download and Configure the Dynamic Inventory Script

Download the dynamic inventory script (oci_inventory.py) and the default configuration file (oci_inventory.ini) from the following:

Important

Before you can use the script, ensure that you have a valid Oracle Cloud Infrastructure configuration. For guidance configuring ~/.oci/config, see SDK and CLI Configuration File.

Script and Configuration Details

The Python script, oci_inventory.py, uses the Oracle Cloud Infrastructure Python SDK to query compute instances in your Oracle Cloud Infrastructure tenancy and then uses this information to create a dynamic inventory that you can use with your Ansible playbooks. Use arguments in the Python script to control the configuration profile and the tenancy compartment that you query against.

You can use the configuration file, oci_inventory.ini, to control how inventory details are cached, and to control which Oracle Cloud Infrastructure profile to use. This file allows you to modify host names, and to control how hosts are named in the inventory list that is generated.

Command-Line Arguments

The oci_inventory.py script accepts the following command-line arguments:

usage: oci_inventory.py [-h] [--list] [--host HOST] [-config CONFIG_FILE]
                        [--profile PROFILE] [--compartment COMPARTMENT]
                        [--parent-compartment-ocid PARENT_COMPARTMENT_OCID]
                        [--fetch-hosts-from-subcompartments] [--refresh-cache]
                        [--debug] [--auth {api_key,instance_principal}]
                        [--enable-parallel-processing]
                        [--max-thread-count MAX_THREAD_COUNT]
                        [--freeform-tags FREEFORM_TAGS]
                        [--defined-tags DEFINED_TAGS]Produce an Ansible Inventory file based on OCIoptional arguments:
  -h, --help            show this help message and exit
  --list                List instances (default: True)
  --host HOST           Get all information about a compute instance
  -config CONFIG_FILE, --config-file CONFIG_FILE
                        OCI config file location
  --profile PROFILE     OCI config profile for connecting to OCI
  --compartment COMPARTMENT
                        Name of the compartment for which dynamic inventory
                        must be generated. If you want to generate a dynamic
                        inventory for the root compartment of the tenancy,
                        specify the tenancy name as the name of the
                        compartment.
  --parent-compartment-ocid PARENT_COMPARTMENT_OCID
                        Only valid when --compartment is set. Parent
                        compartment ocid of the specified compartment.Defaults
                        to tenancy ocid.
  --fetch-hosts-from-subcompartments
                        Only valid when --compartment is set. Default is
                        false. When set to true, inventory is built with the
                        entire hierarchy of the given compartment.
  --refresh-cache, -r   Force refresh of cache by making API requests to OCI.
                        Use this option whenever you are building inventory
                        with new filter options to avoid reading cached
                        inventory. (default: False - use cache files)
  --debug               Send debug messages to STDERR
  --auth {api_key,instance_principal}
                        The type of authentication to use for making API
                        requests. By default, the API key in your config will
                        be used. Set this option to `instance_principal` to
                        use instance principal based authentication. This
                        value can also be provided in the
                        OCI_ANSIBLE_AUTH_TYPE environment variable.
  --enable-parallel-processing
                        Inventory generation for tenants with huge number of
                        instances might take a long time.When this flag is
                        set, the inventory script uses thread pools to
                        parallelise the inventory generation.
  --max-thread-count MAX_THREAD_COUNT
                        Only valid when --enable-parallel-processing is set.
                        When set, this script uses threads to improve the
                        performance of building the inventory. This option
                        specifies the maximum number of threads to use.
                        Defaults to 50. This value can also be provided in the
                        settings config file.
  --freeform-tags FREEFORM_TAGS
                        Freeform tags provided as a string in valid JSON
                        format. Example: { "stage": "dev", "app": "demo"} Use
                        this option to build inventory of only those hosts
                        which are tagged with all the specified key-value
                        pairs.
  --defined-tags DEFINED_TAGS
                        Defined tags provided as a string in valid JSON
                        format. Example: {"namespace1": {"key1": "value1",
                        "key2": "value2"}, "namespace2": {"key": "value"}} Use
                        this option to build inventory of only those hosts
                        which are tagged with all the specified key-value
                        pairs.

Environment Variables

The oci_inventory.py script accepts several environment variables, which are listed in the following table.

Environment Variable Description
OCI_CONFIG_FILE Specifies which Oracle Cloud Infrastructure SDK configuration file to use.
OCI_INI_PATH Specifies which inventory script configuration file to use.
OCI_CONFIG_PROFILE Species which profile in the SDK configuration file to use.
OCI_USER_ID Specifies the OCID of the user to use for fetching the inventory.
OCI_USER_FINGERPRINT Specifies the user's key-pair fingerprint that is being used to fetch the inventory.
OCI_USER_KEY_FILE Specifies the full path to the private key of the user that is being used to fetch the inventory. The path must include the private key file name.
OCI_TENANCY Specifies the OCID of the tenancy to use for fetching the inventory.
OCI_REGION Specifies the Oracle Cloud Infrastructure region to use for fetching the inventory.
OCI_USER_KEY_PASS_PHRASE Specifies the pass phrase for the key (if the key is encrypted) to use for fetching the inventory.
OCI_CACHE_DIR Specifies the directory where the inventory script cache files reside. The script creates a file named ansible-oci.cache to this directory.
OCI_CACHE_MAX_AGE The number of seconds that a cache file is valid. To disable caching and retrieve the latest inventory, set this value to 0 (zero).
OCI_HOSTNAME_FORMAT The format for listing host names in the inventory file that is generated. Use fqdn to list hosts using the fully qualified domain name (FQDN) of the instance. Use public_ip to list hosts using public IP address. Use private_ip to list hosts using private IP address.
OCI_ANSIBLE_AUTH_TYPE Specifies which type of authentication to use for making API requests. By default, the API key in your configuration is used. To use instance-principal-based authentication, set the value to instance_principal.

Order of Precedence

Following is the order of precedence for configurations that are used by the dynamic inventory script:

  1. Command-line arguments.
  2. Environment variables.
  3. Configuration settings in the selected profile in your Oracle Cloud Infrastructure configuration file.

Note

The default configuration file used by the inventory script is ./oci_inventory.ini. The Oracle Cloud Infrastructure SDK configuration file, however, defaults to ~/.oci/config. The script reads the DEFAULT profile from the config file if no profile name is specified.

The inventory list that is generated by the dynamic inventory script is grouped using the following attributes:

  • The region in which the compute instance resides.
  • The name of the compartment the compute instance belongs to.
  • The Availability Domain the compute instance is in.
  • The vcn_id of the vcn the compute instance is in.
  • The subnet_id of the subnet the compute instance is in.
  • The security_list_ids of the subnet the compute instance is in.
  • The image_id of the image used to launch the compute instance.
  • Shape of the compute instance.
  • The instance's free-form tags, with the group name set to tag_<tag_name>=<tag_value>.
  • The instance's defined tags, with the group name set to <tag_namespace>#<tag_name>=<tag_value>.
  • Oracle Cloud Infrastructure compute instance metadata (key-value pairs), with the group name set to <metadata-key>=<metadata-value>.
  • Oracle Cloud Infrastructure compute instance extended metadata (key-value pairs), with the group name set to <metadata-key>=<metadata-value>.

Important

By default, all non-alphanumeric characters in group names and host names are replaced with an underscore (_) when the inventory is generated except hash (#), equals (=), period (.) and dash (-) . This allows you to use these names as Ansible group names. To disable this default substitution, set sanitize_names to False in the dynamic inventory settings file, whose default location is ./oci_inventory.ini). To also replace the dash (-) when sanitize_names is True, set replace_dash_in_names to True in the settings file.

How to Use Dynamic Inventory

Using Dynamic Inventory During Playbook Execution

To use your dynamic inventory, first ensure that you have a correct Oracle Cloud Infrastructure SDK configuration file. Optionally, you can also have an oci_inventory.ini file.

Invoke ansible-playbook using the following command:

$ ansible-playbook -i <path-to-inventory-file>/oci_inventory.py <your-playbook-using-the-generated-inventory>

Alternatively, use the ANSIBLE_HOSTS environment variable by using the following command:

$ ANSIBLE_HOSTS=<path-to-inventory-file>/oci_inventory.py ansible-playbook <your-playbook-using-the-generated-inventory>

Disabling the Cache and Fetching the Latest Inventory List

If you are running the dynamic inventory script in a stand-alone manner, you can ignore the cached inventory list and fetch the most current inventory list by using the --refresh (-r) argument, as shown in the following example:

$ \<path-to-inventory-file\>/oci_inventory.py --refresh

If instead you use the inventory script during an Ansible playbook invocation, set the OCI_CACHE_MAX_AGE environment variable to 0 (zero) to ignore the cached list, and fetch the latest compute instance, as shown in the following example:

$ OCI_CACHE_MAX_AGE=0 ansible-playbook -i <path-to-inventory-file>/oci_inventory.py <your-playbook-using-the-generated-inventory>

Debugging the Inventory List

To examine the inventory list, run the dynamic inventory script using the --list argument, as shown here:

$ \<path-to-inventory-file\>/oci_inventory.py --list

If you wish to print additional debug information to STDERR, use the --debug argument, as shown:

$ \<path-to-inventory-file\>/oci_inventory.py --debug

Retrieve Information About a Host

You can configure the inventory script to provide information about a specified host by using the --host argument and providing the host's IP address, as shown:

$ \<path-to-inventory-file\>/oci_inventory.py --host <host IP address>

The command returns the following set of variables and values:

{
  "availability_domain": "IwGV:US-ASHBURN-AD-1",
  "compartment_id": "ocid1.compartment.oc1..<xxxxxEXAMPLExxxxx>",
  "defined_tags": {},
  "display_name": "ansible-test-instance",
  "extended_metadata": {},
  "freeform_tags": {},
  "id": "ocid1.instance.oc1.iad.<xxxxxEXAMPLExxxxx>",
  "image_id": "ocid1.image.oc1.iad.<xxxxxEXAMPLExxxxx>",
  "ipxe_script": null,
  "launch_mode": "CUSTOM",
  "launch_options": {
     "boot_volume_type": "ISCSI",
     "firmware": "UEFI_64",
     "network_type": "VFIO",
     "remote_data_volume_type": "ISCSI"
  },
  "lifecycle_state": "AVAILABLE",
  "metadata": {
     "baz": "quux",
     "foo": "bar"
  },
  "region": "iad",
  "shape": "VM.Standard1.1",
  "source_details": {
    "image_id": "ocid1.image.oc1.iad.<xxxxxEXAMPLExxxxx>",
  "source_type": "image"
  },
  "time_created": "2018-01-16T12:13:35.336000+00:00"
}

Troubleshooting the Dynamic Inventory Script

If the inventory list generated by the inventory script does not include all of the compute instances in your tenancy, review the following information.

User Permissions

Ensure that the user OCID (specified using either the OCI_USER environment variable, or the profile section in your SDK configuration file) has the policy permissions to list the compute instances. To see a list of permissions for API operations, see Details for the Core Services.

The inventory script makes API calls for the following operations:

  • ListCompartments
  • ListVNICAttachments
  • GetSubnet
  • GetVCN
  • GetVNIC
  • GetInstance

Hostname Format

The default for OCI_HOSTNAME_FORMAT is public_ip. The dynamic inventory generated using OCI_HOSTNAME_FORMAT set to public_ip contains only compute instances that have a public IP address. This can be useful in cases where the Ansible controller node is outside the VCN, since Ansible can only reach instances that have public IP addresses.

However, if running Ansible in a compute instance within your VCN, and it has access to all of the subnets within your VCN, including compute instances that have private IP addresses, you must set the OCI_HOSTNAME_FORMAT to private_ip to list compute instances using their private IP addresses.