f5 Ansible
f5 Ansible
Release 1.0.0
F5 Networks
1 Getting Started 3
2 Version support 5
4 Connection or delegation 11
6 Filing Issues 17
7 Module Index 19
10 Guidelines 189
11 Architecture 193
13 Upstreaming 209
20 pycodestyle 237
i
21 Design Patterns 239
ii
F5 Ansible Documentation, Release 1.0.0
This project implements a set of Ansible modules for the BIG-IP platform from F5 Networks.
You can use these modules to create, edit, update, and delete configuration objects on a BIG-IP.
The code is open source, and . Additionally, some modules have been promoted to the and .
User Documentation 1
F5 Ansible Documentation, Release 1.0.0
2 User Documentation
CHAPTER 1
Getting Started
Install the latest version of Python (2.7 minimum) if you do not already have it.
•
3
F5 Ansible Documentation, Release 1.0.0
To view dependencies for a specific module, view the module’s Documentation > Requirements section.
Version support
F5 develops the Ansible modules in tandem with the REST API, and newer versions of BIG-IP provide better support.
F5 has tested these versions of BIG-IP with the Ansible modules:
• 12.1.0
• 12.0.0
• 11.6.0
You may need a later version, depending on what the REST functionality needs.
Note: F5 Ansible modules are not currently supported by F5.
If you need help with anything related to these modules, F5 recommends that you open an issue .
When communicating with F5 on the Issues page, use the github user interface, rather than email.
You should not expose the name of your company when communicating an issue in a public forum.
If you need more in-depth technical assistance, you’re free to ask us to ping you offline and we can handle things there.
5
F5 Ansible Documentation, Release 1.0.0
# Tested platforms:
#
# - NA
#
The above doc block tells you that F5 has not yet tested this particular module on any platforms. This is a fairly safe
bet that the module is not complete yet.
Therefore, F5 does not recommend filing bugs against this module.
Here is another example:
# Tested platforms:
#
# - 11.6.0
# - 12.0.0
#
This module specifies the versions of BIG-IP that F5 has tested. Therefore, you can consider this module to be
“complete” and ready for use.
You can file bugs against these modules.
Follow this tutorial to create a pool, add two nodes to that pool, and assign a virtual server to serve requests to the
nodes in the pool.
You can create your own yaml file to use as a playbook, or follow along with .
Begin by placing the following in your site.yaml:
---
Your BIG-IP is probably not called big-ip01.internal. It might be a different hostname or even an IP address.
Whichever it is, place it in the hosts line.
A pool represents a collection of resources. These resource typically deliver a service that is identical. By assigning
them to a pool, the BIG-IP is able to distribute requests among them.
Add the following to your site.yaml to create a pool called web:
tasks:
- name: Create a pool
bigip_pool:
lb_method: "ratio_member"
name: "web"
password: "admin"
server: "big-ip01.internal"
slow_ramp_time: "120"
user: "admin"
validate_certs: "no"
delegate_to: localhost
7
F5 Ansible Documentation, Release 1.0.0
Now you want to create the nodes in your BIG-IP configuration. Nodes represent the actual devices on your network.
They could be physical gear, VMs, or other devices.
To add the two nodes, put the following in your site.yaml:
Note: It is important that the remaining tasks align vertically with the Add a pool task above. If the spacing
doesn’t line up, Ansible will raise an error.
With the pool created and your nodes in place, you now want to add those nodes to the pool. At this point you can
refer to those nodes as pool members.
- host: "10.10.10.20"
name: "node-2"
Now that you created your pool and the nodes are members of that pool, you want to create a virtual IP address so that
external requests go to the pool members.
The below example uses 172.16.10.108 as the external address, so you likely need to change it for your own
environment.
To create a virtual server, add the following to your site.yaml:
Curious what else is possible with the current modules? Interested in test-driving the modules under development?
Refer to the sidebar for links relevant to your interests.
Want to know the difference between delegate_to and connection:local? See Connection or delegation.
Connection or delegation
Sometimes you might see examples of F5 Ansible playbooks that use connection: local:
tasks:
...
But other times, you will see delegation used. For example:
tasks:
- name: This is a task
bigip_command:
commands:
- tmsh list ltm virtual
delegate_to: localhost
There are three major differences between connection: local and delegate_to: localhost:
• connection: local applies to all hosts
• delegate_to applies to specific hosts
• delegate_to runs your task on one host in the context of another host
11
F5 Ansible Documentation, Release 1.0.0
First, connection: local applies to all hosts in the playbook. If you find yourself mixing and matching BIG-IP hosts
with things like web servers, it would cause your legitimate ssh connections to fail.
This is because when you specify connection: local, every host is now considered to have 12.0.0.1 as their IP address.
This is likely not what you want.
For example, the following playbook is not what you want.
tasks:
- name: Disable pool member for upgrading
bigip_pool_member:
pool: foo
name: "{{ inventory_hostname }}"
state: disabled
The second task is not what you want because it attempts to run the apt module on your local machine. Your
playbook, however, specifically states that it wants to upgrade the remote webserver.
4.3 Delegation
You can remedy this situation with delegate_to. For the most part, you will use this feature when the connection line
is set to ssh (the default).
Delegation allows you to mix and match remote hosts. You continue to use an SSH connection for legitimate purposes,
such as connecting to remove servers, but for the devices that don’t support this option, you delegate their tasks.
For example, this playbook will correct your problem:
tasks:
- name: Disable pool member for upgrading
bigip_pool_member:
pool: foo
name: "{{ inventory_hostname }}"
state: disabled
delegate_to: localhost
The delegate_to parameter delegates the running of the task to some completely different machine.
However, instead of the module having access to that totally different machine’s facts, it instead has the facts of the
inventory item where the delegation happened. This is using the context of the host.
4.4 Summary
Quiz time.
In the above example, even though the first and third tasks are running on the Ansible controller (instead of the remote
webserver), what is the value of the {{ inventory_hostname }} variable?
1. localhost
2. my-web-server
3. something else
If you answered my-web-server then you are correct.
This is context. The task executed on localhost using my-web-server‘s context, and therefore, it is facts.
4.4. Summary 13
F5 Ansible Documentation, Release 1.0.0
When you install Ansible, it includes some F5 modules. These modules are “stable.”
Other F5 modules are not yet installed when you install Ansible. These modules are “unstable.”
The tutorials on this site generally use modules that are stable.
You might need to use unstable modules. For example, you may need to test something, or you just can’t wait for a
module to become stable.
You can install these unstable modules on your system in one of a few ways.
Ansible allows you to put modules in a location that is relative to the project you are working on.
To accomplish this, ensure that an ansible.cfg file exists in the directory that you run Ansible from.
Inside the ansible.cfg file, add the following code.
[defaults]
library=./library
This code instructs Ansible to look for modules in a directory called library that is relative to where the ansible.cfg
file exists.
You can take the modules in the f5-ansible repository and put them in that directory.
Note: Specifying a library directory does not override the system location where Ansible searches for modules.
It only tells Ansible to “look here first” when importing a module. Therefore, if a module in the specified library
directory does not exist, Ansible will fall back to the system location and look for the module there.
You can also specify multiple locations by separating them with a colon. For example, if you have two different
directories that have two different sets of modules in them, you might do something like this.
15
F5 Ansible Documentation, Release 1.0.0
[defaults]
library=./library:./unstable
In the example above, when looking for a module named foo.py, Ansible will follow this order:
1. ./library/foo.py
2. ./unstable/foo.py
3. Recursively through /usr/local/lib/PYTHON_VERSION/site-packages/ansible/modules/
Whichever method you choose is up to you.
Different systems can put Ansible in different locations. The recommended way to install Ansible (via pip) puts the
modules here:
• /usr/local/lib/PYTHON_VERSION/site-packages/ansible/modules/extras/network/f5/
To install the F5 modules in this repository, you can copy the contents of the library/ directory that F5 provides into
the location mentioned above.
On Mac OS X, you can use the following location for the modules:
• /Library/Frameworks/Python.framework/Versions/[PYTHON_VERSION]/lib/python[PYTHON_VERSION]/site-
packages/ansible/modules/extras/network/f5
For example.
cp library/* /usr/local/lib/PYTHON_VERSION/site-packages/ansible/modules/extras/
˓→network/f5/
This command overwrites all of the modules with the ones in this repository. If you want only one or two modules,
then just copy those. For example:
cp library/bigip_iapp_service.py /usr/local/lib/PYTHON_VERSION/site-packages/ansible/
˓→modules/extras/network/f5/
5.3 Caveats
If you use method #1 and then update your Ansible installation, the update will remove the changes you had made to
your installation.
For this reason, F5 recommends you put modules in your own personal directory and referencing that directory through
your ansible.cfg file.
Filing Issues
Issues, you’ll inevitably run into them. The F5 Module developers are only human (though lauded as superhuman at
times) and therefore we are bound to make mistakes. When we do, it is incumbent upon you, the reader, to call us to
task to fix these issues. Let’s look more at what it takes to file a good, high quality issue, that will allow us to triage
the problem as quickly as possible and get to a solution.
6.1 Be verbose
When you file an issue with the F5 Ansible modules, we will present you with an Issue template. In it we will ask you
questions about your environment, what F5 product and version you are using, etc.
What we’re really interested in here is gathering information so that we can reproduce your environment. We refer
to this reproduction as a “repro”. For us to be successful in repro’ing your issue, we need...no, fanatically demand!...
information about your environment. The more the merrier...to a degree.
Some things we want to know are
• What F5 product?
• What version of that product?
• What Ansible version?
• What python version?
• Whether or not you are using a module in Ansible upstream or one directly from this repo (we have hashes for
this)
• Ansible plays that reproduce the problem
• If this is a feature request, tmsh commands that can be used to meet your needs
• If this is a feature request for a module, an example (in your own YAML) what you think the parameters to the
module would look like.
• Whether you have uploaded a qkview to F5 (we will ask you to contact us offline if you have so we can find
your account)
17
F5 Ansible Documentation, Release 1.0.0
and the list goes on and on. Don’t worry, you don’t need to remember all of the above after reading this, we’ll ask you
again in the Issue template. It all helps, us get a better idea of how your device is configured and how your Ansible
environment is configured.
Some of the things that we do not want, and will never ask for are
• passwords
• license keys
• for you to publicly disclose your company or company contact info. We may as you to contact us “offline”
though.
I need to harp on this because this is something that some people do...and it’s not something you should do.
Two things happen when you comment on closed issues
• We can’t repro is properly in our code-base
• We don’t usually see the notification for it
Let’s take a moment to illustrate why commenting on old issues is a problem for our code base.
You see, when you open an Issue with us, we will create new files in the integration test directory that are named after
your issue.
For example, if you open an issue and it is given the number 1234, then we will create an issue-01234.yaml in our
source tree. This file is related to your issue and no other issues. It is where we, the developers, will work to ensure
that your problem is solved and that we have a historical record of your problem so that all future work we do on the
F5 Ansible modules will continue to work for whatever problem it is that we solved.
This is our means by which we repro your issue, or (in technical mumbo-jumbo) “create a repro” of your issue.
If you do not create a new issue, then this who process is thrown into chaos. We would need to re-visit old stuff and
make changes to previously working code. We would now have a conflict where-by we wouldnt know which issue
this code was meant to fix. We wouldn’t have a clean repro that we could archive as time went on, etc etc etc.
Plain and simple, do not comment on closed issues.
Module Index
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
19
F5 Ansible Documentation, Release 1.0.0
Options
Examples
password: secret
name: active_policy
state: present
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Sends an arbitrary command to an BIG-IP node and returns the results read from the device. This module
includes an argument that will cause the module to wait for a specific condition before returning or timing out
if the condition is not met.
Options
Examples
- name: run show version and check to see if output contains BIG-IP
bigip_command:
commands: show sys version
wait_for: result[0] contains BIG-IP
server: lb.mydomain.com
password: secret
user: admin
validate_certs: no
delegate_to: localhost
bigip_command:
commands:
- show sys version
- list ltm virtual
server: lb.mydomain.com
password: secret
user: admin
validate_certs: no
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manages a BIG-IP configuration by allowing TMSH commands that modify running configuration, or merge
SCF formatted files into the running configuration. Additionally, this module is of significant importance be-
cause it allows you to save your running configuration to disk. Since the F5 module only manipulate running
configuration, it is important that you utilize this module to save that running config.
Options
Examples
- name: Reset the BIG-IP configuration, for example, to RMA the device
bigip_config:
reset: yes
save: yes
server: lb.mydomain.com
password: secret
user: admin
validate_certs: no
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Allows one to run different config-sync actions. These actions allow you to manually sync your configuration
across multiple BIG-IPs when those devices are in an HA pair.
Options
Examples
- name: Sync configuration from most recent device to the current host
bigip_configsync_actions:
device_group: foo-group
sync_most_recent_to_device: yes
server: lb.mydomain.com
user: admin
password: secret
validate_certs: no
delegate_to: localhost
validate_certs: no
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the objectpath Python package on the host. This is as easy as pip install objectpath.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manages device IP configuration settings for HA on a BIG-IP. Each BIG-IP device has synchronization and
failover connectivity information (IP addresses) that you define as part of HA pairing or clustering. This module
allows you to configure that information.
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• This module is primarily used as a component of configuring HA pairs of BIG-IP devices.
• Requires BIG-IP >= 12.1.x.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Managing device groups allows you to create HA pairs and clusters of BIG-IP devices. Usage of this module
should be done in conjunction with the bigip_configsync_actions to sync configuration across the pair
or cluster if auto-sync is disabled.
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• This module is primarily used as a component of configuring HA pairs of BIG-IP devices.
• Requires BIG-IP >= 12.1.x.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manages members in a device group. Members in a device group can only be added or removed, never updated.
This is because the members are identified by unique name values and changing that name would invalidate the
uniqueness.
Options
Examples
state: present
user: admin
with_items: "{{ hostvars.keys() }}"
run_once: true
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
- name: Set the banner for the SSHD service from a string
bigip_device_sshd:
banner: enabled
banner_text: banner text goes here
password: secret
server: lb.mydomain.com
user: admin
delegate_to: localhost
- name: Set the banner for the SSHD service from a file
bigip_device_sshd:
banner: enabled
banner_text: "{{ lookup('file', '/path/to/file') }}"
password: secret
server: lb.mydomain.com
user: admin
delegate_to: localhost
user: admin
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host This is as easy as pip install f5-sdk.
• Requires BIG-IP version 12.0.0 or greater
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manage the trust relationships between BIG-IPs. Devices, once peered, cannot be updated. If updating is
needed, the peer must first be removed before it can be re-added to the trust.
• f5-sdk
• netaddr
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• bigsuds
• distutils
Options
Examples
hostname: lb.mydomain.com
type: A
zone: organization.com
state: present
ttl: 10
options:
domain_name: elliot.organization.com
ip_address: 10.1.1.1
Notes
Note:
• Requires the bigsuds Python package on the remote host. This is as easy as pip install bigsuds
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• foo
• f5-sdk
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the remote host. This is as easy as pip install f5-sdk
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• This module manages DNS zones described in the iControl Management documentation
• bigsuds
• distutils
Options
Examples
Notes
Note:
• Requires the bigsuds Python package on the remote host. This is as easy as pip install bigsuds
• https://devcentral.f5.com/wiki/iControl.Management__Zone.ashx
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
Synopsis
• f5-sdk
Options
Examples
Notes
Note:
• F5 developed module ‘f5-sdk’ required
• Best run as a local_action in your playbook
• Requires administrative privileges for user
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• DEPRECATED
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
DEPRECATED
Synopsis
• bigsuds
Options
Examples
Notes
Note:
• Requires BIG-IP software version >= 11.4
• F5 developed module ‘bigsuds’ required (see http://devcentral.f5.com)
• Best run as a local_action in your playbook
• Tested with manager and above account privilege level
• provision facts were added in 2.2
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manage BIG-IP data center configuration. A data center defines the location where the physical network com-
ponents reside, such as the server and link objects that share the same subnet on the network. This module is
able to manipulate the data center definitions in a BIG-IP.
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
• netaddr
Options
Examples
user: admin
password: secret
state: disabled
name: my_pool
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manage BIG-IP server configuration. This module is able to manipulate the server definitions in a BIG-IP.
• f5-sdk
Options
Examples
delegate_to: localhost
addresses:
- address: 4.4.4.1
translation: 192.168.14.1
- address: 4.4.4.2
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• bigsuds
Options
Examples
Notes
Note:
• Requires BIG-IP software version >= 11.4
• F5 developed module ‘bigsuds’ required (see http://devcentral.f5.com)”
• Best run as a local_action in your playbook
• Tested with manager and above account privilege level
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
- name: var__vs_address
value: 1.1.1.1
- name: pm__apache_servers_for_http
value: 2.2.2.1:80
- name: pm__apache_servers_for_https
value: 2.2.2.2:80
delegate_to: localhost
- name: Try to remove the iApp template before the associated Service is
˓→removed
bigip_iapp_template:
name: web_frontends
state: absent
register: result
failed_when:
- not result|success
- "'referenced by one or more applications' not in result.msg"
- "none"
- 80
- 0
- name: server_pools__servers
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manages TCL iApp templates on a BIG-IP. This module will allow you to deploy iApp templates to the BIG-
IP and manage their lifecycle. The conventional way to use this module is to import new iApps as needed
or by extracting the contents of the iApp archive that is provided at downloads.f5.com and then importing all
the iApps with this module. This module can also update existing iApps provided that the source of the iApp
changed while the name stayed the same. Note however that this module will not reconfigure any services
that may have been created using the bigip_iapp_service module. iApps are normally not updated in
production. Instead, new versions are deployed and then existing services are changed to consume that new
template. As such, the ability to update templates in-place requires the force option to be used.
Options
Examples
- name: Update a template in place that has existing services created from
˓→it.
bigip_iapp_template:
content: "{{ lookup('template', 'iapp-new.tmpl') }}"
force: yes
password: secret
server: lb.mydomain.com
state: present
user: admin
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manages Javascript iApp packages on a BIG-IP. This module will allow you to deploy iAppLX packages to the
BIG-IP and manage their lifecycle.
Options
Examples
bigip_iapplx_package:
package: "{{ roles_path }}/files/MyApp-0.1.0-0001.noarch.rpm'"
password: secret
server: lb.mydomain.com
state: present
user: admin
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the rpm tool be installed on the host. This can be accomplished through different ways on each plat-
form. On Debian based systems with apt; apt-get install rpm. On Mac with brew; brew install
rpm. This command is already present on RedHat based systems.
• Requires BIG-IP < 12.1.0 because the required functionality is missing on versions earlier than that.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
Synopsis
• f5-sdk
Options
Examples
- name: Add the iRule contained in template irule.tcl to the LTM module
bigip_irule:
content: "{{ lookup('template', 'irule.tcl') }}"
module: ltm
name: MyiRule
password: secret
server: lb.mydomain.com
state: present
user: admin
delegate_to: localhost
- name: Add the iRule contained in static file irule.tcl to the LTM module
bigip_irule:
module: ltm
name: MyiRule
password: secret
server: lb.mydomain.com
src: irule.tcl
state: present
user: admin
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manage license installation and activation on BIG-IP devices. This module provides two different ways to
license a device. Either via a activation key (which requires a connection back to f5.com) or, with the content of
a license and dossier that you have acquired manually.
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• M
• a
• n
• a
• g
• e
• s
•
• F
• 5
•
• B
• I
• G
• –
• I
• P
•
• L
• T
• M
•
• h
• t
• t
• p
•
• m
• o
• n
• i
• t
• o
• r
• s
• .
Options
Examples
password: secret
name: my_http_monitor
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• DEPRECATED
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
DEPRECATED
Synopsis
• bigsuds
Options
Examples
Notes
Note:
• Requires BIG-IP software version >= 11
• F5 developed module ‘bigsuds’ required (see http://devcentral.f5.com)
• Best run as a local_action in your playbook
• Monitor API documentation: https://devcentral.f5.com/wiki/iControl.LocalLB__Monitor.ashx
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• M
• a
• n
• a
• g
• e
• s
•
• F
• 5
•
• B
• I
• G
• –
• I
• P
•
• L
• T
• M
•
• h
• t
• t
• p
• s
•
• m
• o
• n
• i
• t
• o
• r
• s
• .
Options
Examples
user: admin
password: secret
name: my_http_monitor
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• The BIG-IP has an SNMP data collecting agent (DCA) that can query remote SNMP agents of various types,
including the UC Davis agent (UCD) and the Windows 2000 Server agent (WIN2000).
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• M
• a
• n
• a
• g
• e
• s
•
• F
• 5
•
• B
• I
• G
• –
• I
• P
•
• L
• T
• M
•
• t
• c
• p
•
• m
• o
• n
• i
• t
• o
• r
• s
•
• v
• i
• a
•
• i
• C
• o
• n
• t
• r
• o
• l
•
• S
• O
• A
• P
•
• A
• P
• I
• .
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• M
• a
• n
• a
• g
• e
• s
•
• F
• 5
•
• B
• I
• G
• –
• I
• P
•
• L
• T
• M
•
• t
• c
• p
•
• e
• c
• h
• o
•
• m
• o
• n
• i
• t
• o
• r
• s
• .
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• M
• a
• n
• a
• g
• e
• s
•
• F
• 5
•
• B
• I
• G
• –
• I
• P
•
• L
• T
• M
•
• t
• c
• p
•
• h
• a
• l
• f
• –
• o
• p
• e
• n
•
• m
• o
• n
• i
• t
• o
• r
• s
• .
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• DEPRECATED
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
DEPRECATED
Synopsis
• bigsuds
Options
Examples
# Note that the BIG-IP automatically names the node using the
# IP address specified in previous play's host parameter.
# Future plays referencing this node no longer use the host
# parameter but instead use the name parameter.
# Alternatively, you could have specified a name with the
# name parameter when state=present.
# The BIG-IP GUI doesn't map directly to the API calls for "Node ->
# General Properties -> State". The following states map to API monitor
# and session states.
#
# Enabled (all traffic allowed):
# monitor_state=enabled, session_state=enabled
# Disabled (only persistent or active connections allowed):
# monitor_state=enabled, session_state=disabled
# Forced offline (only active connections allowed):
# monitor_state=disabled, session_state=disabled
#
# See https://devcentral.f5.com/questions/icontrol-equivalent-call-for-b-
˓→ node-down
user: admin
password: mysecret
state: present
session_state: disabled
monitor_state: disabled
partition: Common
name: 10.20.30.40
delegate_to: localhost
Notes
Note:
• Requires BIG-IP software version >= 11
• F5 developed module ‘bigsuds’ required (see http://devcentral.f5.com)
• Best run as a local_action in your playbook
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manages general policy configuration on a BIG-IP. This module is best used in conjunction with the
bigip_policy_rule module. This module can handle general configuration like setting the draft state
of the policy, the description, and things unrelated to the policy rules themselves. It is also the first module that
should be used when creating rules as the bigip_policy_rule module requires a policy parameter.
• f5-sdk
Options
Examples
- name: Add multiple rules to the new policy - Added in the order they are
˓→specified
bigip_policy_rule:
policy: Policy-Foo
name: "{{ item.name }}"
conditions: "{{ item.conditions }}"
actions: "{{ item.actions }}"
with_items:
- name: rule1
actions:
- type: forward
pool: pool-svrs
conditions:
- type: http_uri
path_starts_with: /euro
- name: HomePage
actions:
- type: forward
pool: pool-svrs
conditions:
- type: http_uri
path_starts_with: /HomePage/
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
Options
Examples
vars:
policy_rules:
- name: rule1
actions:
- type: forward
pool: pool-svrs
conditions:
- type: http_uri
path_starts_with: /euro
- name: rule2
actions:
- type: forward
pool: pool-svrs
conditions:
- type: http_uri
path_starts_with: /HomePage/
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• DEPRECATED
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
DEPRECATED
Synopsis
• bigsuds
Options
Examples
bigip_pool:
server: lb.mydomain.com
user: admin
password: secret
state: present
name: my-pool
partition: Common
lb_method: round_robin
delegate_to: localhost
Notes
Note:
• Requires BIG-IP software version >= 11
• F5 developed module ‘bigsuds’ required (see http://devcentral.f5.com)
• Best run as a local_action in your playbook
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
• Python >= 2.7
Options
Examples
name: my-pool
partition: Common
lb_method: round_robin
delegate_to: localhost
server: lb.mydomain.com
user: admin
password: secret
state: present
name: my-pool
partition: Common
monitor_type: m_of_n
quorum: 1
monitors:
- http
- tcp
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires BIG-IP software version >= 12.
• F5 developed module ‘F5-SDK’ required (https://github.com/F5Networks/f5-common-python).
• Best run as a local_action in your playbook.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• DEPRECATED
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
DEPRECATED
Synopsis
• bigsuds
Options
Examples
pool: my-pool
partition: Common
host: "{{ ansible_default_ipv4["address"] }}"
port: 80
description: web server
connection_limit: 100
rate_limit: 50
ratio: 2
delegate_to: localhost
# The BIG-IP GUI doesn't map directly to the API calls for "Pool ->
# Members -> State". The following states map to API monitor
# and session states.
#
# Enabled (all traffic allowed):
# monitor_state=enabled, session_state=enabled
# Disabled (only persistent or active connections allowed):
# monitor_state=enabled, session_state=disabled
# Forced offline (only active connections allowed):
# monitor_state=disabled, session_state=disabled
#
# See https://devcentral.f5.com/questions/icontrol-equivalent-call-for-b-
˓→ node-down
monitor_state: disabled
pool: my-pool
partition: Common
host: "{{ ansible_default_ipv4["address"] }}"
port: 80
delegate_to: localhost
Notes
Note:
• Requires BIG-IP software version >= 11
• F5 developed module ‘bigsuds’ required (see http://devcentral.f5.com)
• Best run as a local_action in your playbook
• Supersedes bigip_pool for managing pool members
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• M
• a
• n
• a
• g
• e
• s
•
• c
• l
• i
• e
• n
• t
•
• S
• S
• L
•
• p
• r
• o
• f
• i
• l
• e
• s
•
• o
• n
•
• a
•
• B
• I
• G
• –
• I
• P
• .
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP software version >= 12
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manage BIG-IP module provisioning. This module will only provision at the standard levels of Dedicated,
Nominal, and Minimum.
Options
Examples
user: admin
validate_certs: no
delegate_to: localhost
- name: Provision a dedicated SWG. This will unprovision every other module
bigip_provision:
server: lb.mydomain.com
module: swg
password: secret
level: dedicated
user: admin
validate_certs: no
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manages creating and downloading qkviews from a BIG-IP. Various options can be provided when creating
qkviews. The qkview is important when dealing with F5 support. It may be required that you upload this
qkview to the supported channels during resolution of an SRs that you may have opened.
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• This module does not include the “max time” or “restrict to blade” options.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Sends an arbitrary command to a BIG-IP node and returns the results read from the device. This module
includes an argument that will cause the module to wait for a specific condition before returning or timing out
if the condition is not met. This module is different from the bigip_command module, insofar as it does not
automatically run commands in tmsh.
Options
Examples
- name: Run show version and check to see if output contains BIG-IP
bigip_raw:
commands: show sys version
wait_for: result[0] contains BIG-IP
server: lb.mydomain.com
password: secret
user: admin
validate_certs: no
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
Options
Examples
remote_host: 10.10.10.10
remote_port: 1234
password: secret
server: lb.mydomain.com
user: admin
validate_certs: no
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• netaddr
• f5-sdk
Options
Examples
- name: Allow only GRE and IGMP protocols access to this Self IP
bigip_selfip:
name: self1
password: secret
server: lb.mydomain.com
state: absent
user: admin
validate_certs: no
allow_service:
- gre:0
- igmp:0
delegate_to: localhost
- name: Allow all TCP, but no other protocols access to this Self IP
bigip_selfip:
name: self1
password: secret
server: lb.mydomain.com
state: absent
user: admin
validate_certs: no
allow_service:
- tcp:0
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the netaddr Python package on the host.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• bigsuds
Options
Examples
Notes
Note:
• Requires the bigsuds Python package on the host if using the iControl interface. This is as easy as pip install
bigsuds
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
name: johnd
state: absent
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Notes
– Status
– Support
Synopsis
• foo
• f5-sdk
Options
Notes
Note:
• Requires the f5-sdk Python package on the remote host. This is as easy as pip install f5-sdk
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• This module only supports version v1 and v2c of SNMP.
• The network option is not supported on versions of BIG-IP < 12.1.0 because the platform did not support that
option until 12.1.0. If used on versions < 12.1.0, it will simply be ignored.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
Synopsis
• foo
• f5-sdk
Options
Notes
Note:
• Requires the f5-sdk Python package on the remote host. This is as easy as pip install f5-sdk
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
• isoparser
Options
Examples
password: secret
software: /root/BIGIP-11.6.0.0.0.401.iso
state: present
delegate_to: localhost
- name: Install (upload, install) base image. Create volume if not exists
bigip_software:
server: lb.mydomain.com
user: admin
password: secret
software: /root/BIGIP-11.6.0.0.0.401.iso
volume: HD1.1
state: installed
delegate_to: localhost
- name: Install (upload, install) base image and hotfix. Create volume if
˓→not exists
bigip_software:
server: lb.mydomain.com
user: admin
password: "secret
software: /root/BIGIP-11.6.0.0.0.401.iso
hotfix: /root/Hotfix-BIGIP-11.6.0.3.0.412-HF3.iso
volume: HD1.1
state: installed
delegate_to: localhost
- name: Activate (upload, install, reboot) base image. Create volume if not
˓→exists
bigip_software:
server: lb.mydomain.com
user: admin
password: secret
software: /root/BIGIP-11.6.0.0.0.401.iso
volume: HD1.1
state: activated
delegate_to: localhost
- name: Activate (upload, install, reboot) base image and hotfix. Create
˓→volume if not exists
bigip_software:
server: lb.mydomain.com
user: admin
password: secret
software: /root/BIGIP-11.6.0.0.0.401.iso
hotfix: /root/Hotfix-BIGIP-11.6.0.3.0.412-HF3.iso
volume: HD1.1
state: activated
delegate_to: localhost
- name: Activate (upload, install, reboot) base image and hotfix. Reuse
˓→inactive volume in volumes with prefix.
bigip_software:
server: lb.mydomain.com
user: admin
password: secret
software: /root/BIGIP-11.6.0.0.0.401.iso
hotfix: /root/Hotfix-BIGIP-11.6.0.3.0.412-HF3.iso
reuse_inactive_volume: yes
state: activated
delegate_to: localhost
bigip_software:
server: lb.mydomain.com
user: admin
password: secret
hotfix: "http://fake.com/Hotfix-12.1.2.1.0.271-HF1.iso"
hotfix_md5sum: "http://fake.com/Hotfix-12.1.2.1.0.271-HF1.iso.md5"
software: "http://fake.com/BIGIP-12.1.2.0.0.249.iso"
software_md5sum: "http://fake.com/BIGIP-12.1.2.0.0.249.iso.md5"
state: activated
reuse_inactive_volume: True
delegate_to: localhost
server: lb.mydomain.com
user: admin
password: secret
software: "http://fake.com/BIGIP-12.1.2.0.0.249.iso"
software_md5sum: "http://fake.com/BIGIP-12.1.2.0.0.249.iso.md5"
volume: HD1.1
state: installed
delegate_to: localhost
bigip_software:
server: lb.mydomain.com
user: admin
password: secret
hotfix: "http://fake.com/Hotfix-12.1.2.1.0.271-HF1.iso"
hotfix_md5sum: "http://fake.com/Hotfix-12.1.2.1.0.271-HF1.iso.md5"
software: /root/BIGIP-11.6.0.0.0.401.iso
state: activated
reuse_inactive_volume: True
delegate_to: localhost
bigip_software:
server: lb.mydomain.com
user: admin
password: secret
hotfix: /root/Hotfix-12.1.2.1.0.271-HF1.iso
software: "http://fake.com/BIGIP-12.1.2.0.0.249.iso"
software_md5sum: "http://fake.com/BIGIP-12.1.2.0.0.249.iso.md5"
state: activated
reuse_inactive_volume: True
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
• Requires the isoparser Python package on the host. This can be installed with pip install isoparser
• Requires the lxml Python package on the host. This can be installed with pip install lxml
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Collect information about installed volumes, existing ISOs for images and hotfixes on the BIG-IP device.
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host This is as easy as pip install f5-sdk
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• This module will import/delete SSL certificates on BIG-IP LTM. Certificates can be imported from certificate
and key files on the local disk, in PEM format.
Options
Examples
password: secret
state: present
cert_src: /path/to/cert.crt
key_src: /path/to/key.key
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• This module does not behave like other modules that you might include in roles where referencing files or
templates first looks in the role’s files or templates directory. To have it behave that way, use the Ansible file or
template lookup (see Examples). The lookups behave as expected in a role context.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• This module will import/delete SSL keys on a BIG-IP. Keys can be imported from key files on the local disk, in
PEM format.
Options
Examples
password: secret
state: present
content: "{{ lookup('file', '/path/to/key.key') }}"
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• This module does not behave like other modules that you might include in roles where referencing files or
templates first looks in the role’s files or templates directory. To have it behave that way, use the Ansible file or
template lookup (see Examples). The lookups behave as expected in a role context.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
Synopsis
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP version 12.0.0 or greater
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
- name: Install (upload, install) UCS without installing the license portion
bigip_ucs:
server: lb.mydomain.com
user: admin
password: secret
ucs: /root/bigip.localhost.localdomain.ucs
state: installed
no_license: yes
delegate_to: localhost
- name: Install (upload, install) UCS except the license, and bypassing the
˓→platform check
bigip_ucs:
server: lb.mydomain.com
user: admin
password: secret
ucs: /root/bigip.localhost.localdomain.ucs
state: installed
no_license: yes
no_platform_check: yes
delegate_to: localhost
bigip_ucs:
server: lb.mydomain.com
user: admin
password: secret
ucs: /root/bigip.localhost.localdomain.ucs
state: installed
passphrase: MyPassphrase1234
delegate_to: localhost
user: admin
password: secret
ucs: bigip.localhost.localdomain.ucs
state: absent
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Only the most basic checks are performed by this module. Other checks and considerations need to be taken into
account. See the following URL. https://support.f5.com/kb/en-us/solutions/public/11000/300/sol11318.html
• This module does not handle devices with the FIPS 140 HSM
• This module does not handle BIG-IPs systems on the 6400, 6800, 8400, or 8800 hardware platform.
• This module does not verify that the new or replaced SSH keys from the UCS file are synchronized between the
BIG-IP system and the SCCP
• This module does not support the ‘rma’ option
• This module does not support restoring a UCS archive on a BIG-IP 1500, 3400, 4100, 6400, 6800, or 8400
hardware platform other than the system from which the backup was created
• The UCS restore operation restores the full configuration only if the hostname of the target system matches the
hostname on which the UCS archive was created. If the hostname does not match, only the shared configuration
is restored. You can ensure hostnames match by using the bigip_hostname Ansible module in a task before
using this module.
• This module does not support re-licensing a BIG-IP restored from a UCS
• This module does not support restoring encrypted archives on replacement RMA units.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• This module is used for fetching UCS files from remote machines and storing them locally in a file tree, orga-
nized by hostname. Note that this module is written to transfer UCS files that might not be present, so a missing
remote UCS won’t be an error unless fail_on_missing is set to ‘yes’.
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• BIG-IP provides no way to get a checksum of the UCS files on the system via any interface except, perhaps,
logging in directly to the box (which would not support appliance mode). Therefore, the best this module can
do is check for the existence of the file on disk; no checksumming.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manage user accounts and user attributes on a BIG-IP. Typically this module operates only on the
REST API users and not the CLI users. There is one exception though and that is if you specify the
username_credential of root. When specifying root, you may only change the password. Your
other parameters will be ignored in this case. Changing the root password is not an idempotent operation.
Therefore, it will change it every time this module attempts to change it.
• f5-sdk
Options
Examples
- name: Make the user 'johnd' an admin and set to advanced shell
bigip_user:
server: lb.mydomain.com
user: admin
password: secret
name: johnd
partition_access: all:admin
shell: bash
state: present
delegate_to: localhost
# Note that the second time this task runs, it would fail because
# The password has been changed. Therefore, it is recommended that
# you either,
#
# * Put this in its own playbook that you run when you need to
# * Put this task in a `block`
# * Include `ignore_errors` on this task
- name: Change the Admin password
bigip_user:
server: lb.mydomain.com
user: admin
password: secret
state: present
username_credential: admin
password_credential: NewSecretPassword
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP versions >= 12.0.0
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk
• Facts are placed in the bigip variable
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manages vCMP guests on a BIG-IP. This functionality only exists on actual hardware and must be enabled by
provisioning vcmp with the bigip_provision module.
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• This module can take a lot of time to deploy vCMP guests. This is an intrinsic limitation of the vCMP system
because it is booting real VMs on the BIG-IP device. This boot time is very similar in length to the time it takes
to boot VMs on any other virtualization platform; public or private.
• When BIG-IP starts, the VMs are booted sequentially; not in parallel. This means that it is not unusual for a
vCMP host with many guests to take a long time (60+ minutes) to reboot and bring all the guests online. The
BIG-IP chassis will be available before all vCMP guests are online.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manage ZoneRunner Views on a BIG-IP. ZoneRunner is a feature of the GTM module. Therefore, this module
should only be used on BIG-IP systems that have the GTM module enabled. The SOAP connection has a number
of known limitations when it comes to updating Views. It is only possible to
• bigsuds
Options
Examples
Notes
Note:
• Requires the bigsuds Python package on the remote host. This is as easy as pip install bigsuds
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
• netaddr
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• DEPRECATED
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
DEPRECATED
Synopsis
• bigsuds
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires BIG-IP software version >= 11
For help in developing on modules, should you be so inclined, please read community, dev_guide/developing_test_pr
and dev_guide/developing_modules.
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
• netaddr
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires BIG-IP software version >= 11
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• f5-sdk
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires BIG-IP versions >= 12.0.0
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• You can wait for BIG-IP to be “ready”. By “ready”, we mean that BIG-IP is ready to accept configuration.
• This module can take into account situations where the device is in the middle of rebooting due to a configuration
change.
Options
Examples
bigip_wait:
timeout: 300
password: secret
server: lb.mydomain.com
user: admin
delegate_to: localhost
- name: Wait for BIG-IP to be ready, don't start checking for 10 seconds
bigip_wait:
delay: 10
password: secret
server: lb.mydomain.com
user: admin
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• Manages license pools of different types. The type of the license pool determines the arguments that are provided
to this module. BIG-IQ supports a variety of types of licenses and this module provides a means to manage them.
Options
Examples
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Return Values
• Notes
– Status
– Support
Synopsis
• __LONG DESCRIPTION__.
Options
Examples
user: "admin"
delegate_to: localhost
Return Values
Common return values are documented here common_return_values, the following are the fields unique to this module:
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• bigsuds
• requests
Options
Examples
Notes
Note:
• Requires the bigsuds Python package on the host if using the iControl interface. This is as easy as pip install
bigsuds
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
password: "secret"
server: "lb.mydomain.com"
state: "present"
user: "admin"
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manages members in a license pool. By adding and removing members from a pool, you will implicitly be
licensing and un-licensing them.
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manages L2/L3 configuration of a BIG-IP via iWorkflow. This module is useful in the event that you have a new
BIG-IP that does not yet have VLANs and Self-IPs configured on it. You can use this module on a discovered,
managed, device to configure those settings via iWorkflow. You do not need touse this module if you have an
existing BIG-IP that has its L2/L3 configuration already complete. In that cae, it is sufficient to just use the
iworkflow_managed_device module and iWorkflow will automatically discover the node information
for you.
Options
Examples
interfaces:
- local_address: "10.0.2.12"
subnet_address: "10.0.2.0/24"
virtual_address: "10.144.128.137"
- local_address: "10.2.0.81"
subnet_address: "10.2.0.0/24"
name: "external"
server: "iwf.mydomain.com"
password: "secret"
user: "admin"
validate_certs: "no"
delegate_to: localhost
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Requires the netaddr Python package on the host. This is as easy as pip install netaddr.
• This module does not support updating of existing nodes that were created with a
cli_password_credential. The onboarding process will change your device’s
cli_username_credential password, which will prevent you from using this module (without
knowing the password) a second time.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manages L4/L7 Service on iWorkflow. Services can only be created and otherwise managed by tenants on
iWorkflow. Since all of the F5 modules assume the use of the administrator account, the user of this module will
need to include the tenant option if they want to use this module with the admin account.
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the remote host. This is as easy as pip install f5-sdk.
• L4/L7 Services cannot be updated once they have been created. Instead, you must first delete the service and
then re-create it.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
• Manages Service Templates on iWorkflow. Service templates are created by the iWorkflow administrator and
are consumed by iWorkflow tenants in the form of L4/L7 services. The Service Template can be configured to
allow tenants to change certain values of the template such as the IP address of a VIP, or the port that a Virtual
Server listens on.
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the remote host. This is as easy as pip install f5-sdk
• Requires the deepdiff Python package on the Ansible controller host. This is as easy as pip install deepdiff.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Required the netaddr Python package on the host. This is as easy as pip install netaddr.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Tenants are not useful unless you associate them with a connector using the
iworkflow_tenant_connector module.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• Tenants are not useful unless you associate them with a connector using the
iworkflow_tenant_connector module.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
• Synopsis
• Requirements (on host that executes module)
• Options
• Examples
• Notes
– Status
– Support
Synopsis
Options
Examples
Notes
Note:
• Requires the f5-sdk Python package on the host. This is as easy as pip install f5-sdk.
• For more information on using Ansible to manage F5 Networks devices see https://www.ansible.com/ansible-f5.
Status
This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface.
Support
Note:
• (D): This marks a module as deprecated, which means a module is kept for backwards compatibility but usage
is discouraged. The module documentation details page may explain more about this rationale.
7.2.1 F5
Note:
• (D): This marks a module as deprecated, which means a module is kept for backwards compatibility but usage
is discouraged. The module documentation details page may explain more about this rationale.
Before you start contributing to any project sponsored by F5 Networks, Inc. (F5) on GitHub, you will need to sign a
Contributor License Agreement (CLA).
If you are signing as an individual, we recommend that you talk to your employer (if applicable) before signing the
CLA since some employment agreements may have restrictions on your contributions to other projects. Otherwise by
submitting a CLA you represent that you are legally entitled to grant the licenses recited therein.
If your employer has rights to intellectual property that you create, such as your contributions, you represent that you
have received permission to make contributions on behalf of that employer, that your employer has waived such rights
for your contributions, or that your employer has executed a separate CLA with F5.
If you are signing on behalf of a company, you represent that you are legally entitled to grant the license recited
therein. You represent further that each employee of the entity that submits contributions is authorized to submit such
contributions on behalf of the entity pursuant to the CLA.
Click the link below to download the PDF:
F5 Contributor License Agreement (CLA)
183
F5 Ansible Documentation, Release 1.0.0
Getting involved
First and foremost, we expect you to bring a good attitude. These modules are developed out of our own personal
interests in Ansible; there is no official team here.
With that said, we want to keep the environment from getting bogged down in a bad mood.
The development of a module will require some effort on your part. Often times the countless reviews might seem
frustrating, but believe us, we do it for good reason.
By becoming involved with developing a module, you’re accepting that your contribution will probably not be accepted
right off the bat. If you’re willing to work with us though, and understand the direction we’re headed in, you will more
than likely find your module landing here.
We expect that you stay up to date with the documentation of this site concerning module development. As time goes
on, things change and new practices are adopted. As this happens, we try to keep the documentation up to date with
these changes.
If you develop a module use an out-of-date convention, we will tell you so upon review. It is then expected that you
take the initiative to fix it.
Part of Ansible’s requirements for this is that the people listed in the author field (usually those who wrote the module)
take responsibility for the ongoing maintenance and support of the module.
Understandably this might be a big issue for you, so we are offering to assist. When your module is merged to our
repo here, we lists ourselves as one of the authors of the code.
185
F5 Ansible Documentation, Release 1.0.0
With this in place, and with the addition of us opening the PR with Ansible upstream, we think this will be sufficient
to meet their needs for ongoing maintenance. This is a joint effort though, so lets work together to ensure that the
module stays in Core. Modules that can no longer be supported by their authors are removed from Ansible.
While module development is the primary focus of most contributors, it’s understandable that you may not know how
to write Python, or may not have any interest in writing code to begin with.
That’s ok. Here are some existing things you can do to assist.
9.2.1 Documentation
This is always needed. I write documentation that focuses on many of the moving parts here, but I can’t cover it all
and will inevitably miss things.
Submitting documentation improvements is encouraged.
The unit tests in the test/ directory can always use more love. Unit tests run fast and so more of them is not a burden
on the test runner.
Add more test cases for your particular usage scenarios or any scenarios that may have been missed.
I personally only add enough unit tests to be reasonably comfortable that the code will execute right. This, unfortu-
nately, does not cover many of the functional test cases. So writing unit test versions of functional tests is of huge
benefit.
We don’t have modules to cover all of the ways our products are used. If you find that a module is missing from the
repo and you think needs to be added, I will entertain those ideas on the Github Issues page
Even the existing modules do not cover all the bells and whistles that customers use.
If a module is missing a parameter that you think it should have, raise and issue and we will consider it.
The Ansible modules make use of the F5 Python SDK for all of their work. In the SDK, all work is accomplished via
the product REST APIs and this just happens to fit in perfectly with the tool Postman.
If you want to help us work on new modules without involving yourself in Python code, a great way to start is to write
Postman collections for the APIs that configure on the BIG-IP what you want to configure.
If you provide us with the Postman collections, this makes it really easy for us to write the Ansible module itself.
This is the approach that many of the F5 teams who do not work in software land all day long take because it is super
effective. Bonus points for collections that address differences in APIs between versions of BIG-IP
Using the modules is the best way to iron out bugs. By using the modules in the way that you expect them to work is
a great way to find bugs.
During the development process, we write tests with specific user personas in mind. Your usage patterns may not
reflect those personas though and that might break the module.
Using the modules is the best way to get both code and documentation correct. If it’s not obvious to you via the
documentation about how a module works, then I guarantee it is unclear to many more people.
Righting those wrongs helps you and future users.
Playbooks show people how to make use of the module when paired with other modules. Playbooks also are the way
that people inevitably use all these modules, so if you write playbooks that make use of them, this allows people to
copy/paste the actual usage for their own benefit.
Ansible’s role features provide the opportunity for us to build new sets of configuration for an F5 product.
There has been some effort to begin writing role that would be useful for different scenarios (such as the bigip-
hardening role) but this effort has not been fully tackle yet.
Anyone can write roles as they are just collections of files, templates, modules, and tasks that you are already writing
for some purpose.
Writing more roles helps spread the usage of the modules.
If you’re an F5 employee, there are even more ways to help. Refer to the go/ansible link for more details.
When Ansible introduces some new check that causes a whole lot of errors (such as when they added pep8 checking)
they put all of the findings in a legacy file and fix the code that they’re interested.
On one hand, this allows them to fix what they need to fix.
On the other hand, it results in problems like this
ERROR: build/lib/ansible/modules/system/capabilities.py:139:55: E202 whitespace
˓→before ']'
ERROR: The 1 sanity test(s) listed below (out of 1) failed. See error output above
˓→for details.
It turns out that there is some post-processing that happens to whittle down this huge list. What is post-processed is
enumerated here
• local/ansible/test/sanity/pep8/legacy-ignore.txt
While this ends up limiting the amount of errors that are raised by automated testing, it also puts a bandage over the
problem without fixing the actual problems.
I consider this a poor excuse for a “fix”. So it’s your, or our, job to make sure that F5 anything never makes it in this
list. But it doesn’t stop there.
As a good netizen, it is also your job to assist in eliminating these legacy files (the text files, not the modules) by
FIXING all the errors that are raised.
Ultimately, this makes F5’s job easier because when we run the commands to check for this stuff, we’re no longer
seeing a hundred-bajillion errors being raised by their tools.
9.4 Conclusion
One final thing that will require effort on your part that, frankly, we cannot help with, is that of endorsement.
The Ansible work here is by no means supported by F5. If you want that to change, then you will need to initiate that
change. Speaking with your SEs, AMs, SAs, etc etc, is the best way to drive that change.
When we run our mouths about orchestration tools, it falls on deaf ears. If this is valuable to your organization, then
say so.
Guidelines
Guidelines are written for you, the contributor, to understand what we expect from our contributors and to provide
guidance on the direction we are taking the modules.
Since Ansible 2.2, it is a requirement that all new F5 modules are written to use the f5-sdk.
Prior to 2.2, modules may of been written in bigsuds or requests (for SOAP and REST respectively). Modules
written using bigsuds can continue to be extended using it.
Backward compatibility of older modules should be maintained, but because bigsuds and f5-sdk can co-exist, it
is recommended that all future features be written using f5-sdk.
BIG-IP’s have two API interfaces; SOAP and REST. As a general rule of thumb, the SOAP API should be considered
deprecated. While this is not an official stance from F5, there is clearly more of a push in the REST direction than the
SOAP direction.
New functionality to the SOAP interface continues to be added, but only under certain circumstances.
If you are writing a bugfix for a module that uses bigsuds, you should continue to use bigsuds to maintain
backward compatibility.
If you are adding new functionality to an existing module that uses bigsuds but the new functionality requires
f5-sdk, you may add it using f5-sdk.
Base the name of the module on the part of BIG-IP that the modules manipulates. (A good rule of thumb is to refer to
the API being used in the f5-sdk).
189
F5 Ansible Documentation, Release 1.0.0
Don’t further abbreviate names - if something is a well known abbreviation due to it being a major component of
BIG-IP, that’s fine, but don’t create new ones independently (e.g. LTM, GTM, ASM, etc. are fine)
If a module that you need does not yet exist, it is equally likely that the REST API in the f5-sdk has also not yet been
developed. Please refer to the following github project
• https://github.com/F5Networks/f5-common-python
Open an Issue with that project to add the necessary APIs so that a proper Ansible module can be written to use them.
The following guidelines pertain to how you should use the f5-sdk in the modules that you develop. We’ll focus on
the most common scenarios that you will encounter.
10.4.1 Importing
Wrap import statements in a try block and fail the module later if the import fails.
f5-sdk
try:
from f5.bigip import ManagementRoot
from f5.bigip.contexts import TransactionContextManager
HAS_F5SDK = True
except ImportError:
HAS_F5SDK = False
def main():
if not HAS_F5SDK:
module.fail_json(msg='f5-sdk required for this module')
Connecting to an F5 product is handled for you automatically. You can control which product you are communicating
with by changing the appropriate value in your ArgumentSpec class.
For example, to specify that your module is one that communicates with a BIG-IP, The minimum viable ArgumentSpec
you can write is illustrated below.
class ArgumentSpec(object):
def __init__(self):
self.argument_spec = dict()
self.f5_product_name = 'bigip'
Note the special key f5_product_name. By changing this value, you are able to change the ManagementRoot which
will be provided to your module.
The following is a list of allowed values for this key
• bigip
• bigiq
• iworkflow
Inside your module, the ManagementRoot is contained in the ModuleManager under the self.client.api object.
Use of the object is done in the same way that you work normally use the ManagementRoot of an F5-SDK product.
For example, the code snippet below illustrates a “normal” method of using the F5-SDK
# Module code
...
try:
result = self.want.api.tm.ltm.pools.pool.create(foo='bar')
except iControlUnexpectedHTTPError as ex:
raise F5ModuleError(str(ex))
...
# End of module code
In all cases which you encounter it, it is correct to catch internal exceptions and re-raise them (if necessary) with the
F5ModuleError class.
The python code underlying the Ansible modules should be written to be compatible with both Python 2.7 and 3.
The travis configuration contained in this repo will verify that your modules are compatible with both versions. Use
the following cheat-sheet to write compatible code.
• http://python-future.org/compatible_idioms.html
It is recommended that you use the testing facilities that we have paired with this repository. When you open PR’s,
our testing tools will run the PR against supported BIG-IP versions in our testing facilities.
By doing using our test harnesses, you do not need to have your own devices or VE instances to do your testing
(although if you do that’s fine).
We currently have the following devices in our test harness
• 12.0.0 (BIGIP-12.0.0.0.0.606)
• 12.1.0 (BIGIP-12.1.0.0.0.1434)
• 12.1.0-hf1 (BIGIP-12.1.0.1.0.1447-HF1)
• 12.1.0-hf2 (BIGIP-12.1.0.2.0.1468-HF2)
• 12.1.1 (BIGIP-12.1.1.0.0.184)
• 12.1.1-hf1 (BIGIP-12.1.1.1.0.196-HF1)
• 12.1.1-hf2 (BIGIP-12.1.1.2.0.204-HF2)
• 12.1.2 (BIGIP-12.1.2.0.0.249)
• 12.1.2-hf1 (BIGIP-12.1.2.1.0.264-HF1)
• 13.0.0 (BIGIP-13.0.0.0.0.1645)
• 13.0.0-hf1 (BIGIP-13.0.0.1.0.1668-HF1)
The above list runs the risk of becoming outdated because the actual source of truth can be found here
Architecture
193
F5 Ansible Documentation, Release 1.0.0
Code Conventions
The F5 modules attempt to follow a set of coding conventions that apply to all new and existing modules.
These conventions help new contributors quickly develop new modules. Additionally, they help existing contributors
maintain the current modules.
Where possible, we try to automate the validation of these coding conventions so that you are aware of mistakes and
able to fix them yourself without having to have the maintainers intervene.
For more information on what tools perform these checks, refer to the tests page.
When writing your modules and their accompanying tests and docs, please follow the below coding conventions.
In reference to Jeff Geerling’s page here, this format looks like this.
195
F5 Ansible Documentation, Release 1.0.0
There are several reasons that we use this format. Among them are Geerling’s reasons.
• The structure is all valid YAML, using the structured list/map syntax mentioned in the beginning of this post.
• Strings, booleans, integers, octals, etc. are all preserved (instead of being converted to strings).
• Each parameter must be on its own line, so you can’t chain together mode: 0755, owner: root,
user: root to save space.
• YAML syntax highlighting works slightly better for this format than key=value, since each key will be
highlighted, and values will be displayed as constants, strings, etc.
In addition to those reasons, there are also some situations that, if you use the simple key=value format will raise
syntax errors. Finally, it saves on space and, in the maintainers opinion, is easier to read and know (by looking) what
the arguments to the module are.
The parameters to your modules in the Roles and Playbooks that are developed here must be in alphabetic order.
GOOD
- name: My task
bigip_module:
alpha: "foo"
beta: "bar"
gamma: "baz"
BAD
- name: My task
bigip_module:
alpha: "foo"
gamma: "baz"
beta: "bar"
This provides for consistency amongst module usage as well as provides a way to see at a glance if a module has the
correct parameters.
Ansible supports a simple form of typing for your parameters. If there is a value that is a string, it should be represented
as a string using double quotes.
GOOD
- name: My task
bigip_module:
alpha: "foo"
beta: "bar"
BAD
- name: My task
bigip_module:
alpha: foo
beta: bar
For numeric characters, you should not use any quotes because this can cause some modules to raise ‘type’ errors if
the expected value is a number and you provide it with a number wrapped in quotes
GOOD
- name: My task
bigip_module:
alpha: 1
beta: 100
BAD
- name: My task
bigip_module:
alpha: "1"
beta: "100"
A YAML file usually begins with three dashes. As such, you should have that be a part of your own YAML files.
GOOD
---
- name: My task
bigip_module:
alpha: 1
beta: 100
BAD
- name: My task
bigip_module:
alpha: "1"
beta: "100"
When your Playbooks encounter errors, the name of the task is always called out in the failure. If you do not provide
a name, then Ansible creates a name for you using the module call itself.
Naming your tasks allows you to quickly reference where a failure occurred.
GOOD
- name: My task
bigip_module:
alpha: 1
beta: 100
BAD
- bigip_module:
alpha: "1"
beta: "100"
The DOCUMENTATION variable is also required by Ansible upstream as it serves as the source of the module
documentation that is generated on their site.
Good documentation is essential to people being able to use the module so it must be included.
GOOD
DOCUMENTATION = '''
---
module: bigip_device_ntp
short_description: Manage NTP servers on a BIG-IP
description:
- Manage NTP servers on a BIG-IP
version_added: "2.1"
options:
...
'''
BAD
Useful and valid examples are crucial for people new to Ansible and to the module itself.
When providing examples, be mindful of what you provide. If you developed the module with a specific use case in
mind, be sure to include that use case. It may be applicable to a large majority of users and, therefore, may eliminate
a significant portion of their time that they would otherwise spend figuring out what is or is not needed.
GOOD
EXAMPLES = '''
- name: Set the banner for the SSHD service from a string
bigip_device_sshd:
banner: "enabled"
banner_text: "banner text goes here"
password: "admin"
server: "bigip.localhost.localdomain"
user: "admin"
delegate_to: localhost
'''
BAD
The RETURN variable provides documentation essential to determining what, if any, information is returned by the
operation of the module.
End users of the module will reference this documentation when they want to use the register keyword.
The RETURN field should include the parameters that have been changed by your module. If nothing has been changed,
then no values need be returned.
GOOD
RETURN = '''
full_name:
description: Full name of the user
returned: changed
type: string
sample: "John Doe"
'''
BAD
If your module does not return any information, then an empty YAML string is sufficient
GOOD
..code-block:: python
RETURN = ‘’‘# ‘’‘
There is a good possibility that multiple people will work to maintain the module over time, so it is a good idea to
make the author keyword in your module a list.
GOOD
author:
- Tim Rupp (@caphrim007)
BAD
Both Ansible and this repository are maintained on Github. Therefore, for maintenance reasons we require your Github
handle. Additionally, your email address may change over time.
GOOD
author:
- Tim Rupp (@caphrim007)
BAD
author:
- Tim Rupp <caphrim007@gmail.com>
This is a simple spacing convention to ensure that everything is properly spaced over.
GOOD
options:
server:
description:
- BIG-IP host
required: true
user:
^^
BAD
options:
server:
description:
- BIG-IP host
required: true
user:
^^^^
Ansible provides existing facilities that can be used to read in file contents to a module’s parameters.
If your module can accept a string or a file containing a string, then assume that users will be using the lookup plugins.
For example, SSL files are typically strings. SSH keys are also strings even if they are contained in a file. Therefore,
you would delegate the fetching of the string data to a lookup plugin.
There should be no need to use the python open facility to read in the file.
GOOD
some_module:
string_param: "{{ lookup('file', '/path/to/file') }}"
BAD
some_module:
param: "/path/to/file"
options:
state:
description:
- The state of things
choices:
- present
- absent
BAD
options:
state:
description:
- The state of things
choices: ['enabled', 'disabled']
In the DOCUMENTATION section notes, you should specify what version of BIG-IP the module requires.
At this time, that version is 12.0.0, so your DOCUMENTATION string should reflect that.
GOOD
notes:
- Requires BIG-IP version 12.0.0 or greater
BAD
Any version less than 12.0.0.
If your module requires functionality greater than 12.0.0 it is also acceptable to specify that in the DOCUMENTATION
block.
General Exceptions are bad because they hide unknown errors from you, the developer. If a bug report comes in and
is being caused by an exception that you do not handle, it will be exceedingly difficult to debug it.
Instead, only catch the F5ModuleError exception that is provided by the f5-sdk. Specifically raise this module and
handle those errors. If an unknown error occurs, a full traceback will be produced that will more easily allow you to
debug the problem.
GOOD
try:
// do some things here that can cause an Exception
except bigsuds.OperationFailed as e:
raise F5ModuleError('Error on setting profiles : %s' % e)
GOOD
if foo:
// assume something successful happens here
else:
raise F5ModuleError('Error on baz')
BAD
try:
// do some things here that can cause an Exception
except bigsuds.OperationFailed as e:
raise Exception('Error on setting profiles : %s' % e)
BAD
if foo:
// assume something successful happens here
else:
raise Exception('Error on baz')
Check-mode allows Ansible to run your Playbooks in a dry-mode sort of operation. This is very handy when you want
to run a set of tasks but are not sure what will happen when you do.
Since BIG-IPs are usually considered a sensitive device to handle, there should always be a check-mode implemented
in your module.
Some folks like local_action and some folks like delegation. Delegation is more applicable to general-purpose Ansible,
so for that reason I want to get people in the habit of using and understanding it.
Therefore, do not use local_action when defining examples. Instead, use delegate_to.
GOOD
BAD
For consistency, always using the following values for the given parameters
• user: “admin”
• password: “secret”
• server: “lb.mydomain.com”
This allows you to not have to overthink the inclusion of your example.
GOOD
BAD
To enable easier debugging when something goes wrong, ensure that you assign values before you return those values.
GOOD
def exists(self):
result = self.client.api.tm.gtm.pools.pool.exists(
name=self.want.name,
partition=self.want.partition
)
return result
BAD
def exists(self):
return self.client.api.tm.gtm.pools.pool.exists(
name=self.want.name,
partition=self.want.partition
)
The reason that the above BAD example is considered bad is that when it comes time to debug the value of a variable,
it requires that you change the code to do an assignment operation anyway.
For example, using q to debug the value of the above requires that you implicitly assign the value of the API call before
you do this,
...
result = self.client.api....
q.q(result)
...
When the code does not do a assignment, then you are required to change the code before you are able to debug the
code.
When a developer takes on a new issue that requires changes to code to get working, these changes should be tested
with a new functional test yaml file located in the module’s test/integration/PRODUCT/targets directory.
For example.
Consider the Github Issue 59 which is relevant to the bigip_virtual_server module.
The developer needed to add new code to the module. So to verify that the new code is tested, the developer should
add a new file to the module’s targets directory here
• test/functional/bigip/bigip_virtual_server/tasks
The name of the file should be
• issue-59.yaml
And inside of the file should be any and all work that is required to,
• Setup the test
• Perform the test
• Teardown the test
Any issues that are reported on github should follow the same pattern, however the filenames of those modules should
be
• ansible-xxxxx.yaml
So-as not to step on the numeric namespace that is used natively in the f5-ansible repository.
The correct way to set a RETURN variable whose module has no returnable things is like this according to bcoca.
Ansible’s test runner makes use of pytest, so the acceptable way of excluding lines from code coverage is documented
here.
• http://coverage.readthedocs.io/en/coverage-4.2/excluding.html
The cases where you would want to use this include the various *_on_device and *_from_device methods in modules
that make direct calls to the remote BIG-IPs.
This convention is done to eliminate the total number of columns in use, but also to increase readability when long
lines tend to scroll off screen. Even with a 160 column limit for this project, long lines, and many lines, can begin to
grow less compact.
BAD
GOOD
For the same reason given above concerning compactness, lists should follow the same rule. The ending bracket should
be on a new line as well, aligned with the beginning of the variable name
BAD
GOOD
License header
Each module requires a license header which includes the GPL3 license.
Here is the common license header.
If the module under development is your original work, then you can include your name in the copyright above.
If you are only contributing an existing module, then it is not necessary to include a copyright line at the top. Instead,
accepting the F5 CLA is sufficient to get code merged into our branch.
This variable should be included first in your module. It specifies metadata for the module itself. It can always look
the same. Here is it as would be defined in code.
This convention comes to us courtesy of Ansible module authoring rules. This convention is used to limit the amount
of verbosity in module code. Additionally, there is a risk of conflict (who is right? docs? or code?) that can occur if
this convention is not followed.
Ansible, by default, make a parameter not required. Therefore, it is also redundant to provide it again in your docu-
mentation.
BAD
...
login:
description:
- Specifies, when checked C(enabled), that the system accepts SSH
communications.
choices:
- enabled
- disabled
required: False
...
GODE
...
login:
description:
- Specifies, when checked C(enabled), that the system accepts SSH
communications.
choices:
- enabled
- disabled
...
Another convention from Ansible, similar to the required: False convention, this convention is applying the rule to the
default. Since default: None is already the value that Ansible uses (in code), it is redundant to provide it again in the
docs.
BAD
...
login:
description:
- Specifies, when checked C(enabled), that the system accepts SSH
communications.
choices:
- enabled
- disabled
default: None
...
GODE
...
login:
description:
- Specifies, when checked C(enabled), that the system accepts SSH
communications.
choices:
- enabled
- disabled
...
Do not decompose to a *_device method if the using method is itself an *_device method
This convention is in place to limit the total amount of function decomposition that you will inevitably try to put into
the code. Some level of decomposition is good because it isolated the code that targets the device (what we refer to as
*_device methods) from the code in the module that does not communicate with the device.
This method of isolation is how we extend modules when there is a divergence in the API code, or when the means of
transporting information from and to the device changes.
You can take this decomposition too far though. Refer to the examples below for an illustration of this. When you go
to far, the correction is to merge the two methods.
BAD
GOOD
This convention remains valid when the particular line of code that you are using is a single line. Therefore, if the
upload_file line were used in many places in the code, it is still correct to merge the methods instead of having a
different method for it.
The only time when it would be correct to decompose it is if the “other” methods were not *_device methods.
Upstreaming
Modules that are currently in incubation are named as normal modules are that you would find in the Ansible product.
They are easily distinguished by their filename not including a leading underscore.
These modules can only be obtained through the installation steps outlined in the ‘Installation‘_ docs.
An incubating module may or may not be working at any point in time. While we prefer to not break any of them
during development, we recognize that sometimes that is part of the process.
Note: Just because a module is incubation does not mean that it is unstable. Many modules remain in the incubator
because there has not been sufficient interest from the community either internal or external to release them.
A module in incubation should have an associated Issue in Github so that its progress can be tracked and so that others
do not repeat work.
A module is considered to be in a mature state once it has met all of the standards that have been established for it.
• http://docs.ansible.com/ansible/dev_guide/testing.html
• ‘upstreaming requirements‘_
• ‘coding conventions‘_
209
F5 Ansible Documentation, Release 1.0.0
At that point in its development, we will make the request to upstream Ansible for the module’s inclusion.
13.3 Releases
After a module is upstreamed, there will continue to be a period of time that must pass before it is released as part of
the core Ansible product.
That release schedule is shown in the ROADMAP files near the top of each file.
Depending on what version is currently stable, upstreamed modules will be part of the next major stable release.
For example.
If 2.3 is the current stable version and a module was upstreamed to core, it would not appear as part of pip install
ansible until version 2.4 was released.
You can get the modules before that point in time, but you must do so manually. The link to the ‘stable modules is
here‘_.
Upstreaming Process
The upstreaming process is summarized below. Only one person should be concerned with upstreaming things.
Ansible provides an Issue template that will be shown to you automatically when you create a new PR in Github. You
should fill out the various fields in it, making sure to include the following in one of the “Summary”, “Description”,
or related fields.
Below is an example of what has been provided in the past and you should use it as an example of what you too should
provide.
Including the extra information that shows your due diligence in writing and testing the module is important because
it helps ensure the Ansible maintainers, and our customers, that the code has been written well.
Generally speaking the upstreaming window is open each one week around the times of the Networking meeting. Here
is the Networking team’s schedule.
• https://github.com/ansible/community/blob/master/MEETINGS.md#wednesdays
During that time, you will need to comment on the Ansible Networking Groups issue tracker for new PRs. This can
be found here.
• https://github.com/ansible/community/issues/110
The Networking team will address your PRs at their weekly meeting, which you are expected to attend.
211
F5 Ansible Documentation, Release 1.0.0
Writing a Module
Let’s explore what it takes to write a module using the provided guidelines and standards.
The first step is to decide what you will call your module. For this tutorial we will recreate the functionality of
the bigip_device_sshd module as it provides good examples of the common idioms you will encounter when
developing or maintaining modules.
Because this module already exists, let’s just slightly change the name of our module to the following
bigip_device_ssh
This name will additionally prevent you from tab’ing to the existing sshd module.
There are a number of files and directories that need to be created to hold the various tests and validation code in
addition to just your module.
To create the necessary directories and files, an executable file is available for you to use to set these directories up
automatically.
$> ./devtools/bin/stubber.py --module MODULE_NAME stub
When it finishes running, you will have the necessary files available to begin working on your module.
The stubber creates a number of files that you need to then go through and do some form of development on. These
files are
213
F5 Ansible Documentation, Release 1.0.0
• docs/modules/MODULE_NAME.rst
• library/MODULE_NAME.py
• test/integration/MODULE_NAME.yaml
• test/integration/targets/MODULE_NAME/
• test/unit/bigip/test_MODULE_NAME.py
The next chunk of code that you will insert describes the module, what parameters is accepts, who the au-
thors/maintainers are, its dependencies, etc.
Let’s look at the code that we will add to our module.
DOCUMENTATION = '''
---
module: bigip_device_sshd
short_description: Manage the SSHD settings of a BIG-IP
description:
- Manage the SSHD settings of a BIG-IP
version_added: "2.5"
options:
banner:
description:
- Whether to enable the banner or not
choices:
- enabled
- disabled
banner_text:
description:
- Specifies the text to include on the pre-login banner that displays
when a user attempts to login to the system using SSH
inactivity_timeout:
description:
- Specifies the number of seconds before inactivity causes an SSH
session to log out
log_level:
description:
- Specifies the minimum SSHD message level to include in the system log
choices:
- debug
- debug1
- debug2
- debug3
- error
- fatal
- info
- quiet
- verbose
login:
description:
- Specifies, when checked C(enabled), that the system accepts SSH
communications
port:
description:
- Port that you want the SSH daemon to run on
notes:
- Requires the f5-sdk Python package on the host This is as easy as pip
install f5-sdk
extends_documentation_fragment: f5
requirements:
- f5-sdk
author:
- Tim Rupp (@caphrim007)
'''
Most documentation variables have a common set of keys and only differ in the values of those keys.
The keys that one commonly finds are
• module
• short_description
• description
• version_added
• options
• notes
• requirements
• author
• extends_documentation_fragment
Note: The extends_documentation_fragment key is special as it is what will automatically inject the variables user,
password, server, server_port and validate_certs into your documentation. It should be used for all modules.
Additionally, you should take note that Ansible upstream has several rules for their documentation blocks. At the time
of this writing, the rules include
• If a parameter is not required, do not include a required: false field in the parameter’s DOCUMENTATION
section.
The examples variable contains the most common use cases for this module.
I personally think that setting of the banner will be the most common case, but future authors are free to add to my
examples.
These examples will also serve as a basis for the functional tests that we will write shortly.
For this module, our EXAMPLES variable looks like this.
EXAMPLES = '''
- name: Set the banner for the SSHD service from a string
bigip_device_sshd:
banner: enabled
banner_text: banner text goes here
password: secret
server: lb.mydomain.com
user: admin
delegate_to: localhost
- name: Set the banner for the SSHD service from a file
bigip_device_sshd:
banner: enabled
banner_text: "{{ lookup('file', '/path/to/file') }}"
password: secret
server: lb.mydomain.com
user: admin
delegate_to: localhost
The pattern which we follow is that we always return what changed in the module’s parameters when the module has
finished running.
The parameters that I am referring to here are the ones that are not considered to be the “standard” parameters to the
F5 modules. Some exceptions to this rule apply. For example, where the state variable contains more states than just
absent and present, such as in the bigip_virtual_server module.
For our module these include,
• banner
• banner_text
• inactivity_timeout
• log_level
• login
The RETURN variable describes these values, specifies when they are returned and provides examples of what the
values returned might look like.
When the Ansible module documentation is generated, these values are presented in the form of a table. Here is the
RETURN variable that we would place in our module file.
The next section in our code is the block of code where our ‘import‘s happen.
This code usually just involves importing the module_util helper libraries, but may also include imports of other
libraries if you are working with legacy code.
For this module our import block is the following
try:
from ansible.module_utils.f5_utils import iControlUnexpectedHTTPError
except ImportError:
HAS_F5SDK = False
In 90% of cases, this code is boilerplate and can be ignored by the developer when writing a module. stubber.py takes
care of this for you.
The next block of code is the skeleton for our module’s Manager class. We encapsulate most of our module’s steering
code inside this class. It acts as the traffic cop, determining which path the module should take to reach the desired
outcome.
The Manager class is where the specifics of your code will be. The stubber will create a generic version of this for
you. It is your responsibility to change the API calls as needed.
Below are examples of the different versions of the design standards that have existed at one point or another
• version 3.3 (proposed)
• version 3.2 (current)
• version 3.1
• version 3
• version 2
• version 1
Note: The ModuleManager class will change over time as our design standards change. The above examples are used
for historical reference and training.
With the implementation details of the module complete, we move on to the code that hooks the module up to Ansible
itself.
def main():
Next, we generate the common argument spec using a utility method of Ansible.
argument_spec = f5_argument_spec()
With the argument_spec generated, we update the values in it to match the options we declared in our
DOCUMENTATION variable earlier.
The values that you must specify here are, again, the ones that are not common to all F5 modules. Below is the code
we need to update our argument_spec
meta_args = dict(
allow=dict(required=False, default=None),
banner=dict(required=False, default=None, choices=CHOICES),
banner_text=dict(required=False, default=None),
inactivity_timeout=dict(required=False, default=None, type='int'),
log_level=dict(required=False, default=None, choices=LEVELS),
login=dict(required=False, default=None, choices=CHOICES),
port=dict(required=False, default=None, type='int')
)
argument_spec.update(meta_args)
After the argument_spec has been updated, we instantiate an instance of our class, providing the
argument_spec and the value that indicates we support Check mode.
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True
)
All F5 modules must support Check Mode as it allows an administrator to determine whether a change will be made
or not when the module is run against their devices.
The next block of code that is added is a general execution of your class.
We wrap this execution inside of a try...except statement to ensure that we handle know errors and bubble up known
errors.
Never include a general Exception handler here because it will hide the details of an unknown exception that we
require when debugging an unhandled exception.
try:
obj = BigIpDeviceSshd(check_mode=module.check_mode, **module.params)
result = obj.flush()
module.exit_json(**result)
except F5ModuleError as e:
module.fail_json(msg=str(e))
The final two lines in your module inform Python to execute the module’s code if the script being run is itself exe-
cutable.
if __name__ == '__main__':
main()
Due to the way that Ansible works, this means that the main function will be called when the module is sent to the
remote device (or run locally) but will not be called if the module is imported.
You would import the module if you were using it outside of Ansible, or in some sort of test environment where you
do not want the module to actually run.
15.5 Testing
Providing tests with your module is a crucial step for having it merged and subsequently pushed upstream. We rely
heavily on testing.
In this section I will go in to detail on how our tests are organized and how you can write your own to ensure that your
modules works as designed.
It is not required that you specify connection-related variables for each task. These values are provided for you
automatically at the playbook level.
These values include,
• server
• server_port
• user
• password
• validate_certs
We make use of the pycodestyle command to ensure that our modules meet certain coding standards and compat-
ibility across Python releases.
You can run the style tests via the make command
make style
Before submitting your own module, it is recommended that your module pass the style tests we ship with the reposi-
tory. We will ask you to update your code to meet these requirements if it does not.
This is probably the most important part of testing, so let’s go in to detail on this part.
Functional tests are required during module submission so that we (F5) and you, the developer, can agree that a module
works on a particular platform.
We will test your module on a variety of versions automatically when a new PR is submitted, and from there provide
feedback if something does not fly.
Structure of tests
Test file stubs are created for you automatically when you stub a new module.
First, let’s look at the layout of a set of tests. A test is composed of a role whose name matches the name of the module
that is being tested.
This role is placed in the tests/integration/targets/ directory.
So, for our example, our test role looks like this.
• test/integration/targets/MODULE_NAME/
Inside of this role is everything that you would associate with a normal role in ansible.
Consider the following examples.
• if your test requires static files be used, then a files/ directory should be in your role.
• if your test requires template data (for example iRules) for its input, then a templates/ directory should be in
your role.
• all roles will perform some work to test the module, so a tasks/ directory should be in your role.
Now let’s dig in to what a test should look like.
---
Information specific to the tests that you need to run should be put in the defaults/main.yaml file of your test role.
By putting them there, you allow individuals to override values in your test by providing arguments to the CLI at
runtime.
All tests that change data should also include a test right after it that tries to perform the same test, but whose result is
expected to not change.
These are called idempotent tests because they ensure that the module only changes settings if the setting needs to be
changed.
Here is an example of the previous test as an idempotent test
- name: Assert Set the SSHD allow string to a specific IP - Idempotent check
assert:
that:
- not result|changed
To call the test and run it, this repo includes a make command that is available for all modules. The name of the make
target is the name of your module.
So, for our example, that make command would be.
• make bigip_device_ssh
This command will run the module functional tests for you in debug mode.
You may optionally call the tests with the literal ansible-playbook command if you need to do things like,
• stepping (–step)
• starting at a particular task (–start-at-task)
• running tasks by tag name (–tags issue-00239)
To run the tests without make, first, change to the following directory.
• test/integration
Next, find the playbook that matches the module you wish to test. Using this playbook, run ansible-playbook as you
normally would. A hosts file is included for you in the working directory you are in.
An example command might be,
If you include files inside of the files/, templates, or other directories in which the content of that file was auto-generated
or pulled from a third party source, you should include a README.md file in your role’s directory.
Inside of this file, you can include steps to reproduce any of the input items that you include in the role subdirectories.
In addition, this place is also a good location to include references to third party file locations if you have included
them in the tests. For example, if you were to include iRules or other things that you downloaded and included from
DevCentral or similar.
The README.md is there for future developers to reference the information needed to re-create any of the inputs to
your tests in case they need to.
When writing your tests, you should concern yourself with “undoing” what you previously have done to the test
environment.
Test testing environment (at the time of this writing) boots harnesses for each suite of tests. That means that all tests
are run on the same harness.
Therefore, any changes you may make in one of the integration tests might accidentally be used as a basis in subse-
quent tests. You do not want this because it makes using additional the ansible-playbook arguments specified above
exceedingly difficult.
Therefore, please cleanup after yourself. Since you need to test the absent case in most cases, this is a good opportunity
to do that.
Deprecating Code
Our Ansible modules follow a strategy of deprecation which is intended to give the user of the modules ample time to
upgrade to a new version of Ansible.
New releases of Ansible happen, at the time of this writing, about once a quarter.
With this in mind, the following process should allow a user 3 to 6 months to upgrade their Ansible installation to
the new code. If the user misses this 3 to 6 month period, then they can upgrade incrementally (2.1 -> 2.2 -> 2.3)
instead of upgrading directly to the latest version and, in the process, test that the incremental versions work with their
playbooks.
To raise warnings about deprecated functionality, the module developer should add the following method to their
ModuleManager class.
Additionally, the module developer should add the calling of that method when they collect the changes to report to
the user. For example,
225
F5 Ansible Documentation, Release 1.0.0
And finally, the module developer should populate the __warnings key of their changes attribute as needed. For
example, in the bigip_gtm_wide_ip module, the following is used in the lb_method property when it sees you are
using an option name that is deprecated. For example,
The changes attribute is typically updated during the call to _update_changed_options during update, or
_set_changed_options during create.
If your module needs to detect changes outside of those two general methods, you should be doing so inside of the
should_update method.
Note: To do your own ad-hoc detection inside of should_update, you will need to overload the base classes’ method.
If you do this, you should decide whether or not it is still necessary to call the base classes’ method during the call to
your overloaded method.
With that in place, you will find yourself with warning messages being raised by Ansible when you use the deprecated
functionality.
Below is an excerpt from how one might deprecate an option that we no longer want to use. You may do this for a
number of reasons, but in most cases it is due to the original name not making sense in the context it is used.
For example, you might have named the original option rules when the more appropriate name for the option would
have been irules.
Note: Ansible allows for aliasing of options so that specifying one is equivalent to specifying another. This is not
the situation that we are referring to here. It is still perfectly acceptable to use option aliases if you want to. These
guidelines are for when you specifically want to remove options that are presumably already in use.
Here is a sample ArgumentSpec from the version where we made the mistake. Let’s assume that this mistake was
made in version 2.0.
Now, we wish to deprecate that option name. So, in version 2.1 of Ansible, we would do something like this.
Additionally, we would include the warnings necessary to make the user of the module aware that they are using
deprecated functionality (the rules option).
Finally, during the release cycle of Ansible 2.2, we would want to change our spec to look like so.
Thus, removing the deprecated functionality.
Also, do not forget to remove any mention of the deprecation inside the actual module code. We don’t want the legacy
code to stick around. This helps keep technical debt at bay.
Code Conventions
The following is a document that describes some of the design decisions that went into the F5 Ansible modules and
why they were made. This document is intended to address any contributor, or customer, questions on why I did what
I did and the known limitations for this design.
At F5, regardless of what you might here or read online, tmsh is not considered to be a formal API.
Now, there are some people who will try to argue about this and justify their argument by saying that, “well, tmsh is a
publicly available way to interact with the BIG-IP, therefore it is implicitly an API”.
While tmsh is indeed a publicly available way to interact with the BIG-IP, it is not considered by anyone at F5 to be
an API. You will notice, compared to other APIs that are formal, that it has none of the features of “real” APIs.
In addition to missing many features of “normal” APIs, it also is not guaranteed to be consistent across versions of
BIG-IP.
You should not rely on tmsh for anything except in cases where you have no other choice. And in those cases, you
must handle the versioning of it yourself.
227
F5 Ansible Documentation, Release 1.0.0
17.1.2 The company had decided to put all their effort into REST
When the REST pattern of API development became popular, F5 put some work into making a REST wrapper around
tmsh. That is what you have today; a wrapper around calls to tmsh.
To understand why the REST API is where the company has put more effort, you need to understand the history of the
SOAP API at F5.
It is surprisingly difficult for a team to develop for the SOAP API. The REST API is easier to code for. Additionally,
the REST APIs curiously map almost directly to the tmsh command you would use. Coincidence? Hardly. Remember,
it’s tmsh.
There is still new functionality being added to SOAP, but most of the engineers at F5 are focused on providing REST
functionality.
• It’s natively built into most all programming languages
• It’s more easily supported in our future javascript-based iAppLX effort
• It’s pretty close to native tmsh
17.1.3 SSH on BIG-IP can cause auth errors when under heavy load
For better or worse, while SSH is about as native today as telnet was in the past, it actually takes a fair amount of
resources to establish an SSH connection to a remote device.
You see this in Ansible today with their use of ControlMaster and pipelining. Ansible saw that just the act of repeatedly
connecting to the remote device over SSH caused a significant amount of lag.
A real-life example, a customer had been using modules (that they had developed) that used SSH under the hood to
connecto the BIG-IP and were seeing “F5 Authorization Required” 95% of the time. With SOAP this dropped to 4%
and with REST this dropped to 1%.
When we investigated things further, we noticed that when the BIG-IP was under load, the normal behavior of Ansible,
namely this,
sshpass -d57 ssh -C -o ControlMaster=auto -o ControlPersist=60s
-o StrictHostKeyChecking=no -o User=ansible -o ConnectTimeout=10 -o
ControlPath=/tmp/ansible_tower_JR8zTS/cp/ansible-ssh-%h-%p-%r -tt
10.192.73.218 'tmsh delete sys connection'
This constraint is relevant to the developers who actually code these modules. For the first iteration of the modules,
what I refer to 1st-gen, the modules were written by primarily two people who were not F5 employees.
For the 2nd-gen modules, they were all written by one guy; me, an F5 employee. This was when F5 began put more
skin in the Ansible game.
For the 3rd-gen modules, they were written primarily by myself and one other F5 employee. Then, they were tested
and promoted by several other F5 employees.
The reason that I bring these points up is to emphasize just how __few__ people are actually working on the modules
that you are using.
There is no “Ansible team” at F5. Due to my limited resources, I placed a priority on ease-of-development and testing.
I needed to churn reliable product out at a rather fast pace compared to the pace that all other F5 products are released.
My timeline was weeks, not bi-yearly like BIG-IP releases.
SOAP has different APIs for every configuration point. Literally. If you need to set the description of a Virtual Server,
you need to use the set_description API, but if you need to set a destination of the same Virtual Server you need to use
the set_destination_v2 API. It’s v2 because there is also a set_destination API that must be used for anything before
version 11 of BIG-IP.
This is kinda frustrating from a developer point of view because you need to know all these different APIs.
It’s frustrating from the admin’s point of view because each API is another round-trip to the BIG-IP. Each time we
need to talk to BIG-IP it means a slow-down and a chance that a failure could happen.
This can be worked around through the use of Transactions in SOAP, but that just _another_ thing that the users of the
API need to be aware of when writing any sort of integrations with BIG-IP.
REST configures based on a “resource” so many APIs are implicitly transactional without needing to use transactions.
Additionally, these resources mean that you only need to refer to __one__ API when changing most things about a
particular object in BIG-IP.
For example, using our virtual server example above, instead of 2 or more APIs, there is only one;
/mgmt/tm/ltm/virtual. Sending a GET request to the resource returns a single JSON payload where you can change the
description or destination as needed and then send a PATCH back to the BIG-IP with those changed values.
Also, it works like this across __all__ of the resources in BIG-IP. Which means once you have learned how to use one
resource, you’ve essentially learned how to use all of them.
Note: It should be noted that due to bugs in the REST API this is not __always__ true, but it is true enough that you
can consider it “the way things are” and handle the edge cases as you encounter them. Indeed, we handle just such
edge cases for you in the f5-sdk so that you don’t need to care. That is one of the many reasons to use the SDK; we
iron out the inconsistencies in the API.
From a developer point-of-view, this requirement to learn a convention instead of learning a library of API calls means
that new developers can be onboarded more quickly and existing developers can more easily add new functionality
and support existing functionality.
From an admin point of view, this means that we need to make fewer round-trips to your BIG-IP and this should
therefore speed up the operations that we do perform on the BIG-IP.
The tool underlying all future Ansible F5 module development is the F5 Python SDK.
BIG-IP is not F5’s only product. BIG-IQ and iWorkflow are two other products that we make. Both of these products
natively use REST API communication for __all__ of their functionality.
Indeed, if you use a network inspector like those built-into Chrome or Firefox, you can see the actual APIs these F5
products communicate with and the payloads that they use.
Ok, fine, but “these products ship on something that has SSH access” you might say. That’s true, but in the future they
won’t. Teams developing these products are rapidly turning them into standalone applications; what we refer to as
“TMOS independence”.
So in the future they will __not__ have CLI’s other than whatever is provided by the operating system that hosts them.
Also, each of these products provides functionality that allows they to proxy requests directly to the BIG-IPs that they
manage. We refer to this as “REST Proxy”. That these tools provide such native support is testament to how REST is
considered to be a first-class citizen for configuring our devices.
If you look at the API landscape, nearly every vendor API is REST-like. It’s becoming increasingly uncommon to see
SOAP APIs because, compared to JSON-over-HTTP using HTTP verbs, SOAP is just a little too heavy-handed.
Most applications can represent their data structures just fine using JSON. Its largely unnecessary to provide anything
bigger than just a JSON payload. Languages can natively transform scalars, lists, and dictionaries to the data structures
native to the language.
Indeed, even in a complicated system like BIG-IP, all of our data structures can be represented by a JSON payload.
To make the adoption of our APIs easier for those admining our box and integrating with it, it was important to use
technology that was already familiar to them.
Since customers are already largely exposed to REST-like APIs from their dealings with other vendors, it was natural
to make use of the REST API instead of some other format, or, direct SSH communication.
17.1.8 The people working on this codebase work with REST and the SDK every
day
The F5 OpenStack team began the trend of SDK development with their work on our Openstack integration. This
progressed to include my adopting their work in Ansible. Today, the people who are working on Ansible modules are
the same developers who were initially working on the F5 Python SDK.
Furthermore, we are introducing more teams at F5 to the Python SDK so that they too may integrate it into their testing
procedures.
So as you can see, the majority of the new work being done at F5 is being done by people who are familiar with REST.
There is a sizable amount of pre-existing work in test harnesses and other stuff at F5 that is based on SSH, but the
experts that were involved in writing that have since left the company and no expertise exists to further develop it; nor
do those teams want to put further development into it.
With this increasing body of knowledge around our REST API, it makes less sense to attempt to support SSH.
17.1.9 The Ansible persistent network connection was not mature at the time
Persistent network device connections was released in Ansible 2.3. A __significant__ amount of work on the modules
however, had already been done prior to this release.
To expect that one guy (Tim) to,
• change all those 30 modules
• support both modes (API and SSH) of configuring the remote device
• that had taken multiple years to write
was not something I wanted to undertake.
I honestly leave this open as an exercise for the end user. If you are deeply interested in making SSH happen, then by
all means go after it. Modules that come out of F5 directly though will remain REST based for the foreseeable future.
A common ask from customers and colleagues is to mimic the behavior of the “replace-all-with” tmsh functionality
via Ansible modules. The following document discusses challenges and proposes solutions for this feature when it is
requested.
18.1 Challenges
By it’s nature, Ansible is not designed to support something such as replace-all-with. Ansible modules are normally
intended to be run per-device and therefore should, in most cases, be accepting a single item of configuration and
applying it per that device.
For example,
The above task, iterated per host, would create a number of SNAT pools. There is the desire, however, to remove all
the existing and replace with a new list. Suppose that you did not know what the existing SNAT pools were. In that
case, how would you remove the existing to add new ones?
This pattern of “unit of work per host” becomes an anti-pattern when applied to replace-all-with. This is because there
is no way to reliably tell the module to
• Delete all the existing
• Add what I give you
Since the module only knows about what it receives at time of execution and not about what the Play is doing as a
whole (or even that its in a loop) you cannot specify, for example a replace_all_with parameter.
It’s also unacceptable to have something like an append parameter because, again, the module is not aware that it is in
a loop or what the greater Play is doing.
There may be some ability to make the module aware by specifying these list squashing modules in Ansible’s default
squash_actions configuration variable, but this is a very untenable solution because we would be either
• Changing core code
• Asking users to create custom ansible.cfg files every time they use BIG-IPs
233
F5 Ansible Documentation, Release 1.0.0
18.2 Proposals
What I propose is to provide the user with the ability to know what exists so that they can use the absent state of a
module to remove all existing instances. This will be done using a *_facts module for the manipulation module in
question.
Using the above example of bigip_snat_pool, the facts module would be bigip_snat_pool_facts. The user could
provide filtering params such as those they can supply to the bigip_snat_pool module to return only values that meet
those criteria.
The user can then store those returned values using a register variable and then loop over the values to delete them all
before adding new ones.
For example,
Additionally, I would like to pursue the development of modules to support transactions such as
• bigip_transaction
This could be used to ensure that the above example is done in a way that would tolerate a failure between deleting
and re-creating SNAT pools. Thus, the replace-all-with functionality would essentially be retained.
For example,
Note the addition of Transactions above. This new functionality would be put into the f5_utils module_utils code
inside of Ansible to be supported across all modules.
For modules that do not support it, a @property would be defined to return only None.
For example,
This is similar in how the bigip_partition module always returns None for the partition parameter because you cannot
create partitions inside of partitions.
All properties should read from self._values[key]
All property.setters should write to self._values[key]
The ‘key’ in the self._values dictionary should match the API resource attribute. This allows us to easily determine
Deprecating functionality
In a module, it may be necessary to raise warnings to the user due to deprecated functionality.
Normally, deprecations are done in the ArgumentSpec, such as when using the removed_in_version key shown below.
but that is only relevant when the parameter itself is deprecated. There are other deprecation scenarios for instance
where the parameter is a list of choices and the choices themselves are deprecated.
For example, consider the following parameter
One may need to deprecate the values themselves in favor of other values.
This may seem like a simple thing that one could add code to fix, but doing so would also lead to an increase in
technical debt. Having a mapping of old values to new values should be considered an anti-pattern and something that
is a candidate for deprecation.
To announce deprecations (for all things) you can use the removed_in_version field mentioned above, but you can also
have more customized deprecations raised by your module.
To do this, begin by amending the __init__ method of your Parameters class to define a __warnings variable.
Next, we need to add a new method to the ModuleManager, or, class specific manager (such as those used when
forking logic; ie, bigip_gtm_pool)
The definition of this method is the following
The third and final step is to actually make use of the deprecation code that you set up previously. Do do that, you
want to append to the aforementioned __warnings field.
An example is show below.
235
F5 Ansible Documentation, Release 1.0.0
pycodestyle
237
F5 Ansible Documentation, Release 1.0.0
Design Patterns
21.1 CRUDable
• bigip_static_route
• bigip_snmp
21.3 Executable
• bigip_command
239
F5 Ansible Documentation, Release 1.0.0
iworkflow_tenant_connector
• bigip_remote_syslog
Class variables
The following class variables are common attributes that each Parameters class needs to define.
22.1 updatables
Specifies a list of Parameters properties to that are considered updatable by the module. This is used when doing
should_update()‘ comparisons and setting properties in self.changes.
22.2 api_attributes
Specifies a list Parameters properties to provide to the api_params()‘ method when generating valid sets of attributes
for resources in the REST API.
You will likely need to write adapter methods that call the properties used internally by the module when writing these.
For example
The reason that we use this method instead of the map method is because there may be cases where the value used in
api_params() is not a single property but a set of properties that need to be combined.
This is used by the api_params method to generate a valid set of attributes to provide to the REST API. Typically this
dictionary does NOT provide the name and partition parameters. These values should be specified specifically in the
(create|update|delete)_on_device methods
22.3 returnables
Specifies a list of Parameters properties for the to_return() method to iterate over when supplying
“changed” options back to the user
241
F5 Ansible Documentation, Release 1.0.0
22.4 api_map
We need to have a dictionary or a list of some stuff because there are times when the API parameters can not be written
as methods. For example, the bigip_device_dns APIs parameters include
This attribute is mapped to forwarders in the Ansible module.
The pattern that I had been developing is to use methods decorated as properties in python and then to call those
methods when setting values and getting values.
For example, the “dns.proxy.__iter__” API attribute would be mapped to the _values key “forwarders”. Normally I
would set the set the API attributes directly in the dictionary. I would need to get those API specific keys however
when I am returning the values to compare. this makes the getters for the Module options look messy though.
Next I thought about having the API attributes have their own @property decorators, but this won’t work in the “dns”
case mention above.
NEED a pattern for a single Ansible Option Parameter that returns 2 API attributes. For example in the
bigip_virtual_server module there is an option called enabled vlans. This, however, actually sets two (possibly 3)
values in the API
• vlans (list
• vlansDisabled (boolean True)
• vlansEnabled (boolean True)
what is a pattern that, that supports that?
The pattern is that the api_attributes is an arbitrary list of attributes that you want to send to the API.
The api_params() method uses this list to iterate over the
param_api_map does not work for situations where the Ansible->API relationship is 1->n (bigip_virtual_server with
enabled_vlans) param_api_map only works for 1->1
Requirements
• easy attribute comparison in Ansible parameters format with BIG-IP API values
• ability to consume API attributes that cannot be written as python functions (dns.proxy.__iter__ for exam-
ple)
params_spec=dict(
cache=’dns.cache’, forwarders=’dns.proxy.__iter__’, name_servers=’nameServers’,
search=’search’, ip_version=’include’
)
updatables = [ ‘cache’, ‘forwarders’, ‘name_servers’, ‘search’, ‘ip_version’
]
)
Common classes
Nearly every module (see exceptions) should have the following classes. These classes are used to support the stated
design patterns.
• Parameters
• ModuleManager
• ArgumentSpec
243
F5 Ansible Documentation, Release 1.0.0
Defaulting to None
It should be noted that you should never specify default values in your ArgumentSpec. For example, the following is
incorrect
But, shouldn’t you be using the actual defaults?
Answer: No
The reason that you provide no defaults is to support cases where the user does not specify a value for a particular
option. If that happens, then you should not step on that parameter if it is preconfigured.
If a user had a setting that they want to keep and you specified a default value, then in the first opportunity that they
forgot to specify that value, you would end up replacing that value with your default.
This is a bad idea.
Ansible defaults required to False and default to None. Therefore, there is no need to specify these default values.
245
F5 Ansible Documentation, Release 1.0.0
The ‘‘@property‘ decorators you see represent an adapter pattern. Inside of the ModuleManager, when data needs to
be compared (what you have vs what you want), that data is returned by these properties in a known format.
The API’s resource attributes differ in structure and name from the options that a user can provide to a module.
For example, an API resource may have an attribute called minSupportedBIGIPVersion. The user facing portion of the
module though, may refer to this attribute as min_bigip_version. There are a number of reasons to do this.
• it provides an abstraction of the API so the name of the thing being modified is not closely tied to the imple-
mentation of the API.
• many times the API attribute names are vague, this abstraction makes them more clear
• the Resource Attributes use camelCase variable naming, while some of python and nearly all of Ansible use
snake_case variable naming.
For future developer clarity’s sake, all of the attributes that we are interested in are typically compared by the option
name that they would have in Ansible and not the Resource attribute name.
This allows a developer to look at the names of variables and match them to the names of the options in the Ansible
module.
While the names of properties usually mirror the names of the module options available to the user, the values of those
properties do not.
Values of the properties reflect the values that are accepted by the API resource. This is done because, ultimately, the
values that we need to deal with at the values that are going to be used to update the API.
Therefore, when we receive options from the module, we transform them into the values that would appropriate for
the API. When we receive values from the API, we might order them or cast some of their values to specific types so
that comparisons can occur, but otherwise we dont really touch them.
So,
1. property name reflects module option
2. property getter reflects the appropriate Resource attribute value
247
F5 Ansible Documentation, Release 1.0.0
248 Chapter 25. What is the layer of @property decorators all about?
CHAPTER 26
This is because there are some cases where you do not know ahead of time what the value of that property should be.
Often it takes two or more options be set before another option can be known.
Consider a module that accepts an IP address option and a gateway mask option, but needs to return a CIDR represen-
tation of those two values. Without getting both values, we cannot produce the one value. That is who we calculate
the necessary value at time of getattr, and not at the time of setattr.
249
F5 Ansible Documentation, Release 1.0.0
This is important in case there is a pattern we miss for adapting API attributes and module params.
This test suite is found at the following location
test/misc/test_module_utils.py
251
F5 Ansible Documentation, Release 1.0.0
252 Chapter 27. Use the module_utils test suite to verify AnsibleF5Parameters classes
CHAPTER 28
Never import *
9 times out of 10 you are doing this because you are using one of the following variables
• BOOLEANS
• BOOLEANS_TRUE
• BOOLEANS_FALSE
It is, however, an anti-pattern to import from * and it will be caught by the Ansible unit tests. Instead, specifically
include each thing that you want to use.
253
F5 Ansible Documentation, Release 1.0.0
In many cases, the values that you process from the user will match the values that you send to BIG-IP.
For example, consider the following parameters to a module
Above, the module code that implements this is a collection of different adapters that collectively allow the module to
convert the information the user provides to it into a format that it is able to send to the BIG-IP and vice-versa.
This class is a way for the module developer to complete the cycle of
User (params) -> Module -> REST -> Module -> User (changed params)
Due to most of the adapters being concerned with how they should be adapting data to meet the format expect by the
REST API, the Changes class is concerned with how to adapt the data to meet the format expected by the end user.
If there is a need to change the value to something that is more “human” so that the user can understand it, that job is
undertaken by the Changes module.
An example of it in use is the bigip_device_connectivity module where it acts as a way to translate BIG-IP’s represen-
tation of “none” (any6) to the human word “none”
Examples of modules that use the Changes class are,
• bigip_gtm_datacenter
• bigip_device_connectivity
• bigip_device_group
255
F5 Ansible Documentation, Release 1.0.0
When comparing values to detect changed-ness, there are situations where the default comparison method will not be
appropriate for you use. The default comparison method essentially just does a simple comparison.
The source of this method illustrates its simplicity
As you can see, it is quite simple and does not take into consideration anything more complicated than simply the
values being compared.
This differencing is not conducive to more complicated data structures or types of data.
The above fails to satisfy this simple (albeit erroneous due to established patterns) difference.
Note: This is logically incorrect because the Adapter pattern that you should be using for the Parameters class
mandates that @property values should return a specific data type (in the above case int) and should never be non-
deterministic.
To check for differences in more complicated data structures, the module author should make use of the Difference
class.
The definition of the Difference class is the following
By default, it does nothing more than uses the simple comparison to diff the parameters provided, and discovered, by
the module.
To make use of it, you must do the following.
First, define this class in your module.
Second, add @property methods for each of the values that you want to compare. Remember, the properties of the
Parameter classes are the names that are exposed to the module user and not the names of REST API parameters
themselves (unless it perfectly matches) because the REST API camel-cases all parameter names.
So, if we were interested in providing custom diffing for the members module parameter, we may add this as a
@property to the Difference class like so.
These @property methods must be named after the Parameter you want to compare. Additionally, the return value of
these @property definitions is one of two values.
257
F5 Ansible Documentation, Release 1.0.0
This adapter pattern is useful for converting data values from user inputs to REST outputs. It’s definition is,
The API Map Adapter pattern adapts a known REST attribute to a predefined Parameters method. The
return value of this method is a correct payload for the REST attribute.
This pattern is frequently used as a way for the module developer to translate the input provided to them by the user
into a format that is consumable by the REST API.
The following is an example of this kind of adapter.
259
F5 Ansible Documentation, Release 1.0.0
1-to-1 Adapter
YAML represents the banner parameter as a simple key with a simple value. The actual REST payload contains an
attribute called banner and it takes an actual value called enabled. This is represented in code by the ArgumentSpec
class.
This is considered to be the most simple form of a parameter definition by the F5 Ansible modules because it is nearly
a 1 to 1 translation of Ansible to F5.
The following is an example of this kind of adapter.
261
F5 Ansible Documentation, Release 1.0.0
Parts of the f5-ansible repository contain information that is considered sensitive in nature, and therefore needs to have
a particular amount of due-diligence applied when handling it.
Information of that sort includes, but is not limited to,
• Product keys
• Internal URLs
• System configurations that are not relevant to the general public
To address the concerns of exposing this information in a plain-text manner, the authors have put in place a series of
GPG encrypted files. The remainder of this document explains how this system works.
There are many existing tools that can help address the problem of storing secret information in an otherwise public
place. These include, but are not limited to,
• blackbox (from StackExchange)
• git-crypt
• git-secret
• Keyringer
• Pass
• Transcrypt
The tool that we use is blackbox primarily because
• It works in our docker containers
• It has a large number of stars and forks
• It is just shell wrappers around GPG
263
F5 Ansible Documentation, Release 1.0.0
33.2 Using it
To make use of the system, the first thing you must do is create a set of GPG keys to be used for encryption and
decryption of secrets.
Creating a key can be done with the gpg command. Consider the following example
This command will ask you a couple of questions related to your new keypair. They are,
• Real name
• Email address
For example,
To proceed, answer O (the letter, not the number) and the command will proceed to ask you for a passphrase in a
separate window.
6------------------------------------^@
< Please enter the passphrase to |
< protect your new key |
< |
< Passphrase: ________________________________________ |
< |
< <OK> <Cancel> |
^@-----------------------------------5
If you do nothing else correctly for this procedure, you must absolutely get this step correct. Your passphrase is
considered hallowed ground. If Tim had his way, it would be a fire-able offense to disclose it. This is super important,
so listen.
Your passphrase is what is used to decrypt and encrypt sensitive data in the f5-ansible repository. If it is compromised,
then the information contained withing the gpg encrypted files is assumed to be compromised.
Now, because we include these gpg files in git, this also means that the compromised versions are accessible even if
we rotate the keys.
So it is your job to choose a passphrase (note I did not say pass**word**) that is sufficiently long to hedge the risk of
having it discovered computationally.
Once you have a passphrase chosen, enter it in the aforementioned box. Pressing Enter will ask you to re-enter the
passphrase.
6------------------------------------^@
< Please re-enter this passphrase |
< |
< Passphrase: ________________________________________ |
< |
< <OK> <Cancel> |
^@-----------------------------------5
Pressing Enter after typing the passphrase a second time will generate the necessary public and private keys for you,
as well as add them to your GPG keychain locally on disk.
For example,
root@9f1cc7b78557:~#
You can verify that your keys exist in your keyring with the following command
gpg --list-keys
If you were successful, you will see your key in the list.
Note: Be aware that when you created your key, it was given an expiration date a couple years (two by default) in the
future. It is critical that you perform a key renewal as your key becomes due for expiration. Instructions for doing this
can be found here
With your keys generated, you can now include them in the Docker development containers that are provided with
f5-ansible.
In the devtools/docker-compose.yaml file in this repository is a config section that resembles the following
- type: bind
source: ~/.gnupg
target: /gpg
This configuration instructs docker-compose to create a path in your container (at runtime) that maps the .gnupg
directory in your home directory to the /gpg directory in the container.
If you need to change the location in which your GPG keys are found on your local filesystem, the recommended place
to change that is in the configuration above.
Determining what you should and should not encrypt is the first step in this process.
Generally speaking we encrypt anything that is “F5 specific”. This is kind of vague though, so here are some examples,
• Websites that are internal to F5
• License keys used for integration tests
• Configuration of system that is irrelevant to the public (insofar as it would not help them in any way to have)
For all of those, and more, instances, we encrypt.
Adding new files to the encryption process starts with the following command
blackbox_register_new_file path/to/file.ext
Note: The suite of blackbox_ commands is your interface to the process of encryption and decryption. There are
many commands that one can use. The ones you are most likely to use are,
• blackbox_register_new_file
• blackbox_decrypt_all_files
• blackbox_deregister_file
• blackbox_edit_start
• blackbox_edit_end
• blackbox_list_files
A requested feature of the F5 modules has been the ability to use SSH to configure them.
I looked into this possibility and after discussing with Michael about it, it was suggested that to retain the ability to
parse structured output (ie, the REST output) that we should try to use local curl commands to the same APIs and that
we would therefore get the same results which we could sent to our existing Parameter classes.
This sounded goo, but it has some deficiencies that a user needs to be aware of before they can make use of it.
By far the largest limitation is that there are only two roles who are actually able to use the “Advanced shell” also
known as “bash”.
• Administrator
• Resource Administrator
All other roles are limited to the tmsh shell only. This results in two problems.
First, since you are in tmsh, you do not natively have a curl command that you can use. Normally you would be able
to use curl because it is installed and is a standard feature of the system. However, you do not have a curl command
that can be run from, for example tmsh run util...
This first problem can actually be worked around if you have one of the two roles mention above, associated with your
account.
If you have either role, you can make use of curl through the tmsh run util bash command.
269
F5 Ansible Documentation, Release 1.0.0
• https://support.f5.com/csp/article/K12815
I will reiterate some of those restrictions below.
• Access to the Advanced shell (bash) has been removed.
• Administrative access is limited to the Configuration utility, bigpipe shell (bpsh), and Traffic Management Shell
(tmsh)
• The root user cannot log in to the device by any means, including the serial console.
• To disable Appliance mode, you must contact F5 for assistance in removing Appliance mode from your license
file and then perform a clean installation of the software.
The above restrictions essentially make it exceedingly difficult to configure the device using an API that provides
structured data. Additionally, it may make some actions that we take in the modules completely impossible such as
uploading file data which would appear to require SCP functionality in the case of Appliance Mode.
As it stands, the above requirements would mean that we would need to rely on tmsh itself to accomplish anything.
This means working with a tool that does not provide structured output; only free form output.
Indeed there is a –oneline argument that may be supplied to tmsh commands, but it is not clear to the author how
parseable, or reliable, this format is.
34.3 Conclusion
For the above reasons, if CLI functionality is pursued for any of these modules, it is my recommendation that the
functionality only be allowed for users who are of one of the following roles,
• Administrator
• Resource Administrator
Note that it is not required that the user of the modules need worry about which partitions they are allowed to access.
With these roles you can access all of them.
Without making this a requirement, it may not be possible to provide a user of the modules with a reliable way to
configure the system due to restrictions that are put in place by other roles.
Issue Management
When doing triage of new or existing Issues, please abide by the following conventions.
• If the issue seems to be, by your best judgement, a bug, add the label bug-report to it. This will assist F5’s
support organization in the care and feeding of the F5 modules.
271
F5 Ansible Documentation, Release 1.0.0
If you are an F5’er, then you have access to an internal docker registry.
If you are reading this, then you should also know what that registry is. If not, then visit this link
These instructions are only relevant to you if you are an F5’er. If not, feel free to skip over this document.
At this registry there is an organization named f5ansible. There are several repositories in this organization. For
instance,
• f5ansible/py2.7
• f5ansible/py3.5
• f5ansible/py3.6
• etc
You get the idea.
Each of these images is, as their name implies, a different Docker environment for each version of Python that we
develop and test upon.
These containers are also named in the various image keys inside of the docker-compose file contained in this reposi-
tory. For example,
services:
py2.7:
image: f5ansible/py2.7:devel
build:
context: ..
All of the containers that you see are built nightly at midnight by a trigger that is fired when a Jenkins job completes.
That job is found in this jenkins-job-builder file.
273
F5 Ansible Documentation, Release 1.0.0
• test/pipeline/ci.f5.f5-ansible-public-to-private.yaml
Therefore, when you come in the next morning (assuming you work in Seattle) you will have a new set of docker
images available to you.
The first step required to get these updated containers on a regular basis is that you must log in to the registry service
mentioned above and get a set of encrypted credentials that the service can provide you with.
Clicking the settings for your account (upper right corner of the registry) you will be presented with the option of a
CLI password.
Click the associated link and you will be asked to verify your current password. Enter it as required.
In the modal dialog window that appears you have the option of choosing Docker Configuration. Click that tab.
Follow the instructions on screen to properly configure your ~/.docker/config.json file.
F5 has its own registry for containers. To configure your docker-compose files to use it, start by locating the following
file
• devtools/docker-compose.site.example.yaml
Next, copy this file, renaming it to the following.
• devtools/docker-compose.site.yaml
Finally, open the file for editing. Inside of the file is a descriptive header that will instruct you on how to edit the file.
In particular, you need to add the URL of the F5 Docker registry. If you do not know what this is, ask a co-worker for
assistance.
With the above setup and configured, you can pull the images using the docker-compose command. For example,
In this tutorial I will outline the steps you need to take to add a new person to the list of allowed admins for handling
the encrypted data in this repository.
You should do this whenever you have deemed it necessary that a new person should be assigned to handle secure
information.
Our policy is that the developers responsible for this software will be granted access to this repository.
Additionally, there may be an unspecified number of robot services that have subkeys registered in the list of admins.
These keys have no business editing the content of the admin file. They must still be able to decrypt the content of the
entire repository as needed to do their job; run CI/CD testing and deployment.
275
F5 Ansible Documentation, Release 1.0.0
All of the work can be done inside of the development containers that are available in the ./devtools/bin directory. In
this example I will use the run-py2.7 script to launch the relevant container.
We are going to begin with the person who wants to be added.
To perform these steps, start by firing up the py2.7 (or equivalent) container.
Within this container, use the gpg2 –gen-key command to create the keypair you will use. An example is shown below.
Note: Use "gpg2 --full-generate-key" for a full featured key generation dialog.
root@d7f809815281:/here#
With this complete, you should see your email address when using the gpg2 –list-keys command.
We assume that you have created an initial keypair to use for encryption. If you have not yet done that, follow the
instructions below in the (Creating a keypair)[] section.
Begin by starting that container with the necessary script
This command will leave you at a new shell prompt. Within this new prompt, the next step is to create a new branch
which will contain the pull request with your admin addition in it. This can be done with git
blackbox_addadmin foo.bar@f5.com
When this command finishes, there will be several new files which are shown as modified. Additionally, the black-
box_addadmin command will instruct you on the command you need to use to commit these changes.
root@d7f809815281:/here#
You may now push the PR to the Github repository and follow the normal PR process.
First, verify and merge the PR sent by the user wishing to be added.
Note: Adding a new user to the public key chain in the steps above is not, immediately, a security risk. This is because
you have not yet re-encrypted the files. If you mistakenly merge a PR from a bad actor, you should immediately reverse
Next, merge the aforementioned PR into the repository. After that, you will want to rebase your own fork of the code
to include this new merge commit
root@a710b12b1e97:/here# blackbox_update_all_files
========== blackbox administrators are:
caphrim007@gmail.com
HypePDSvc
k.austria@f5.com
========== Importing keychain: START
gpg: key DBE7B40B4ACC6C92: public key "Kat Austria <k.austria@f5.com>" imported
gpg: Total number processed: 10
gpg: imported: 1
gpg: unchanged: 9
========== Importing keychain: DONE
========== ENCRYPTED FILES TO BE RE-ENCRYPTED:
devtools/secrets/jenkins_jobs.ini.secret.gpg
...
test/runner/roles/harness/vars/TwoArmed-bigiq-5.3.0.yaml.gpg
test/runner/roles/harness/vars/TwoArmed-iworkflow-2.1.0.yaml.gpg
========== FILES IN THE WAY:
devtools/secrets/jenkins_jobs.ini.secret
test/heat/jenkins-secondary-params.yaml
test/pipeline/ci.f5.f5-ansible-public-to-private-parameters.include.yaml
test/runner/roles/harness/vars/TwoArmed-bigip-12.1.2-hf1.yaml
Press ENTER to proceed and re-encrypt all of the secrets. You will be asked for your own encryption password in the
process.
...
========== RE-ENCRYPTING FILES:
========== PROCESSING "devtools/secrets/jenkins_jobs.ini.secret"
========== Encrypting: devtools/secrets/jenkins_jobs.ini.secret
========== Encrypting: DONE
...
========== PROCESSING "test/runner/roles/harness/vars/TwoArmed-iworkflow-2.1.0.yaml"
========== EXTRACTED test/runner/roles/harness/vars/TwoArmed-iworkflow-2.1.0.yaml
========== Encrypting: test/runner/roles/harness/vars/TwoArmed-iworkflow-2.1.0.yaml
========== Encrypting: DONE
========== COMMITING TO VCS:
[devel f7021f1] Re-encrypted keys
35 files changed, 49 insertions(+)
rewrite devtools/secrets/jenkins_jobs.ini.secret.gpg (100%)
...
rewrite test/runner/roles/harness/vars/TwoArmed-bigiq-5.3.0.yaml.gpg (100%)
rewrite test/runner/roles/harness/vars/TwoArmed-iworkflow-2.1.0.yaml.gpg (100%)
========== DONE.
Likely next step:
git push
blackbox will end with telling you what the likely next step is; git push. Indeed, if you view the git log, you can see
there is a new commit there for the re-encryption process.
commit f7021f14193d7d81f22920c2dbe0f16d90f08f17
Author: Tim Rupp <caphrim007@gmail.com>
Date: Tue Nov 7 00:30:07 2017 +0000
Re-encrypted keys
Therefore, do the push as requested. Once this is done, the new maintainer will have the ability to decrypt the secrets.
Parameter classes
The modules make use of a Parameter class that acts as a rudimentary two-way adapter. This class adapts data in the
following ways,
• Ansible module parameters submitted by the user into REST API attributes
• REST API attributes into Ansible module parameters for comparison and internal data structures.
This method has served most modules well, for a number of modules though, the abstraction has been difficult to work
with. This largely stems from instances where,
• The api_map maps resource attribute names to Ansible module parameter names which are similarly named but
have wildly different values
• When a name conflict results in not knowing “how to best” determine if you are dealing with the API’s values
or the Module’s values. We have side-stepped this problem in certain situations by checking for the existence of
the kind key and comparing it to what we know to be the _real_ kind key for the resource
• We need to include resource attributes in the updatables key because there is no other way to get them into the
api_params method. The error is doing this even if that updatables addition is not an Ansible module parameter.
The updatables list is intended to be a list of only Ansible module parameter names.
• It has been difficult to do Difference engine comparisons if the values that need to be compared (API values) are
not in the updatables array because only those values are diff’d.
In an attempt to settle the difficulty of using the “big adapter”, as I lovingly call it, a different pattern is being tested
where different classes (inheriting from a Parameters base class) will be used for the Ansible module parameters
(ModuleParameters) and the REST API parameters (ApiParameters).
Additionally, the base Parameters class will be changing its base definition to remove the __getattr__ definition that
it has. This definition has introduced an added layer of difficulty when debugging problems because it implicitly
swallows and errors that may be raised by invalid “dot” attribute access. For example, self.want.baz where exceptions
raised in baz may be swallowed. The only indication that this has happened is that a post q.q call will never happen.
For example,
...
q.q("started here")
281
F5 Ansible Documentation, Release 1.0.0
In the above (when the situation that I described above happens) the second q.q call will never happen. There will be
no entry in the q log file location, but success of the module may actually happen! This is a can of worms, so we need
to eliminate it before we regret it.
The base Parameters class will also have it’s signature changed from,
to a version that allows for a free-form of parameters and selectively chooses “special” parameters to do key things
with. The new signature is,
This allows us to expand on what the “valid” kwargs to the init method are. To begin with, there are two args that the
base Parameters classes will know about. They are,
• params
• client
The former is no different than the way things work today; the exception being that you will need to be explicit when
supplies params to a Parameters derived class because params is no longer just assumed to be the default. To change
you code, would require the following be done,
# legacy version
self.want = Parameters(self.client.module.params)
be changed to
# current version
self.want = ModuleParameters(params=self.client.module.params)
The later client parameter is new to the Parameters base class. In existing code bases it is possible to add this
functionality to your concrete Parameter classes, but it is not obvious how, nor well-documented.
For example, today the following would need to be accomplished,
self.want = Parameters()
self.want.client = self.client
self.want.update(self.client.module.params)
self.want = ModuleParameters(
client=self.client,
params=self.client.module.params
)
Any concrete params class that inherits from the Parameters base class will be able to use the method show above.
The client= feature seems like it was added only to make the above easier and more explicit. That, however, was more
an unintended consequence than a goal. The real purpose for doing the above was for the following
• BIG-IQ
• Unit tests (for BIG-IQ)
Note: My assumptions here are based on the work that others have done in this area. When I wrote this, I did not
have first-hand experience with BIG-IQ; only the iWorkflow codebase (which was originally a fork of BIG-IQ).
You see, the BIG-IQ code-base will require situations where the concrete Parameters classes themselves will be
responsible for reading data from the remote device.
This is because, in many circumstances, we cannot know all of the resources and their attributes that we need to deal
without, without querying for data using a resource attribute itself as input.
Surprisingly, we know this is going to be a problem, because we’ve already experienced it. Where? In iWorkflow.
You see, iWorkflow’s REST API was created from a fork (long ago in a galaxy far far away) of an older BIG-IQ
code base. Many of the similarities have disappeared over time, but the one thing that has remained constant is that
BIG-IQ’s API is one where you have to do a HUGE amount of “extra” work to just do what you need to do.
That means that concrete Parameters will need to do this work so that the user does not need to. For example, you’re
setting yourself up for failure if you plan on using Postman to work with your BIG-IQ. Good luck with that. The
Ansible modules deliberately provide a layer of “niceness” that you simply do not get with direct API communication.
But that’s A-OK, because all that direct API stuff and what concrete class needs to have a client really all boils down
to “implementation details”. The developers (you because you’re reading this) need to worry about it; the users do not.
283