CiscoISE / terraform-provider-ciscoise

Terraform Provider for Cisco ISE
https://registry.terraform.io/providers/CiscoISE/ciscoise/latest/docs
MIT License
10 stars 4 forks source link

Resource id format is hard to work with #34

Closed chetanph closed 2 years ago

chetanph commented 2 years ago

Is your feature request related to a problem? Please describe. No

Describe the solution you'd like Would like the ability to refer to id and name of a resource directly rather than having to parse id string for UUID and name.

Consider this policy set:

resource "ciscoise_device_administration_policy_set" "asa" {
  parameters {
    rank        = 0
    state       = "enabled"
    name        = "ASA Firewalls"
    description = "ASA Firewalls"
    condition {
      condition_type  = "ConditionAttributes"
      is_negate       = "false"
      dictionary_name = "DEVICE"
      attribute_name  = "Device Type"
      operator        = "startsWith"
      attribute_value = "All Device Types"
    }
    service_name = "Default Device Admin"
  }
}

Once a policy set is created, its UUID is then required to create authentication and authorization rules.

resource "ciscoise_device_administration_authentication_rules" "policy_set_asa_authc_rule_default" {
  parameters {
    policy_id            = <UUID>                  <----- this is where UUID is required
    identity_source_name = "Internal Users"
    if_auth_fail         = "REJECT"
    if_process_fail      = "DROP"
    if_user_not_found    = "REJECT"
    rule {
      name    = "Default"
      state   = "enabled"
      default = "true"
    }
  }
}

In current design, once a resource is created, it's id is returned in a format like "id:=05d9d6fd-f30b-45f2-900f-577948283817\\name:=ASA Firewalls".

It'd be better to return id as just the UUID and name as resource's name, e.g. this will work really well if it was possible.

resource "ciscoise_device_administration_authentication_rules" "policy_set_asa_authc_rule_default" {
  parameters {
    policy_id            = ciscoise_device_administration_policy_set.asa.id
    <-- snippet -->
  }
}

Similarly, if name for a managed resource needs to be referred in other place e.g.

# Network Device Groups
resource "ciscoise_network_device_group" "location_rcdn" {
  parameters {
    othername   = "Location" # NDG Type
    description = "Richardson"
    name = join("#", [
      "Location", "All Locations", "RCDN"
    ])
  }
}

resource "ciscoise_network_device_group" "device_type_firewall" {
  parameters {
    othername   = "Device Type" # NDG Type
    description = "Firewall"
    name = join("#", [
      "Device Type", "All Device Types", "FIREWALL"
    ])
  }
}

## Have to use group names when creating the devices

It'd be idea to work with ciscoise_network_device_group.location_rcdn.name and ciscoise_network_device.device_type_firewall.name.

Describe alternatives you've considered

Alternatives used for id:

  1. Tried to use ciscoise_device_administration_policy_set.asa.parameters[0].id but this is always null
  2. Other option that sort of works for now is converting id to JSON and the decode it.
locals {
  // "id:=05d9d6fd-f30b-45f2-900f-577948283817\\name:=ASA Firewalls"
  policy_set_asa = jsondecode(
    replace(
      replace(
        replace(
          replace(
            ciscoise_device_administration_policy_set.asa.id, "\\", "\", \"" # separator
          ), ":=", "\": \""                                                  # attribute: value
        ), "/^/", "{\""                                                      # start of string
      ), "/$/", "\"}"                                                        # end of string
    )
  )
}

This is quite ugly and will need to be done for every policy set and other similar instances where id of a managed resource needs to be referred in other places. You can suggest better alternatives too. But ideally would just like to refer using resource.id

Alternative used for name:

  1. repeat the same string in every place OR
  2. ciscoise_device_administration_policy_set.asa.parameters[0].name
resource "ciscoise_network_device" "rcdn_asa" {
  parameters {
    name        = "RCDN-ASA01"
    description = "Primary RCDN ASA"
    network_device_group_list = [
      ciscoise_network_device_group.device_type_firewall.parameters[0].name,
      ciscoise_network_device_group.location_rcdn.parameters[0].name
    ]
    network_device_iplist {
      ipaddress = "10.0.0.10"
      mask      = 32
    }
    tacacs_settings {
      shared_secret        = "Cisco!23"
      connect_mode_options = "OFF"
    }
  }
}
fmunozmiranda commented 2 years ago

Hi @chetanph, I think you're taking terraform id, that is why it's hard for you to work with it. The resource attributes come on an item struct, you can take id and name parameters. I'm going let you an example. Let know us if this work for you.

resource "ciscoise_device_administration_authentication_rules" "policy_set_asa_authc_rule_default" {
  parameters {
    policy_id            =  ciscoise_device_administration_policy_set.asa.item[0].id                <----- this is where UUID is required
    identity_source_name = "Internal Users"
    if_auth_fail         = "REJECT"
    if_process_fail      = "DROP"
    if_user_not_found    = "REJECT"
    rule {
      name    = "Default"
      state   = "enabled"
      default = "true"
    }
  }
}

NOTE

In terraform.tfstate you can see more details included on resource


chetanph commented 2 years ago

Thanks @fmunozmiranda! For both id and name, accessing them via resource.item[0] works fine.

fmunozmiranda commented 2 years ago

Happy to help.