PaloAltoNetworks / terraform-provider-prismacloud

Terraform PrismaCloud provider
https://www.terraform.io/docs/providers/prismacloud/
Mozilla Public License 2.0
54 stars 65 forks source link

Saved search cannot be deleted #181

Open rinaudjaws opened 1 year ago

rinaudjaws commented 1 year ago

Hello,

Can we reopen and review this issue? https://github.com/PaloAltoNetworks/terraform-provider-prismacloud/issues/20. I'm facing the same issue that saved searches are not destroyed which leads to manually deleting the resources from the console.

Regards, Joaquin

welcome-to-palo-alto-networks[bot] commented 1 year ago

:tada: Thanks for opening your first issue here! Welcome to the community!

rinaudjaws commented 1 year ago

Any update on this issue?

nikitapanw commented 1 year ago

Hello @rinaudjaws, Could you share more details on this, we tried reproducing the issue from our end, but we are not able to reproduce it. Saved search destroy is working fine for us. If you are trying to delete the saved-search which is attached to the policy, then it can't be deleted, you need to delete the policy first to delete the saved search. Thanks

comrumino commented 8 months ago

@nikitapanw , the issue can be reproduced below. I believe the update code is missing Saved = true, per prisma-cloud-go source and api docs: "A best practice is to copy data from the results of a search history, update the data as necessary, and set the saved parameter to true."

resource "terraform_data" "query" {
  # Used as a lifecycle trigger to force recreate of prismacloud_rql_search whenever the query changes.
  # It is advised to remove the rql search from state whenever it is necessary to update the query
  # - https://registry.terraform.io/providers/PaloAltoNetworks/prismacloud/latest/docs/resources/saved_search
  input = replace(var.search_rql_syntax, "\n", " ")
}

resource "prismacloud_rql_search" "this" {
  search_type = var.search_query_type
  query       = terraform_data.query.output
  limit       = -1
  skip_result = true
  time_range {
    relative {
      unit   = var.search_time_unit
      amount = var.search_time_amount
    }
  }
}

resource "prismacloud_saved_search" "this" {
  name        = local.search_query_name
  description = var.search_policy_description
  search_id   = prismacloud_rql_search.this.search_id
  query       = prismacloud_rql_search.this.query
  cloud_type  = var.search_policy_cloud_type
  time_range {
    relative {
      unit   = prismacloud_rql_search.this.time_range[0].relative[0].unit
      amount = prismacloud_rql_search.this.time_range[0].relative[0].amount
    }
  }
  lifecycle {
    replace_triggered_by = [terraform_data.query]
  }
}

Hope that helps!

comrumino commented 8 months ago

@jamesholland-uk @btorresgil , any chance someone from Palo would accept a PR on this bug?

jamesholland-uk commented 8 months ago

@comrumino: I'm redirecting this question to @AnushreeHS, I'm not involved in this provider

comrumino commented 7 months ago

Thanks! I wasn't sure who is.

comrumino commented 7 months ago

@nikitapanw @rinaudjaws this is how we worked around the limitation in our internal module.

resource "terraform_data" "query" {
  # Used as a lifecycle trigger to force recreate of prismacloud_rql_search whenever the query changes.
  # It is advised to remove the rql search from state whenever it is necessary to update the query
  # - https://registry.terraform.io/providers/PaloAltoNetworks/prismacloud/latest/docs/resources/saved_search
  input = replace(var.rql_search_query, "\n", " ")
}

resource "prismacloud_rql_search" "this" {
  search_type = var.rql_search_type
  query       = terraform_data.query.output
  limit       = -1
  skip_result = true
  time_range {
    relative {
      unit   = var.search_time_unit
      amount = var.search_time_amount
    }
  }
  lifecycle {
    replace_triggered_by = [terraform_data.query]
  }
}

resource "time_static" "this" {
  # Workaround for https://github.com/PaloAltoNetworks/terraform-provider-prismacloud/issues/181
  # This timestamp is updated whenever the query changes. By giving a saved search a new name
  # and using for_each, we can create a different resource while avoiding name collision and remove
  # the old saved search from state. See terraform_data.query comment for more details.
  lifecycle {
    replace_triggered_by = [terraform_data.query]
  }
}

resource "prismacloud_saved_search" "this" {
  for_each    = toset([var.rql_search_query]) # Workaround for issues/181
  name        = "${var.policy_name} ${time_static.this.rfc3339}"
  description = var.policy_description
  search_id   = prismacloud_rql_search.this.search_id
  query       = prismacloud_rql_search.this.query
  cloud_type  = var.policy_cloud_type
  time_range {
    relative {
      unit   = prismacloud_rql_search.this.time_range[0].relative[0].unit
      amount = prismacloud_rql_search.this.time_range[0].relative[0].amount
    }
  }
}

resource "prismacloud_policy" "this" {
  name                     = var.policy_name
  description              = var.policy_description
  policy_type              = lookup(lookup(var.prisma_rqlsearch_type_to_policy_types, var.rql_search_type, {}), "policy_type", "")
  cloud_type               = var.policy_cloud_type
  enabled                  = var.policy_enabled
  restrict_alert_dismissal = var.policy_restrict_alert_dismissal
  recommendation           = var.policy_remediation_recommendation
  rule {
    name     = var.policy_name
    criteria = prismacloud_saved_search.this[var.rql_search_query].search_id
    parameters = {
      "savedSearch" : "true",
      "withIac" : "false",
    }
    rule_type = lookup(lookup(var.prisma_rqlsearch_type_to_policy_types, var.rql_search_type, {}), "policy_rule_type", "")
  }
  severity = var.policy_severity

  dynamic "compliance_metadata" {
    for_each = var.compliance_metadata
    content {
      compliance_id = compliance_metadata.value["compliance_id"]
    }
  }
}
comrumino commented 7 months ago

@AnushreeHS can you review the PR.