From d60ebcfd1fbfd095b0ce8d2daf3deb052cf967a2 Mon Sep 17 00:00:00 2001 From: Andrea Testino Date: Mon, 6 Oct 2025 13:45:07 -0400 Subject: [PATCH 1/2] fix(aaa): set unused YANG choice options to null in dot1x config Change dot1x authentication to set unused YANG choice options to null instead of false. YANG choice containers allow only one active option (group OR local OR cache OR radius). Setting multiple options causes device to apply last value and ignore others. Before: a2_local = try(...) == "local" ? true : false a2_cache = try(...) == "cache" ? true : false After: a2_local = try(...) == "local" ? true : null a2_cache = try(...) == "cache" ? "cache" : null When module sets a2_group = "sw_radius_group" and a2_cache = false, Terraform coerces false to string "false". Provider serializes both values. Device applies cache: false and ignores group setting. With null values, provider IsNull() check skips serialization. Only selected choice option is sent to device. Resolves state/reality drift where Terraform state showed correct values but device configuration was incomplete. Modified: iosxe_aaa.tf (lines 174-192) --- iosxe_aaa.tf | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/iosxe_aaa.tf b/iosxe_aaa.tf index dd58c4c..40ca5e9 100644 --- a/iosxe_aaa.tf +++ b/iosxe_aaa.tf @@ -173,22 +173,22 @@ resource "iosxe_aaa_authentication" "aaa_authentication" { dot1x = try(length(local.device_config[each.value.name].aaa.authentication.dot1xs) == 0, true) ? null : [for e in local.device_config[each.value.name].aaa.authentication.dot1xs : { name = try(e.name, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.name, null) - a1_group = try(!contains(["local", "cache", "radius"], try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0])), false) ? try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.logins.methods[0]) : null - a1_local = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "local" ? true : false - a1_cache = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "cache" ? true : false - a1_radius = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "radius" ? true : false - a2_group = try(!contains(["local", "cache", "radius"], try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1])), false) ? try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.logins.methods[1]) : null - a2_local = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "local" ? true : false - a2_cache = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "cache" ? true : false - a2_radius = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "radius" ? true : false - a3_group = try(!contains(["local", "cache", "radius"], try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2])), false) ? try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.logins.methods[2]) : null - a3_local = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "local" ? true : false - a3_cache = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "cache" ? true : false - a3_radius = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "radius" ? true : false - a4_group = try(!contains(["local", "cache", "radius"], try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3])), false) ? try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.logins.methods[3]) : null - a4_local = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "local" ? true : false - a4_cache = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "cache" ? true : false - a4_radius = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "radius" ? true : false + a1_group = try(!contains(["local", "cache", "radius"], try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0])), false) ? try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0]) : null + a1_local = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "local" ? true : null + a1_cache = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "cache" ? "cache" : null + a1_radius = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "radius" ? true : null + a2_group = try(!contains(["local", "cache", "radius"], try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1])), false) ? try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1]) : null + a2_local = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "local" ? true : null + a2_cache = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "cache" ? "cache" : null + a2_radius = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "radius" ? true : null + a3_group = try(!contains(["local", "cache", "radius"], try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2])), false) ? try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2]) : null + a3_local = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "local" ? true : null + a3_cache = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "cache" ? "cache" : null + a3_radius = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "radius" ? true : null + a4_group = try(!contains(["local", "cache", "radius"], try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3])), false) ? try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3]) : null + a4_local = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "local" ? true : null + a4_cache = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "cache" ? "cache" : null + a4_radius = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "radius" ? true : null }] dot1x_default_a1_group = try(!contains(["local"], try(local.device_config[each.value.name].aaa.authentication.dot1x_defaults[0], local.defaults.iosxe.configuration.aaa.authentication.dot1x_defaults[0])), false) ? try(local.device_config[each.value.name].aaa.authentication.dot1x_defaults[0], local.defaults.iosxe.configuration.aaa.authentication.dot1x_defaults[0]) : null From c4a2694f2382a2904470e1a7bcbd489862c17c63 Mon Sep 17 00:00:00 2001 From: Andrea Testino Date: Mon, 27 Oct 2025 17:01:02 -0400 Subject: [PATCH 2/2] chore: dict array --- iosxe_aaa.tf | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/iosxe_aaa.tf b/iosxe_aaa.tf index 40ca5e9..0d993bb 100644 --- a/iosxe_aaa.tf +++ b/iosxe_aaa.tf @@ -173,22 +173,23 @@ resource "iosxe_aaa_authentication" "aaa_authentication" { dot1x = try(length(local.device_config[each.value.name].aaa.authentication.dot1xs) == 0, true) ? null : [for e in local.device_config[each.value.name].aaa.authentication.dot1xs : { name = try(e.name, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.name, null) - a1_group = try(!contains(["local", "cache", "radius"], try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0])), false) ? try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0]) : null - a1_local = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "local" ? true : null - a1_cache = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "cache" ? "cache" : null - a1_radius = try(e.methods[0], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0], null) == "radius" ? true : null - a2_group = try(!contains(["local", "cache", "radius"], try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1])), false) ? try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1]) : null - a2_local = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "local" ? true : null - a2_cache = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "cache" ? "cache" : null - a2_radius = try(e.methods[1], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1], null) == "radius" ? true : null - a3_group = try(!contains(["local", "cache", "radius"], try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2])), false) ? try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2]) : null - a3_local = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "local" ? true : null - a3_cache = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "cache" ? "cache" : null - a3_radius = try(e.methods[2], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2], null) == "radius" ? true : null - a4_group = try(!contains(["local", "cache", "radius"], try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3])), false) ? try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3]) : null - a4_local = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "local" ? true : null - a4_cache = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "cache" ? "cache" : null - a4_radius = try(e.methods[3], local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3], null) == "radius" ? true : null + a1_cache = try(e.methods[0].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].cache, false) && try(e.methods[0].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].method, null) != null ? try(e.methods[0].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].method, null) : null + a1_local = try(e.methods[0].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].method, null) == "local" ? true : null + a1_radius = try(e.methods[0].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].method, null) == "radius" ? true : null + a1_group = !contains(["local", "radius"], try(e.methods[0].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].method, "")) && !try(e.methods[0].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].cache, false) ? try(e.methods[0].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[0].method, null) : null + a2_cache = try(e.methods[1].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].cache, false) && try(e.methods[1].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].method, null) != null ? try(e.methods[1].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].method, null) : null + a2_local = try(e.methods[1].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].method, null) == "local" ? true : null + a2_radius = try(e.methods[1].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].method, null) == "radius" ? true : null + a2_group = !contains(["local", "radius"], try(e.methods[1].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].method, "")) && !try(e.methods[1].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].cache, false) ? try(e.methods[1].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[1].method, null) : null + a3_cache = try(e.methods[2].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].cache, false) && try(e.methods[2].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].method, null) != null ? try(e.methods[2].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].method, null) : null + a3_local = try(e.methods[2].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].method, null) == "local" ? true : null + a3_radius = try(e.methods[2].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].method, null) == "radius" ? true : null + a3_group = !contains(["local", "radius"], try(e.methods[2].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].method, "")) && !try(e.methods[2].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].cache, false) ? try(e.methods[2].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[2].method, null) : null + # Method 4 (a4) + a4_cache = try(e.methods[3].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].cache, false) && try(e.methods[3].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].method, null) != null ? try(e.methods[3].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].method, null) : null + a4_local = try(e.methods[3].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].method, null) == "local" ? true : null + a4_radius = try(e.methods[3].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].method, null) == "radius" ? true : null + a4_group = !contains(["local", "radius"], try(e.methods[3].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].method, "")) && !try(e.methods[3].cache, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].cache, false) ? try(e.methods[3].method, local.defaults.iosxe.configuration.aaa.authentication.dot1xs.methods[3].method, null) : null }] dot1x_default_a1_group = try(!contains(["local"], try(local.device_config[each.value.name].aaa.authentication.dot1x_defaults[0], local.defaults.iosxe.configuration.aaa.authentication.dot1x_defaults[0])), false) ? try(local.device_config[each.value.name].aaa.authentication.dot1x_defaults[0], local.defaults.iosxe.configuration.aaa.authentication.dot1x_defaults[0]) : null