Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opsgenie_integration_action conditions order is not stable causing "in-place" updates though nothing changes #430

Closed
granter1 opened this issue Apr 11, 2024 · 12 comments

Comments

@granter1
Copy link

granter1 commented Apr 11, 2024

Hi there,

Thank you for opening an issue. Please note that we try to keep the Terraform issue tracker reserved for bug reports and feature requests. For general usage questions, please see: https://www.terraform.io/community.html.

Terraform Version

Terraform v1.3.6
on darwin_arm64

  • provider registry.terraform.io/opsgenie/opsgenie v0.6.35

Affected Resource(s)

Please list the resources as a list, for example:

  • opsgenie_integration_action

Terraform Configuration Files

resource "opsgenie_integration_action" "integration_action" {
  integration_id = my_integration.id

  create {
    name = "createAction"
    order = 1
    ...
    filter {
      type = "match-all-conditions"
      conditions {
        field = "Subject"
        operation = "contains"
        expected_value = "FIRING"
      }
      conditions {
        field = "eventType"
        operation = "equals"
        expected_value = "create"
      }
   ...

Expected Behavior

opsgenie_integration_action Filter Conditions should be ordered and idempotent. Running a new plan without any changes should show no changes

Actual Behavior

When replanning without any code changes, the Conditions list order is constantly changing and updated in-place. No amount of applies or reordering fixes this

!       create {
            name                                 = "createAction"
            # (18 unchanged attributes hidden)

!           filter {
                # (1 unchanged attribute hidden)

!               conditions {
!                   expected_value = "create" -> "FIRING"
!                   field          = "event_type" -> "Subject"
!                   operation      = "equals" -> "contains"
!                   order          = 0 -> 1
                    # (1 unchanged attribute hidden)
                }
!               conditions {
!                   expected_value = "FIRING" -> "create"
!                   field          = "subject" -> "eventType"
!                   operation      = "contains" -> "equals"
!                   order          = 0 -> 2
                    # (1 unchanged attribute hidden)
                }
            }
        }
    }

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Create integration_action with more than 1 conditions attribute
  2. terraform plan
  3. terraform apply
  4. terraform plan

Important Factoids

This is the same for all integration_actions; create, close, acknowledge, ignore, add_note

References

This looks to be a similar issue as to the one raised and solved in #332

granter1 added a commit to granter1/terraform-provider-opsgenie that referenced this issue Apr 11, 2024
@bendyna-vitalii
Copy link

+1

@mcbrineellis
Copy link

I have the same issue. Have opened a support ticket with Atlassian regarding this.

@mcbrineellis
Copy link

Opsgenie has opened this issue based on my support request:
https://jira.atlassian.com/browse/OPSGENIE-2160

Please vote and follow over there if you're impacted.

@mcbrineellis
Copy link

mcbrineellis commented Jul 17, 2024

Atlassian has marked OPSGENIE-2160 as resolved. I assume this means the fix will be coming in a release soon?

@stonkie
Copy link

stonkie commented Jul 17, 2024

Atlassian has marked OPSGENIE-2160 as resolved. I assume this means the fix will be coming in a release soon?

@mcbrineellis I think the issue should be reopened. The guy who closed it merged this PR the same day : #440

It deployed as version 0.6.36 of the provider which I tested and still has the issue. I can't tell how the code change could have fixed the issue either.

@mcbrineellis
Copy link

Atlassian has marked OPSGENIE-2160 as resolved. I assume this means the fix will be coming in a release soon?

@mcbrineellis I think the issue should be reopened. The guy who closed it merged this PR the same day : #440

It deployed as version 0.6.36 of the provider which I tested and still has the issue. I can't tell how the code change could have fixed the issue either.

Yeah I had the same thought. I'll open another support ticket to ask more details. Kind of irritating that Atlassian isn't responding to issues reported here...

@koushik-swaminathan
Copy link
Contributor

koushik-swaminathan commented Jul 18, 2024

Hi @mcbrineellis, there seems to be a misunderstanding, the ticket was closed by mistake assuming it was fixed since a ticket with a similar issue was closed. I'm taking a look at this ticket, apologies!

@koushik-swaminathan
Copy link
Contributor

Hi @granter1 , @stonkie and @mcbrineellis
I have fixed the issue in the latest release (v0.6.37). Please let me know if this version fixes the drift.

@mcbrineellis
Copy link

Nice!!! Just did a quick test and it looks good to me. Finally my terraform plans will actually show my changes!

No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.

Great work @koushik-swaminathan I appreciate that :)

@granter1
Copy link
Author

@mcbrineellis @koushik-swaminathan - the error is still occurring for me on opsgenie/opsgenie v0.6.37.

What am I missing here? I've tried completely destroying the integrations and recreating fresh, also tried the order value starting at 0 and 1. The outcome is the same each time

@mcbrineellis
Copy link

@mcbrineellis @koushik-swaminathan - the error is still occurring for me on opsgenie/opsgenie v0.6.37.

What am I missing here? I've tried completely destroying the integrations and recreating fresh, also tried the order value starting at 0 and 1. The outcome is the same each time

Hmm, can you share an example of your integration action code? It’s working as expected for me now.

@admerzeau
Copy link

Hi @koushik-swaminathan, @mcbrineellis,

I've encountered the same issue while using version v0.6.37 of the Opsgenie provider.

Below is a minimal Terraform configuration that demonstrates the problem:

terraform {
  required_providers {
    opsgenie = {
      source  = "opsgenie/opsgenie"
      version = "0.6.37"
    }
  }
}

provider "opsgenie" {
  api_key = "my-key"
}

resource "opsgenie_api_integration" "cloudwatch" {
  name = "cloudwatch-tf"
  type = "CloudWatch"

  enabled = true
}

resource "opsgenie_integration_action" "this" {

  count          = 1
  integration_id = opsgenie_api_integration.cloudwatch.id

  dynamic "create" {
    for_each = { for idx, alert in var.alerts : idx + 1 => alert }
    content {
      name    = create.value.name
      order   = create.key
      tags    = concat(create.value.tags, ["cloudwatch"])
      user    = "CloudWatch"
      note    = try(create.value.note, null)
      alias   = "{{Region}} - {{AlarmName}}"
      source  = try(create.value.source, null)
      message = try(create.value.message, "{{Subject}}")

      description = chomp(join("\n", compact([
        "{{AlarmDescription}}",
        "{{NewStateReason}}",
        try(create.value.runbook, null) != null ? "Runbook: ${create.value.runbook}" : null,
        try(create.value.dashboard, null) != null ? "Dashboard: ${create.value.dashboard}" : null,
        "Time: {{StateChangeTime}}"
      ])))

      entity                         = try(create.value.entity, null)
      alert_actions                  = try(create.value.alert_action, null)
      priority                       = try(create.value.priority, "{{priority}}")
      extra_properties               = try(create.value.extra_properties, {})
      custom_priority                = try(create.value.custom_priority, null)
      ignore_responders_from_payload = try(create.value.ignore_responders_from_payload, false)
      ignore_teams_from_payload      = try(create.value.ignore_teams_from_payload, false)

      filter {
        type = "match-all-conditions"
        conditions {
          field          = "NewStateValue"
          operation      = "contains"
          expected_value = "ALARM"
        }
        conditions {
          field          = "AlarmName"
          operation      = "equals"
          expected_value = create.value.name
        }
      }

      dynamic "responders" {
        for_each = create.value.opgenie_team != null ? [create.value.opgenie_team] : []
        content {
          id   = data.opsgenie_team.teams[create.value.opgenie_team].id
          type = "team"
        }
      }

    }
  }

  close {
    name  = "Close alert"
    alias = "{{Region}} - {{AlarmName}}"
    filter {
      type = "match-all-conditions"
      conditions {
        field          = "NewStateValue"
        operation      = "equals"
        expected_value = "OK"
      }
      conditions {
        field          = "OldStateValue"
        operation      = "equals"
        expected_value = "ALARM"
      }
    }
  }

}

output "api_key" {
  value     = opsgenie_api_integration.cloudwatch.api_key
  sensitive = true
}

data "opsgenie_team" "teams" {
  for_each = { for alert in var.alerts : alert.opgenie_team => alert if alert.opgenie_team != null }

  name = each.key
}

variable "alerts" {
  type = list(object({
    name         = string
    tags         = optional(list(string), [])
    priority     = string
    source       = optional(string, "CloudWatch")
    message      = optional(string, "{{Subject}}")
    runbook      = optional(string)
    dashboard    = optional(string)
    opgenie_team = optional(string)
  }))
  default = [
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 1"
    "opgenie_team" = null
    "priority" = "P2"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 2"
    "opgenie_team" = null
    "priority" = "P2"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 3"
    "opgenie_team" = null
    "priority" = "P2"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 4"
    "opgenie_team" = null
    "priority" = "P2"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 5"
    "opgenie_team" = null
    "priority" = "P3"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 6"
    "opgenie_team" = null
    "priority" = "P2"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 7"
    "opgenie_team" = null
    "priority" = "P2"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 8"
    "opgenie_team" = null
    "priority" = "P1"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 9"
    "opgenie_team" = null
    "priority" = "P1"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  },
  {
    "dashboard" = null
    "message" = "{{Subject}}"
    "name" = "Alert 10"
    "opgenie_team" = null
    "priority" = "P3"
    "runbook" = null
    "source" = "CloudWatch"
    "tags" = []
  }
]
}

I did some testing and noticed that the issue only arises when more than 10 actions are added hence it seems that the problem is related to how the provider paginates results from the GET /actions/ and compares them with the Terraform state; but this is just a guess.

To avoid getting into the permanent drift in the above code just remove any item in the alerts list.

Let me know if any additional information is needed. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants