Using Declarative Onboarding in a Docker Container

Important

This community-supported solution for DO running in a Docker container is being archived as of DO 1.16. F5 will no longer provide new versions of DO running in a container.

F5 Networks has created a community-supported Docker Container with Declarative Onboarding installed (1.2.0). You can use this container to create new BIG-IP systems. This can be extremely useful for automating BIG-IP configurations.

Prerequisites

  1. You must have Docker installed (https://www.docker.com/get-started/) and running.
  2. You must have a target BIG-IP system running version v13.1 or later to use Declarative Onboarding.
  3. If running Docker on Microsoft Windows, you must make sure the drive in which you are working (for example, your C: drive) is shared in the Docker settings.
  4. Once your container is running, you must use the target parameters in your Declarative Onboarding declaration as described on this page.

Downloading and starting the Declarative Onboarding Docker container

The first task is to download (pull) the Docker image from Docker Hub. If you plan on adding base authentication, see Adding Basic Authentication for guidance on the directory structure for pulling the image.

  1. Download the F5 Declarative Onboarding Docker image using the following command syntax: docker pull f5devcentral/f5-do-container:<tag name>. The <tag name> is optional and allows you to include a specific tag using :<tagname> after f5-Declarative Onboarding-container. If you do not include a tag, it downloads the latest version (:latest).
    Once the download is complete, you should see a status message stating the image was downloaded.
  2. Run Declarative Onboarding container using the command: docker run --name do_container --rm -d -p 8443:443 -p 8080:80 f5devcentral/f5-do-container:latest. –name do_container is optional and can be changed to any name you want, it’s just an easy way to identify this container.
  3. To test the Docker image is functional, you can use one of the following options (the following examples use localhost, you can use an IP address in place of localhost if your client and container are on different devices):
    • From your RESTful client, use GET to send https://localhost:8443/mgmt/shared/declarative-onboarding/example
    • Run the following cURL command: curl -k https://localhost:8443/mgmt/shared/declarative-onboarding/example

The system returns an example Declarative Onboarding declaration.


Sending a declaration to a BIG-IP using the Docker container

To send a declaration to a BIG-IP system you use the new target parameters in the Declarative Onboarding class (see the example below). These parameters specify the BIG-IP system where you want to send the configuration, and the user account with permission to access that BIG-IP system.

Again, the following examples use localhost, you can use an IP address in place of localhost if your client and container are on different devices.

To send a declaration with the container using a RESTful client, use https://localhost:8443/mgmt/shared/declarative-onboarding, and then POST a declaration.

To send a declaration with the container using cURL, use curl -sku admin:admin -H "Content-Type: application/json" -X POST https://localhost:8443/mgmt/shared/declarative-onboarding and then include the declaration.

Example declaration snippet using a RESTful client

To send a declaration from the container with a RESTful client like Postman, use the targetHost, targetUsername, and targetPassphrase parameters as shown in the following example (using values from your configuration). In this example, your declaration would continue after the last (schemaVersion) line.

Additionally, see JSON Pointers for information on using JSON/Declarative Onboarding pointers in your declaration.

{

     "class": "DO",
     "targetHost": "192.0.2.76",
     "targetPort": 8443,
     "targetUsername": "admin",
     "targetPassphrase": "myAdminPassword",
     "declaration": {
         "class": "Device",
         "schemaVersion": "1.0.0",
         ...
     }
}

Container-specific parameters

Parameter Options Required? Description/Notes
targetHost string YES IP address or host name of the target BIG-IP system to which you want to send the configuration.
targetPort integer NO TCP port number of management service on targetHost. If you do not specify a targetPort, Declarative Onboarding uses a default of 0, meaning it will auto-discover the target port.
targetTokens object NO One or more HTTP headers (each a property, like ‘X-F5-Auth-Token’: ‘MF6APSRUYKTMSDBEOOEWLCNSO2’) you want to send with queries to the targetHost management service as authentication/authorization tokens
targetUsername string YES Username of the principal authorized to modify configuration of targetHost (may not include the character ‘:’). NOTE: This is generally not required to configure ‘localhost’ because client authentication and authorization precede invocation of DO. It is also not required for any targetHost if you populate targetTokens.
targetPassphrase string YES Passphrase for targetUsername account. This is generally not required to configure ‘localhost’ and is not required when you populate targetTokens.

Example declaration snippet using cURL

To send a declaration from the container with cURL, use the same parameters as described in the preceding table. The rest of your declaration would continue after the last (schemaVersion) line.

curl -sku admin:admin -H "Content-Type: application/json" -X POST https://localhost:8443/mgmt/shared/declarative-onboarding -d ‘{
    "class": "DO",
    "targetHost": "192.0.2.76",
    "targetUsername": "admin",
    "targetPassphrase": "admin",
    "declaration": {
        "class": "Device",
        "schemaVersion": "1.0.0",
…}

Adding Basic Authentication

To enable Basic authentication, which allows you to protect your container running Declarative Onboarding, you can COPY or MOUNT the authentication configuration and user password files to your container using the following instructions.

Notes and requirements for adding Basic authentication

  • You should be at least somewhat familiar with the Docker command line.
  • You should have knowledge of Apache .htpasswd for adding Basic authentication. See the Apache documentation for details.
  • While we include commands for Microsoft Windows in this section, getting paths and directories set up in Windows can be tricky, so we recommend using a Linux-based system to add Basic authentication.
  • In our example, we are using a hashed value for the password admin. We strongly recommend you use a different password. Use an htpasswd generator to generate a value for a stronger password.

  1. Choose a local directory that will be mounted as a volume for the container to handle authentication. From that directory, pull the Declarative Onboarding image from Docker hub (see Downloading and starting the Declarative Onboarding Docker container)

  2. Inside that root directory, create a new directory named basic-auth. You will create two sub-directories in this directory. If you want to use different names for your directories, you must modify the command to use the appropriate directories when you run the container.

    1. Inside the basic-auth directory you created, create a directory named auth directory.

    2. In the auth directory, create a file named basic.conf with the following content:

      AuthType basic
      AuthName "private area"
      AuthUserFile /etc/www/pass/.htpasswd-users
      Require valid-user
      
    3. In the basic-auth directory, create another directory named pass.

    4. In the auth directory, create a file named .htpasswd-users your user name and a hashed password. Again, this example uses admin for the password, use http://www.htaccesstools.com/htpasswd-generator/ to generate a hash for a stronger password.:

      admin:$apr1$DTbcp1qi$vJ2AXcB.Ma8zznKJLEXKv.
      
  3. Run Declarative Onboarding container at the root directory. This maps the two directories you created to two directories inside the container for Apache.

    • If you are using a Linux-based system, use the following command: docker run -d -p 8443:443 -p 8080:80 -v `pwd`/basic-auth/auth/:/usr/local/apache2/conf/auth/ -v `pwd`/basic-auth/pass/:/etc/www/pass/ f5devcentral/f5-do-container
    • If you are using Windows, use the following command: docker run -d -p 8443:443 -p 8080:80 -v %cd%/basic-auth/auth/:/usr/local/apache2/conf/auth/ -v %cd%/basic-auth/pass/:/etc/www/pass/ f5devcentral/f5-do-container
  4. Open your RESTful API client such as Postman, and log with the basic Auth you just configured, in our example, using admin for the username and password.

  5. Test your docker container to get info from BIG-IP using step 3 of Downloading and starting the Declarative Onboarding Docker container.

Full declaration using the Declarative Onboarding container

This example uses a simple example declaration using the container.

{
    "class": "DO",
    "targetHost": "1.2.3.4",
    "targetUsername": "admin",
    "targetPassphrase": "myAdminPassword",
    "declaration": {
        "schemaVersion": "1.0.0",
        "class": "Device",
        "label": "Use App Services Gateway to onboard a BIG-IP",
        "Common": {
            "class": "Tenant",
            "hostname": "bigip.example.com",
            "dbvars": {
                "class": "DbVariables",
                "ui.advisory.enabled": true,
                "ui.advisory.color": "green",
                "ui.advisory.text": "/Common/hostname"
            },
            "myLicense": {
                "class": "License",
                "licenseType": "regKey",
                "regKey": "MMKGX-UPVPI-YIEMK-OAZIS-KQHSNAZ"
            },
            "myDns": {
                "class": "DNS",
                "nameServers": [
                    "8.8.8.8",
                    "2001:4860:4860::8844"
                ],
                "search": [
                    "f5.com"
                ]
            },
            "myNtp": {
                "class": "NTP",
                "servers": [
                    "0.pool.ntp.org",
                    "1.pool.ntp.org",
                    "2.pool.ntp.org"
                ],
                "timezone": "UTC"
            },
            "root": {
                "class": "User",
                "userType": "root",
                "oldPassword": "foo",
                "newPassword": "bar"
            },
            "admin": {
                "class": "User",
                "userType": "regular",
                "password": "asdfjkl",
                "shell": "bash"
            },
            "guestUser": {
                "class": "User",
                "userType": "regular",
                "password": "foobar",
                "partitionAccess": {
                    "Common": {
                        "role": "guest"
                    }
                }
            },
            "anotherUser": {
                "class": "User",
                "userType": "regular",
                "password": "foobar",
                "shell": "none",
                "partitionAccess": {
                    "all-partitions": {
                        "role": "guest"
                    }
                }
            },
            "myProvisioning": {
                "class": "Provision",
                "ltm": "nominal"
            },
            "internal": {
                "class": "VLAN",
                "tag": 4093,
                "mtu": 1500,
                "interfaces": [
                    {
                        "name": "1.2",
                        "tagged": true
                    }
                ]
            },
            "internal-self": {
                "class": "SelfIp",
                "address": "10.10.0.100/24",
                "vlan": "internal",
                "allowService": "default",
                "trafficGroup": "traffic-group-local-only"
            },
            "external": {
                "class": "VLAN",
                "tag": 4094,
                "mtu": 1500,
                "interfaces": [
                    {
                        "name": "1.1",
                        "tagged": true
                    }
                ]
            },
            "external-self": {
                "class": "SelfIp",
                "address": "10.20.0.100/24",
                "vlan": "external",
                "allowService": "none",
                "trafficGroup": "traffic-group-local-only"
            },
            "default": {
                "class": "Route",
                "gw": "10.10.0.1",
                "network": "default",
                "mtu": 1500
            }
        }
    }
}