jfrog / terraform-provider-xray

Terraform provider to manage JFrog Xray
https://jfrog.com/xray/
Apache License 2.0
149 stars 12 forks source link

xray_ignore_rule doesnt have an update resource function, causes error #156

Closed gschaffer-cxn closed 8 months ago

gschaffer-cxn commented 8 months ago

Describe the bug We wanted to change and xray ignore rule to edit the component being edited. The change is very basic just remove the component version

Requirements for and issue Perform a basic update on a resource

     -  component_name  = "gav://org.yaml:snakeyaml:1.33"
    +  component_name  = "gav://org.yaml:snakeyaml
  # xray_ignore_rule.compontent["IR44"] will be updated in-place
  ~ resource "xray_ignore_rule" "compontent" {
        id         = "doesnt matter"
        # (6 unchanged attributes hidden)
      - component {
          - name = "gav://org.yaml:snakeyaml:1.33" -> null
        }
      + component {
          + name = "gav://org.yaml:snakeyaml"
        }
    }

Expected behavior Terraform updates the resource

Additional context Terraform produces an error like this

│ Error: doesn't support update
│ 
│   with xray_ignore_rule.compontent["IR44"],
│   on ignore_rules.tf line 1, in resource "xray_ignore_rule" "compontent":
│    1: resource "xray_ignore_rule" "compontent" {
│ 
╵

My quick investigation produces that ignore_rule doesnt have an update function specified, so if my understanding is correct it causes the error. https://github.com/jfrog/terraform-provider-xray/blob/bc0277c8e6b2aba32ac252954bd1708e66249a6e/pkg/xray/resource_xray_ignore_rule.go#L549

The error message is generated when terraform tries to call the update function of that schema https://github.com/hashicorp/terraform/blob/main/internal/legacy/helper/schema/resource.go#L314

alexhung commented 8 months ago

@gschaffer-cxn This is because the Xray API for Ignore Rules do not support update.

I will need to mark the name attribute with ForceNew: true so that when it is changed, Terraform will know to delete the original resource and create a new one.

gschaffer-cxn commented 8 months ago

@alexhung figured its something like this. I was able to use null resource and lfecycle rules to set up a parameterzed ForceNew like behavior, but hope this gets implemented soon.

resource "null_resource" "ignore_rule_trigger" {
  for_each = local.xray_component_ignore_rules
  # Changes to any input variable would require a retrigger
  triggers = {
    notes = each.value.notes
    # trigger requires everything to be string
    cves = join(",", each.value.vulnerabilities)
    component_name = each.value.component_name
  }
}

resource "xray_ignore_rule" "compontent" {
  for_each = local.xray_component_ignore_rules
  # note can be max 255 characters, trimming
  notes           = substr("${each.key}-${each.value.notes}", 0, 255)
  cves = each.value.vulnerabilities
  component {
    name = each.value.component_name
  }

  lifecycle {
    replace_triggered_by = [null_resource.ignore_rule_trigger[each.key]]
  }
}

This causes the null resource to count as trigger for replacement, and replace_triggered_by can act on this. Not the prettiest workaround but its better than manual tainting.

alexhung commented 8 months ago

@gschaffer-cxn I've released a new version which should trigger Terraform to re-create the resource if name, version, etc. is changed.