BIG-IP Next Central Manager API with Postman
In my last article I dove into the Central Manager AS3 endpoints with thecURL command. As I was preparing for this one, I thought it would work better as a live stream than a traditional article. Here's the stream you can watch in the replay, and the resources I mentioned on the stream are posted below. Show description: I've been working with the BIG-IP Next API from the API reference and with curl on the command line, and I gotta tell you, as much as I don't love Postman, it's super handy when learning an API. In this episode of DevCentral Connects, I'll download the collection from the Next documentation, get the environment variables set up, and walk through some of the tasks available in the collection to start working with the BIG-IP Next API. Resources BIG-IP Next Articles on DevCentral BIG-IP Next Academy group on DevCentral Embracing AS3: Foundations BIG-IP Next automation: AS3 basics BIG-IP Next automation: Working with the AS3 endpoints 20.0 Postman collection 20.1 Postman collection 20.2 Postman collection45Views1like0CommentsBIG-IP Next Central Manager API with Python
I've been working with the BIG-IP Next API with curl on the command line and with the Postman GUI app as well. Both useful as I am getting comfortable with the API, but not my favorite tools in the toolbox, which is python. In this episode of DevCentral Connects, I'll share the early stages of a tool I'm building for working with BIG-IP Next in python and walk through some tasks with the BIG-IP Next API.15Views0likes0CommentsBIG-IP Next Central Manager API with Postman
I've been working with the BIG-IP Next API from the API reference and with curl on the command line, and I gotta tell you, as much as I don't love Postman, it's super handy when learning an API. In this episode of DevCentral Connects, I'll download the collection from the Next documentation, get the environment variables set up, and walk through some of the tasks available in the collection to start working with the BIG-IP Next API.14Views0likes0CommentsBIG-IP Next Automation: Working with the AS3 API endpoints
In my last article I covered the basics of AS3 as it relates to getting started with automation with BIG-IP Next. I also walked through an application migration in a previous article that addresses some of the issues you'll need to work through moving to Next, but whereas I touched the AS3 slightly in the workflow, all the work was accomplished in the Central Manager web UI. In this article, I'll walk you through creating two applications, one a simple DNS load balancing application and the other a TLS-protected HTTP application with an associated iRule. For each application, I'll use the compatibility interface and the Next-specific interface for working through the CRUD operations. Creating the declarations You can go about this a few different ways. You can start from the AS3 schema reference and climb up from scratch, you can spin up Visual Studio Code and work with the F5 Extension to interrogate your own BIG-IP configurations and use the AS3 Config Converter to automagically do the work for you, or you can just ask chatGPT to generate the AS3 for you to get started like I did. And after that didn't work without a lot of tweaking...I went back to VSCode. Example 1 - DNS application service declaration Here's what I ended up with for the DNS application service: { "$schema": "https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/master/schema/latest/as3-schema.json", "class": "AS3", "declaration": { "class": "ADC", "schemaVersion": "3.37.0", "id": "urn:uuid:3a71dceb-f56c-4dc1-901a-2feae0244c46", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "Common": { "class": "Tenant", "Shared": { "class": "Application", "template": "shared", "vip.ns-cluster-1": { "layer4": "udp", "pool": "pool.ns-cluster-1", "translateServerAddress": true, "translateServerPort": true, "class": "Service_UDP", "profileUDP": { "bigip": "/Common/udp" }, "virtualAddresses": [ "10.100.100.100" ], "virtualPort": 53, "snat": "auto" }, "pool.ns-cluster-1": { "members": [ { "addressDiscovery": "static", "servicePort": 53, "serverAddresses": [ "10.10.100.101", "10.10.100.102", "10.10.100.103", "10.10.100.104" ], "shareNodes": true } ], "monitors": [ { "bigip": "/Common/udp" } ], "class": "Pool" } } } } } Note that in BIG-IP Next, there isn't an alternative to the AS3 class, so that wrapper for the ADC class declaration is unnecessary and will result in an error if posted. So the only change required at this time is to remove the wrapper, and change common/shared to tenant1/dnsapp1 as shown below. { "class": "ADC", "schemaVersion": "3.37.0", "id": "urn:uuid:3a71dceb-f56c-4dc1-901a-2feae0244c46", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "tenant1": { "class": "Tenant", "dnsapp1": { "class": "Application", "template": "shared", "vip.ns-cluster-1": { "layer4": "udp", "pool": "pool.ns-cluster-1", "translateServerAddress": true, "translateServerPort": true, "class": "Service_UDP", "profileUDP": { "bigip": "/Common/udp" }, "virtualAddresses": [ "10.100.100.100" ], "virtualPort": 53, "snat": "auto" }, "pool.ns-cluster-1": { "members": [ { "addressDiscovery": "static", "servicePort": 53, "serverAddresses": [ "10.10.100.101", "10.10.100.102", "10.10.100.103", "10.10.100.104" ], "shareNodes": true } ], "monitors": [ { "bigip": "/Common/udp" } ], "class": "Pool" } } } } But wait! There's more!Now that I'm channeling my inner Billy Mays, the declaration is not quite ready for Next. After a quick test or five or six, there are some problems with my schema in the move to Next. Here are the necessary changes, followed by the final declaration I'll used with the API endpoints. Swapped out the UDP monitor for ICMP since there is not currently a UDP monitor available Removed the profileUDP, layer4, and translateServerPort attributes from the Service_UDP class { "class": "ADC", "schemaVersion": "3.37.0", "id": "urn:uuid:3a71dceb-f56c-4dc1-901a-2feae0244c46", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "tenant1": { "class": "Tenant", "dnsapp1": { "class": "Application", "template": "shared", "vip.ns-cluster-1": { "pool": "pool.ns-cluster-1", "translateServerAddress": true, "class": "Service_UDP", "virtualAddresses": [ "10.100.100.100" ], "virtualPort": 53, "snat": "auto" }, "pool.ns-cluster-1": { "members": [ { "addressDiscovery": "static", "servicePort": 53, "serverAddresses": [ "10.10.100.101", "10.10.100.102", "10.10.100.103", "10.10.100.104" ], "shareNodes": true } ], "monitors": [ "icmp" ], "class": "Pool" } } } } Example 2 - TLS-protected HTTP application service with iRule declaration And here's the HTTP application service as converted in VSCode but without the AS3 class wrapper: { "class": "ADC", "schemaVersion": "3.37.0", "id": "urn:uuid:bd9c9728-8c20-4c4d-a625-68450e35e133", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "Common": { "class": "Tenant", "Shared": { "class": "Application", "template": "shared", "vip.acme_labs": { "layer4": "tcp", "pool": "pool.acme_labs", "iRules": [ { "use": "/Common/Shared/full_uri_decode" } ], "translateServerAddress": true, "translateServerPort": true, "class": "Service_HTTPS", "serverTLS": "/Common/Shared/cssl.acme_labs", "profileHTTP": { "bigip": "/Common/http" }, "profileTCP": { "bigip": "/Common/tcp" }, "redirect80": false, "virtualAddresses": [ "172.16.101.133" ], "virtualPort": 443, "snat": "auto" }, "pool.acme_labs": { "loadBalancingMode": "least-connections-member", "members": [ { "addressDiscovery": "static", "servicePort": 80, "serverAddresses": [ "172.16.102.5" ], "shareNodes": true } ], "monitors": [ { "bigip": "/Common/http" } ], "class": "Pool" }, "www.acmelabs.com": { "class": "Certificate", "certificate": { "bigip": "/Common/www.acmelabs.com" }, "privateKey": { "bigip": "/Common/www.acmelabs.com" } }, "cssl.acme_labs": { "certificates": [ { "certificate": "/Common/Shared/www.acmelabs.com" } ], "class": "TLS_Server", "tls1_0Enabled": true, "tls1_1Enabled": true, "tls1_2Enabled": true, "tls1_3Enabled": false, "singleUseDhEnabled": false, "insertEmptyFragmentsEnabled": true }, "full_uri_decode": { "class": "iRule", "iRule": { "base64": "d2hlbiBIVFRQX1JFUVVFU1QgewogICMgZGVjb2RlIG9yaWdpbmFsIFVSSS4KICBzZXQgdG1wVXJpIFtIVFRQOjp1cmldCiAgc2V0IHVyaSBbVVJJOjpkZWNvZGUgJHRtcFVyaV0KICAjIHJlcGVhdCBkZWNvZGluZyB1bnRpbCB0aGUgZGVjb2RlZCB2ZXJzaW9uIGVxdWFscyB0aGUgcHJldmlvdXMgdmFsdWUuCiAgd2hpbGUgeyAkdXJpIG5lICR0bXBVcmkgfSB7CiAgICBzZXQgdG1wVXJpICR1cmkKICAgIHNldCB1cmkgW1VSSTo6ZGVjb2RlICR0bXBVcmldCiAgfQogIEhUVFA6OnVyaSAkdXJpCiAgbG9nIGxvY2FsMC4gIk9yaWdpbmFsIFVSSTogW0hUVFA6OnVyaV0iCiAgbG9nIGxvY2FsMC4gIkZ1bGx5IGRlY29kZWQgVVJJOiAkdXJpIgp9" } } } } } This is mostly ok with the exception of the certificate handling in lines 56-70. If I was posting this back to my local BIG-IP in place of the imperative configuration it'd be fine. But Central Manager has no context for where those certificates are so I'll need to do a little work here to prep the declaration. I need to drop the certificate and key into the Certificate class (your security-sense should be tingling, remember these are private keys so in your environment you'd be pulling these credentials in from a vault and NOT storing these in a file) and then updating the reference to the local object in the TLS_Server class. NOTE: It might be confusing for long-time BIG-IP users, but the TLS_Server class in AS3 is the equivalent of a client-ssl profile, and the TLS_CLIENT class in AS3 is the equivalent of a server-ssl profile. This change was made in AS3 to align more with industry-standard nomenclature. After these changes, and changes to Common/Shared, the updated declaration is shown below. { "class": "ADC", "schemaVersion": "3.37.0", "id": "urn:uuid:bd9c9728-8c20-4c4d-a625-68450e35e133", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "tenant2": { "class": "Tenant", "httpsapp1": { "class": "Application", "template": "shared", "vip.acme_labs": { "layer4": "tcp", "pool": "pool.acme_labs", "iRules": [ { "use": "/Common/Shared/full_uri_decode" } ], "translateServerAddress": true, "translateServerPort": true, "class": "Service_HTTPS", "serverTLS": "/Common/Shared/cssl.acme_labs", "profileHTTP": { "bigip": "/Common/http" }, "profileTCP": { "bigip": "/Common/tcp" }, "redirect80": false, "virtualAddresses": [ "172.16.101.133" ], "virtualPort": 443, "snat": "auto" }, "pool.acme_labs": { "loadBalancingMode": "least-connections-member", "members": [ { "addressDiscovery": "static", "servicePort": 80, "serverAddresses": [ "172.16.102.5" ], "shareNodes": true } ], "monitors": [ { "bigip": "/Common/http" } ], "class": "Pool" }, "www.acmelabs.com": { "class": "Certificate", "certificate": "-----BEGIN CERTIFICATE-----\nMIIHQTCCBimgAwIBAgIQFxO0vIztEEcAAAAAUQF6LjANBgkqhkiG9w0BAQsFADCBujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEwxSzAeFw0yMDAzMjYyMTExNTZaFw0yMjAzMTQyMTQxNTVaMGoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRowGAYDVQQKExFGNSBOZXR3b3JrcywgSW5jLjEYMBYGA1UEAwwPKi5lbWVhLmY1c2UuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt6FDfpu8jBbE8dew0m5t2ax/p6LE0mI0BMJIZA1TxglDvQjgVethDPWp7rTr655ZNuYUZ4p/QV/Uummo0NxhE4VQyIK1tcKnGs/tX2BVmx/augrcqOpGwZKAeKsRDxB8UBS/BmovlQQgRqBym3lg7AewI20BwtSvrCSviGmByBPW7cjOFoe8n706XZvEDFiZgj/OuV2V1giCzqqKUJ5mLAqSh25465IVcTJQxKkok668rHOgpUO2GDav7cnrtLm71Oxv6m64gcQJ+e2xzaxa0/OfykuXn4W84RFKwm6im3lAbgNI+CwCjTNtXXs88TxMG49GuTol9ddeS+4aF9GvCQIDAQABo4IDkDCCA4wwKQYDVR0RBCIwIIIPKi5lbWVhLmY1c2UuY29tgg1lbWVhLmY1c2UuY29tMIIB9wYKKwYBBAHWeQIEAgSCAecEggHjAeEAdwBVgdTCFpA2AUrqC5tXPFPwwOQ4eHAlCBcvo6odBxPTDAAAAXEYy223AAAEAwBIMEYCIQDAvv+hvpE9l0BnPH3ouvKJOyTTrLNRK6qZiHrEm9G3iAIhAIlqyaByyF2OHUAqNnfk7DalviCjaHPzqEmYnsrMIXV9AHYAh3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8AAAFxGMttuQAABAMARzBFAiEAnH87ThX2oxA89e1wDaslF8zZrbu/OG8Jx3I7zqVAtkACIB90UYajoUjMoqTP36sb/tU6N776FNsflbScLedtiqPSAHcAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFxGMtt3wAABAMASDBGAiEAh6gVTPW97krycFbcH9OcLu/lTRSkfeCbMqUYBXlCtKICIQCmGMSIJNZYFIM3mTD0hb2VDGOMCjHkAE5hiJ5VuLEgswB1ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAABcRjLbbQAAAQDAEYwRAIgdBV5qHR7nM97nmvdlSK3QLcsq+cr6qd+xns+9Wbv1pcCIBMdw4C5iEMKpwdyLRDR86jQC2v8op/klavXFfYGZ9QyMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5lbnRydXN0Lm5ldC9sZXZlbDFrLmNybDBLBgNVHSAERDBCMDYGCmCGSAGG+mwKAQUwKDAmBggrBgEFBQcCARYaaHR0cDovL3d3dy5lbnRydXN0Lm5ldC9ycGEwCAYGZ4EMAQICMGgGCCsGAQUFBwEBBFwwWjAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMwYIKwYBBQUHMAKGJ2h0dHA6Ly9haWEuZW50cnVzdC5uZXQvbDFrLWNoYWluMjU2LmNlcjAfBgNVHSMEGDAWgBSConB03bxTP8971PfNf6dgxgpMvzAdBgNVHQ4EFgQUaEk3Dl8YuTsNPJ0vhVIKTKZfnNIwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAD8DmFFgnU2veCzDyeoF12bbZfF9oA3nOTY7z2WjYy7/5hyKg6FXKwkXVji13g6RNFVQ03mqcXTN8/AhnHz7dnhWF39WhdH08suWLQrmIT2dPBKTF1aQcURIpOddemsZMx6NCFjgcAHLcK/nPDPsfMXq5tRXInjPyGd38TooIeAfGGPiTrgL3UU8ByQPxriOf4V5i66BOWH8wDViPBeXaDSdgcXhrDXAAt/nArVmI7orK+t/0iCzoeg9pGH39+/G1VansfbTcBbKnqVCxDplUiCXLlD17mN45n9estajf4tnpiXkqBIC14o742HAeqpV9T9wzUbJFo5BWMtpHtPZu2A==\n-----END CERTIFICATE-----", "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAt6FDfpu8jBbE8dew0m5t2ax/p6LE0mI0BMJIZA1TxglDvQjgVethDPWp7rTr655ZNuYUZ4p/QV/Uummo0NxhE4VQyIK1tcKnGs/tX2BVmx/augrcqOpGwZKAeKsRDxB8UBS/BmovlQQgRqBym3lg7AewI20BwtSvrCSviGmByBPW7cjOFoe8n706XZvEDFiZgj/OuV2V1giCzqqKUJ5mLAqSh25465IVcTJQxKkok668rHOgpUO2GDav7cnrtLm71Oxv6m64gcQJ+e2xzaxa0/OfykuXn4W84RFKwm6im3lAbgNI+CwCjTNtXXs88TxMG49GuTol9ddeS+4aF9GvCQIDAQABAoIBAGeJbdz9QppaXEFgNDryOM37DR8gD4nwBRSJ1vdS7GFE6AS19Id9aAM+oMoPCNaZOgRSRj77QDVEK1XQLXdWSwYOrTXhPUN2tXHQuy6DysDkfRdY+IHlVm/egsGG8t9jlDQy/mJHjPygjvJDlVtEXPm4e//9fni0IzkUlkR7+MkuMT3vvKGYnUNTlI1hJokcNJ75r91O82j+qQsmvJG3FOUn0DpnEBgIvEbFvD3wMHY1K/fTUsBVJMKkjjXmjykGB9y7V4oKHQLsxH+lrUneWdD/s23hoVgAV31YeXtf7mI/eWPJt6DiGwTfaNcNcptvwugsR/7jCWaKS9Hya/qbJuECgYEA6wNm2doCmwl6ksbKSik0VgVha7DN3VjoFTDFcYZNfjB/kr6/xSODbAxJMwQdevFj2eWQxeHZnJc96x2xWzCA3mp1BhNzcfT8XRZ4LMcLUpcl1VXUEVc562vL8AdVuSODDc/rBXP/aFSXGdE+ZSPhYBrNlnK1FY10aaGsrEaRxL8CgYEAyAcyKVKY+wpdweiVXsUHIHAwQUmi8pKd1j5KlCjJkn2Wtiqex0v1eDy2/iKrZDWRiRFE4WOIb7A9GYm7FfqDyn9WvVNI0bz8Ywi+bCTdawGZ8H328q3R4/xIPprGmKV6olQHHUGZUNkLTK+cDHK4w9JRSf9kB6PUgGnBTgZoFjcCgYB/E2bQ03ZnOLfjl8QYV7Fp9hzYa1DVqFZN5wJMQW+zlSvWQHhXc72Ddh06jbYXHWF9mAkxRs8xQgKEGJknEtIL8gp3D5tz+iFfgF/Y7oPr07jsYy15du3lo3MxxfWPV2ls1YlieHeZhWvy1NblP4KFQdj6yemqzsMsvvQsbzgw5wKBgQCASZ0yQ3c6Cnv3UWP7VAIuG8XXGZMYYFA6h9jtDPu6qDFwxATxbRYR916lvzaNHo4oiprSszNd7npBVsRWZEUCKolHA5NAcSStn34BfeNELdK9Gwy2uCRVRAhRnpKgdAEi+yFU8i2SXKGSnU5H7Yvyi4D3JITTIY+4jBseH53CIQKBgByjoPYp+eMXpUmg4W5M1irXGm8sjrRBKvnxu9L+etvajWIb+AUAtoNoQmcKpf8bBK84PdCwiDSQmRDbWieT9RsSqbyWOcQf2C2L0qujUb+bM+kSTYp4oAV/rukoZ46NHjYBE3NbI7HcspWbpu5zl0Ke9pLvDwFwrmRy5KM7EiSh\n-----END RSA PRIVATE KEY-----" }, "cssl.acme_labs": { "certificates": [ { "certificate": "www.acmelabs.com" } ], "class": "TLS_Server", "tls1_0Enabled": true, "tls1_1Enabled": true, "tls1_2Enabled": true, "tls1_3Enabled": false, "singleUseDhEnabled": false, "insertEmptyFragmentsEnabled": true }, "full_uri_decode": { "class": "iRule", "iRule": { "base64": "d2hlbiBIVFRQX1JFUVVFU1QgewogICMgZGVjb2RlIG9yaWdpbmFsIFVSSS4KICBzZXQgdG1wVXJpIFtIVFRQOjp1cmldCiAgc2V0IHVyaSBbVVJJOjpkZWNvZGUgJHRtcFVyaV0KICAjIHJlcGVhdCBkZWNvZGluZyB1bnRpbCB0aGUgZGVjb2RlZCB2ZXJzaW9uIGVxdWFscyB0aGUgcHJldmlvdXMgdmFsdWUuCiAgd2hpbGUgeyAkdXJpIG5lICR0bXBVcmkgfSB7CiAgICBzZXQgdG1wVXJpICR1cmkKICAgIHNldCB1cmkgW1VSSTo6ZGVjb2RlICR0bXBVcmldCiAgfQogIEhUVFA6OnVyaSAkdXJpCiAgbG9nIGxvY2FsMC4gIk9yaWdpbmFsIFVSSTogW0hUVFA6OnVyaV0iCiAgbG9nIGxvY2FsMC4gIkZ1bGx5IGRlY29kZWQgVVJJOiAkdXJpIgp9" } } } } } I didn't mention it above, but you'll notice that the iRule is base64 encoded. The conversion to AS3 in VSCode did that automatically. You can do the same for the certificate and privateKey attributes as well if you want, but that'll need the base64 attribute within the curly brackets like the iRule. Billy Mays here again...buy 1, get another free!Like the DNS app, there are a few things native to classic in this declaration that aren't supported in Next, so we need to make a few more changes after a few tests: I removed profileHTTP and profileTCP attributes from the Service_HTTPS class. These are allowed, but since I am not setting anything non-default, I don't need them. As is, they were not acceptable referencing bigip classic profiles Removed layer4 and translateServerPort attributes from the Service_HTTPS class as they are not currently supported in Next Removed tls1_Enabled, singleUseDhEnabled, and insertEmptyFragmentsEnabled attributes from TLS_Server class as they are not currently supported in Next. Added the ciphers attribute with RSA value to the TLS_Server class. The instance would not accept the deployment without this, I got an expired or invalid certificate error without it. Changed the iRules refererence in the Service_HTTPS class from a classic BIG-IP object to a local declaration object. These final changes resulted in the following declaration I'll use with the API endpoints: { "class": "ADC", "schemaVersion": "3.37.0", "id": "urn:uuid:bd9c9728-8c20-4c4d-a625-68450e35e133", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "tenant2": { "class": "Tenant", "httpsapp1": { "class": "Application", "template": "shared", "vip.acme_labs": { "pool": "pool.acme_labs", "iRules": [ "full_uri_decode" ], "translateServerAddress": true, "class": "Service_HTTPS", "serverTLS": "cssl.acme_labs", "redirect80": false, "virtualAddresses": [ "172.16.101.133" ], "virtualPort": 443, "snat": "auto" }, "pool.acme_labs": { "loadBalancingMode": "least-connections-member", "members": [ { "addressDiscovery": "static", "servicePort": 80, "serverAddresses": [ "172.16.102.5" ], "shareNodes": true } ], "monitors": [ "http" ], "class": "Pool" }, "www.acmelabs.com": { "class": "Certificate", "certificate": "-----BEGIN CERTIFICATE-----\nMIIC3DCCAcSgAwIBAgIGAZAW7PncMA0GCSqGSIb3DQEBDQUAMC8xCzAJBgNVBAYTAlVTMSAwHgYDVQQDExdteXNlbGZzaWduZWQudGVzdC5sb2NhbDAeFw0yNDA2MTQxMzI1NDdaFw0zNDA2MTIxMzI1NDdaMC8xCzAJBgNVBAYTAlVTMSAwHgYDVQQDExdteXNlbGZzaWduZWQudGVzdC5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMYpeRm4f1mPgW7STMM4gZXZ5p02nCWshNwVkaOLpRJAOdR2ZpuhLW4tWpAssvmTRlS0cFjZKA6ecVg4Q7+wvw7dIG8gVAviOqmHb6sDaomBTn3+ISFYW0Uxb1GNvZqlktJQI7hCsaS5Kf/f4pImVa8jQffWTdgLwxCm+0suaXy1XykVOCdOs1lsCOHjMoVREWxLIAtzMpqdO+8IRhSJgPJPf3GnY861T0LDjuT5rgwY1qK/H2NuEcPWOWVtqTN9aQAz9cKxDbJq48U8adzrl6G8uUYlEPEtneePErygy8wRk8KkVNkuDj5gQKxi3b3Q8/K7bPhh9aUnZRQWmhVTw2kCAwEAATANBgkqhkiG9w0BAQ0FAAOCAQEAOh3doWxnjb5j5XojnEtYUWJG6yw9a3xZhEiq7myWz7apmy5eAe0QAL9kFAuiBwgjqwzPCXzMDp21FdLC+o9Znx5A8kXE2W2G+h36kc21f3v0jumRdkU1zZ9py9iKHAOUSAYsALNWH4mosFFbodpqcFZL7Fqmh/AoIcqY3GqSWOZ6geYbMIOwTZFnsuE1LTjJrnypz1ZyglGoftzU9j501aq3eJ3YUyRIZ28/ARJxn4sUfdvjvs31EdFEOOC6hwN2U7JXdWWK/fATTenglSkUqChJRW6kRL7uFf6FCCZjXyGINJnOYVz+8gxDWA557+ogYfEquQVML5gvMK9Ff67W6A==\n-----END CERTIFICATE-----", "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAxil5Gbh/WY+BbtJMwziBldnmnTacJayE3BWRo4ulEkA51HZmm6Etbi1akCyy+ZNGVLRwWNkoDp5xWDhDv7C/Dt0gbyBUC+I6qYdvqwNqiYFOff4hIVhbRTFvUY29mqWS0lAjuEKxpLkp/9/ikiZVryNB99ZN2AvDEKb7Sy5pfLVfKRU4J06zWWwI4eMyhVERbEsgC3Mymp077whGFImA8k9/cadjzrVPQsOO5PmuDBjWor8fY24Rw9Y5ZW2pM31pADP1wrENsmrjxTxp3OuXoby5RiUQ8S2d548SvKDLzBGTwqRU2S4OPmBArGLdvdDz8rts+GH1pSdlFBaaFVPDaQIDAQABAoIBAEUsIv7MfX/o7TifJnabGfkSOEM21ej8wOAGk3EwhO3LB6TXs9etuqsUH+HmCI/ATjOxTOpm22nG+y/dbCDU9MyeefzwnwYK8YlOIrfimGTpg1nNxQjby/hqWj5wqPf7xjWuDdn7RgGHNVcBcxirUwuw1g1KfJ/m8y+z6lKDIAWMuPegPFgQy0UoJmE5gjtdNYuRrPKESfjdgYhbmzl75k2zqm35Ngwgvp6YYq1jeGpDb4lDBDvn9KdpScC1y9w++7k4n1AyMZXsfgn3oSiFp9G6rZNraykOPYkQu309DVBqYtW0DHSU/xDYh1MTwJEwhcISYu12s2PIDGv/prgMRwUCgYEA7SdaqLT0B/btPkO84gnRx40rgsSM8gPewiVHerc95/tR6tCdMg1eNGJEK+biZMR/oxLQ3Ajr14BE3O8Dxhcqx/5vdo5qrX2oytDkl87oObK5rL0kdlmg/SQdnCsG/GkGtZlXLdMmjibSglGn23E69bsS0+IHspZnT2KHb1v1OZcCgYEA1ejfdHxmyOe+ke9QYn0umLLI/u6vDm6qkzEJrmzkpjrQrwftYRBeSr7CRJdRWtQ6dKA6kGZEfumFMg0ptFtwDGuLnzXek8UC3gKXjDnHyTugTXLprgB3A1AUYy0jvxmMTY8/AZLmDnqXma1WFnyxIUrTbzQq6uJPD4b33cWciv8CgYEAumnT1ocex1/uzqG6SEeFsYEjMZBEZjxqjlt1W13MeJxRoO1Ikz50zWJsycGcNa9L0SiKKluM3wGBn9T1N3GgfEJg5WU/L4517q7S8Q1/91KopsKqdakwZatM5yPfQutfjcGyCGBQjy6vDCcZdeIEgYICY7DpchTNslX1tbAoC5MCgYA9f9hOyz1Z4Zbeqik4R7lP2YcEFGdsBNExxFV+Onx6dkptKCBNWcFiR/necorHTGEKCs8LmPt0aXsL6tDks61BROI9geVeIrQyVBhyDmKsLmJmIfWhOyz8XNefs+ilFplJ6zc4Ip3V59USL82iZXMfmT20qRD1ut70Hd/BeQEKzQKBgQCoiTGlal7FaOHZmjvPOc6lzvOC2RIZL3yT5U1r9XsMFC2pPU/YinTc0cEpMmbeqLKuINjKOYyVp8HZEdpB6atU/WYDT2INe7VaphWpHkd5F56plzo0hlTDr1eFlHBsj23MVFR/UvpL0PeGzfnBd7ga2s0ymWDDnIhMJKzwu5GvDw==\n-----END RSA PRIVATE KEY-----" }, "cssl.acme_labs": { "certificates": [ { "certificate": "www.acmelabs.com" } ], "ciphers": "RSA", "class": "TLS_Server", "tls1_1Enabled": true, "tls1_2Enabled": true, "tls1_3Enabled": false }, "full_uri_decode": { "class": "iRule", "iRule": { "base64": "d2hlbiBIVFRQX1JFUVVFU1QgewogICMgZGVjb2RlIG9yaWdpbmFsIFVSSS4KICBzZXQgdG1wVXJpIFtIVFRQOjp1cmldCiAgc2V0IHVyaSBbVVJJOjpkZWNvZGUgJHRtcFVyaV0KICAjIHJlcGVhdCBkZWNvZGluZyB1bnRpbCB0aGUgZGVjb2RlZCB2ZXJzaW9uIGVxdWFscyB0aGUgcHJldmlvdXMgdmFsdWUuCiAgd2hpbGUgeyAkdXJpIG5lICR0bXBVcmkgfSB7CiAgICBzZXQgdG1wVXJpICR1cmkKICAgIHNldCB1cmkgW1VSSTo6ZGVjb2RlICR0bXBVcmldCiAgfQogIEhUVFA6OnVyaSAkdXJpCiAgbG9nIGxvY2FsMC4gIk9yaWdpbmFsIFVSSTogW0hUVFA6OnVyaV0iCiAgbG9nIGxvY2FsMC4gIkZ1bGx5IGRlY29kZWQgVVJJOiAkdXJpIgp9" } } } } } OK, we have our declarations handy, now we can move on to working this the API endpoints! CRUD operations We sure love our acronyms in tech, don't we? CRUD stands for create, read, update, and delete. These are the most common operations for interacting with an API. (If you've used the iControl REST interface before on classic BIG-IP, you know that we need to perform additional operations like running commands (load, save, run, etc), so that needed to be folded in somehow to the CRUD model. We'll address those use cases in future articles.) Before we can use the API endpoints, however, we need to be authenticated to the Central Manager. This requires a login request that returns a bearer token to be used in subsequent requests. I wrote a short bash script to get the token which I set to a local variable in my shell. First, the script: #!/bin/zsh token=$(curl -ks --location 'https://172.16.31.105/api/login' \ --header 'Content-Type: application/json' \ --data '{ "username": "admin", "password": "notsofastmyfriend" }' | jq -r '.access_token') echo $token Next, setting the token variable for use in future commands: jrahm@mymac as3testing % token=$(./gt.sh) jrahm@mymac as3testing % echo $token D1RrEpn1RCHpm5FrGCIiXrwu3coSO8vWGT8e8kHLd2QbeUUiGAgw6pFb1B2l2bHeG7KsrqiipfuNGbx/DaCyUDQ0niaDiQizHIj6w7xOIWLNd5e/Bz2emGskM959E7CnMRTV36qPpu0SLDJsdvThZf6wLvm9oe5cX25Uqzf2/6Y+eNxDLs2WjsA4IFFRO2QWkjrq807kxJIoIX8BvICSxyjlx7PEQkWBAdUV7z6zayX03FtA3lqR66dzzMtIr9L7na+T7/i5cqSETGYQYt1z4a996oA/jMcAEy5J6PsuinCdN3ZZNt5Bfi4ck/5/bA3RJEZR8niU5u77DGasckdcUlRjl0/8UOgmEq19BRopAGFCXvRyiX/g6CVR6NDNG5dlmVjVcJ2+IzYJ8utGfr7raKMIgDIEn/G1AVqy0kj+x2ANdHpo0PQG678JoXChHObiDwjcOMrUiW2cC/YMLp36lcBEgp0uySokSwwYBTJjLJezFE74I+x154yDIWYD0+I8xbIqAHA4a3IxMljR14wowIJp84SxfeuJcrcUAZESzw== Now that I don't have to worry about re-upping on my token while working with curl at the command line, let's work through each of these CRUD operations in order. Application service create operation The create operation is accomplished with an HTTP POST method. As we are creating an object, we need to send some data along with that. That data in our case is the AS3 declaration. I put each declaration in a file Compatibility interface It's a single request to deploy the workload with the compatibility interface to the /api/v1/spaces/default/appsvcs/declare endpoint with a target_address of the instances as a query parameter. Interestingly, the successful declaration is returned to you in its entirety in the response. DNS App jrahm@mymac as3testing % curl -sk \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d "@dns-app.json" \ --location 'https://172.16.2.105/api/v1/spaces/default/appsvcs/declare?target_address=172.16.2.161' | jq . { "declaration": { "class": "ADC", "id": "urn:uuid:3a71dceb-f56c-4dc1-901a-2feae0244c46", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "schemaVersion": "3.37.0", "tenant1": { "class": "Tenant", "dnsapp1": { "class": "Application", "pool.ns-cluster-1": { "class": "Pool", "members": [ { "addressDiscovery": "static", "serverAddresses": [ "10.10.100.101", "10.10.100.102", "10.10.100.103", "10.10.100.104" ], "servicePort": 53, "shareNodes": true } ], "monitors": [ "icmp" ] }, "template": "shared", "vip.ns-cluster-1": { "class": "Service_UDP", "pool": "pool.ns-cluster-1", "snat": "auto", "translateServerAddress": true, "virtualAddresses": [ "10.100.100.100" ], "virtualPort": 53 } } } }, "results": [ { "code": 200, "host": "172.16.2.161", "message": "success", "runTime": 1948, "tenant": "tenant1" } ] } HTTPS App jrahm@mymac as3testing % curl -sk \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d "@https-app.json" \ --location 'https://172.16.2.105/api/v1/spaces/default/appsvcs/declare?target_address=172.16.2.161' | jq . { "declaration": { "class": "ADC", "id": "urn:uuid:bd9c9728-8c20-4c4d-a625-68450e35e133", "label": "Converted Declaration", "remark": "Generated by Automation Config Converter", "schemaVersion": "3.37.0", "tenant2": { "class": "Tenant", "httpsapp1": { "class": "Application", "cssl.acme_labs": { "certificates": [ { "certificate": "www.acmelabs.com" } ], "ciphers": "RSA", "class": "TLS_Server", "tls1_1Enabled": true, "tls1_2Enabled": true, "tls1_3Enabled": false }, "full_uri_decode": { "class": "iRule", "iRule": { "base64": "d2hlbiBIVFRQX1JFUVVFU1QgewogICMgZGVjb2RlIG9yaWdpbmFsIFVSSS4KICBzZXQgdG1wVXJpIFtIVFRQOjp1cmldCiAgc2V0IHVyaSBbVVJJOjpkZWNvZGUgJHRtcFVyaV0KICAjIHJlcGVhdCBkZWNvZGluZyB1bnRpbCB0aGUgZGVjb2RlZCB2ZXJzaW9uIGVxdWFscyB0aGUgcHJldmlvdXMgdmFsdWUuCiAgd2hpbGUgeyAkdXJpIG5lICR0bXBVcmkgfSB7CiAgICBzZXQgdG1wVXJpICR1cmkKICAgIHNldCB1cmkgW1VSSTo6ZGVjb2RlICR0bXBVcmldCiAgfQogIEhUVFA6OnVyaSAkdXJpCiAgbG9nIGxvY2FsMC4gIk9yaWdpbmFsIFVSSTogW0hUVFA6OnVyaV0iCiAgbG9nIGxvY2FsMC4gIkZ1bGx5IGRlY29kZWQgVVJJOiAkdXJpIgp9" } }, "pool.acme_labs": { "class": "Pool", "loadBalancingMode": "least-connections-member", "members": [ { "addressDiscovery": "static", "serverAddresses": [ "172.16.102.5" ], "servicePort": 80, "shareNodes": true } ], "monitors": [ "http" ] }, "template": "shared", "vip.acme_labs": { "class": "Service_HTTPS", "iRules": [ "full_uri_decode" ], "pool": "pool.acme_labs", "redirect80": false, "serverTLS": "cssl.acme_labs", "snat": "auto", "translateServerAddress": true, "virtualAddresses": [ "172.16.101.133" ], "virtualPort": 443 }, "www.acmelabs.com": { "certificate": "-----BEGIN CERTIFICATE-----\nMIIC3DCCAcSgAwIBAgIGAZAW7PncMA0GCSqGSIb3DQEBDQUAMC8xCzAJBgNVBAYTAlVTMSAwHgYDVQQDExdteXNlbGZzaWduZWQudGVzdC5sb2NhbDAeFw0yNDA2MTQxMzI1NDdaFw0zNDA2MTIxMzI1NDdaMC8xCzAJBgNVBAYTAlVTMSAwHgYDVQQDExdteXNlbGZzaWduZWQudGVzdC5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMYpeRm4f1mPgW7STMM4gZXZ5p02nCWshNwVkaOLpRJAOdR2ZpuhLW4tWpAssvmTRlS0cFjZKA6ecVg4Q7+wvw7dIG8gVAviOqmHb6sDaomBTn3+ISFYW0Uxb1GNvZqlktJQI7hCsaS5Kf/f4pImVa8jQffWTdgLwxCm+0suaXy1XykVOCdOs1lsCOHjMoVREWxLIAtzMpqdO+8IRhSJgPJPf3GnY861T0LDjuT5rgwY1qK/H2NuEcPWOWVtqTN9aQAz9cKxDbJq48U8adzrl6G8uUYlEPEtneePErygy8wRk8KkVNkuDj5gQKxi3b3Q8/K7bPhh9aUnZRQWmhVTw2kCAwEAATANBgkqhkiG9w0BAQ0FAAOCAQEAOh3doWxnjb5j5XojnEtYUWJG6yw9a3xZhEiq7myWz7apmy5eAe0QAL9kFAuiBwgjqwzPCXzMDp21FdLC+o9Znx5A8kXE2W2G+h36kc21f3v0jumRdkU1zZ9py9iKHAOUSAYsALNWH4mosFFbodpqcFZL7Fqmh/AoIcqY3GqSWOZ6geYbMIOwTZFnsuE1LTjJrnypz1ZyglGoftzU9j501aq3eJ3YUyRIZ28/ARJxn4sUfdvjvs31EdFEOOC6hwN2U7JXdWWK/fATTenglSkUqChJRW6kRL7uFf6FCCZjXyGINJnOYVz+8gxDWA557+ogYfEquQVML5gvMK9Ff67W6A==\n-----END CERTIFICATE-----", "class": "Certificate", "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAxil5Gbh/WY+BbtJMwziBldnmnTacJayE3BWRo4ulEkA51HZmm6Etbi1akCyy+ZNGVLRwWNkoDp5xWDhDv7C/Dt0gbyBUC+I6qYdvqwNqiYFOff4hIVhbRTFvUY29mqWS0lAjuEKxpLkp/9/ikiZVryNB99ZN2AvDEKb7Sy5pfLVfKRU4J06zWWwI4eMyhVERbEsgC3Mymp077whGFImA8k9/cadjzrVPQsOO5PmuDBjWor8fY24Rw9Y5ZW2pM31pADP1wrENsmrjxTxp3OuXoby5RiUQ8S2d548SvKDLzBGTwqRU2S4OPmBArGLdvdDz8rts+GH1pSdlFBaaFVPDaQIDAQABAoIBAEUsIv7MfX/o7TifJnabGfkSOEM21ej8wOAGk3EwhO3LB6TXs9etuqsUH+HmCI/ATjOxTOpm22nG+y/dbCDU9MyeefzwnwYK8YlOIrfimGTpg1nNxQjby/hqWj5wqPf7xjWuDdn7RgGHNVcBcxirUwuw1g1KfJ/m8y+z6lKDIAWMuPegPFgQy0UoJmE5gjtdNYuRrPKESfjdgYhbmzl75k2zqm35Ngwgvp6YYq1jeGpDb4lDBDvn9KdpScC1y9w++7k4n1AyMZXsfgn3oSiFp9G6rZNraykOPYkQu309DVBqYtW0DHSU/xDYh1MTwJEwhcISYu12s2PIDGv/prgMRwUCgYEA7SdaqLT0B/btPkO84gnRx40rgsSM8gPewiVHerc95/tR6tCdMg1eNGJEK+biZMR/oxLQ3Ajr14BE3O8Dxhcqx/5vdo5qrX2oytDkl87oObK5rL0kdlmg/SQdnCsG/GkGtZlXLdMmjibSglGn23E69bsS0+IHspZnT2KHb1v1OZcCgYEA1ejfdHxmyOe+ke9QYn0umLLI/u6vDm6qkzEJrmzkpjrQrwftYRBeSr7CRJdRWtQ6dKA6kGZEfumFMg0ptFtwDGuLnzXek8UC3gKXjDnHyTugTXLprgB3A1AUYy0jvxmMTY8/AZLmDnqXma1WFnyxIUrTbzQq6uJPD4b33cWciv8CgYEAumnT1ocex1/uzqG6SEeFsYEjMZBEZjxqjlt1W13MeJxRoO1Ikz50zWJsycGcNa9L0SiKKluM3wGBn9T1N3GgfEJg5WU/L4517q7S8Q1/91KopsKqdakwZatM5yPfQutfjcGyCGBQjy6vDCcZdeIEgYICY7DpchTNslX1tbAoC5MCgYA9f9hOyz1Z4Zbeqik4R7lP2YcEFGdsBNExxFV+Onx6dkptKCBNWcFiR/necorHTGEKCs8LmPt0aXsL6tDks61BROI9geVeIrQyVBhyDmKsLmJmIfWhOyz8XNefs+ilFplJ6zc4Ip3V59USL82iZXMfmT20qRD1ut70Hd/BeQEKzQKBgQCoiTGlal7FaOHZmjvPOc6lzvOC2RIZL3yT5U1r9XsMFC2pPU/YinTc0cEpMmbeqLKuINjKOYyVp8HZEdpB6atU/WYDT2INe7VaphWpHkd5F56plzo0hlTDr1eFlHBsj23MVFR/UvpL0PeGzfnBd7ga2s0ymWDDnIhMJKzwu5GvDw==\n-----END RSA PRIVATE KEY-----" } } } }, "results": [ { "code": 200, "host": "172.16.2.161", "message": "success", "runTime": 1950, "tenant": "tenant2" } ] } Next-specific interface With this approach, you send the document first with the /api/v1/spaces/default/appsvcs/documents endpoint and then deploy with the /api/v1/spaces/default/appsvcs/documents/<id>/deployments endpoint. The document and deployment each have their own object ID, and then the deployment also has a task ID that can be referenced in the logs. DNS App jrahm@mymac as3testing % curl -skX POST \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d "@dns-app.json" \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents | jq . { "Message": "Application service created successfully", "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3" } }, "id": "d5d0a360-75ec-434c-9802-62083a26c4d3" } jrahm@mymac as3testing % curl -skX POST \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d '{"target": "172.16.2.161"}' \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3/deployments | jq . { "Message": "Deployment task created successfully", "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3/deployments" } }, "id": "ed48899b-fcb0-4a60-b8f2-2c0e012aa28d", "task_id": "771beda9-5ca4-4049-bebc-97b9d52da524" } HTTPS App jrahm@mymac as3testing % curl -skX POST \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d "@https-app.json" \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents | jq . { "Message": "Application service created successfully", "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/3102ce15-e3d4-498f-a466-60f4bf02c2ab" } }, "id": "3102ce15-e3d4-498f-a466-60f4bf02c2ab" } jrahm@mymac as3testing % curl -skX POST \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d '{"target": "172.16.2.161"}' \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents/3102ce15-e3d4-498f-a466-60f4bf02c2ab/deployments | jq . { "Message": "Deployment task created successfully", "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/3102ce15-e3d4-498f-a466-60f4bf02c2ab/deployments" } }, "id": "400e2b06-b451-4035-a26b-beaf90b283a5", "task_id": "f529800a-f515-4bec-9cfe-1f3214dec229" } Central Manager view of API-deployed apps This is the result in Central Manager after deploying the two applications via the two different methodologies. Notice the different naming scheme applied to each approach. Application service read operation The read operation is accomplished with an HTTP GET method. No payload is necessary on the request. Compatibility interface Note here that both the DNS and HTTP apps will be returned, and for that matter, both could have been deployed together as well! Also note that this is for apps on the targeted instance only, however. The AS3 deployments follow the curl command options. jrahm@mymac as3testing % curl -sk \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ "https://172.16.2.105/api/v1/spaces/default/appsvcs/declare?target_address=172.16.2.161" | jq . { "class": "ADC", "controls": null, "schemaVersion": "3.0.0", "target": { "address": "172.16.2.161" }, "tenant1": { "class": "Tenant", "dnsapp1": { "class": "Application", "pool.ns-cluster-1": { "class": "Pool", "members": [ { "addressDiscovery": "static", "serverAddresses": [ "10.10.100.101", "10.10.100.102", "10.10.100.103", "10.10.100.104" ], "servicePort": 53, "shareNodes": true } ], "monitors": [ "icmp" ] }, "template": "shared", "vip.ns-cluster-1": { "class": "Service_UDP", "pool": "pool.ns-cluster-1", "snat": "auto", "translateServerAddress": true, "virtualAddresses": [ "10.100.100.101" ], "virtualPort": 53 } } }, "tenant2": { "class": "Tenant", "httpsapp1": { "class": "Application", "cssl.acme_labs": { "certificates": [ { "certificate": "www.acmelabs.com" } ], "ciphers": "RSA", "class": "TLS_Server", "tls1_1Enabled": true, "tls1_2Enabled": true, "tls1_3Enabled": false }, "full_uri_decode": { "class": "iRule", "iRule": { "base64": "d2hlbiBIVFRQX1JFUVVFU1QgewogICMgZGVjb2RlIG9yaWdpbmFsIFVSSS4KICBzZXQgdG1wVXJpIFtIVFRQOjp1cmldCiAgc2V0IHVyaSBbVVJJOjpkZWNvZGUgJHRtcFVyaV0KICAjIHJlcGVhdCBkZWNvZGluZyB1bnRpbCB0aGUgZGVjb2RlZCB2ZXJzaW9uIGVxdWFscyB0aGUgcHJldmlvdXMgdmFsdWUuCiAgd2hpbGUgeyAkdXJpIG5lICR0bXBVcmkgfSB7CiAgICBzZXQgdG1wVXJpICR1cmkKICAgIHNldCB1cmkgW1VSSTo6ZGVjb2RlICR0bXBVcmldCiAgfQogIEhUVFA6OnVyaSAkdXJpCiAgbG9nIGxvY2FsMC4gIk9yaWdpbmFsIFVSSTogW0hUVFA6OnVyaV0iCiAgbG9nIGxvY2FsMC4gIkZ1bGx5IGRlY29kZWQgVVJJOiAkdXJpIgp9" } }, "pool.acme_labs": { "class": "Pool", "loadBalancingMode": "least-connections-member", "members": [ { "addressDiscovery": "static", "serverAddresses": [ "172.16.102.5" ], "servicePort": 80, "shareNodes": true } ], "monitors": [ "http" ] }, "template": "shared", "vip.acme_labs": { "class": "Service_HTTPS", "iRules": [ "full_uri_decode" ], "pool": "pool.acme_labs", "redirect80": false, "serverTLS": "cssl.acme_labs", "snat": "auto", "translateServerAddress": true, "virtualAddresses": [ "172.16.101.133" ], "virtualPort": 443 }, "www.acmelabs.com": { "certificate": "-----BEGIN CERTIFICATE-----\nMIIC3DCCAcSgAwIBAgIGAZAW7PncMA0GCSqGSIb3DQEBDQUAMC8xCzAJBgNVBAYTAlVTMSAwHgYDVQQDExdteXNlbGZzaWduZWQudGVzdC5sb2NhbDAeFw0yNDA2MTQxMzI1NDdaFw0zNDA2MTIxMzI1NDdaMC8xCzAJBgNVBAYTAlVTMSAwHgYDVQQDExdteXNlbGZzaWduZWQudGVzdC5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMYpeRm4f1mPgW7STMM4gZXZ5p02nCWshNwVkaOLpRJAOdR2ZpuhLW4tWpAssvmTRlS0cFjZKA6ecVg4Q7+wvw7dIG8gVAviOqmHb6sDaomBTn3+ISFYW0Uxb1GNvZqlktJQI7hCsaS5Kf/f4pImVa8jQffWTdgLwxCm+0suaXy1XykVOCdOs1lsCOHjMoVREWxLIAtzMpqdO+8IRhSJgPJPf3GnY861T0LDjuT5rgwY1qK/H2NuEcPWOWVtqTN9aQAz9cKxDbJq48U8adzrl6G8uUYlEPEtneePErygy8wRk8KkVNkuDj5gQKxi3b3Q8/K7bPhh9aUnZRQWmhVTw2kCAwEAATANBgkqhkiG9w0BAQ0FAAOCAQEAOh3doWxnjb5j5XojnEtYUWJG6yw9a3xZhEiq7myWz7apmy5eAe0QAL9kFAuiBwgjqwzPCXzMDp21FdLC+o9Znx5A8kXE2W2G+h36kc21f3v0jumRdkU1zZ9py9iKHAOUSAYsALNWH4mosFFbodpqcFZL7Fqmh/AoIcqY3GqSWOZ6geYbMIOwTZFnsuE1LTjJrnypz1ZyglGoftzU9j501aq3eJ3YUyRIZ28/ARJxn4sUfdvjvs31EdFEOOC6hwN2U7JXdWWK/fATTenglSkUqChJRW6kRL7uFf6FCCZjXyGINJnOYVz+8gxDWA557+ogYfEquQVML5gvMK9Ff67W6A==\n-----END CERTIFICATE-----", "class": "Certificate", "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEAxil5Gbh/WY+BbtJMwziBldnmnTacJayE3BWRo4ulEkA51HZmm6Etbi1akCyy+ZNGVLRwWNkoDp5xWDhDv7C/Dt0gbyBUC+I6qYdvqwNqiYFOff4hIVhbRTFvUY29mqWS0lAjuEKxpLkp/9/ikiZVryNB99ZN2AvDEKb7Sy5pfLVfKRU4J06zWWwI4eMyhVERbEsgC3Mymp077whGFImA8k9/cadjzrVPQsOO5PmuDBjWor8fY24Rw9Y5ZW2pM31pADP1wrENsmrjxTxp3OuXoby5RiUQ8S2d548SvKDLzBGTwqRU2S4OPmBArGLdvdDz8rts+GH1pSdlFBaaFVPDaQIDAQABAoIBAEUsIv7MfX/o7TifJnabGfkSOEM21ej8wOAGk3EwhO3LB6TXs9etuqsUH+HmCI/ATjOxTOpm22nG+y/dbCDU9MyeefzwnwYK8YlOIrfimGTpg1nNxQjby/hqWj5wqPf7xjWuDdn7RgGHNVcBcxirUwuw1g1KfJ/m8y+z6lKDIAWMuPegPFgQy0UoJmE5gjtdNYuRrPKESfjdgYhbmzl75k2zqm35Ngwgvp6YYq1jeGpDb4lDBDvn9KdpScC1y9w++7k4n1AyMZXsfgn3oSiFp9G6rZNraykOPYkQu309DVBqYtW0DHSU/xDYh1MTwJEwhcISYu12s2PIDGv/prgMRwUCgYEA7SdaqLT0B/btPkO84gnRx40rgsSM8gPewiVHerc95/tR6tCdMg1eNGJEK+biZMR/oxLQ3Ajr14BE3O8Dxhcqx/5vdo5qrX2oytDkl87oObK5rL0kdlmg/SQdnCsG/GkGtZlXLdMmjibSglGn23E69bsS0+IHspZnT2KHb1v1OZcCgYEA1ejfdHxmyOe+ke9QYn0umLLI/u6vDm6qkzEJrmzkpjrQrwftYRBeSr7CRJdRWtQ6dKA6kGZEfumFMg0ptFtwDGuLnzXek8UC3gKXjDnHyTugTXLprgB3A1AUYy0jvxmMTY8/AZLmDnqXma1WFnyxIUrTbzQq6uJPD4b33cWciv8CgYEAumnT1ocex1/uzqG6SEeFsYEjMZBEZjxqjlt1W13MeJxRoO1Ikz50zWJsycGcNa9L0SiKKluM3wGBn9T1N3GgfEJg5WU/L4517q7S8Q1/91KopsKqdakwZatM5yPfQutfjcGyCGBQjy6vDCcZdeIEgYICY7DpchTNslX1tbAoC5MCgYA9f9hOyz1Z4Zbeqik4R7lP2YcEFGdsBNExxFV+Onx6dkptKCBNWcFiR/necorHTGEKCs8LmPt0aXsL6tDks61BROI9geVeIrQyVBhyDmKsLmJmIfWhOyz8XNefs+ilFplJ6zc4Ip3V59USL82iZXMfmT20qRD1ut70Hd/BeQEKzQKBgQCoiTGlal7FaOHZmjvPOc6lzvOC2RIZL3yT5U1r9XsMFC2pPU/YinTc0cEpMmbeqLKuINjKOYyVp8HZEdpB6atU/WYDT2INe7VaphWpHkd5F56plzo0hlTDr1eFlHBsj23MVFR/UvpL0PeGzfnBd7ga2s0ymWDDnIhMJKzwu5GvDw==\n-----END RSA PRIVATE KEY-----" } } } } Next-specific interface With this interface, Central Manager lists out all the documents, including the compatibility interface applications. jrahm@mymac as3testing % curl -sk \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents | jq ._embedded.appsvcs [ { "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/3102ce15-e3d4-498f-a466-60f4bf02c2ab" } }, "created": "2024-06-17T17:38:08.186126Z", "deployments": [ { "id": "400e2b06-b451-4035-a26b-beaf90b283a5", "instance_id": "a4148c93-5306-4605-b8bb-92d6b1f78c26", "target": { "instance_ip": "172.16.2.161" }, "last_successful_deploy_time": "2024-06-17T17:38:42.404675Z", "modified": "2024-06-17T17:38:42.404675Z", "last_record": { "id": "64894415-38d0-49f9-989d-8f00c88196b3", "task_id": "f529800a-f515-4bec-9cfe-1f3214dec229", "start_time": "2024-06-17T17:38:41.103539Z", "status": "completed" } } ], "deployments_count": { "total": 1, "completed": 1 }, "id": "3102ce15-e3d4-498f-a466-60f4bf02c2ab", "name": "httpsapp1", "tenant_name": "tenant2", "type": "AS3" }, { "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/7938a0a2-b5d4-4687-99f8-e73d9e6b3d51" } }, "created": "2024-06-17T17:52:41.397543Z", "deployments": [ { "id": "0c50d882-f8d1-4833-af31-2b71e465f2f5", "instance_id": "a4148c93-5306-4605-b8bb-92d6b1f78c26", "target": { "instance_ip": "172.16.2.161" }, "last_successful_deploy_time": "2024-06-17T17:54:51.531445Z", "modified": "2024-06-17T17:54:51.531445Z", "last_record": { "id": "a8f786a5-f1c6-4f99-83bb-59cc024e1c34", "task_id": "ee1a3afa-c9d4-4e29-9271-632bbb93b6e7", "start_time": "2024-06-17T17:54:50.167979Z", "status": "completed" } } ], "deployments_count": { "total": 1, "completed": 1 }, "id": "7938a0a2-b5d4-4687-99f8-e73d9e6b3d51", "modified": "2024-06-17T17:54:50.164813Z", "name": "tenant1.dnsapp1.NzKPI4xZ", "tenant_name": "default", "type": "AS3" }, { "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/87ec6d3a-063d-4660-b32a-08cf183a21a8" } }, "created": "2024-06-17T17:50:02.621622Z", "deployments": [ { "id": "5da24b69-491e-45a1-b8eb-18395c4b2b12", "instance_id": "a4148c93-5306-4605-b8bb-92d6b1f78c26", "target": { "instance_ip": "172.16.2.161" }, "last_successful_deploy_time": "2024-06-17T17:50:03.929715Z", "modified": "2024-06-17T17:50:03.929715Z", "last_record": { "id": "1f3bc580-da07-4c26-b4d2-7e8bcb632869", "task_id": "dc8fbdc8-4dd0-4aeb-9e7d-cf3038d42c07", "start_time": "2024-06-17T17:50:02.640417Z", "status": "completed" } } ], "deployments_count": { "total": 1, "completed": 1 }, "id": "87ec6d3a-063d-4660-b32a-08cf183a21a8", "name": "tenant2.httpsapp1.NzKPI4xZ", "tenant_name": "default", "type": "AS3" }, { "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3" } }, "created": "2024-06-17T17:56:04.957896Z", "deployments": [ { "id": "ed48899b-fcb0-4a60-b8f2-2c0e012aa28d", "instance_id": "a4148c93-5306-4605-b8bb-92d6b1f78c26", "target": { "instance_ip": "172.16.2.161" }, "last_successful_deploy_time": "2024-06-17T17:56:34.410606Z", "modified": "2024-06-17T17:56:34.410606Z", "last_record": { "id": "7178d940-5ae7-4c18-bca6-6f7d14604d5e", "task_id": "771beda9-5ca4-4049-bebc-97b9d52da524", "start_time": "2024-06-17T17:56:33.123687Z", "status": "completed" } } ], "deployments_count": { "total": 1, "completed": 1 }, "id": "d5d0a360-75ec-434c-9802-62083a26c4d3", "name": "dnsapp1", "tenant_name": "tenant1", "type": "AS3" } ] Application service update operation For the update operation, this could be an HTTP PUT or PATCH method, depending on what the endpoints support. PUT is supposed to be a total replacement and PATCH a partial replacement, but I've found the implementations of many APIs to not follow this pattern. These methods require a payload with the request. In this section forward, we'll focus more on the mechanics of the API rather than the specifics on the application services, so I might work with one or the other unless both need attention. Compatibility interface This is where I throw a curveball at you! As the compatibility interface is intended to match BIG-IP classic AS3 behavior so it is in fact, uh, compatible, the operation for an update is actually still a POST as if you're creating the application service for the first time, so there's no need to do anything new here. Make the change to your declaration and POST as shown in the create section and you're good to go. Next-specific interface To modify the AS3 application service, the API reference states that the PUT method should be used, and the declaration should be complete. So I changed the virtual server IP address in the declaration and sent a PUT request to the appropriate document ID and it was successfully deployed. jrahm@mymac as3testing % curl -skX PUT \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d "@dns-app.json" \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3 | jq . { "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3" } }, "deployments": [ { "Message": "Update deployment task created", "id": "ed48899b-fcb0-4a60-b8f2-2c0e012aa28d", "task_id": "b07fa2de-7d73-4c7e-988a-1383cc45e441" } ], "id": "d5d0a360-75ec-434c-9802-62083a26c4d3", "message": "Application service updated successfully" } Application service delete operation An HTTP DELETE method performs the delete operation. Typically you just need the object ID in the request URL to remove the desired object. This is the fun part, at least in the lab environment. BLOW STUFF UP! Just kidding, but not really. I, like the Joker before me, like to make things go bye bye. Maybe if the Joker could have been a force for good he'd be a great chaos engineer. Compatibility interface This is where I put up the RED FLAG and caution you to know what you're doing here. If you send a DELETE to the compatibility interface with an empty payload you can blow away ALL the AS3 configuration on that instance. So don't do that... Instead, make sure you include the tenant name in the URI as shown below. jrahm@mymac as3testing % curl -skX DELETE \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ --location 'https://172.16.2.105/api/v1/spaces/default/appsvcs/declare/tenant1?target_address=172.16.2.161' { "declaration":{}, "results":[ { "code":200, "host":"172.16.2.161", "message":"success", "runTime":1331, "tenant":"tenant1" } ] } Next-specific interface You have two options here. You can delete the deployment only (you'll need to provide the document ID and the deployment ID) and then choose whether to the leave the draft or delete it (I show the document delete as well): jrahm@mymac as3testing % curl -skX DELETE \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d '{"target": "172.16.2.161"}' \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3/deployments/ed48899b-fcb0-4a60-b8f2-2c0e012aa28d | jq . { "Message": "Delete Deployment task created successfully", "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3/deployments/ed48899b-fcb0-4a60-b8f2-2c0e012aa28d" } }, "id": "ed48899b-fcb0-4a60-b8f2-2c0e012aa28d", "task_id": "9c5a8fe0-d8b9-4b41-a47f-3283586c88f1" } jrahm@mymac as3testing % curl -skX DELETE \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d '{"target": "172.16.2.161"}' \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3/ | jq . { "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/d5d0a360-75ec-434c-9802-62083a26c4d3/" } }, "id": "d5d0a360-75ec-434c-9802-62083a26c4d3", "message": "The application has been deleted successfully" } Or you can delete the document outright in one step which will clean up the deployment as well: jrahm@mymac as3testing % curl -skX DELETE \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d '{"target": "172.16.2.161"}' \ https://172.16.2.105/api/v1/spaces/default/appsvcs/documents/3102ce15-e3d4-498f-a466-60f4bf02c2ab/ | jq . { "_links": { "self": { "href": "/api/v1/spaces/default/appsvcs/documents/3102ce15-e3d4-498f-a466-60f4bf02c2ab/" } }, "deployments": [ { "Message": "Delete Deployment task created successfully", "id": "/declare/3102ce15-e3d4-498f-a466-60f4bf02c2ab/deployments/400e2b06-b451-4035-a26b-beaf90b283a5", "task_id": "73001fa0-2690-4906-96d6-52c2bb162bb0" } ], "id": "3102ce15-e3d4-498f-a466-60f4bf02c2ab", "message": "The application delete has been submitted successfully" } One more AS3 schema insight This article focused on the API endpoints and to make things simpler I used a declaration that works with both approaches. That said, if you are starting out with BIG-IP Next, you don't need the ADC or Tenant classes in your declaration, you can instead use a named document and start at the application class. Check out this diff in VSCode for the DNS app used in this article. Next up... I've been configuration-focused in the first couple of articles in the automation series. In the next article, I'll walk through some of the BIG-IP Next Postman collection, looking at system as well as configuration things. The visual experience in Postman might be a little easier on the eyes for those getting started than a bunch of curl commands. Stay tuned! Resources BIG-IP Next AS3 Schema BIG-IP Next API Reference Manage Application Services on Central Manager with AS3204Views2likes0CommentsGetting Started with BIG-IP Next: Upgrading Central Manager
Upgrades are one of the major improvements in moving from BIG-IP classic to Next. Whereas there is no direct analog for Central Manager in BIG-IP classic, the improvements from the BIG-IP/BIG-IQ upgrade experience will be noticeable. Simplification is the goal, and in my first Central Manager upgrade experience, I'd say that bar has been reached. In this article, I'll walk you through performing an upgrade to a standalone Central Manager. When HA for Central Manager is released, I'll update this article with those details. The installation steps on Clouddocs (links in the resources at the end of this article) make note that you should upgrade your instances before Central Manager, so keep that in mind as you build out your procedure sets for BIG-IP Next operations. For production I'd also recommend taking a backup of Central Manager as well (I'll do a walkthrough of that process in the coming weeks) but for discovery on my BIG-IP Next journey, I'll skip that step and nuke/pave if I have an issue. The first step in the upgrade process is to download the BIG-IP Next Central Manager upgrade package. After you have the upgraded package, login to your Central Manager. Click in the upper left on the tic-tac-toe board. Then in the dropdown menu that appears, select the System option. There's only one option here currently, and that's the upgrade button. Go ahead and click it. There will be a couple notes on the new window about resources and information on the unavailability to perform tasks during the upgrade. Go ahead and click next. If you didn't grab the package yet, the link to do so is included on this menu page. I selected the upload file option, selected the package from my downloads, and uploaded the file. You'll get the "green means go" checkbox when it's ready, at which point you can click the upgrade button. On the "Are you sure?" alert dialog, go ahead and click yes, upgrade. At this point, the upgrade will begin. On my upgrade, session was grayed out and I could not interact with the Central Manager interface, so my session timed out. I had trouble getting back in for several minutes, but when I got back in, I was presented with this alert dialog. You can click close here. And with that, you can see the new version of code. Congratulations on your first upgrade of Central Manager. Resources Upgrade BIG-IP Next Central Manager277Views2likes4CommentsMigrating from BIG-IP Classic to BIG-IP Next with Central Manager Migration Assistant
Partner Enablement Workshop: Migrating from BIG-IP Classic to BIG-IP Next with Central Manager Migration Assistant Tuesday, June 18 10 am PT / 1 pm ET During this hands-on lab session for F5 partners, attendees will explore F5 BIG-IP Next Central Manager Migration Assistant, an integrated solution that does not require additional licensing. Throughout this session, technical partner solution engineers will perform preparatory steps to migrate from BIG-IP Classic to BIG-IP Next, showcasing the first step to assist customers in their BIG-IP Next migration journey. This session will show how to transfer BIG-IP applications (version 12.1 or later) and their application management services to BIG-IP Next. With BIG-IP Next Central Manager, easily use each BIG-IP device's UCS file to migrate the application services and deploy an instance of BIG-IP Next. Register here: https://www.f5.com/go/event/channel-partner-enablement-workshops-north-america88Views0likes1CommentBIG-IP Next Automation: AS3 Basics
I need a little Mr. Miyagi right now to grab my face and intently look me in the eye and give me a "Concentrate! Focus power!" For those of you youngins' who don't know who that is, he's the OG Karate Kid mentor. Anyway, I have a thousand things I want to say about AS3 but in this article, I'll attempt to cut this down to a narrow BIG-IP Next-specific context to get you started. It helps that last December I did a five-part streaming series on AS3 in the BIG-IP classic context. If you haven't seen that, you have my blessing to stop right now, take some time to digest AS3 conceptually and practice against workloads and configurations in BIG-IP classic that you know and understand, before returning here to embrace all the newness of BIG-IP Next. AS3 is FOUNDATIONAL in BIG-IP Next In classic BIG-IP, you could edit the bigip.conf file directly, use tmsh commands, or iControlREST commands to imperatively create/modify/delete BIG-IP objects. With the exception of system configuration and shared configuration objects, this is not the case with BIG-IP Next. All application configuration is AS3 at its lowest state level. This doesn't mean you have to work primarily in AS3 configuration. If you utilize the migration utility in Central Manager, it will generate the AS3 necessary to get your apps up and running. Another option is to use the built-in http FAST template (we'll cover FAST in later articles) to build out an application from scratch in the GUI. But if you use features outside the purview of that template, or you need to edit your migration output, you'll need to work in the AS3 configuration declaration, even if just a little bit. Apples to Apples It's a fun card game, no? My family takes it to snarky absurd levels of sarcasm, to the point that when we play with "outsiders" we get lots of blank looks and stares as we're all rolling on the floor laughing. Oh well, to each his own. But we're here to talk about AS3, right? Well, in BIG-IP Next, there is a compatibility interface for AS3, such that you can take a declaration from BIG-IP classic and as long as the features within that declaration are supported, it should "just work" via the Central Manager API. That's pretty cool, right? Let's start with a basic application declaration from the recent video posted by Mark_Dittmerexploring the API differences between classic and Next. { "class": "ADC", "schemaVersion": "3.0.0", "id": "generated-for-testing", "Tenant_1": { "class": "Tenant", "App_1": { "class": "Application", "Service_1": { "class": "Service_HTTP", "virtualAddresses": [ "10.0.0.1" ], "virtualPort": 80, "pool": "Pool_1" }, "Pool_1": { "class": "Pool", "members": [ { "servicePort": 80, "serverAddresses": [ "10.1.0.1", "10.1.0.2" ] } ] } } } } A simple VIP with a pool with two pool members. A toy config to be sure, but it is useful here to show the format (JSON) of an AS3 declaration and some of the schema as well. With the compatibility interface, this same declaration can be posted to a classic BIG-IP like this: POST https://<BIG-IP IP Address>/mgmt/shared/appsvcs/declare Or a BIG-IP Next instance like this: POST https://<Central Manager IP Address>/api/v1/spaces/default/appsvcs/declare?target_address=<BIG-IP Next instance IP Address> For those already embracing AS3, this compatibility interface in BIG-IP Next should make the transition easier. AS3 Workflow in BIG-IP Next With BIG-IP classic, you had to install the AS3 package (technically an iControl LX, or sometimes referenced as an iApps v2 package) onto each BIG-IP system you wanted to use the AS3 declarative configuration model on. Each BIG-IP was an island, and the configuration management of the overall system of BIG-IPs was reliant on an external system for source of truth. With BIG-IP Next, the Central Manager API has native AS3 support so there are no packages to install to prepare the environment. Also, Central Manager is the centralized AS3 interface for all Next instances. This has several benefits: A singular and centralized source of truth for your configuration management No external package management requirements Tremendous improvement in API performance management since most of the heavy lifting is offloaded from the instances and onto Central Manager and the control-plane functionality that remains on the instance is intentionally designed for API-first operations The general application deployment workflow introduced exclusively for Next is twofold: Create an application service First, you create the application service on Central Manager. You can use the same JSON declaration from the section above here, only the API endpoint is different: POST https://<Central Manager IP Address>/api/v1/spaces/default/appsvcs/documents A successful transaction will result in an application service document on Central Manager. A couple notes on this at time of writing: Documents created through the API are not validated against the journeys migration tool that is available for use in the Central Manager GUI. Documents are not schema validated at the attribute level of classes, so whereas a class used in classic might be supported in Next, some of the attributes might not be. This means that whereas the document creation process can appear successful, the deployment will fail if classes and/or class attributes supported in classic BIG-IP are present in the AS3 declarations when an attempt to apply to an instance occurs. Deploy the application service Assuming, however, all your AS3 work is accurate to the Next-supported schema, you post the specified document by ID to the target BIG-IP Next instance, here as a JSON payload versus a query parameter on the compatibility endpoint shown earlier. POST https://<Central Manager IP Address>/api/v1/spaces/default/appsvcs/documents/<Document ID>/deployments { "target": "<BIG-IP Next Instance IP Address>" } At this point, your service should be available to receive traffic on the instance it was deployed on. Next Up... Now that we have the theory in place, join me next time where we'll take a look at working with a couple application services through both approaches. Resources CM App Services Management AS3 Schema AS3 User Guide (classic, but useful) AS3 Reference Guide (classic, but useful) AS3 Foundations (streaming series)474Views0likes0CommentsMitigating Application Threats with BIG-IP Next WAF
Overview of BIG-IP Next In today's modern world where the digital landscape is continuously evolving and security threats are becoming more sophisticated, the need for a robust and adaptive security solution is essential. BIG-IP Next is a next-generation solution which is setting a new standard for safeguarding your digital assets, protecting your applications, and empowering enterprises with the highest security efficacy.BIG-IP Next is the modernized solution optimized to simplify operations, enhance performance, and strengthen security. As per the official website, BIG-IP Next simplifies day-to-day ADC operations and accelerates application time-to-market through automation so that you can focus more on getting your apps online. BIG-IP Next’s modern, highly scalable software architecture is designed for maximum resiliency to support vast, dynamic application portfolios and their most complex traffic management and security policies, ensuring that applications are always available to end users. BIG-IP Next also provides deep insights into your application health, network performance, traffic patterns, and security threats to improve business decision-making. For a quick overview of BIG-IP Next and how the next-generation attributes can help you with your existing or new deployments, check out the video below. Here are some of the key capabilities that you can checkout and learn how you can mitigate app threats and security complexity with BIG-IP Next WAF: 1. Deploy HTTPS application with WAF Protection The first step in protecting your applications starts with onboarding your application in BIG-IP Next instance and creating a WAF security policy as per application requirements. Finally creating load balancers and applying the above-created WAF policies. Next, users can monitor the application traffic by navigating to their respective security dashboards and take necessary steps as per security insights. For more details, see this video. 2. Create and Manage Security Policies Sometimes creating security policies can be a time-consuming job, and BIG-IP Next has made this user-friendly for creating and managing security policies from a centralized UI. Users can create, delete or update their existing policies in fewer steps and can apply them directly to the applications, thereby decreasing the application delivery time to market. You can check out the video below for more details. 3. Create Security Policies using Templates One more advantage of BIG-IP Next is the support for creating security policies using templates and it’s just a one-click action using 'F5 BIG-IP Next’. Users can make use of default templates and protect their applications with zero effort, for ex. Using the Violation Rating Template. For more information, check below video. 4. Security Policy Migration Going through existing BIG-IP security policies and then creating the same ones in BIG-IP Next solution can be time-consuming. This is made easy so that users can migrate their security policy from 'F5 Advanced WAF' to 'F5 BIG-IP Next WAF' in a simple manner. With fewer steps, you can have your entire WAF security posture up without going through the rough step of creating them from scratch. Please refer to the video below for more insights. 5. Signatures and Threat Campaigns Update Regular update of attack signatures and threat campaigns is a vital step in safeguarding your applications against the latest attacks. This process is super easy using ‘F5 BIG-IP Next’ so that applications can mitigate them without the need for downtime. For step-by-step procedure to update signatures and threat campaigns, please check the video below. You can also check out the demo link below for detailed insights of how BIG-IP Next WAF enables the migration of apps and policies between BIG-IP TMOS and BIG-IP Next. The demo also shows how to deploy new web applications with WAF security policies included within BIG-IP Next Central Manager and finally how to analyze and respond to security incidents within the Next WAF dashboard. Reference links What is BIG-IP Next? | DevCentral Getting Started with BIG-IP Next: Fundamentals | DevCentral https://www.f5.com/products/big-ip-services/big-ip-next196Views1like1CommentGetting Started with BIG-IP Next: Configuring Instance High Availability
With BIG-IP classic, there are a lot of design choices to make and steps on both systems to arrive at an HA pair. With BIG-IP Next, this is simplified quite a bit. Once configured, the highly available pair is treated by Central Manager as a single entity. There might be alternative options in the future, but as of version 20.1, HA for instances is active/standby only. In this article, I'll walk you through the steps to configure HA for instances in the Central Manager GUI. Background and Prep Work I set up two HA systems in my preparation for this article. The first had dedicated interfaces for the management interface, the external and internal traffic interfaces, and the HA interface. So when configuring the virtual machine, I made sure each system had four NICs. For the second, I merged all the non-management interfaces on a single NIC and used vlan tagging, so those systems had two NICs. In my lab that looks like this: The IP addressing scheme in my lab is shown below. First the four NIC system: 4-NIC System next-4nic-a next-4nic-b floating mgmt 172.16.2.152/24 172.16.2.153/24 172.16.2.151/24 cntrlplane ha (vlan 245) 10.10.245.1/30 10.10.245.2/30 NA dataplane ha (int 1.3) 10.0.5.1/30 10.0.5.2/30 NA dataplane ext (int 1.1) 10.0.2.152/24 10.0.2.153/24 10.0.2.151/24 dataplane int (int 1.2) 10.0.3.152/24 10.0.3.153/24 10.0.3.151/24 And now the two NIC system: 2-NIC System next-2nic-a next-2nic-b floating mgmt 172.16.2.162/24 172.16.2.163/24 172.16.2.161/24 cntrlplane ha (vlan 245) 10.10.245.5/30 10.10.245.6/30 NA dataplane ha (vlan 50) 10.0.5.5/30 10.0.5.6/30 NA dataplane ext (vlan 30) 10.0.2.162/24 10.0.2.163/24 10.0.2.161/24 dataplane int (vlan 40) 10.0.3.162/24 10.0.2.163/24 10.0.3.161/24 Beyond the self IP addresses for your traffic interfaces, you'll need additional IP addresses for the floating address, the control-plane HA sub-interfaces (which are created for you), and teh data-plane HA interfaces. Before proceeding, make sure you have a plan for network segmentation and addressing similar to above, you've installed two like instances, and that one (and only one) of them is licensed. Configuration This walk through is for the 2-NIC system shown above, but the steps are mostly the same. First, login to Central Manager, and click on Manage Instances. Click on the standalone mode for the system you want to be active initially in your HA pair. For me, that's next-2nic-a. (You can also just click on the system name and then select HA in the menu, but this saves a click.) In the pop-up dialog, select Enable HA. Read the notes below to make sure your systems are ready to be paired. On this screen, a list of available standalone systems will populate. Click the down arrow and select your second system, next-2nic-b in my case. Then click Next. On this next prompt, you'll need to create two vlans, one for the control plane and one for the data plane. The control plane mechanics are taken care of for you and you don't need to plan connectivity other than to select an available vlan that won't conflict with anything else in your system. For the data plane, you need to have a dedicated vlan and/or interface set aside. Click Create VLAN for the control plane. Name and tag your vlan. In my case I used cp-ha as my vlan name and tag 245. Click Done. Now click Create VLAN for the data plane. Because I'm tagging all networks on the 2-NIC system, my own interface is 1.1. So I named my data plan vlan dp-ha, set the tag to 50, selected interface 1.1, and clicked Done. Now that both HA VLANs have been created, click Next. On this screen, you'll name your HA pair system. This will need to be unique from other HA pairs, so plan accordingly. I named mine next-ha-1, but that's generic and unlikely to be helpful in your environment. Then set your HA management IP, this is how Central Manager will connect to the HA pair. You can enable auto-failback if desired, but I left that unchecked. For the HA Nodes Addresses, I referenced my addressing table posted at the top of this article and filled those in as appropriate. When you get those filled out, click Next. Now you'll be presented with a list of your traffic VLANs. On my system I have v102-ext and v103-int for my external and internal networks. First, I clicked v102-ext. On this screen you'll need to add a couple rows so you can populate the active node IP, the standby node IP, and the floating IP. The order doesn't matter, but I ordered them as shown, and again referenced my addressing table. Once populated, click Save. That will return you to this screen, where you'll notice that v102-ext now has a green checkbox where the yellow warning was. Now click into your other traffic VLAN (v103-int in my case) if applicable to your environment or skip this next step. This is a repeat of the external traffic network for the internal traffic network. I referenced my address table one more time and filled the details out as appropriate, then clicked Save. Make sure that you have green checkboxes on the traffic VLANs, then click Next. Review the summary of the HA settings you've configured, and if everything looks right, click Deploy to HA. On the "are you sure?" dialog where you're prompted to confirm your deployment, click Yes, Deploy. You'll then see messaging at the top of the HA configuration page for the instance indicating that HA is being created. Also note that the Mode on this page during creation still indicates standalone. Once the deployment is complete, you'll see the mode has changed to HA and the details for your active and standby nodes are provided. Also present here is the Enable automatic failover option, which is enabled by default. This is for software upgrades. If left enabled, the standby unit will be upgraded first, a failover will be executed, and the the remaining system will be upgraded. If in your HA configuration you specified auto-failback, then after the second system is upgraded there will be another failover executed to complete the process. And finally, as seen in the list of instances, there are three now instead of four, with next-ha-1 taking the place of next-2nic-a and next-2nic-b from where we started. Huzzah! You now have a functioning BIG-IP Next HA pair. After we conclude the "Getting Started" series, we'll start to look at the benefits of automation around all the tasks we've covered so far, including HA. The click-ops capabilities are nice to have, but I think you'll find the ability to automate all this from a script or something like an Ansible playbook will really start to drive home the API-first aspects of Next.534Views1like4Comments