f5-appsvcs-extension
f5-appsvcs-extension copied to clipboard
Push fails when data group keyDataType changes
Environment
- Application Services Version: 3.53.0
- BIG-IP Version: 17.1.1.3
Summary
Pushing a declaration fails when the keyDataType for a data group changes, for example from 'integer' to 'string'.
Steps To Reproduce
Steps to reproduce the behavior:
- Submit the following declaration:
{
"$schema": "https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/refs/heads/main/schema/latest/as3-schema-3.53.0-7.json",
"class": "AS3",
"action": "deploy",
"persist": true,
"declaration": {
"class": "ADC",
"schemaVersion": "3.53.0",
"id": "services_test.yaml_2025-03-06T08:27:52.982135",
"label": "services_test.yaml",
"remark": "Generated F5 AS3 declaration document",
"updateMode": "selective",
"as3-common-partition": {
"class": "Tenant",
"app_acme": {
"class": "Application",
"acme_http": {
"class": "Service_Generic",
"virtualAddresses": [
"10.0.0.1"
],
"virtualPort": 80,
"pool": "pool_acme_http",
"persistenceMethods": []
},
"pool_acme_http": {
"class": "Pool",
"monitors": [],
"members": [
{
"servicePort": 80,
"serverAddresses": [
"192.168.1.1",
"192.168.1.2"
]
}
],
"loadBalancingMode": "round-robin"
},
"dg-test_dg_5": {
"class": "Data_Group",
"keyDataType": "integer",
"records": [
{
"key": 10
},
{
"key": 20
}
]
}
}
}
}
}
- Then submit this declaration which changes
keyDataTypeof data group 'dg-test_dg_5' to 'string':
{
"$schema": "https://raw.githubusercontent.com/F5Networks/f5-appsvcs-extension/refs/heads/main/schema/latest/as3-schema-3.53.0-7.json",
"class": "AS3",
"action": "deploy",
"persist": true,
"declaration": {
"class": "ADC",
"schemaVersion": "3.53.0",
"id": "services_test.yaml_2025-03-06T08:36:56.980691",
"label": "services_test.yaml",
"remark": "Generated F5 AS3 declaration document",
"updateMode": "selective",
"as3-common-partition": {
"class": "Tenant",
"app_acme": {
"class": "Application",
"acme_http": {
"class": "Service_Generic",
"virtualAddresses": [
"10.0.0.1"
],
"virtualPort": 80,
"pool": "pool_acme_http",
"persistenceMethods": []
},
"pool_acme_http": {
"class": "Pool",
"monitors": [],
"members": [
{
"servicePort": 80,
"serverAddresses": [
"192.168.1.1",
"192.168.1.2"
]
}
],
"loadBalancingMode": "round-robin"
},
"dg-test_dg_5": {
"class": "Data_Group",
"keyDataType": "string",
"records": [
{
"key": "foo"
},
{
"key": "bar"
}
]
}
}
}
}
}
- Observe the following error response:
{
"results": [
{
"code": 422,
"message": "declaration failed",
"response": "0107074b:3: Unable to change data group (/as3-common-partition/app_acme/dg-test_dg_5) type. Must remove existing entries first.",
"host": "localhost",
"tenant": "as3-common-partition",
"runTime": 5330,
"declarationId": "services_test.yaml_2025-03-06T08:36:56.980691"
}
],
"declaration": {
"as3-common-partition": {
"class": "Tenant",
"app_acme": {
"class": "Application",
"acme_http": {
"class": "Service_Generic",
"virtualAddresses": [
"10.0.0.1"
],
"virtualPort": 80,
"pool": "pool_acme_http",
"persistenceMethods": [],
"layer4": "any",
"profileIPOther": {
"bigip": "/Common/ipother"
},
"profileL4": "basic",
"serviceDownImmediateAction": "none",
"shareAddresses": false,
"enable": true,
"maxConnections": 0,
"snat": "auto",
"addressStatus": true,
"mirroring": "none",
"lastHop": "default",
"translateClientPort": false,
"translateServerAddress": true,
"translateServerPort": true,
"nat64Enabled": false,
"httpMrfRoutingEnabled": false,
"rateLimit": 0,
"adminState": "enable"
},
"pool_acme_http": {
"class": "Pool",
"monitors": [],
"members": [
{
"servicePort": 80,
"serverAddresses": [
"192.168.1.1",
"192.168.1.2"
],
"enable": true,
"connectionLimit": 0,
"rateLimit": -1,
"dynamicRatio": 1,
"ratio": 1,
"priorityGroup": 0,
"adminState": "enable",
"addressDiscovery": "static",
"shareNodes": false,
"routeDomain": 0
}
],
"loadBalancingMode": "round-robin",
"allowNATEnabled": true,
"allowSNATEnabled": true,
"minimumMembersActive": 1,
"reselectTries": 0,
"serviceDownAction": "none",
"slowRampTime": 10,
"minimumMonitors": 1
},
"dg-test_dg_5": {
"class": "Data_Group",
"keyDataType": "integer",
"records": [
{
"key": 10
},
{
"key": 20
}
],
"storageType": "internal"
},
"template": "generic",
"enable": true
},
"enable": true,
"defaultRouteDomain": 0,
"useCommonRouteDomainTenant": true,
"optimisticLockKey": ""
},
"class": "ADC",
"schemaVersion": "3.53.0",
"id": "services_test.yaml_2025-03-06T08:36:56.980691",
"label": "services_test.yaml",
"remark": "Generated F5 AS3 declaration document",
"updateMode": "selective",
"controls": {
"archiveTimestamp": "2025-03-06T14:41:07.694Z",
"class": "Controls",
"dryRun": false,
"logLevel": "error",
"trace": false,
"traceResponse": false
}
},
"code": 422
}
Expected Behavior
Being a declarative configuration approach, AS3 should make the necessary changes to the LTM config as requested in the declaration.
Actual Behavior
The config push fails with an error indicating that manual intervention is required:
"response": "0107074b:3: Unable to change data group (/as3-common-partition/app_acme/dg-test_dg_5) type. Must remove existing entries first.",
Manual/imperative intervention should not be required when pushing a declarative configuration.
@ee-github Data Groups are typed objects in BIG-IP. Changing the keyDataType is treated as a destructive change, but AS3 doesn’t delete and recreate objects by default — especially not if it might affect other config.
AS3 performs non-disruptive updates where possible. Changing the type would require deleting the old data group and recreating it, which could break references.
Recommendation: Choose keyDataType carefully up front.
Avoid changing the type for existing named data groups unless you explicitly handle deletion.