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