Creating New Templates¶
Templates are BIG-IP AS3 declarations that have been parameterized. This page has a short tutorial to help template authors get started creating template sets, with a more detailed explanation of the templates and their syntax.
We recommend template authors read the GUI Overview to fully understand how templates are processed in the system.
In order to use the BIG-IP FAST CLI, which provides template validation and previewing, Node Package Manager (npm) must be installed. BIG-IP FAST CLI is a community-supported authoring tool that template authors may use. It is installed onto the client PC/laptop, not on BIG-IP, and is used to validate templates as they are being built or modified.
For more information on the npm tool and community, visit npm.
Some familiarity with the command line is assumed, and we recommend the BIG-IP FAST npm module, @f5devcentral/f5-fast-core
, is installed globally.
This provides the BIG-IP FAST command line tools to validate and render templates during authoring.
Help text is provided and accessed via: fast --help
.
For more information on a given command use the --help
flag combined with a command: fast <command> --help
:

npm install -g @f5devcentral/f5-fast-core
fast validate <filename>
fast packageTemplateSet <templateSetPath>
Under the vscode extension settings, press F1, type f5, select “F5: Settings”, click add item button, or
Add device from the F5 HOSTS view. Click F5: Add HOST button in top right of the extension view for “F5 HOSTS”
See the Create a device and connect section for more information.
Hello World example¶
Choose an example AS3 declaration that fits your use case. See Example declarations for AS3 examples.
For our example we are creating a simple Hello World template using the Example 1: Simple HTTP application then uploading it to BIG-IP FAST.
Partition (tenant) named
Sample_01
Application named
A1
Virtual server (HTTP) named
service
, with a VIP at10.0.1.10
Pool named
web_pool
with 2 members monitored by the default HTTP health monitorNode IP addresses listed as
serverAddresses
,192.0.1.10
and192.0.1.11
Later sections go into detail about the template specification and its entire feature set.
Create a file named hello.mst, then copy the following AS3 declaration into it:
{ "class": "AS3", "action": "deploy", "persist": true, "declaration": { "class": "ADC", "schemaVersion": "3.0.0", "id": "urn:uuid:33045210-3ab8-4636-9b2a-c98d22ab915d", "label": "Sample 1", "remark": "Simple HTTP application with RR pool", "Sample_01": { "class": "Tenant", "A1": { "class": "Application", "service": { "class": "Service_HTTP", "virtualAddresses": [ "10.0.1.10" ], "pool": "web_pool" }, "web_pool": { "class": "Pool", "monitors": [ "http" ], "members": [{ "servicePort": 80, "serverAddresses": [ "192.0.1.10", "192.0.1.11" ] }] } } } } }
Save the file.
Parameterization is changing static, hard coded sections to variables that are filled in at deploy time.
For this example, the following items are changed:
{
"class": "AS3",
"action": "deploy",
"persist": true,
"declaration": {
"class": "ADC",
"schemaVersion": "3.0.0",
"id": "urn:uuid:33045210-3ab8-4636-9b2a-c98d22ab915d",
"label": "Sample 1",
"remark": "Simple HTTP application with RR pool",
"{{tenant_name}}": {
"class": "Tenant",
"{{application_name}}": {
"class": "Application",
"service": {
"class": "Service_HTTP",
"virtualAddresses": [
"{{virtual_address}}"
],
"pool": "web_pool"
},
"web_pool": {
"class": "Pool",
"monitors": [
"http"
],
"members": [{
"servicePort": 80,
"serverAddresses": {{server_addresses::array}}
}]
}
}
}
}
}
Once the declaration is parameterized to fit your needs, it is the template you use to deploy your BIG-IP(s).
If the BIG-IP FAST npm module is installed globally on your system, we can validate it and try rendering it with the following command:
fast validate hello.mst
Create the following file named params.json:
{ "tenant_name": "TestTenant", "application_name": "MyTestApp", "virtual_address": "0.0.0.0", "server_addresses": [ "10.0.0.1", "10.0.0.2" ] }
Using this file, the following command will show an example render:
fast render hello.mst params.json
To add this to the system, the template can be placed into a template set package. From the command line:
fast packageTemplateSet <folder containing mst>
Make note of the file location, and the size of the file (in bytes). Note: file size must be less than 1MB or the transfer fails.
Upload the file to the BIG-IP system using cURL from a Linux shell using the following syntax:
$ curl -sku <BIG-IP username>:<BIG-IP password> --data-binary @<path to zip file> -H "Content-Type: application/octet-stream" -H "Content-Range: 0-<content-length minus 1>/<content-length>" -H "Content-Length: <file size in bytes>" -H "Connection: keep-alive" https://<IP address of BIG-IP>/mgmt/shared/file-transfer/uploads/<zipfile-name>.zip
For example:
$ curl -sku admin:Pass1w0rd! --data-binary @example.zip -H "Content-Type: application/octet-stream" -H "Content-Range: 0-1298/1299" -H "Content-Length: 1299" -H "Connection: keep-alive" https://192.0.2.87/mgmt/shared/file-transfer/uploads/example.zip
This example returns the following:
{"remainingByteCount":0,"usedChunks":{"0":1299},"totalByteCount":1299,"localFilePath":"/var/config/rest/downloads/example.zip","temporaryFilePath":"/var/config/rest/downloads/tmp/example.zip","generation":0,"lastUpdateMicros":1582756171238125}
Install the newly uploaded template set using the following syntax:
curl -sku <BIG-IP username>:<BIG-IP password> -X POST -d '{"name": "<zip file name without .zip extension>"}' -H "Content-Type: application/json" https://<IP address of BIG-IP>/mgmt/shared/fast/templatesets
For example:
curl -sku admin:Pass1w0rd -X POST -d '{"name": "example"}' -H "Content-Type: application/json" https://192.0.2.87/mgmt/shared/fast/templatesets
Example response:
{ "code":200, "message":"" }
The template will validate and be added to the system. When navigating to the FAST Templates tab, the new template set should be available, with the Hello World template ready for use. The rest of this page explains more about what the templating system can do. By using JSON schema alongside the templates, BIG-IP FAST provides a powerful system for validating template parameters ensuring applications get deployed as expected.
Template Specification¶
Templates abide by the following rules:
Templates are text files with sections marked off called variables
Variables will be marked for replacement at render time
Variables are surrounded with double curly braces, {{ and }}
Variables can specify a type: name::type
Primitive Types
string (default)
text (for strings with new lines and escape characters)
number
integer
boolean
array
Example¶
The following is an example of a simple BIG-IP FAST template that will render an AS3 declaration:
{
"class": "ADC",
"schemaVersion": "3.11.0",
"{{tenant_name}}": {
"class": "Tenant",
"{{application_name}}": {
"class": "Application",
"template": "http",
"serviceMain": {
"class": "Service_HTTP",
"virtualAddresses": ["{{virtual_address}}"],
"pool": "web_pool_{{port}}"
},
"web_pool_{{port}}": {
"class": "Pool",
"monitors": [
"http"
],
"members": [
{
"servicePort": {{port::integer}},
"serverAddresses": {{server_addresses::array}}
}
]
}
}
}
}
In the example template, we have some variables: tenant_name, application_name, virtual_address, port, and server_addreses. Some have annotations, like port::integer. The integer annotation signifies the value of port must be an integer.
Variables may be used in multiple places. If a variable is annotated somewhere in the file, an unannotated version of that variable will respect the annotation.
From the variables, a schema is generated. This schema describes the parameters that must be provided to render the template. These parameters will show up in the form representation of the template in the GUI.
The following schema will get auto-generated from the example:
{
"properties": {
"tenant_name" : {
"type": "string"
},
"application_name" : {
"type": "string"
},
"virtual_address" : {
"type": "string"
},
"server_addresses" : {
"type": "array"
},
"port" : {
"type": "integer"
},
}
}
This example ‘view’ passes validation using the schema:
{
"tenant_name" : "myTenant",
"application_name" : "simple_http_1",
"virtual_address" : "10.0.0.1",
"server_addresses" : [ "10.0.1.1", "10.0.2.2" ],
"port" : 80
}
This information is collected in the form UI and compiled into a parameter object like the example. The information is passed along to the template renderer, and the variable names are replaced with their parameter values.
The final declaration is generated by providing the previous view with the provided template:
{
"class": "ADC",
"schemaVersion": "3.11.0",
"myTenant": {
"class": "Tenant",
"simple_http_1": {
"class": "Application",
"template": "http",
"serviceMain": {
"class": "Service_HTTP",
"virtualAddresses": ["10.0.0.1"],
"pool": "web_pool_80"
},
"web_pool_80": {
"class": "Pool",
"monitors": [
"http"
],
"members": [
{
"servicePort": 80,
"serverAddresses": [ "10.0.1.1", "10.0.2.2" ]
}
]
}
}
}
}
Extended Types¶
BIG-IP FAST also allows specification of custom types using JSON schema. Schema files are placed in the template set (i.e., the directory along side the template files). Each file must have a .json extension and contain valid JSON schema. Schemas listed in the definitions will be made available to templates using the following syntax:
name:schema_name:type
name is the name of the variable, as before
schema_name is the name of the JSON schema file, excluding the extension
type is the property name of the definition being referenced
For example:
...
{
"class": "{{service_type:f5:service}}"
...
}
...
BIG-IP FAST has support for enums and custom formats can be applied to the primitive types outlined in the previous section. The variable in the example is a service type from the f5 schema named service_type. The service schema is an enum containing the AS3 basic services, Service_HTTP, Service_HTTPS, Service_L4, Service_UDP, and Service_TCP.
The definition from f5.json:
{
"service": {
"type": "string",
"enum": [
"Service_HTTP",
"Service_HTTPS",
"Service_TCP",
"Service_UDP",
"Service_L4"
],
"default": "Service_HTTP"
}
}
Arrays of primitives should work fine but have not been extensively tested.
Objects are not yet supported.
Up-front validation using the schema will help to prevent failed deployments by notifying the user prior to deployment when a value has an invalid format. Therefore, when designing a template, the appropriate schema definition should be used for each variable. For example, if the virtual IP address is a variable, use schema to validate if the input is an IPv4 or IPv6 address.
Important
When authoring a template, be cautious when entering sensitive data into your template such as passwords, certificates and monitor information to name a few. BIG-IP FAST does not encrypt the data and it will remain as plain text. Careful consideration should be made when adding this type of data onto the template.
F5 BIG-IP AS3 Secrets¶
Secrets are things such as passphrases, ssl certificate/keys, etc. AS3 declarations made for BIG-IP FAST templates should follow best practices for AS3 secrets outside of BIG-IP FAST. See the F5 AS3 JSON schema documentation for additional information.
Keeping Template Text Secret¶
The template may be viewed from the BIG-IP FAST UI via the BIG-IP FAST Templates tab, select the template then the View Template button, which is located at the bottom of the template. If there is a static, plain text passphrase in the template, it will be displayed. For cases where the passphrase is part of an AS3 declaration, the template author may wish to substitute an encrypted passphrase to prevent leaking the password when sharing or backing up the template files. To obtain the encrypted value, submit the declaration directly to AS3, and retrieve the passphrase object that is returned by AS3 into the BIG-IP FAST template.
For example, if the template contains the following certificate definition:
{
"webcert": {
"class": "Certificate",
"remark": "in practice we recommend using a passphrase",
"certificate": "-----BEGIN CERTIFICATE-----\nMIICnDCCAgWgAwIBAgIJAJ5n2b0OCEjwMA0GCSqGSIb3DQEBCwUAMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRQwEgYDVQQKDAtmNV9OZXR3b3JrczEbMBkGA1UEAwwSc2FtcGxlLmV4YW1wbGUubmV0MB4XDTE3MTEyNjE5NTAyNFoXDTE4MDIyNTE5NTAyNFowZzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFDASBgNVBAoMC2Y1X05ldHdvcmtzMRswGQYDVQQDDBJzYW1wbGUuZXhhbXBsZS5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALEsuXmSXVQpYjrZPW+WiTBjn491mwZYT7Q92V1HlSBtM6WdWlK1aZN5sovfKtOX7Yrm8xa+e4o/zJ2QYLyyv5O+t2EGN/4qUEjEAPY9mwJdfzRQy6Hyzm84J0QkTuUJ/EjNuPji3D0QJRALUTzu1UqqDCEtiN9OGyXEkh7uvb7BAgMBAAGjUDBOMB0GA1UdDgQWBBSVHPNrGWrjWyZvckQxFYWO59FRFjAfBgNVHSMEGDAWgBSVHPNrGWrjWyZvckQxFYWO59FRFjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAJeJ9SEckEwPhkXOm+IuqfbUS/RcziifBCTmVyE+Fa/j9pKSYTgiEBNdbJeBEa+gPMlQtbV7Y2dy8TKx/8axVBHiXC5geDML7caxOrAyHYBpnx690xJTh5OIORBBM/a/NvaR+P3CoVebr/NPRh9oRNxnntnqvqD7SW0U3ZPe3tJc\n-----END CERTIFICATE-----",
"privateKey": "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-256-CBC,D8FFCE6B255601587CB54EC29B737D31\n\nkv4Fc3Jn0Ujkj0yRjt+gQQfBLSNF2aRLUENXnlr7Xpzqu0Ahr3jS1bAAnd8IWnsR\nyILqVmKsYF2DoHh0tWiEAQ7/y/fe5DTFhK7N4Wml6kp2yVMkP6KC4ssyYPw27kjK\nDBwBZ5O8Ioej08A5sgsLCmglbmtSPHJUn14pQnMTmLOpEtOsu6S+2ibPgSNpdg0b\nCAJNG/KHe+Vkx59qNDyDeKb7FZOlsX30+y67zUq9GQqJEDuysPJ2BUNP0IJXAjst\nFIt1qNoZew+5KDYs7u/lPxcMGTirUhgI84Jy4WcDvSOsP/tKlxj04TbIE3epmSKy\n+TihHkwY7ngIGtcm3Sfqk5jz2RXoj1/Ac3SW8kVTYaOUogBhn7zAq4Wju6Et4hQG\nRGapsJp1aCeZ/a4RCDTxspcKoMaRa97/URQb0hBRGx3DGUhzpmX9zl7JI2Xa5D3R\nmdBXtjLKYJTdIMdd27prBEKhMUpae2rz5Mw4J907wZeBq/wu+zp8LAnecfTe2nGY\nE32x1U7gSEdYOGqnwxsOexb1jKgCa67Nw9TmcMPV8zmH7R9qdvgxAbAtwBl1F9OS\nfcGaC7epf1AjJLtaX7krWmzgASHl28Ynh9lmGMdv+5QYMZvKG0LOg/n3m8uJ6sKy\nIzzvaJswwn0j5P5+czyoV5CvvdCfKnNb+3jUEN8I0PPwjBGKr4B1ojwhogTM248V\nHR69D6TxFVMfGpyJhCPkbGEGbpEpcffpgKuC/mEtMqyDQXJNaV5HO6HgAJ9F1P6v\n5ehHHTMRvzCCFiwndHdlMXUjqSNjww6me6dr6LiAPbejdzhL2vWx1YqebOcwQx3G\n-----END RSA PRIVATE KEY-----",
"passphrase": {
"ciphertext": "ZjVmNQ==",
"protected": "eyJhbGciOiJkaXIiLCJlbmMiOiJub25lIn0"
}
}
The “protected” field (in base64) indicates that the value of “ciphertext” is in plain text. Literal translation to {“alg”:”dir”,”enc”:”none”}. Submit a declaration containing this definition to AS3. In the body of the response, you will find:
{
"passphrase": {
"ciphertext": "JE0kbGkkOFpmMi9oMnpYb1VkVjJpbFpHd28vUT09",
"protected": "eyJhbGciOiJkaXIiLCJlbmMiOiJmNXN2In0="
"miniJWE": true
}
}
In the response, the value of “protected” has changed to indicate SecureVault encryption (literally {“alg”:”dir”,”enc”:”f5sv”}), and “ciphertext” is the encrypted secret. These examples are directly tied to AS3, and works only for protected ciphertext elements in a declaration.
See also
Secrets in AS3 Declarations for a more expanded definition of AS3 secrets.
Service Discovery¶
Amazon Web Services (AWS)
Azure
Consul
Event
FQDN
Google Compute Engine (GCE)