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 configcan be a subset of thecurrent config
Therefore f5os_restconf_config will perform the following actions:
- remove the
state(and*:state) keys from thecurrent configJSON 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_ignoreconfig_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.