iosxe_restconf code for TACACS Server
Opened this issue · 5 comments
Hi I have this JSON result from tacacs API..
{
"Cisco-IOS-XE-aaa:server": [
{
"name": "ISE1",
"address": {
"ipv4": "1.1.1.1"
},
"key": {
"encryption": "7",
"key": "XXX"
}
},
{
"name": "ISE2",
"address": {
"ipv4": "2.2.2.2"
},
"key": {
"encryption": "7",
"key": "XXX"
}
}
]
}
How i can translate this code above to use iosxe_restconf, because i want to create another line of ISE config.
I'm using this code below but its failed.
resource "iosxe_restconf" "aaa_server" {
path = "Cisco-IOS-XE-native:native/tacacs"
lists = [
{
name = "Cisco-IOS-XE-aaa:server"
key = "name"
items = [
{
name = "ISE3",
address = jsonencode(
{"ipv4": "3.3.3.3"}
),
key = jsonencode(
{"key": {
"encryption": "7",
"key": "XXXX"
}
}
)
}
]
}
]
}
Error result :
╷
│ Error: Client Error
│
│ with iosxe_restconf.aaa_server,
│ on main.tf line 102, in resource "iosxe_restconf" "aaa_server":
│ 102: resource "iosxe_restconf" "aaa_server" {
│
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:malformed-message ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/tacacs ErrorMessage:invalid value for: address in /ios:native/ios:tacacs/ios-aaa:server[ios-aaa:name='ISE3']/ios-aaa:address ErrorInfo:}]} {PatchId:
│ GlobalStatus:{Ok:false Errors:{Error:[]}} EditStatus:{Edit:[]} Errors:{Error:[]}}
Thanks.
Hi @ipeph, a question of fact: Does this dedicated resource work with your setup at all?: https://registry.terraform.io/providers/CiscoDevNet/iosxe/latest/docs/resources/tacacs_server
As @jabielecki mentioned, the dedicated resource would be the preferred method of configuration. When using iosxe_restconf
there is no need to use jsonencode()
, you would address nested elements using a "path" syntax:
resource "iosxe_restconf" "aaa_server" {
path = "Cisco-IOS-XE-native:native/tacacs"
lists = [
{
name = "Cisco-IOS-XE-aaa:server"
key = "name"
items = [
{
name = "ISE3"
"address/ipv4" = "3.3.3.3"
"key/key" = "ABCDEFG"
}
]
}
]
}
Hi @ipeph, a question of fact: Does this dedicated resource work with your setup at all?: https://registry.terraform.io/providers/CiscoDevNet/iosxe/latest/docs/resources/tacacs_server
Hi @jabielecki, yes correct i could use that but i had some problem using this resource.
resource "iosxe_tacacs_server" "ISE1" {
name = "ISE1"
address_ipv4 = "1.1.1.1"
key = "XXXXXXX"
}
resource "iosxe_tacacs_server" "ISE2" {
name = "ISE2"
address_ipv4 = "2.2.2.2"
key = "XXXXXXX"
}
Output
# iosxe_tacacs_server.APDC3 will be updated in-place
~ resource "iosxe_tacacs_server" "ISE1" {
id = "Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server=ISE1"
~ key = "153B2F41061B3E2C0667132B170D1514" -> "XXXXXXX"
name = "ISE1"
# (1 unchanged attribute hidden)
}
# iosxe_tacacs_server.APDC4 will be updated in-place
~ resource "iosxe_tacacs_server" "ISE2" {
id = "Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server=ISE2"
~ key = "10672D540726070322500C2220223022" -> "XXXXXXX"
name = "ISE2"
# (1 unchanged attribute hidden)
}
╷
│ Error: Client Error
│
│ with iosxe_tacacs_server.ISE1,
│ on main.tf line 127, in resource "iosxe_tacacs_server" "ISE1":
│ 127: resource "iosxe_tacacs_server" "ISE1" {
│
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:invalid-value ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server ErrorMessage:inconsistent value: Device refused one or more commands ErrorInfo:}]}
│ {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}} EditStatus:{Edit:[]} Errors:{Error:[]}}
╵
╷
│ Error: Client Error
│
│ with iosxe_tacacs_server.ISE2,
│ on main.tf line 133, in resource "iosxe_tacacs_server" "ISE2":
│ 133: resource "iosxe_tacacs_server" "ISE2" {
│
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:invalid-value ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/tacacs/Cisco-IOS-XE-aaa:server ErrorMessage:inconsistent value: Device refused one or more commands ErrorInfo:}]}
│ {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}} EditStatus:{Edit:[]} Errors:{Error:[]}}
Sometimes the state is not sync because terraform sometimes read the encypted value of tacacs so i though i could use the iosxe_restconf resource directly.
As @jabielecki mentioned, the dedicated resource would be the preferred method of configuration. When using
iosxe_restconf
there is no need to usejsonencode()
, you would address nested elements using a "path" syntax:resource "iosxe_restconf" "aaa_server" { path = "Cisco-IOS-XE-native:native/tacacs" lists = [ { name = "Cisco-IOS-XE-aaa:server" key = "name" items = [ { name = "ISE3" "address/ipv4" = "3.3.3.3" "key/key" = "ABCDEFG" } ] } ] }
Hi @danischm,
Thanks this is work perfectly like charm. And i have some request if its ok with you, this example is not listed on the documentation, maybe if this example can be added on the documentation.
Thanks.
Hi @danischm,
I have another question.
I have this API result from this URL.
https://{{host}}:{{port}}/restconf/data/Cisco-IOS-XE-native:native/aaa/authenticaiton
{
"Cisco-IOS-XE-aaa:authentication": {
"attempts": {
"login": 4
},
"enable": {
"default": {
"group": "tacacs+",
"enable": [
null
]
}
},
"login": [
{
"name": "default",
"a1": {
"local": [
null
]
},
"a2": {
"group": "tacacs+"
}
}
]
}
}
How i can translate this into correct terraform code ?
I tried this 2 code below, and having an error after applying the code.
1st code
resource "iosxe_restconf" "aaa_authentication" {
path = "Cisco-IOS-XE-native:native/aaa/authentication"
attributes = {
"attempts/login" = 4
"enable/default/group" = "tacacs+"
"enable/default/enable" = null
"login/name" = "default"
"login/a1/local" = null
"login/a2/group" = "tacacs+"
}
}
output:
Plan: 1 to add, 0 to change, 0 to destroy.
iosxe_restconf.aaa_authentication: Creating...
╷
│ Error: Client Error
│
│ with iosxe_restconf.aaa_authentication,
│ on main.tf line 175, in resource "iosxe_restconf" "aaa_authentication":
│ 175: resource "iosxe_restconf" "aaa_authentication" {
│
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:malformed-message ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/aaa/Cisco-IOS-XE-aaa:authentication ErrorMessage:0: Internal error ErrorInfo:}]} {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}}
│ EditStatus:{Edit:[]} Errors:{Error:[]}}
╵
2nd code
resource "iosxe_restconf" "aaa_authentication" {
path = "Cisco-IOS-XE-native:native/aaa/authentication"
lists = [
{
name = "Cisco-IOS-XE-aaa:authentication"
key = "login"
items = [
{
"attempts/login" = 4
"enable/default/group" = "tacacs+"
"enable/default/enable" = null
"login/name" = "default"
"login/a1/local" = null
"login/a2/group" = "tacacs+"
}
]
}
]
}
output
iosxe_restconf.aaa_authentication: Creating...
╷
│ Error: Client Error
│
│ with iosxe_restconf.aaa_authentication,
│ on main.tf line 187, in resource "iosxe_restconf" "aaa_authentication":
│ 187: resource "iosxe_restconf" "aaa_authentication" {
│
│ Failed to configure object (PATCH), got error: HTTP Request failed: StatusCode 400, RESTCONF errors {Error:[{ErrorType:application ErrorTag:malformed-message ErrorAppTag: ErrorPath:/Cisco-IOS-XE-native:native/aaa/Cisco-IOS-XE-aaa:authentication ErrorMessage:0: Internal error ErrorInfo:}]} {PatchId: GlobalStatus:{Ok:false Errors:{Error:[]}}
│ EditStatus:{Edit:[]} Errors:{Error:[]}}