Per-Application Declarations

BIG-IP AS3 3.50 introduces a per-application deployment model, which enables AS3 declarations to include only some tenant applications, leaving other applications in a tenant unaltered. This can greatly simplify updating the BIG-IP AS3 configuration (especially when the initial declaration is very large with many applications), and ease automated deployments.

In previous releases, BIG-IP AS3 only supported a tenant-based model. This meant all applications had to be included in the tenant; if you posted a declaration that did not include existing applications in that tenant, AS3 deleted them. With the per-application deployment model, you send a request to a new endpoint, which includes the tenant as a part of the URI. This allows you post a declaration that contains only one or more applications, and AS3 leaves the other applications in the tenant untouched.

Note

The source of truth for the BIG-IP configuration remains the entire declaration. This feature allows you to update this declaration without resending the entire declaration, similar to the PATCH method.
You can use this per-application functionality together with traditional AS3 declarations, as long as you keep in mind when you post a traditional (non-per-application) declaration, it is the source of truth and configures the tenant according to the objects contained in that declaration.

If you have feedback on this feature, please open a GitHub issue at https://github.com/F5Networks/f5-appsvcs-extension/issues

Per-application schema for validation

Starting with BIG-IP AS3 3.56, AS3 ships with a separate consolidated schema file specifically for validating per-application declarations. Previously, the standard AS3 JSON schema could not validate per-application declarations because they use a different structure (no AS3, ADC, or Tenant wrapper classes).

The per-application schema file is named per-app-schema.json and is available alongside the other schema files in the AS3 release on the F5 AS3 GitHub releases page.

You can use this schema to validate your per-application declarations locally before sending them to the BIG-IP, which can help catch errors early and reduce load on the BIG-IP system.

Enabling/disabling the per-application feature

Per-Application deployments will be enabled by default, but can be disabled on the /settings endpoint. For more information about the settings endpoint, see Settings Endpoint.

To enable per-application deployments, send a POST to HTTPS://<BIG-IP IP address>/mgmt/shared/appsvcs/settings with the following request body:

perAppDeploymentAllowed: true

To see the current settings, or verify the per-application feature is enabled, send a GET request to HTTPS://<BIG-IP IP address>/mgmt/shared/appsvcs/settings.

Example per-application declaration

A per-application declaration is similar to a traditional declaration, but there is no Tenant class and the per-application declaration uses a different AS3 endpoint. The per-application declaration allows all CRUD operations to a specific tenant and application in the URI path without specifying the tenant in the declaration.

The following is an example per-application declaration (note the lack of the Tenant class).

{
    "id": "per-app-declaration",
    "schemaVersion": "3.50.0",
    "controls": {
        "class": "Controls",
        "logLevel": "debug",
        "trace": true
    },
    "Application1": {
        "class": "Application",
        "service": {
            "class": "Service_HTTP",
            "virtualAddresses": [
                "192.0.2.1"
            ],
            "pool": "pool"
        },
        "pool": {
            "class": "Pool",
            "members": [
                {
                    "servicePort": 80,
                    "serverAddresses": [
                        "192.0.2.10",
                        "192.0.2.20"
                    ]
                }
            ]
        }
    }
}

POSTing a per-application

The URI path for POSTing a per-application declaration is /appsvcs/declare/<tenant>/applications.

For example, you could send the example declaration to: POST HTTPS://192.0.2.10/mgmt/shared/appsvcs/declare/ExampleTenant/applications

This would update the tenant named ExampleTenant as specified in the URI, with the application Application1 as specified in the example declaration.

Note

If you send a POST request and use a tenant name in the URI that does not already exist, AS3 creates a tenant with that name, and puts the applications into the tenant.

Using GET to view applications

There are two API paths you can use for GET requests to per-application declarations:

  • /appsvcs/declare/<tenant>/applications <br>
  • /appsvcs/declare/<tenant>/applications/[<application>]

For example:

GET HTTPS://192.0.2.10/mgmt/shared/appsvcs/declare/ExampleTenant/applications retrieves all applications in ExampleTenant.

GET HTTPS://192.0.2.10/mgmt/shared/appsvcs/declare/ExampleTenant/applications/applicationName retrieves the applicationName application only in ExampleTenant.

You can also send a GET request to the /declare endpoint, and the entire declaration is returned.

Deleting a per-application declaration

To delete a specific application, you can send a DELETE request to /appsvcs/declare/<tenant>/applications/[<application name>].

You must specify the application(s) you want to delete as a part of the URI. If you delete all of the applications in a tenant, AS3 deletes the tenant as well.

For example, to delete the Application1 application from the previous example: DELETE HTTPS://192.0.2.10/mgmt/shared/appsvcs/declare/ExampleTenant/applications/Application1


Additional per-application declarations

The following are additional example declarations for per-application deployments.

Per-Application example with multiple applications in the declaration

The following example includes two applications in the per-application declaration.

{
    "id": "per-app-declaration",
    "schemaVersion": "3.50.0",
    "controls": {
        "class": "Controls",
        "logLevel": "debug",
        "trace": true
    },
    "Application1": {
        "class": "Application",
        "service": {
            "class": "Service_HTTP",
            "virtualAddresses": [
                "192.0.2.1"
            ],
            "pool": "pool"
        },
        "pool": {
            "class": "Pool",
            "members": [
                {
                    "servicePort": 80,
                    "serverAddresses": [
                        "192.0.2.10",
                        "192.0.2.20"
                    ]
                }
            ]
        }
    },
    "Application2": {
        "class": "Application",
        "service": {
            "class": "Service_HTTP",
            "virtualAddresses": [
                "192.0.2.2"
            ],
            "pool": "pool"
        },
        "pool": {
            "class": "Pool",
            "members": [
                {
                    "servicePort": 80,
                    "serverAddresses": [
                        "192.0.2.30",
                        "192.0.2.40"
                    ]
                }
            ]
        }
    }
}

Per-Application example with a pool

This example is a per-application declaration that includes an application with only a pool (no virtual service, or other objects).

{
    "id": "per-app-declaration",
    "schemaVersion": "3.50.0",
    "controls": {
        "class": "Controls",
        "logLevel": "debug",
        "trace": true
    },
    "app1": {
        "class": "Application",
        "template": "generic",
        "pool1": {
            "class": "Pool",
            "loadBalancingMode": "round-robin",
            "minimumMembersActive": 1,
            "reselectTries": 0,
            "serviceDownAction": "none",
            "slowRampTime": 11,
            "minimumMonitors": 1
        }
    }
}

Per-Application example with a JSON profile

This example shows a per-application declaration that includes a JSON profile. The JSON profile allows the BIG-IP system to parse, validate, and constrain JSON data that passes through the system.

For more information on JSON profiles, see the Profiles page.

{
    "schemaVersion": "3.56.0",
    "Application1": {
        "class": "Application",
        "jsonProfileSample": {
            "class": "JSON_Profile",
            "remark": "Sample JSON profile for per-app declaration",
            "parentProfile": {
                "bigip": "/Common/json"
            },
            "maximumBytes": 65536,
            "maximumEntries": 2048,
            "maximumNonJsonBytes": 32768
        },
        "service": {
            "class": "Service_HTTP",
            "virtualAddresses": [
                "192.0.2.10"
            ],
            "virtualPort": 80,
            "snat": "auto",
            "pool": "jsonPool",
            "profileJSON": {
                "use": "jsonProfileSample"
            }
        },
        "jsonPool": {
            "class": "Pool",
            "monitors": [
                "tcp"
            ],
            "members": [
                {
                    "servicePort": 80,
                    "serverAddresses": [
                        "192.0.2.12",
                        "192.0.2.13"
                    ]
                }
            ]
        }
    }
}

Per-Application example with an SSE profile

This example shows a per-application declaration that includes a Server-Sent Events (SSE) profile. The SSE profile allows the BIG-IP system to manage SSE traffic, which is used for server-to-client streaming over HTTP.

For more information on SSE profiles, see the Profiles page.

{
    "schemaVersion": "3.56.0",
    "Application1": {
        "class": "Application",
        "sseProfileSample": {
            "class": "SSE_Profile",
            "remark": "Sample SSE profile for per-app declaration",
            "parentProfile": {
                "bigip": "/Common/sse"
            },
            "maxBufferedMsgBytes": 65536,
            "maxFieldNameSize": 1024
        },
        "service": {
            "class": "Service_HTTP",
            "virtualAddresses": [
                "192.0.2.20"
            ],
            "virtualPort": 80,
            "snat": "auto",
            "pool": "ssePool",
            "profileSSE": {
                "use": "sseProfileSample"
            }
        },
        "ssePool": {
            "class": "Pool",
            "monitors": [
                "tcp"
            ],
            "members": [
                {
                    "servicePort": 80,
                    "serverAddresses": [
                        "192.0.2.22",
                        "192.0.2.23"
                    ]
                }
            ]
        }
    }
}