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.

Important

Most of the example declarations have been updated in the documentation for AS3 3.20 to remove any template that was specified, and rename any virtual services that used the name serviceMain to service. In AS3 3.20, the generic template is the default, which allows services to use any name.

This also means that many of these declarations on a version prior to 3.20 they will fail unless you add a template. See this FAQ entry and this Troubleshooting entry for more information.

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 service.
  • 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",
      "service": {
        "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",
        "service": {
          "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",
        "service": {
          "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


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.
{
    "class": "ADC",
    "schemaVersion": "3.5.0",
    "id": "Service_Generic",
    "Sample_misc_02": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "generic_virtual": {
                "class":"Service_Generic",
                "virtualAddresses": [
                    "192.0.2.140"
                ],
                "virtualPort": 8080
            }
        }
    }
}

Back to top


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",
            "testItem": {
                "class": "Service_Generic",
                "virtualPort": 200,
                "virtualAddresses": [
                    "192.0.2.21"
                ],
                "metadata": {
                    "example": {
                        "value": "example",
                        "persist": true
                    }
                }
            }
        }
    }
}

Back to top


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 service 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",
        "service": {
          "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


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 class.

..IMPORTANT:: When AS3 creates a Service_Address, it is placed in /tenant/serviceAddress (and not /tenant/app/serviceAddress) on the BIG-IP system.

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",
            "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


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",
            "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


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 service.
    • 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",
                    "service": {
                        "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


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 service, using the Service_L4 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 service, using the Service_L4 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",
                "label": "simple tcp app VS_TCP",
                "service": {
                    "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",
                "label": "simple tcp app VS_TCP",
                "service": {
                    "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


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",
            "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


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"}

If you do not use shareNodes or have shareNodes set to false (the default), the nodes are created in the tenant specified in the declaration (however, see the following Warning note about updating this property)

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.

Warning

If you POST a declaration with shareNodes set to true, and then later update the same declaration with shareNodes set to false, the declaration returns Success, however AS3 does not move the nodes, and they remain in /Common. To change this behavior, first DELETE the original declaration, and then re-POST the declaration with shareNodes set to false.

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 service.
  • 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",
            "service": {
                "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 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 service.
  • 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",
            "web_pool2": {
                "class": "Pool",
                "members": [
                    {
                        "serverAddresses": [
                            "10.244.1.58"
                        ],
                        "servicePort": 80,
                        "shareNodes": true
                    }
                ],
                "monitors": [
                    "http"
                ]
            }
        }
    },
    "original_partition": {
        "class": "Tenant",
        "example_app": {
            "class": "Application",
            "service": {
                "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


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",
            "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


Using both a source and destination address for a virtual service

In this example, we show how you can use both a source and destination address for your virtual service (BIG-IP virtual server). For specific information, see the Virtual Server documentation.

The Destination Address is the destination IP address to which the virtual service sends traffic and is required.

The Source Address property is optional, but allows you to specify an IP address or network from which the virtual server accepts traffic. If you include Source Address(es), the virtual server accepts clients only from one of these IP addresses.

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

  • Partition (tenant) named source_example.
  • Two virtual servers named service (the BIG-IP names the second service-1) using the Service_Generic class. Each virtual has a Destination address (the first IP address in the array) and a Source Address (the second IP address in the array).
{
    "class": "ADC",
    "schemaVersion": "3.0.0",
    "id": "declarationId",
    "source_example": {
        "class": "Tenant",
        "app": {
            "class": "Application",
            "service": {
                "class": "Service_Generic",
                "virtualAddresses": [
                    [
                        "192.0.2.11",
                        "1.2.3.4/32"
                    ],
                    [
                        "192.0.2.12",
                        "1.2.3.5/32"
                    ]
                ],
                "virtualPort": 1000
            }
        }
    }
}

Back to top


Creating an internal virtual service

In this example, we show how you can create a virtual service (virtual server with a Type of Internal). This type of virtual service is useful for conditionally forwarding HTTP requests and HTTP responses to a pool of ICAP servers for modification, before sending a request to a web server or returning a response to the client system. For details on this implementation, see the Configuring Content Adaptation for HTTP Requests and Response. For information on BIG-IP virtual servers in general, see K15819.

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

  • Partition (tenant) named Sample_Internal_Virtual.
  • An Application named Internal_Service.
  • A TCP virtual server named service with Type of Internal that references an existing ICAP profile on the BIG-IP.
{
    "class": "ADC",
    "schemaVersion": "3.16.0",
    "label": "Internal_Virtual",
    "remark": "Internal_Virtual",
    "Sample_Internal_Virtual": {
        "class": "Tenant",
        "Internal_Service": {
            "class": "Application",
            "service": {
                "class": "Service_TCP",
                "virtualType": "internal",
                "sourceAddress": "192.0.2.0/24",
                "profileICAP": {
                    "bigip": "/Common/icap"
                }
            }
        }
    }
}

Back to top


Configuring virtual address settings while using Source address filtering

In this example, we show how you can configure virtual service settings on the destination address (such as disabling ARP and ICMP echo) while still specifying a source IP address to enable source address filtering. This is similar to Example 12, but in this case, we are configuring specific settings for the destination address and then including it in the array.

For specific information, see the Virtual Server documentation.

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

  • Partition (tenant) named Sample_src_service_address.
  • An Application named app.
  • A virtual service address with ARP and ICMP echo disabled.
  • A generic virtual server named service with a destination address that uses the virtual address above, and a source address of 1.2.3.4/32.
{
    "class": "ADC",
    "schemaVersion": "3.15.0",
    "id": "declarationId",
    "source_service_address_example": {
        "class": "Tenant",
        "app": {
            "class": "Application",
            "my_service_address": {
                "class": "Service_Address",
                "virtualAddress": "1.1.1.1",
                "arpEnabled": false,
                "icmpEcho": "disable"
            },
            "service": {
                "class": "Service_Generic",
                "virtualAddresses": [
                    [
                        {
                            "use": "my_service_address"
                        },
                        "1.2.3.4/32"
                    ]
                ],
                "virtualPort": 1000
            }
        }
    }
}

Back to top


Referencing pools and iRules in a declaration

In this example, we show how you can reference pools and iRules (including a persistence iRule) with the use pointer in AS3 3.17 and later. The use pointer has been available for other properties in AS3, but this version adds pools, iRules, and persistence Hash iRules.

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

  • Partition (tenant) named Sample_pool_irule.
  • An Application named SampleApp.
  • A virtual server named service with a pool, iRules, and persistence method (which also includes an iRule) referenced later in the declaration.
  • A pool named web_pool.
  • Two iRules (non-functional in this example), named theRule1 and theRule2.
  • A Hash persistence profile (persistRuleEx) that references an iRule (also non-functional) named ruleForPersis.
{
    "class": "ADC",
    "schemaVersion": "3.16.0",
    "id": "8675309",
    "Sample_pool_irule": {
        "class": "Tenant",
        "SampleApp": {
            "class": "Application",
            "service": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                    "10.1.10.10"
                ],
                "pool": {
                    "use": "web_pool"
                },
                "persistenceMethods": [
                    { "use": "persistRuleEx" }
                ],
                "iRules": [
                    "theRule1",
                    { "use": "theRule2" }
                ]
            },
            "web_pool": {
                "class": "Pool",
                "members": [
                    {
                        "servicePort": 80,
                        "serverAddresses": [
                            "10.128.0.209"
                        ]
                    }
                ]
            },
            "theRule1": {
                "class": "iRule",
                "iRule": "when CLIENT_ACCEPTED { }"
            },
            "theRule2": {
                "class": "iRule",
                "iRule": "when HTTP_REQUEST { }"
            },
            "persistRuleEx": {
                "class": "Persist",
                "persistenceMethod": "hash",
                "iRule": { "use": "ruleForPersist" }
            },
            "ruleForPersist": {
                "class": "iRule",
                "iRule": "when CLIENT_ACCEPTED { }"
            }
        }
    }
}

Back to top


Using the userAgent Controls property

In this example, we show how you can use the userAgent property in the Controls class. The userAgent property allows you to set a unique identifier in usage data.

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

  • A Controls class with userAgent set to BIG-IQ/7.1 Configured by API.
  • Partition (tenant) named useragentTenant.
  • An Application named SampleApp.
  • A virtual server named Stream_service.
{
    "class": "ADC",
    "schemaVersion": "3.18.0",
    "id": "userAgent",
    "controls": {
        "class": "Controls",
        "userAgent": "BIG-IQ/7.1 Configured by API"
    },
    "useragentTenant": {
        "class": "Tenant",
        "sampleApp": {
            "class": "Application",
            "Stream_service": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                    "1.2.3.4"
                ],
                "virtualPort": 100
            }
        }
    }
}

Back to top


Using traceResponse to enable traces in AS3 responses

In this example, we show how you can use the traceResponse property to enable more visibility into what AS3 is configuring. This property can be used in the Controls or ADC_Controls classes (links go to the Schema Reference).

AS3 3.20 adds support for using traceResponse in async mode.

This example shows both the declaration and the response from AS3. In the ADC class, we set traceResponse to false, and only set it to true on the tenant. This limits the trace to the tenant only; if you set traceResponse to true at the ADC class level, you would get traces for all tenants in the declaration. You could also get it to true at the ADC level, and then to false for each tenant you do not want to trace.

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

  • Partition (tenant) named trace_tenant.
  • An Application named SampleApp.
  • A virtual server named Sample_service.
{
    "class": "ADC",
    "schemaVersion": "3.18.0",
    "id": "traceResponse",
    "controls": {
        "class": "Controls",
        "traceResponse": false
    },
    "trace_tenant": {
        "class": "Tenant",
        "controls": {
            "class": "Controls",
            "traceResponse": true
        },
        "SampleApp": {
            "class": "Application",
            "Sample_service": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                    "1.2.3.4"
                ],
                "virtualPort": 100
            }
        }
    }
}

Example Response Here is the response returned by AS3 from the declaration, showing the trace for the tenant.

{
    "results": [
        {
            "code": 200,
            "message": "success",
            "lineCount": 22,
            "host": "localhost",
            "tenant": "trace_tenant",
            "runTime": 6304
        }
    ],
    "declaration": {
        "class": "ADC",
        "schemaVersion": "3.18.0",
        "id": "traceResponse",
        "controls": {
            "class": "Controls",
            "traceResponse": false,
            "archiveTimestamp": "2020-02-18T23:02:51.807Z"
        },
        "trace_tenant": {
            "class": "Tenant",
            "controls": {
                "class": "Controls",
                "traceResponse": true
            },
            "SampleApp": {
                "class": "Application",
                "Sample_service": {
                    "class": "Service_HTTP",
                    "virtualAddresses": [
                        "1.2.3.4"
                    ],
                    "virtualPort": 100
                }
            }
        },
        "updateMode": "selective"
    },
    "traces": {
        "trace_tenantDesired": {
            "/trace_tenant/SampleApp/": {
                "command": "sys folder",
                "properties": {},
                "ignore": []
            },
            "/trace_tenant/Service_Address-1.2.3.4": {
                "command": "ltm virtual-address",
                "properties": {
                    "address": "1.2.3.4",
                    "arp": "enabled",
                    "icmp-echo": "enabled",
                    "mask": "255.255.255.255",
                    "route-advertisement": "disabled",
                    "spanning": "disabled",
                    "traffic-group": "default"
                },
                "ignore": []
            },
            "/trace_tenant/SampleApp/Sample_service": {
                "command": "ltm virtual",
                "properties": {
                    "address-status": "yes",
                    "auto-lasthop": "default",
                    "connection-limit": 0,
                    "description": "\"SampleApp\"",
                    "destination": "/trace_tenant/1.2.3.4:100",
                    "ip-protocol": "tcp",
                    "last-hop-pool": "none",
                    "mask": "255.255.255.255",
                    "mirror": "disabled",
                    "persist": {
                        "/Common/cookie": {
                            "default": "yes"
                        }
                    },
                    "policies": {},
                    "profiles": {
                        "/Common/http": {
                            "context": "all"
                        },
                        "/Common/f5-tcp-progressive": {
                            "context": "all"
                        }
                    },
                    "source": "0.0.0.0/0",
                    "source-address-translation": {
                        "type": "automap"
                    },
                    "rules": {},
                    "security-log-profiles": {},
                    "source-port": "preserve",
                    "translate-address": "enabled",
                    "translate-port": "enabled",
                    "nat64": "disabled",
                    "vlans": {},
                    "vlans-disabled": " ",
                    "metadata": {},
                    "clone-pools": {}
                },
                "ignore": []
            },
            "/trace_tenant/": {
                "command": "auth partition",
                "properties": {
                    "default-route-domain": 0
                },
                "ignore": []
            }
        },
        "trace_tenantCurrent": {},
        "trace_tenantDiff": [
            {
                "kind": "N",
                "path": [
                    "/trace_tenant/SampleApp/"
                ],
                "rhs": {
                    "command": "sys folder",
                    "properties": {},
                    "ignore": []
                },
                "tags": [
                    "tmsh"
                ],
                "command": "sys folder",
                "lhsCommand": "",
                "rhsCommand": "sys folder"
            },
            {
                "kind": "N",
                "path": [
                    "/trace_tenant/1.2.3.4"
                ],
                "rhs": {
                    "command": "ltm virtual-address",
                    "properties": {
                        "address": "1.2.3.4",
                        "arp": "enabled",
                        "icmp-echo": "enabled",
                        "mask": "255.255.255.255",
                        "route-advertisement": "disabled",
                        "spanning": "disabled",
                        "traffic-group": "default"
                    },
                    "ignore": []
                },
                "tags": [
                    "tmsh"
                ],
                "command": "ltm virtual-address",
                "lhsCommand": "",
                "rhsCommand": "ltm virtual-address"
            },
            {
                "kind": "N",
                "path": [
                    "/trace_tenant/SampleApp/Sample_service"
                ],
                "rhs": {
                    "command": "ltm virtual",
                    "properties": {
                        "address-status": "yes",
                        "auto-lasthop": "default",
                        "connection-limit": 0,
                        "description": "\"SampleApp\"",
                        "destination": "/trace_tenant/1.2.3.4:100",
                        "ip-protocol": "tcp",
                        "last-hop-pool": "none",
                        "mask": "255.255.255.255",
                        "mirror": "disabled",
                        "persist": {
                            "/Common/cookie": {
                                "default": "yes"
                            }
                        },
                        "policies": {},
                        "profiles": {
                            "/Common/http": {
                                "context": "all"
                            },
                            "/Common/f5-tcp-progressive": {
                                "context": "all"
                            }
                        },
                        "source": "0.0.0.0/0",
                        "source-address-translation": {
                            "type": "automap"
                        },
                        "rules": {},
                        "security-log-profiles": {},
                        "source-port": "preserve",
                        "translate-address": "enabled",
                        "translate-port": "enabled",
                        "nat64": "disabled",
                        "vlans": {},
                        "vlans-disabled": " ",
                        "metadata": {},
                        "clone-pools": {}
                    },
                    "ignore": []
                },
                "tags": [
                    "tmsh"
                ],
                "command": "ltm virtual",
                "lhsCommand": "",
                "rhsCommand": "ltm virtual"
            },
            {
                "kind": "N",
                "path": [
                    "trace_tenant"
                ],
                "rhs": {
                    "command": "auth partition",
                    "properties": {
                        "default-route-domain": 0
                    },
                    "ignore": []
                },
                "tags": [
                    "tmsh"
                ],
                "command": "auth partition",
                "lhsCommand": "",
                "rhsCommand": "auth partition"
            }
        ],
        "trace_tenantScript": "cli script __appsvcs_update {\nproc script::run {} {\nif {[catch {\ntmsh::modify ltm data-group internal __appsvcs_update records none\n} err]} {\ntmsh::create ltm data-group internal __appsvcs_update type string records none\n}\nif { [catch {\ntmsh::create auth partition trace_tenant default-route-domain 0\ntmsh::create sys folder /trace_tenant/SampleApp/\ntmsh::begin_transaction\ntmsh::modify auth partition trace_tenant description \\\"Updated by AS3 at [clock format [clock seconds] -gmt true -format {%a, %d %b %Y %T %Z}]\\\"\ntmsh::create ltm virtual-address /trace_tenant/1.2.3.4 address 1.2.3.4 arp enabled icmp-echo enabled mask 255.255.255.255 route-advertisement disabled spanning disabled traffic-group default\ntmsh::create ltm virtual /trace_tenant/SampleApp/Sample_service address-status yes auto-lasthop default connection-limit 0 description \\\"SampleApp\\\" destination /trace_tenant/1.2.3.4:100 ip-protocol tcp last-hop-pool none mask 255.255.255.255 mirror disabled persist replace-all-with \\{ /Common/cookie \\{ default yes \\} \\} policies none profiles replace-all-with \\{ /Common/http \\{ context all \\} /Common/f5-tcp-progressive \\{ context all \\} \\} source 0.0.0.0/0 source-address-translation \\{ type automap \\} rules none security-log-profiles none source-port preserve translate-address enabled translate-port enabled nat64 disabled vlans none vlans-disabled   metadata none clone-pools none\ntmsh::commit_transaction\n} err] } {\ncatch { tmsh::cancel_transaction } e\nregsub -all {\"} $err {\\\"} err\ntmsh::modify ltm data-group internal __appsvcs_update records add \\{ error \\{ data \\\"$err\\\" \\} \\}\ncatch { tmsh::delete sys folder /trace_tenant/SampleApp/ } e\ncatch { tmsh::delete auth partition trace_tenant } e\n}}\n}"
    }
}

Back to top


Configuring management port log destinations

In this example, we show how you can configure the BIG-IP to use the management port as a log destination in an AS3 declaration.

For more information and manual configuration, see K50040950 on AskF5. For AS3 usage, see Log_Destination in the Schema Reference.

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

  • Partition (tenant) named Management_Port_Log_Destination.
  • An Application named SampleApp.
  • A Log Destination named mgmtLogDest with a type of management-port.
{
    "class": "ADC",
    "schemaVersion": "3.20.0",
    "id": "Management_Port_Log_Destination",
    "Management_Port_Log_Destination": {
        "class": "Tenant",
        "SampleApp": {
            "class": "Application",
            "template": "generic",
            "mgmtLogDest": {
                "class": "Log_Destination",
                "type": "management-port",
                "address": "1.2.3.4",
                "port": 80,
                "protocol": "tcp"
            }
        }
    }
}

Back to top


Sharing IP addresses between virtual servers

In this example, we show how you can use the shareAddress property in an AS3 Service class to easily share IP addresses between virtual servers.

When you use shareAddress, AS3 creates virtual-address objects in the Common partition/tenant instead of putting those objects into the same tenant as the virtual server. This allows you to use the same virtual IP address for a virtual server in a declaration, as you can see in the following example (both use the IP address 10.10.0.111).

Important

While the virtual addresses can be the same, multiple virtual servers cannot share both the same IP address AND port.
shareAddress must be set to true for each service in which you are using the same virtual IP address.

If you do not include shareAddress, or set it to false, the virtual address(es) are put in the tenant/partition specified in the declaration.

You can find the shareAddress property in the Schema Reference in each of the Service classes, for example Schema Reference: Service_HTTP.

Warning

There is currently a known issue with a workaround you could encounter when using shareAddresses. See GitHub Issue 279

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

  • Partition (tenant) named Example_Shared1.
  • An Application named Application1 which includes a virtual server named test.item1 with two virtual addresses on virtual port 8080 and shareAddress set to true.
  • An Application named Application2 which includes a virtual server named test.item2 with two virtual addresses (one of which is the same as item1) on virtual port 8079 and shareAddress set to true.
{
    "class": "AS3",
    "persist": false,
    "declaration": {
        "class": "ADC",
        "schemaVersion": "3.20.0",
        "id": "Pool",
        "Example_Shared1": {
            "class": "Tenant",
            "Application1": {
                "class": "Application",
                "test.item1": {
                    "class": "Service_Generic",
                    "virtualAddresses": [
                        "10.10.0.111",
                        "10.10.0.1"
                    ],
                    "virtualPort": 8080,
                    "shareAddresses": true
                }
            },
            "Application2": {
                "class": "Application",
                "test.item2": {
                    "class": "Service_HTTP",
                    "virtualAddresses": [
                        "10.10.0.111",
                        "10.10.0.5"
                    ],
                    "virtualPort": 8079,
                    "shareAddresses": true
                }
            }
        }
    }
}

Back to top


Configuring serviceDownImmediateAction on a virtual

In this example, we show how you can use the serviceDownImmediateAction property in an AS3 Service class. This property specifies the immediate action the BIG-IP system should respond with upon the receipt of the initial client’s SYN packet, if the availability status of the virtual server is Offline or Unavailable.

This property has the following options:

  • None: Specifies that the system takes no immediate action if the virtual server is reported Offline or Unavailable. This is the default setting.
  • Reset: Specifies that the system resets the connections when the virtual server is reported Offline or Unavailable.
  • Drop: Specifies that the system drops the connections when the virtual server is reported Offline or Unavailable.

While you can specify none for all AS3 Service classes, Drop and Reset are only supported for Services using the TCP protocol.

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

  • Partition (tenant) named tcp_service_action.
  • An Application named app.
  • A TCP virtual server named service which has serviceDownImmediateAction set to drop.
{
    "class": "ADC",
    "schemaVersion": "3.21.0",
    "id": "declarationId",
    "tcp_service_action": {
        "class": "Tenant",
        "app": {
            "class": "Application",
            "service": {
                "class": "Service_TCP",
                "virtualAddresses": [
                    "1.1.1.1"
                ],
                "virtualPort": 1000,
                "serviceDownImmediateAction": "drop"
            }
        }
    }
}

Back to top


Using the /settings endpoint

In this example, we show how you can use the /settings endpoint introduced in AS3 3.23. This endpoint enables the configuration of certain system-wide settings, such as enabling or disabling Burst Handling (currently the only supported setting).

To use the /settings endpoint, you can send a POST or GET request to https://<BIG-IP>/mgmt/shared/appsvcs/settings.

  • GET returns the current configuration settings.
  • POST allows you to change the current settings. See the following example.

AS3 3.27 introduced the serviceDiscoveryEnabled property. For an example, see Disabling Service Discovery.

The following example shows how you can enable the burst handling feature when you POST the following declaration to https://<BIG-IP>/mgmt/shared/appsvcs/settings.
Also see Burst Handling

{
    "burstHandlingEnabled": true
}

Back to top


Configuring a SNAT pool

In this example, we show how you can configure a SNAT pool in an AS3 declaration. A SNAT is an object that maps the source client IP address in a request to a translation address defined on the BIG-IP device. A SNAT pool represents a pool of translation addresses you configure on the BIG-IP system. The original IP address is then mapped to the entire translation pool (SNAT pool).

Tip

You can also use a pointer to a SNAT Pool that exists on the BIG-IP. See Pointer_SNAT_Pool in the Schema Reference for usage.

For more information on SNAT on the BIG-IP, see Overview of SNAT features.

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

  • Partition (tenant) named Sample_SNAT_Pool.
  • An Application named SNAT_app.
  • A virtual server named SNAT_service that references the SNAT pool.
  • A pool named web_pool with two members.
  • A SNAT pool containing two SNAT addresses.
{
    "class": "ADC",
    "schemaVersion": "3.16.0",
    "label": "snat_pool_existing",
    "remark": "reference_snat_pool",
    "Sample_SNAT_Pool": {
        "class": "Tenant",
        "SNAT_app": {
            "class": "Application",
            "SNAT_service": {
                "class": "Service_TCP",
                "virtualPort": 8181,
                "virtualAddresses": [
                    "192.0.2.100"
                ],
                "pool": "web_pool",
                "snat": {
                    "use": "CreateSnatPool"
                }
            },
            "web_pool": {
               "class": "Pool",
               "monitors": [
                  "http"
               ],
               "members": [{
                  "servicePort": 80,
                  "serverAddresses": [
                     "192.0.6.10",
                     "192.0.6.11"
                  ]
               }]
            },
            "CreateSnatPool": {
                "class": "SNAT_Pool",
                "snatAddresses": [
                    "192.0.96.10",
                    "192.0.96.11"
                 ]
            }
        }
    }
}

Back to top


Using an FQDN prefix for BIG-IP nodes

In this example, we show how you use the fqdnPrefix property on BIG-IP nodes introduced in AS3 3.24. This feature is useful for changing the names of nodes created by the FQDN addressDiscovery feature, allowing you to workaround a TMOS restriction in which nodes cannot start with a number.

If you do not specify an fqdnPrefix, AS3 does not modify the name.

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

  • Partition (tenant) named tenant.
  • An Application named fqdn_app.
  • A virtual server named service that references a pool.
  • A pool named fqdn_pool with addressDiscovery set to fqdn and an fqdnPrefix set to fqdn-.
{
    "class": "ADC",
    "schemaVersion": "3.24.0",
    "tenant": {
        "class": "Tenant",
        "fqdn_app": {
            "class": "Application",
            "service": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                    "192.0.2.241"
                ],
                "pool": "fqdn_pool"
            },
            "fqdn_pool": {
                "class": "Pool",
                "members": [
                    {
                        "servicePort": 80,
                        "addressDiscovery": "fqdn",
                        "autoPopulate": true,
                        "fqdnPrefix": "fqdn-",
                        "hostname": "43981389-52e4-494e-b2bb-6832f78f18ec.example.com"
                    }
                ]
            }
        }
    }
}

Back to top


Enabling a MQTT profile on a TCP service in a declaration

In this example, we show you how to add an MQTT (Message Queuing Telemetry Transport) profile to a service (virtual server) in a declaration. The MQTT profile optimizes the performance and bandwidth of mobile environments.

When you enable this profile, AS3 attaches the default MQTT profile found on the BIG-IP. This profile is not configurable in AS3, you simply enable or disable (default) it in your Service_TCP services using the mqttEnabled property.

For more information and manual configuration, see Configuring MQTT Functionality in the BIG-IP documentation.

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

  • Partition (tenant) named tcp_mqtt_enabled.
  • An Application named app.
  • A virtual server named service that has mqttEnabled set to true.
{
    "class": "ADC",
    "schemaVersion": "3.27.0",
    "tcp_mqtt_enabled": {
        "class": "Tenant",
        "app": {
            "class": "Application",
            "service": {
                "class": "Service_TCP",
                "virtualAddresses": [
                    "1.1.1.1"
                ],
                "virtualPort": 1883,
                "mqttEnabled": true
            }
        }
    }
}

Back to top


Retrieving data from URLs that use token-based authentication

In this example, we show how you can fetch data from secured URLs that do not use Basic Authentication, using token (bearer token) authentication (OAuth2 in this example). This is necessary when trying to retrieve data from URLs from locations such as Microsoft Azure Dev Ops, and GitHub (after 11/13/2020) that do not support Basic authentication.

This functionality is enabled by using the new bearer-token authentication method introduced in AS3 3.28. Currently, you must provide the token in the declaration. Future versions may include the ability to retrieve the token.

Your application must be configured appropriately so AS3 can retrieve data from the URLs. For example, if using Azure Dev Ops, see https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow. If using GitHub, see https://docs.github.com/en/rest/guides/basics-of-authentication. If using other applications, see the appropriate documentation.

See Bearer Token in the schema reference for more information and AS3 usage.

Note

This example retrieves a URL as a part of a WAF policy, but bearer token authentication works with any AS3 class that can retrieve data from a URL.

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

  • Partition (tenant) named Example_WAF_Policy.
  • An Application named Example_App.
  • A WAF policy named exampleWAF that retrieves the policy via URL using bearer token authentication, and the token is included in the declaration.
{
    "class": "ADC",
    "schemaVersion": "3.28.0",
    "Example_WAF_Policy": {
        "class": "Tenant",
        "Example_App": {
            "class": "Application",
            "exampleWAF": {
                "class": "WAF_Policy",
                "url": {
                    "url": "https://bigiq.example.com/mgmt/cm/asm/policy-files/download/0da5cae6-f106-3790-a72c-c58fb6b7a512/13.1.0",
                    "authentication": {
                        "method": "bearer-token",
                        "token": {
                            "ciphertext": "ZjVmNQ==",
                            "protected": "eyJhbGciOiJkaXIiLCJlbmMiOiJub25lIn0"
                        }
                    }
                },
                "ignoreChanges": false,
                "enforcementMode": "transparent"
            }
        }
    }
}

Back to top


Referencing an iFile in an iRule declaration

In this example, we show how you can an reference an iFile in a declaration in AS3 3.29 and later using the new iFile class. An iFile is used by an iRule (based on a specific iRule event).

With AS3, you can either reference an iFile you have already uploaded to the BIG-IP system, or if you use the url pointer, you can call an external file from a URL, and AS3 creates the iFile automatically.

For more information on iFiles and iRules, see iFile chapter of the BIG-IP System iRules Concepts guide.

For AS3 usage, see iFile in the Schema Reference.

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

  • Partition (tenant) named TEST_iFile.
  • An Application named SampleApp.
  • An iFile named testIFile which references the file via URL.
  • An iRule named testIRule which contains a base64 encoded iRule (the unencoded example is shown after the declaration).
{
    "class": "ADC",
    "schemaVersion": "3.29.0",
    "id": "iFile",
    "TEST_iFile": {
        "class": "Tenant",
        "SampleApp": {
            "class": "Application",
            "testIFile": {
                "class": "iFile",
                "iFile": {
                    "url": "https://example.com/theIFile"
                }
            },
            "testIRule": {
                "class": "iRule",
                "iRule": {
                    "base64": "d2hlbiBIVFRQX1JFUVVFU1QgewogICAgICAgICBzZXQgaWZpbGVDb250ZW50IFtpZmlsZSBnZXQgIi9URVNUX2lGaWxlL0FwcGxpY2F0aW9uL3Rlc3RJRmlsZSJdCiAgICAgICAgIEhUVFA6OnJlc3BvbmQgMjAwIGNvbnRlbnQgJGlmaWxlQ29udGVudAogICAgICAgICB1bnNldCBpZmlsZUNvbnRlbnQKICAgICAgfQ=="
                }
            }
        }
    }
}

The iRule is base64 encoded in this example. This is the unencoded iRule:

when HTTP_REQUEST {
    set ifileContent [ifile get "/TEST_iFile/Application/testIFile"]
    HTTP::respond 200 content $ifileContent
    unset ifileContent
 }

Back to top


Enabling or disabling NAT and SNAT on a pool

In this example, we show how to enable or disable NAT (network address translation) or SNAT (source network address translation) in a pool in a declaration.

This feature uses two new pool properties, allowNATEnabled and allowSNATEnabled. The default value for both properties is true, meaning both are enabled by default. When set to true, NATs and/or SNATs are automatically enabled for any connections using the pool.

For more information and AS3 usage, see Pool in the Schema Reference.

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

  • Partition (tenant) named Sample_pool_allow-nat_allow-snat.
  • An Application named SampleApp.
  • A virtual server named service which references a pool.
  • A pool named web_pool with both allowNATEnabled set to false and allowSNATEnabled set to true.
{
    "class": "ADC",
    "schemaVersion": "3.29.0",
    "Sample_pool_allow-nat_allow-snat": {
        "class": "Tenant",
        "SampleApp": {
            "class": "Application",
            "service": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                    "10.1.10.10"
                ],
                "pool": {
                    "use": "web_pool"
                }
            },
            "web_pool": {
                "class": "Pool",
                "allowNATEnabled": false,
                "allowSNATEnabled": true,
                "members": [
                    {
                        "servicePort": 80,
                        "serverAddresses": [
                            "10.128.0.209"
                        ]
                    }
                ]
            }
        }
    }
}

Back to top


Using dry-run as an ADC Controls object

In this example, we show how to use dry-run as a part of the ADC_Controls class in AS3 3.30 and later (previously it was only an action in the AS3_Class).

As a reminder, when you submit a declaration using dry-run set to true, AS3 does NOT deploy the declaration or make any changes to the configuration, but responds letting you know whether or not it would succeed. This behavior is the same whether you are using the dry-run action, or as an ADC Controls object described here.

Using dry-run in the ADC Controls class allows you to use other AS3 actions, enabling you to test these declarations before deploying them.

For more information and AS3 usage, see AS3_Class and ADC_Controls in the Schema Reference.

This declaration:

  • Contains an ADC class with dry-run set to true, meaning this will not deploy the configuration to the BIG-IP, but returns information about changes that would have been made.
  • Creates a partition (tenant) named TEST_DNS_Nameserver.
  • Creates an Application named Application.
  • Creates a DNS Nameserver named test.item-foo.
  • Creates a tsigKey named DNS_TSIG_Key with a secret.
{
    "class": "AS3",
    "persist": false,
    "action": "deploy",
    "declaration": {
        "class": "ADC",
        "schemaVersion": "3.30.0",
        "id": "DNS_Nameserver",
        "controls": {
            "class": "Controls",
            "trace": true,
            "logLevel": "debug",
            "traceResponse": true,
            "dryRun": true
        },
        "TEST_DNS_Nameserver": {
            "class": "Tenant",
            "Application": {
                "class": "Application",
                "test.item-foo": {
                    "class": "DNS_Nameserver"
                },
                "tsigKey": {
                    "class": "DNS_TSIG_Key",
                    "secret": {
                        "ciphertext": "ZjVmNQ==",
                        "ignoreChanges": true
                    }
                }
            }
        }
    }
}

Back to top


Using the tag-append-html HTML rule in a declaration

In this example, we show how to use the HTML_Rule tag-append-html (part of Content Profiles), which adds HTML content to append to the tag delimiter. This feature is useful when implementing F5 Shape Security integration.

For AS3 usage, see HTML_Rule in the Schema Reference. AS3 3.31 added support for the remaining rules (see Using HTML rules in a declaration).

For more information, see Content Profiles in the BIG-IP documentation, and tag-append-html in the API Reference.

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

  • Partition (tenant) named TEST_HTML_Rule.
  • An Application named Application.
  • An HTML rule named sample1 that contains HTML content (a script) to append to the tag delimiter matching the tagName of /title.
  • A second HTML rule named sample2 that contains sample HTML content to append to the tag delimiter matching attributeName of pie, attributeValue of apple, and tagName of /dessert.
{
    "class": "ADC",
    "schemaVersion": "3.30.0",
    "id": "HTML_Rule",
    "TEST_HTML_Rule": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "sample1": {
                "class": "HTML_Rule",
                "ruleType": "tag-append-html",
                "remark": "sample1",
                "content": "<script type=\\\"text/javascript\\\" src=\\\"ProvidedJSPath\\?cache\\\"></script> <script type=\\\"text/javascript\\\" src=\\\"ShapeProvidedJSPath\\?async\\\" async></script>",
                "match": {
                    "tagName": "/title"
                }
            },
            "sample2": {
                "class": "HTML_Rule",
                "ruleType": "tag-append-html",
                "remark": "sample2",
                "content": "some content here",
                "match": {
                    "attributeName": "pie",
                    "attributeValue": "apple",
                    "tagName": "/dessert"
                }
            }
        }
    }
}

Back to top


Adding a route domain to a static pool member

This example shows how you can use the routeDomain property on static pool members in AS3 3.31 and later (for auto-discovered pool members, see this example).

The routeDomain property allows you to control the route domain to which pool members belong.

For specific information on route domains on the BIG-IP, see the route domain documentation.

Important

AS3 does not configure route domains (although Declarative Onboarding does). This property allows you to assign an existing route domain to a pool member.

See Pool_Member in the Schema Reference for AS3 usage and information.

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

  • A partition (tenant) named TEST.
  • An Application named Application
  • A virtual server named testVirtual which references the pool.
  • A pool named testPool with one member on port 80 assigned to route domain 100.
{
    "class": "ADC",
    "schemaVersion": "3.31.0",
    "id": "TEST",
    "TEST": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "testVirtual": {
                "class": "Service_HTTP",
                "virtualAddresses": [
                    "1.2.3.4"
                ],
                "pool": {
                    "use": "testPool"
                }
            },
            "testPool": {
                "class": "Pool",
                "members": [
                    {
                        "servicePort": 80,
                        "serverAddresses": [
                            "1.2.3.4"
                        ],
                        "routeDomain": 100
                    }
                ]
            }
        }
    }
}

Using HTML rules in a declaration

In this example, we show how to create an HTML profile that uses the rest of the HTML rules (tag-append-html was added in 3.30).

The rule types are (links to BIG-IP API reference): comment-raise-event, comment-remove, tag-append-html, tag-prepend-html, tag-raise-event, tag-remove, and tag-remove-attribute.

For specific information on these rules, see Content Profiles in the BIG-IP documentation.

For AS3 usage, see HTML_Rule in the Schema Reference.

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

  • Partition (tenant) named TEST_HTML_Profile.
  • An Application named Application.
  • A virtual server named service which references an HTML profile.
  • An HTML profile named htmlProfile which references multiple HTML rules.
  • An example of each type of HTML rules with appropriate properties and values.
{
    "class": "ADC",
    "schemaVersion": "3.31.0",
    "id": "HTML_Profile",
    "TEST_HTML_Profile": {
        "class": "Tenant",
        "Application": {
            "class": "Application",
            "service": {
                "class": "Service_HTTP",
                "virtualPort": 123,
                "virtualAddresses": [
                    "192.0.2.100"
                ],
                "profileHTML": {
                    "use": "htmlProfile"
                }
            },
            "htmlProfile": {
                "class": "HTML_Profile",
                "contentDetectionEnabled": true,
                "contentSelection": [
                    "text/html",
                    "text/xhtml"
                ],
                "rules": [
                    {
                        "use": "commentRaiseEventRule"
                    },
                    {
                        "use": "commentRemoveRule"
                    },
                    {
                        "use": "tagAppendHtmlRule"
                    },
                    {
                        "use": "tagPrependHtmlRule"
                    },
                    {
                        "use": "tagRaiseEventRule"
                    },
                    {
                        "use": "tagRemoveRule"
                    },
                    {
                        "use": "tagRemoveAttributeRule"
                    }
                ]
            },
            "commentRaiseEventRule": {
                "class": "HTML_Rule",
                "label": "c-r-e rule label",
                "remark": "c-r-e rule remark",
                "ruleType": "comment-raise-event"
            },
            "commentRemoveRule": {
                "class": "HTML_Rule",
                "label": "comment remove rule label",
                "remark": "comment remove rule remark",
                "ruleType": "comment-remove"
            },
            "tagAppendHtmlRule": {
                "class": "HTML_Rule",
                "label": "t-a-h rule label",
                "remark": "t-a-h rule remark",
                "ruleType": "tag-append-html",
                "content": "your code here",
                "match": {
                    "attributeName": "pie",
                    "attributeValue": "apple",
                    "tagName": "/dessert"
                }
            },
            "tagPrependHtmlRule": {
                "class": "HTML_Rule",
                "label": "t-p-h rule label",
                "remark": "t-p-h rule remark",
                "ruleType": "tag-prepend-html",
                "content": "your code here",
                "match": {
                    "attributeName": "pie",
                    "attributeValue": "cherry",
                    "tagName": "/dessert"
                }
            },
            "tagRaiseEventRule": {
                "class": "HTML_Rule",
                "label": "t-r-e rule label",
                "remark": "t-r-e rule remark",
                "ruleType": "tag-raise-event",
                "match": {
                    "attributeName": "fork",
                    "attributeValue": "missing",
                    "tagName": "utensil"
                }
            },
            "tagRemoveRule": {
                "class": "HTML_Rule",
                "label": "tag remove rule label",
                "remark": "tag remove rule remark",
                "ruleType": "tag-remove",
                "match": {
                    "attributeName": "plate",
                    "attributeValue": "dirty",
                    "tagName": "dish"
                }
            },
            "tagRemoveAttributeRule": {
                "class": "HTML_Rule",
                "label": "t-r-a rule label",
                "remark": "t-r-a remove rule remark",
                "ruleType": "tag-remove-attribute",
                "attributeName": "removeMeAttribute",
                "match": {
                    "attributeName": "attribName",
                    "attributeValue": "attribValue",
                    "tagName": "tag"
                }
            }
        }
    }
}

Back to top