diff --git a/docs/resources/contact_point.md b/docs/resources/contact_point.md
index 058b2f72a..3c31518a9 100644
--- a/docs/resources/contact_point.md
+++ b/docs/resources/contact_point.md
@@ -50,6 +50,7 @@ resource "grafana_contact_point" "my_contact_point" {
- `googlechat` (Block Set) A contact point that sends notifications to Google Chat. (see [below for nested schema](#nestedblock--googlechat))
- `kafka` (Block Set) A contact point that publishes notifications to Apache Kafka topics. (see [below for nested schema](#nestedblock--kafka))
- `line` (Block Set) A contact point that sends notifications to LINE.me. (see [below for nested schema](#nestedblock--line))
+- `mqtt` (Block Set) A contact point that sends notifications to an MQTT broker. (see [below for nested schema](#nestedblock--mqtt))
- `oncall` (Block Set) A contact point that sends notifications to Grafana On-Call. (see [below for nested schema](#nestedblock--oncall))
- `opsgenie` (Block Set) A contact point that sends notifications to OpsGenie. (see [below for nested schema](#nestedblock--opsgenie))
- `org_id` (String) The Organization ID. If not set, the Org ID defined in the provider block will be used.
@@ -212,6 +213,29 @@ Read-Only:
- `uid` (String) The UID of the contact point.
+
+### Nested Schema for `mqtt`
+
+Required:
+
+- `broker_url` (String) The URL of the MQTT broker.
+- `topic` (String) The topic to publish messages to.
+
+Optional:
+
+- `client_id` (String) The client ID to use when connecting to the broker.
+- `disable_resolve_message` (Boolean) Whether to disable sending resolve messages. Defaults to `false`.
+- `insecure_skip_verify` (Boolean) Whether to skip verification of the server's certificate chain and host name. Defaults to `false`.
+- `message_format` (String) The format of the message to send. Supported values are `json` and `text`.
+- `password` (String, Sensitive) The password to use when connecting to the broker.
+- `settings` (Map of String, Sensitive) Additional custom properties to attach to the notifier. Defaults to `map[]`.
+- `username` (String) The username to use when connecting to the broker.
+
+Read-Only:
+
+- `uid` (String) The UID of the contact point.
+
+
### Nested Schema for `oncall`
diff --git a/examples/resources/grafana_contact_point/_acc_receiver_types.tf b/examples/resources/grafana_contact_point/_acc_receiver_types.tf
index 752b5dda2..52938a087 100644
--- a/examples/resources/grafana_contact_point/_acc_receiver_types.tf
+++ b/examples/resources/grafana_contact_point/_acc_receiver_types.tf
@@ -54,6 +54,16 @@ resource "grafana_contact_point" "receiver_types" {
description = "description"
}
+ mqtt {
+ broker_url = "tcp://localhost:1883"
+ topic = "grafana/alerts"
+ client_id = "client_id"
+ message_format = "json"
+ username = "username"
+ password = "password"
+ insecure_skip_verify = false
+ }
+
opsgenie {
url = "http://opsgenie-api"
api_key = "token"
diff --git a/internal/resources/grafana/resource_alerting_contact_point.go b/internal/resources/grafana/resource_alerting_contact_point.go
index 9f43d236c..0eac8352a 100644
--- a/internal/resources/grafana/resource_alerting_contact_point.go
+++ b/internal/resources/grafana/resource_alerting_contact_point.go
@@ -28,6 +28,7 @@ var (
googleChatNotifier{},
kafkaNotifier{},
lineNotifier{},
+ mqttNotifier{},
oncallNotifier{},
opsGenieNotifier{},
pagerDutyNotifier{},
diff --git a/internal/resources/grafana/resource_alerting_contact_point_notifiers.go b/internal/resources/grafana/resource_alerting_contact_point_notifiers.go
index fee1ef7e3..16af413f8 100644
--- a/internal/resources/grafana/resource_alerting_contact_point_notifiers.go
+++ b/internal/resources/grafana/resource_alerting_contact_point_notifiers.go
@@ -619,6 +619,105 @@ func (o lineNotifier) unpack(raw interface{}, name string) *models.EmbeddedConta
}
}
+type mqttNotifier struct{}
+
+var _ notifier = (*mqttNotifier)(nil)
+
+func (o mqttNotifier) meta() notifierMeta {
+ return notifierMeta{
+ field: "mqtt",
+ typeStr: "mqtt",
+ desc: "A contact point that sends notifications to an MQTT broker.",
+ secureFields: []string{"password"},
+ }
+}
+
+func (o mqttNotifier) schema() *schema.Resource {
+ r := commonNotifierResource()
+ r.Schema["broker_url"] = &schema.Schema{
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The URL of the MQTT broker.",
+ }
+ r.Schema["topic"] = &schema.Schema{
+ Type: schema.TypeString,
+ Required: true,
+ Description: "The topic to publish messages to.",
+ }
+ r.Schema["client_id"] = &schema.Schema{
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The client ID to use when connecting to the broker.",
+ }
+ r.Schema["message_format"] = &schema.Schema{
+ Type: schema.TypeString,
+ Optional: true,
+ ValidateFunc: validation.StringInSlice([]string{"json", "text"}, false),
+ Description: "The format of the message to send. Supported values are `json` and `text`.",
+ }
+ r.Schema["username"] = &schema.Schema{
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "The username to use when connecting to the broker.",
+ }
+ r.Schema["password"] = &schema.Schema{
+ Type: schema.TypeString,
+ Optional: true,
+ Sensitive: true,
+ Description: "The password to use when connecting to the broker.",
+ }
+ r.Schema["insecure_skip_verify"] = &schema.Schema{
+ Type: schema.TypeBool,
+ Optional: true,
+ Default: false,
+ Description: "Whether to skip verification of the server's certificate chain and host name.",
+ }
+ return r
+}
+
+func (o mqttNotifier) pack(p *models.EmbeddedContactPoint, data *schema.ResourceData) (interface{}, error) {
+ notifier := packCommonNotifierFields(p)
+ settings := p.Settings.(map[string]interface{})
+
+ packNotifierStringField(&settings, ¬ifier, "brokerUrl", "broker_url")
+ packNotifierStringField(&settings, ¬ifier, "topic", "topic")
+ packNotifierStringField(&settings, ¬ifier, "clientId", "client_id")
+ packNotifierStringField(&settings, ¬ifier, "messageFormat", "message_format")
+ packNotifierStringField(&settings, ¬ifier, "username", "username")
+ if v, ok := settings["insecureSkipVerify"]; ok && v != nil {
+ notifier["insecure_skip_verify"] = v.(bool)
+ delete(settings, "insecureSkipVerify")
+ }
+
+ packSecureFields(notifier, getNotifierConfigFromStateWithUID(data, o, p.UID), o.meta().secureFields)
+
+ notifier["settings"] = packSettings(p)
+ return notifier, nil
+}
+
+func (o mqttNotifier) unpack(raw interface{}, name string) *models.EmbeddedContactPoint {
+ json := raw.(map[string]interface{})
+ uid, disableResolve, settings := unpackCommonNotifierFields(json)
+
+ unpackNotifierStringField(&json, &settings, "broker_url", "brokerUrl")
+ unpackNotifierStringField(&json, &settings, "topic", "topic")
+ unpackNotifierStringField(&json, &settings, "client_id", "clientId")
+ unpackNotifierStringField(&json, &settings, "message_format", "messageFormat")
+ unpackNotifierStringField(&json, &settings, "username", "username")
+ unpackNotifierStringField(&json, &settings, "password", "password")
+ if v, ok := json["insecure_skip_verify"]; ok && v != nil {
+ settings["insecureSkipVerify"] = v.(bool)
+ }
+
+ return &models.EmbeddedContactPoint{
+ UID: uid,
+ Name: name,
+ Type: common.Ref(o.meta().typeStr),
+ DisableResolveMessage: disableResolve,
+ Settings: settings,
+ }
+}
+
type oncallNotifier struct {
}
diff --git a/internal/resources/grafana/resource_alerting_contact_point_test.go b/internal/resources/grafana/resource_alerting_contact_point_test.go
index a14c91bf4..064751387 100644
--- a/internal/resources/grafana/resource_alerting_contact_point_test.go
+++ b/internal/resources/grafana/resource_alerting_contact_point_test.go
@@ -203,6 +203,15 @@ func TestAccContactPoint_notifiers(t *testing.T) {
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "line.0.token", "token"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "line.0.title", "title"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "line.0.description", "description"),
+ // mqtt
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.#", "1"),
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.broker_url", "*broker_url"),
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.topic", "*topic"),
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.client_id", "client_id"),
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.message_format", "json"),
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.username", "username"),
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.password", "password"),
+ resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.insecure_skip_verify", "true"),
// opsgenie
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "opsgenie.#", "1"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "opsgenie.0.url", "http://opsgenie-api"),