Ansible module approach
f5os_restconf_config
uses the f5networks.f5os
collection to connect to the F5OS system, which uses the ansible httpapi
connection type.
f5os_restconf_config
is not just a simple API client, it performs multiple tasks in the background to simplify the interaction with the F5OS RESTCONF API while allowing a maximum of flexibility.
f5os_restconf_config arguments
vars:
f5os_api_prefix: {{ '/restconf' if ansible_httpapi_port == '8888' else '/api' }}
f5_ps_ansible.f5os.f5os_restconf_config:
uri: "{{ f5os_api_prefix }}/data/api-endpoint/of/resource"
method: PUT # PUT or PATCH, PUT is the default
config: .. # The desired config of the resource
state: present # present or absent, present is the default
keys_ignore: [] # a list of keys in the desired config
# and current config to ignore recursively(!)
config_query: # a JMESPath query to apply to the current configuration
# before it is compared to the desired configuration
GET before PUT/PATCH
The first action is to issue a HTTP GET
to retrieve the current config
(actual resource configuration) and current state
(resource currently present or absent?) from the F5OS system.
If the resource does not exist, the current state
is absent
.
Depending on the desired state
(defined as state: present/absent
, present
is the default), a configuration action would be taken or not.
If the desired state
is absent
and matches the current state
, then no action would be taken and ansible would indicate that with no change made (“ok”).
Otherwise if the desired state
is present
and the current state
is absent
the desired config
(indicated in the config:
specification of the f5os_restconf_config
module) will be submitted using the desired method
(PUT is the default, PATCH is another option).
desired config
and current config
However if both, current state
and desired state
are present
, the current config
will be compared to the desired config
to identify if a change is necessary.
To compare both configs requires:
- to ignore the
state
(and*:state
) elements (keys/properties in json) in thecurrent config
- take care of type differences, such as numbers represented as strings (this differs across resource types and API endpoints)
- format bool values properly (“true”, true, True, ..) in the
desired config
(this is a common issue with Ansible/python booleans and YAML) - to reduce the scope of comparison to relevant config as the
desired config
can be a subset of thecurrent config
Therefore f5os_restconf_config
will perform the following actions:
- remove the
state
(and*:state
) keys from thecurrent config
JSON data structure (actually python dict) - convert all numeric values to strings
- format bool values properly
- see below
Scope of comparison: desired config
vs. current config
Sometimes a config operation is performed on a subset of the overall configuration element or resource, this is specifically true when using the PATCH
method. PATCH allows partial updates to a subset of settings.
This, however, is a problem when trying to determine if the desired config
differs from the current config
as both are not equal.
f5os_restconf_config
therefore offers two options to deal with this challenge:
keys_ignore
config_query
Option keys_ignore
keys_ignore
expects a list of keys which will be removed from the current config
recursively before comparing it the desired config
.
Assuming keys_ignore: ["other"]
the below data would be equal:
# desired config
config:
element:
setting-one: 1
# current config
config:
element:
setting-one: 1
other: # will be ignored
key: value
Option config_query
config_query
applies the specified JMESPath query to the current config
.
The jmespath python module is required for this option to work.
For the previous example, the below jmespath query would achieve the same as keys_ignore: ["other"]
:
f5_ps_ansible.f5os.f5os_restconf_config:
uri: ..
config: ..
config_query: |-
{config: {element: {"setting-one": config.element."setting-one"}}}
Summary
Depending on the complexity of the data returned by the API either keys_ignore
or config_query
should be used.