Miscellaneous declarations

This section contains declarations that do not fit into one of the other categories.

Use the index on the right to locate specific examples.

1: Using PATCH to add a new Application to a Tenant

This example uses the same declaration as in the UDP Example, but we use the PATCH method to add an new Application to the Sample_non_http_01 tenant.

This PATCH creates the following objects on the BIG-IP:

  • A new Application named NewApp.
  • An HTTP service (virtual server) named serviceMain.
  • A pool named web_poolnew with two servers monitored by the default http health monitor.

If necessary, review the declaration in Example 11 (or first use GET https://<BIG-IP>/mgmt/shared/appsvcs/declare/Sample_misc_11).

Then use PATCH https://<BIG-IP>/mgmt/shared/appsvcs/declare with the following body (because this is a new object, we include the new name in the path):

[
  {
    "op": "add",
    "path": "/Sample_non_http_01/NewAPP",
    "value": {
      "class": "Application",
      "template": "http",
      "serviceMain": {
        "class": "Service_HTTP",
        "virtualAddresses": [
          "10.0.1.10"
        ],
        "pool": "web_poolnew"
      },
      "web_poolnew": {
        "class": "Pool",
        "monitors": [
          "http"
        ],
        "members": [{
          "servicePort": 80,
          "serverAddresses": [
            "192.0.1.10",
            "192.0.1.11"
          ]
        }]
      }
    }
  }
]

After submitting this PATCH, the system returns the following (new application highlighted in yellow):

{
  "results": [
    {
      "message": "success",
      "lineCount": 20,
      "code": 200,
      "host": "localhost",
      "tenant": "Sample_non_http_01",
      "runTime": 1330
    }
  ],
  "declaration": {
    "Sample_non_http_01": {
      "class": "Tenant",
      "DNS_Service": {
        "class": "Application",
        "template": "udp",
        "serviceMain": {
          "class": "Service_UDP",
          "virtualPort": 53,
          "virtualAddresses": [
            "10.1.20.121"
          ],
          "pool": "Pool1"
        },
        "Pool1": {
          "class": "Pool",
          "monitors": [
            "icmp"
          ],
          "members": [
            {
              "servicePort": 53,
              "serverAddresses": [
                "10.1.10.100"
              ]
            },
            {
              "servicePort": 53,
              "serverAddresses": [
                "10.1.10.101"
              ]
            }
          ]
        }
      },
      "NewAPP": {
        "class": "Application",
        "template": "http",
        "serviceMain": {
          "class": "Service_HTTP",
          "virtualAddresses": [
            "10.0.1.10"
          ],
          "pool": "web_poolnew"
        },
        "web_poolnew": {
          "class": "Pool",
          "monitors": [
            "http"
          ],
          "members": [
            {
              "servicePort": 80,
              "serverAddresses": [
                "192.0.1.10",
                "192.0.1.11"
              ]
            }
          ]
        }
      }
    }
  },
  "class": "ADC",
  "schemaVersion": "3.0.0",
  "id": "UDP_DNS_Sample",
  "label": "UDP_DNS_Sample",
  "remark": "Sample of a UDP DNS Load Balancer Service",
  "controls": {
    "archiveTimestamp": "2018-06-04T21:54:18.255Z"
  }
}

Back to top

2: Using the Service_Generic class

This simple example shows how you can use the new Service_Generic class. This class allows the BIG-IP to accept any L4 protocols without requiring a fastl4 profile. For usage options, see https://clouddocs.f5.com/products/extensions/f5-appsvcs-extension/latest/refguide/schema-reference.html#service-generic

This declaration creates the following objects on the BIG-IP:

  • Partition (tenant) named Sample_misc_02.
  • A Generic service named generic_virtual on port 8080 (note that because this declaration uses the generic template, the service does not have to be named serviceMain).
{
    "class": "ADC",
    "schemaVersion": "3.5.0",
    "id": "Service_Generic",
    "Sample_misc_02": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "template": "generic",
            "generic_virtual": {
                "class":"Service_Generic",
                "virtualAddresses": [
                    "192.0.2.140"
                ],
                "virtualPort": 8080
            }
        }
    }
}

Back to top

3: Using Metadata in a declaration

This example shows how you can add metadata to a service (virtual server) in a declaration. This can be useful for storing information about the application which could be leveraged by other tools for tasks such as validation or auditing.

This declaration creates the following objects on the BIG-IP:

  • Partition (tenant) named Sample_misc_03.
  • A generic virtual service named testItem with a metadata entry of example.
{
    "class": "ADC",
    "schemaVersion": "3.7.0",
    "id": "Service_Generic",
    "Sample_misc_03": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "template": "generic",
            "testItem": {
                "class": "Service_Generic",
                "virtualPort": 200,
                "virtualAddresses": [
                    "192.0.2.21"
                ],
                "metadata": {
                    "example": {
                        "value": "example",
                        "persist": true
                    }
                }
            }
        }
    }
}

Back to top

4: Virtual service allowing only specific VLANs

This example uses our simple HTTP service in Example 1, but uses a feature introduced in AS3 version 3.2.0, which enables the ability to allow or deny client traffic from specific VLANs (IMPORTANT: The VLAN objects must already exist on the BIG-IP system).

In this case, we are using allowVlans to allow traffic from specific VLANs on our BIG-IP system to access our HTTP service, and denying all other traffic to that service. If we wanted to deny traffic from specific VLANs, we would use rejectVlans instead. In the rejectVlans case, the system would deny traffic from the specified VLANs, and would allow traffic from any other VLAN on the system. If you do not use this property, the system allows all VLANs by default.

This declaration creates the following objects on the BIG-IP:

  • Partition (tenant) named Sample_misc_04.
  • A virtual server named serviceMain which is only accessible from the internal-sales and internal-marketing VLANs (which already exist on the BIG-IP system).
  • A pool named web_pool monitored by the default http health monitor.
{
  "class": "AS3",
  "action": "deploy",
  "persist": true,
  "declaration": {
    "class": "ADC",
    "schemaVersion": "3.2.0",
    "id": "vlan-allow",
    "label": "Sample Security 3",
    "remark": "Simple HTTP application VLAN restriction",
    "Sample_misc_04": {
      "class": "Tenant",
      "A1": {
        "class": "Application",
        "template": "http",
        "serviceMain": {
          "class": "Service_HTTP",
          "virtualAddresses": [
            "10.0.1.10"
          ],
          "pool": "web_pool",
          "allowVlans": [
            { "bigip":"/Common/internal-sales" },
            { "bigip":"/Common/internal-marketing" }
          ]
        },
        "web_pool": {
          "class": "Pool",
          "monitors": [
            "http"
          ],
          "members": [{
            "servicePort": 80,
            "serverAddresses": [
              "192.0.1.10",
              "192.0.1.11"
            ]
          }]
        }
      }
    }
  }
}

Back to top

5: Advertising a route for a Service Address

In this example, we show you how to use the Service Address class to advertise a route in your declaration. The Service_Address class allows you to add a number of properties to your (virtual) server address. This declaration shows how you can use the new routeAdvertisement property to advertise routes. For options and usage, see Schema Reference: Service_Address. This example uses the Service_Generic template.

This declaration creates the following objects on the BIG-IP:

  • Partition (tenant) named Sample_misc_05.
  • A virtual server named theService which includes a pointer to the Service_Address class.
  • A Service_Address class named serviceAddress which includes a number of properties, including routeAdvertisement.
{
    "class":"ADC",
    "schemaVersion":"3.7.0",
    "id":"Service_Address",
    "Sample_misc_05":{
        "class":"Tenant",
        "Application":{
            "class":"Application",
            "template":"generic",
            "theService": {
                "class": "Service_HTTP",
                "virtualPort": 123,
                "virtualAddresses": [
                    {
                        "use": "serviceAddress"
                    }
                ]
            },
            "serviceAddress":{
                "class":"Service_Address",
                "virtualAddress":"123.123.123.123",
                "arpEnabled":false,
                "icmpEcho":"disable",
                "routeAdvertisement":"any",
                "spanningEnabled":true,
                "trafficGroup":"/Common/traffic-group-local-only"
            }
        }
    }
}

Back to top

6: Using Clone Pools in a declaration

AS3 version 3.9.0 adds support for using Clone Pools in a declaration. You can use a clone pool when you want the BIG-IP system to send traffic to a pool of intrusion detection systems (IDSs) or a sniffer device. You can specify ingress, where the system replicates client-side traffic (prior to address translation) to the specified clone pool, or egress, where the system replicates server-side traffic (after address translation) to the specified clone pool, or both (as shown in this example).

This declaration creates the following objects on the BIG-IP:

  • Partition (tenant) named Sample_clone_pool.
  • Two virtual servers named testService and testService-1. The latter is automatically created because we specify two virtual addresses.
  • A standard pool named web_pool monitored by the default HTTP health monitor.
  • Two clone pools named testPoolIngress and testPoolEgress, which replicates ingress and egress traffic respectively.
{
    "class": "ADC",
    "schemaVersion": "3.9.0",
    "id": "TEST_Clone_Pools",
    "remark": "Clone Pools Support",
    "Sample_clone_pool": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "template": "generic",
            "testService": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                    "192.0.2.34",
                    "192.0.2.35"
                ],
                "virtualPort": 80,
                "pool": "web_pool",
                "clonePools": {
                    "ingress": {
                        "use": "testPoolIngress"
                    },
                    "egress": {
                        "use": "testPoolEgress"
                    }
                }
            },
            "testPoolIngress": {
                "class": "Pool",
                "members": [
                    {
                        "servicePort": 443,
                        "serverAddresses": [
                            "192.0.2.51",
                            "192.0.2.52"
                        ]
                    }
                ]
            },
            "testPoolEgress": {
                "class": "Pool",
                "members": [
                    {
                        "servicePort": 443,
                        "serverAddresses": [
                            "192.0.2.54",
                            "192.0.2.55"
                        ]
                    }
                ]
            },
            "web_pool": {
                "class": "Pool",
                "monitors": [
                    "http"
                ],
                "members": [
                    {
                        "servicePort": 80,
                        "serverAddresses": [
                            "192.0.2.72",
                            "192.0.2.73"
                        ]
                    }
                ]
            }
        }
    }
}

Back to top

7: Sending multiple declarations in a single request (container)

AS3 version 3.10.0 adds support for sending multiple declarations to different target BIG-IP devices in a single request. In this example, we are using AS3 in a Docker Container (see AS3 in a Container). This feature allows you configure multiple target BIG-IP devices from the container. This can be useful for orchestration and automation solutions.

This declaration does the following:

  • On the BIG-IP device with IP address 10.10.10.11:
    • AS3 redeploys the 3rd declaration saved in the target device’s declaration history (revisit POST Action: redeploy for more information).
  • On the BIG-IP device with IP address 10.10.10.12:
    • Partition (tenant) named AS3Request_Tenant1.
    • A virtual server named serviceMain.
    • A pool named web_pool1 monitored by the default HTTP health monitor.
[
    {
        "class": "AS3",
        "action": "redeploy",
        "redeployAge": 2,
        "targetHost": "10.10.10.11",
        "targetUsername": "admin",
        "targetPassphrase": "admin"
    },
    {
        "class": "AS3",
        "action": "deploy",
        "targetHost": "10.10.10.12",
        "targetUsername": "admin",
        "targetPassphrase": "admin",
        "declaration": {
            "class": "ADC",
            "schemaVersion": "3.7.0",
            "id": "AS3Request_Tenant1",
            "updateMode": "selective",
            "AS3Request_Tenant1": {
                "class": "Tenant",
                "App1": {
                    "class": "Application",
                    "template": "http",
                    "serviceMain": {
                        "class": "Service_HTTP",
                        "virtualAddresses": [
                            "198.19.192.14"
                        ],
                        "pool": "web_pool1"
                    },
                    "web_pool1": {
                        "class": "Pool",
                        "monitors": [
                            "http"
                        ],
                        "members": [
                            {
                                "servicePort": 80,
                                "serverAddresses": [
                                    "198.19.192.72",
                                    "198.19.192.73"
                                ]
                            }
                        ]
                    }
                }
            }
        }
    }
]

Back to top

8: Sending multiple declarations in a single request (BIG-IQ)

AS3 version 3.10.0 adds support for sending multiple declarations to different target BIG-IP devices in a single request. In this example, we are using AS3 on BIG-IQ (see Using AS3 with BIG-IQ . This allows you to configure more than one BIG-IP device using BIG-IQ.

This declaration does the following:

  • On the BIG-IP device with IP address 10.10.10.13:
    • Partition (tenant) named bigiqTenant1.
    • A virtual server named serviceMain, using the Fast L4 template/class.
    • A pool named pool with a single member on port 8080 monitored by the TCP health monitor on the BIG-IP system.
  • On the BIG-IP device with IP address 10.10.10.14:
    • Partition (tenant) named bigiqTenant2.
    • A virtual server named serviceMain, using the Fast L4 template/class.
    • A pool named pool with a single member on port 8080 monitored by the TCP health monitor on the BIG-IP system.
[
    {
        "class": "ADC",
        "id": "myid1",
        "schemaVersion": "3.7.0",
        "target": {
            "address": "10.10.10.13"
        },
        "bigiqTenant1": {
            "class": "Tenant",
            "fastl4": {
                "class": "Application",
                "template": "l4",
                "label": "simple tcp app VS_TCP",
                "serviceMain": {
                    "class": "Service_L4",
                    "persistenceMethods": [],
                    "pool": "pool",
                    "profileL4": {
                        "bigip": "/Common/fastL4"
                    },
                    "snat": "auto",
                    "virtualAddresses": [
                        "10.11.11.121"
                    ],
                    "virtualPort": 80
                },
                "pool": {
                    "class": "Pool",
                    "members": [
                        {
                            "serverAddresses": [
                                "192.168.128.112"
                            ],
                            "servicePort": 8080
                        }
                    ],
                    "monitors": [
                        {
                            "bigip": "/Common/tcp"
                        }
                    ],
                    "remark": "fastl4"
                }
            }
        }
    },
    {
        "class": "ADC",
        "id": "myid2",
        "schemaVersion": "3.7.0",
        "target": {
            "address": "10.10.10.14"
        },
        "bigiqTenant2": {
            "class": "Tenant",
            "fastl4": {
                "class": "Application",
                "template": "l4",
                "label": "simple tcp app VS_TCP",
                "serviceMain": {
                    "class": "Service_L4",
                    "pool": "pool",
                    "profileL4": {
                        "bigip": "/Common/fastL4"
                    },
                    "snat": "auto",
                    "virtualAddresses": [
                        "10.11.11.131"
                    ],
                    "virtualPort": 80
                },
                "pool": {
                    "class": "Pool",
                    "members": [
                        {
                            "serverAddresses": [
                                "192.168.128.113"
                            ],
                            "servicePort": 8080
                        }
                    ],
                    "monitors": [
                        {
                            "bigip": "/Common/tcp"
                        }
                    ],
                    "remark": "fastl4"
                }
            }
        }
    }
]

Back to top

9: Using Splunk as a log destination

With AS3 version 3.10.0 and later, you can use Splunk as a log destination. This enables the BIG-IP to format the logs in a way that can be used by Splunk. For more information, see the Configuring High Speed Remote Logging chapter of External Monitoring guide.

This declaration creates the following objects on the BIG-IP (note it does not include a virtual server, just a pool and the logging objects):

  • Partition (tenant) named Splunk_Log_Destination.
  • A pool named logPool with one member on port 443.
  • A log destination of type remote high speed log. This is a BIG-IP requirement for logging servers that require data in a specific format.
  • A log destination of type splunk that forwards to the remote high speed log destination.
  • An additional Splunk log destination that forwards to syslog on the BIG-IP device.
{
    "class": "ADC",
    "schemaVersion": "3.10.0",
    "id": "Splunk_Log_Destination",
    "controls": {
        "class": "Controls",
        "trace": true,
        "logLevel": "debug"
    },
    "Splunk_Log_Destination": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "template": "generic",
            "logPool": {
                "class": "Pool",
                "members": [
                    {
                        "servicePort": 443,
                        "serverAddresses": [
                            "192.0.2.53"
                        ]
                    }
                ]
            },
            "remoteHSLog": {
                "class": "Log_Destination",
                "type": "remote-high-speed-log",
                "pool": {
                    "use": "logPool"
                }
            },
            "splunkLog1": {
                "class": "Log_Destination",
                "type": "splunk",
                "forwardTo": {
                    "use": "remoteHSLog"
                }
            },
            "splunkLog2": {
                "class": "Log_Destination",
                "type": "splunk",
                "forwardTo": {
                    "bigip": "/Common/local-syslog"
                }
            }
        }
    }
}

Back to top

10: Using shareNodes to reuse nodes across tenants

The examples in the section show how to use the pool member property shareNodes. This property enables you to take an existing node from a previous declaration and use it in a new declaration without getting a conflict. Without using shareNodes, if you attempt to use a node you used in a previous declaration, you receive an error similar to the following:

{"code":422,"errors":["/new_partition/example_app/web_pool/members: pool member /new_partition/example_app/web_pool/members/0 static address 10.244.1.58 conflicts with bigip node /original_partition/10.244.1.58"],"declarationFullId":"","message":"declaration is invalid"}

Note

You must have the shareNodes property set to true in your original declaration. If you did not, add it to the original declaration and re-POST before attempting to post a new declaration with the node.

There are two declarations in this example, the original declaration and a new declaration.

Original Declaration

The original declaration is a simple declaration that includes a virtual server, a pool, and a pool member with the IP address of 10.244.1.58 with shareNodes set to true.

  • Partition (tenant) named original_partition.
  • A virtual server named serviceMain.
  • A pool named web_pool1 with one member (10.244.1.58) with shareNodes set to true.
{
    "class": "ADC",
    "schemaVersion": "3.0.0",
    "original_partition": {
        "class": "Tenant",
        "example_app": {
            "class": "Application",
            "template": "http",
            "serviceMain": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                  "10.0.7.10"
                ],
                "pool": "web_pool1"
                
            },
            "web_pool1": {
                "class": "Pool",
                "members": [
                    {
                        "serverAddresses": [
                            "10.244.1.58"
                        ],
                        "servicePort": 80,
                        "shareNodes": true
                    }
                ],
                "monitors": [
                    "http"
                ]   
            }
        }
    }
}

New Declaration

This declaration contains two tenants, a new tenant named new_partition that uses the IP address of the node in the original declaration. It also includes the original_partition tenant, with a new node IP address. This example shows how you can essentially move a node between partitions using shareNodes.

You do not need to include the original declaration unless you want to change the original node value. As long as shareNodes was set to true in your original declaration, you can post a new declaration using the node IP address from the original declaration.

  • Partition (tenant) named new_partition
  • A pool named web_pool2 with one member (10.244.1.58, the node IP from the original declaration) with shareNodes set to true (note this example does not contain a virtual service/server).
  • A second partition (tenant) named original_partition.
  • A virtual server named serviceMain.
  • A pool named web_pool1 with one member (10.244.1.28) with shareNodes set to true. Note this changes the node IP address from what was included in the original declaration (this is not required as mentioned in the description of this example).
{
    "class": "ADC",
    "schemaVersion": "3.0.0",
    "new_partition": {
        "class": "Tenant",
        "example_app": {
            "class": "Application",
            "template": "generic",
            "web_pool2": {
                "class": "Pool",
                "members": [
                    {
                        "serverAddresses": [
                            "10.244.1.58"
                        ],
                        "servicePort": 80,
                        "shareNodes": true
                    }
                ],
                "monitors": [
                    "http"
                ]
            }
        }
    },
    "original_partition": {
        "class": "Tenant",
        "example_app": {
            "class": "Application",
            "template": "http",
            "serviceMain": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                  "10.0.7.10"
                ],
                "pool": "web_pool1"
                
            },
            "web_pool1": {
                "class": "Pool",
                "members": [
                    {
                        "serverAddresses": [
                            "10.244.1.28"
                        ],
                        "servicePort": 80,
                        "shareNodes": true
                    }
                ],
                "monitors": [
                    "http"
                ]     
            }
        }
    }
}

Back to top

11: Using the include property to reference one section of a declaration in another section

This example shows how you can use the include property to call a section of a declaration from another part of the same declaration. In the following example, we are showing a WAF policy declaration which uses this feature, although you can use include with any property. See Include in the schema reference for more information and usage.

This declaration creates a WAF policy in /Common using the shared template, and then references

{
    "class": "ADC",
    "schemaVersion": "3.13.0",
    "Common": {
        "class": "Tenant",
        "Shared": {
            "class": "Application",
            "template": "shared",
            "wordpressWafPolicy": {
                "class": "WAF_Policy",
                "url": "https://example.com/wordpress_template_12.0.xml",
                "ignoreChanges": true
            },
            "mobileDefenseProfile": {
                "class": "DOS_Profile",
                "application": {
                    "scrubbingDuration": 42,
                    "remoteTriggeredBlackHoleDuration": 10,
                    "mobileDefense": {
                        "enabled": true,
                        "allowAndroidPublishers": [{
                            "bigip": "/Common/default.crt"
                        }],
                        "allowAndroidRootedDevice": true,
                        "allowIosPackageNames": [
                            "theName"
                        ],
                        "allowJailbrokenDevices": true,
                        "allowEmulators": true,
                        "clientSideChallengeMode": "challenge"
                    }
                }
            },
            "constants": {
                "class": "Constants",
                "securityCollection": {
                    "policyWAF": {
                        "use": "/Common/Shared/wordpressWafPolicy"
                    },
                    "profileDOS": {
                        "use": "/Common/Shared/mobileDefenseProfile"
                    }
                }
            }
        }
    },
    "Tenant1": {
        "class": "Tenant",
        "Application1": {
            "class": "Application",
            "template": "generic",
            "vipOne": {
                "class": "Service_HTTP",
                "virtualPort": 8080,
                "virtualAddresses": [
                    "192.0.2.1"
                ],
                "include": [
                    "/Common/Shared/constants/securityCollection"
                ]
            },
            "vipTwo": {
                "class": "Service_HTTP",
                "virtualPort": 8080,
                "virtualAddresses": [
                    "192.0.2.2"
                ],
                "include": [
                    "/Common/Shared/constants/securityCollection"
                ]
            }
        }
    }
}

Back to top