fortinetdev / terraform-provider-fortimanager

Mozilla Public License 2.0
11 stars 10 forks source link

fortimanager_wantemp_system_sdwan_service: Variables' types #48

Closed Almujalled closed 6 months ago

Almujalled commented 7 months ago

Issue

FortiManager allows defining a list of source/destination addresses and priority_members. In such a case, the API delivers a list of strings. Currently, the provider is prepared to work with strings only.

Proposed Solution

Define a TypeList instead of TypeString for those parameters in question For instance:


"dst": &schema.Schema{
    Type:     schema.TypeList,
    Optional: true,
},

"src": &schema.Schema{
    Type:     schema.TypeList,
    Optional: true,
},

"priority_members": &schema.Schema{
    Type:     schema.TypeList,
    Optional: true,
},
MaxxLiu22 commented 7 months ago

Hi @Almujalled ,

Thank you for the clarification. We will release the next version soon and this issue will be fixed, In that case, the arguments' type changed from String to List in the latest version of FortiManager, in order to maintain compatibility with both old and new versions, we adjust the configuration accordingly by using string values separated by commas within a string. Here's an example reflecting this approach, will let you know once the new version has been released.

resource "fortimanager_wantemp_system_sdwan_service" "trname" {
  wanprof       = "terr112"
  fosid         = 1
  priority_zone = "virtual-wan-link"
  dst           = "EMS_ALL_UNKNOWN_CLIENTS, FABRIC_DEVICE"  <----------------
  src           = "all"
  depends_on    = [fortimanager_wan_template.trname4]
}

resource "fortimanager_wan_template" "trname4" {
  name = "terr112"
  adom = "root"
  type = "wanprof"
}

Thanks, Maxx

MaxxLiu22 commented 7 months ago

Hi @Almujalled ,

FortiManager Provider 1.11.0 was released yesterday. Please upgrade to it, and this issue should be fixed

Thanks, Maxx

Almujalled commented 7 months ago

Hi @MaxxLiu22,

I have tried the string values separated by commas within a string with the new release. At the first apply I am getting the following error message in the terminal and the resource is not created (Or maybe not visible in GUI):

╷
│ Error: Provider produced inconsistent result after apply
│ 
│ When applying changes to module.sdwan_rules.fortimanager_wantemp_system_sdwan_service.this["01_Hub_Fortimanager"], provider
│ "provider[\"registry.terraform.io/fortinetdev/fortimanager\"]" produced an unexpected new value: Root object was present, but now absent.
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

When I try a second apply, the resource gets created but I get a duplicate resource error in the terminal:

╷
│ Error: Error creating WantempSystemSdwanService resource: 
│ err -10033: service/2/name : duplicate. object: system sdwan service name. detail: entry "01_Hub_Fortimanager" duplicated within category "system sdwan service"
│ 
│   with module.sdwan_rules.fortimanager_wantemp_system_sdwan_service.this["01_Hub_Fortimanager"],
│   on .terraform/modules/sdwan_rules/fortinet/fortimanager/sdwan_rules/main.tf line 17, in resource "fortimanager_wantemp_system_sdwan_service" "this":
│   17: resource "fortimanager_wantemp_system_sdwan_service" "this" {
│ 
╵

Here is the module I am using:

locals {
  scopetype = "adom"
  adom      = var.fmgadom
  param     = var.fmgadom
}

resource "fortimanager_exec_workspace_action" "lock" {
  scopetype      = local.scopetype
  adom           = local.adom
  action         = "lockbegin"
  target         = ""
  param          = local.param
  force_recreate = uuid()
  comment        = "Locking ADOM ${local.adom}"
}

resource "fortimanager_wantemp_system_sdwan_service" "this" {
    for_each = var.sdwan_rules

    scopetype        = local.scopetype
    adom             = local.adom

    name             = each.key
    wanprof          = each.value.sdwan_templates
    src              = each.value.src
    dst              = each.value.dst
    priority_members = each.value.priority_members
    protocol         = each.value.protocol
    tie_break        = each.value.tie_break
    sla {
      health_check = each.value.health_check      
    }
    status           = each.value.status

    depends_on = [ fortimanager_exec_workspace_action.lock ]
}

resource "fortimanager_exec_workspace_action" "unlock" {
  scopetype      = local.scopetype
  adom           = local.adom
  action         = "lockend"
  target         = ""
  param          = local.param
  force_recreate = uuid()
  comment        = "Unlocking ADOM ${local.adom}"

  depends_on = [fortimanager_wantemp_system_sdwan_service.this]
}

Here its variables:

variable "sdwan_rules" {
  description = "Map of SD-WAN rules"
  type = map(object({
    sdwan_templates = string
    src = string
    dst = string
    priority_members = string
    protocol = string
    tie_break = string
    health_check = string
    status = string
  }))
  default = {}
}

Here is an example tfvar:

sdwan_rules = {
  "01_Hub_Fortimanager" = {
    sdwan_templates = "SD-WAN_Hub"
    src = "all"
    dst = "SOME_DST_01, SOME_DST_02"
    priority_members = "1, 2"
    protocol = 0
    tie_break = "zone"
    health_check = "ping_internet"
    status = "enable"
  }
}

Any suggestions for troubleshooting? Or is it a bug within the latest release as Terraform is suggesting at the first apply?

MaxxLiu22 commented 7 months ago

Hi @Almujalled ,

Sorry for the inconvenience, and thank you for the detailed information. The reason causing this error, Provider produced inconsistent result after apply is the missing fosid in the fortimanager_wantemp_system_sdwan_service resource. This keyword would be used by Terraform to locate your remote device object. However, when creating, if this argument is not set, the object can still be created with an FMG auto-generated fosid, but Terraform doesn't know that. That is why, when you apply again, Terraform shows there is a duplicate object. I will report this to the development team for improvement. Let me know if adding fosid doesn't solve your issue.

resource "fortimanager_wantemp_system_sdwan_service" "this" { for_each = var.sdwan_rules

scopetype        = local.scopetype
adom             = local.adom
fosid              = 12   --------> any number you specify to substitute auto-generate id
name             = each.key
wanprof          = each.value.sdwan_templates
src              = each.value.src
dst              = each.value.dst
priority_members = each.value.priority_members
protocol         = each.value.protocol
tie_break        = each.value.tie_break
sla {
  health_check = each.value.health_check      
}
status           = each.value.status

depends_on = [ fortimanager_exec_workspace_action.lock ]

}

Thanks, Maxx