terraform-provider-pagerduty: pagerduty_ruleset_rule - empty conditions block causes crash

The PagerDuty provider documentation implies that the way to configure a catch-all rule in a ruleset is via an empty conditions block:

conditions - (Required) Conditions evaluated to check if an event matches this event rule. Is always empty for the catch all rule, though.

However, creating a ruleset rule resource with an empty conditions block results in a crash during the apply phase.

Terraform Version

Terraform v0.12.29
+ provider.newrelic v2.6.0
+ provider.pagerduty v1.7.9

Affected Resource(s)

Please list the resources as a list, for example:

  • pagerduty_ruleset_rule

Terraform Configuration Files

resource "pagerduty_ruleset" "test_ruleset" {
  name = "Test rule set"
  team {
    id = pagerduty_team.covid_green_team.id
  }
}

resource "pagerduty_ruleset_rule" "only_prod_high_priority" {
  ruleset = pagerduty_ruleset.test_ruleset.id
  position = 0
  conditions {
    operator = "and"
    subconditions {
      operator = "contains"
      parameter {
        value = "DEV"
        path = "policy_name"
      }
    }
  }
  actions {
    severity {
      value = "info"
    }
    route {
      value = pagerduty_service.newrelic.id
    }
  }
}

resource "pagerduty_ruleset_rule" "default_route" {
  ruleset = pagerduty_ruleset.test_ruleset.id
  position = 1
  conditions {}
  actions {
    severity {
      value = "warning"
    }
    route {
      value = pagerduty_service.newrelic.id
    }
  }
}

Panic Output

Terraform did panic but the crash log contains some proprietary information. The stack trace from the crash:

panic: interface conversion: interface {} is nil, not map[string]interface {}
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: goroutine 164 [running]:       
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: github.com/terraform-providers/terraform-provider-pagerduty/pagerduty.expandConditions(0xe5b160, 0xc000421630, 0xa)
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    github.com/terraform-providers/terraform-provider-pagerduty@/pagerduty/resource_pagerduty_ruleset_rule.go:290 +0x294
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: github.com/terraform-providers/terraform-provider-pagerduty/pagerduty.buildRulesetRuleStruct(0xc00027f420, 0xc0005bfa80)
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    github.com/terraform-providers/terraform-provider-pagerduty@/pagerduty/resource_pagerduty_ruleset_rule.go:267 +0x100
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: github.com/terraform-providers/terraform-provider-pagerduty/pagerduty.resourcePagerDutyRulesetRuleCreate(0xc00027f420, 0xf8b240, 0xc00039ee60, 0x2, 0x1995cc0)
2020-08-26T22:42:38.867-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    github.com/terraform-providers/terraform-provider-pagerduty@/pagerduty/resource_pagerduty_ruleset_rule.go:599 +0x4b
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: github.com/hashicorp/terraform-plugin-sdk/helper/schema.(*Resource).Apply(0xc000112280, 0xc0004e1950, 0xc0005bfa80, 0xf8b240, 0xc00039ee60, 0xc000254701, 0xc00024f920, 0xc0002547f0)
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    github.com/hashicorp/terraform-plugin-sdk@v1.7.0/helper/schema/resource.go:305 +0x36c
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: github.com/hashicorp/terraform-plugin-sdk/helper/schema.(*Provider).Apply(0xc000112580, 0xc000421918, 0xc0004e1950, 0xc0005bfa80, 0xc00024d168, 0xc0000bd8b8, 0xec0f00)
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    github.com/hashicorp/terraform-plugin-sdk@v1.7.0/helper/schema/provider.go:294 +0xa0
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: github.com/hashicorp/terraform-plugin-sdk/internal/helper/plugin.(*GRPCProviderServer).ApplyResourceChange(0xc0000bc560, 0x127dba0, 0xc000231890, 0xc0004c7380, 0xc0000bc560, 0xc000231890, 0xc000415a80)
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    github.com/hashicorp/terraform-plugin-sdk@v1.7.0/internal/helper/plugin/grpc_provider.go:885 +0x8bb
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: github.com/hashicorp/terraform-plugin-sdk/internal/tfplugin5._Provider_ApplyResourceChange_Handler(0xff5a00, 0xc0000bc560, 0x127dba0, 0xc000231890, 0xc0004c7320, 0x0, 0x127dba0, 0xc000231890, 0xc0001b6480, 0x219)
2020-08-26T22:42:38.868-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    github.com/hashicorp/terraform-plugin-sdk@v1.7.0/internal/tfplugin5/tfplugin5.pb.go:3189 +0x21e
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: google.golang.org/grpc.(*Server).processUnaryRPC(0xc0003a0160, 0x1289980, 0xc0004b1080, 0xc000140600, 0xc000130690, 0x196bd40, 0x0, 0x0, 0x0)      
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    google.golang.org/grpc@v1.23.0/server.go:995 +0x467
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: google.golang.org/grpc.(*Server).handleStream(0xc0003a0160, 0x1289980, 0xc0004b1080, 0xc000140600, 0x0)
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    google.golang.org/grpc@v1.23.0/server.go:1275 +0xd9e
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: google.golang.org/grpc.(*Server).serveStreams.func1.1(0xc000034160, 0xc0003a0160, 0x1289980, 0xc0004b1080, 0xc000140600)
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    google.golang.org/grpc@v1.23.0/server.go:710 +0xc2
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe: created by google.golang.org/grpc.(*Server).serveStreams.func1
2020-08-26T22:42:38.869-0400 [DEBUG] plugin.terraform-provider-pagerduty_v1.7.9.exe:    google.golang.org/grpc@v1.23.0/server.go:708 +0xa8

Expected Behavior

What should have happened?

I expected the provider to create a catch-all rule in my rule set.

Actual Behavior

What actually happened?

Terraform crashed.

Steps to Reproduce

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

  1. Create a manifest with a ruleset and a rule set rule with an empty conditions block
  2. Apply and watch it crash

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 15
  • Comments: 17 (8 by maintainers)

Most upvoted comments

@stmcallister thanks for the details, sounds logical.

But, IMHO, there’s a misalignment between PagerDuty API and terraform provider here. Terraform provider makes possible to create a catch-all rule, which is unsupported by the API. As you said, the catch-all rule is created at the same time as its ruleset.

The only solution we currently have is to import the catch-all rule into terraform before being able to update it. Unfortunately, terraform doesn’t allow to automagically import resources when applying a configuration. That make manual work mandatory, which in turns breaks a full gitops workflow.

Another solution could be: since the catch-all rule is automatically created right after the ruleset, we can (and should) consider it as a ruleset property. Thus, having a ruleset resource like:

resource "pagerduty_ruleset" "foo" {
    name = "Primary Ruleset"
    team {
        id = pagerduty_team.foo.id
    }
    default_action {
        [like pagerduty_ruleset_rule resource definition]
    }
}

Would allow people to create ruleset AND corresponding catch-all customization in a single operation.

Hope this will help

@stmcallister any news on this topic ? It would be a very usefull improvement to avoid multiple “apply/import/update/apply” setup

As discussed during Quaterly Terraform Roundtable, another design is to add the catch_all only into pagerduty_ruleset block. Using previous example, it could be like:

resource "pagerduty_ruleset" "foo" {
    name = "Primary Ruleset"
    team {
        id = pagerduty_team.foo.id
    }
    default_action {
      route {
        value = pagerduty_service.catch_all_service.id
      }
    }
}