Repository: honeycombio/terraform-provider-honeycombio
Pull request #529 (2024-08-12 20:05:51)

rel: v0.26.0

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/529?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 78.53%. Comparing base [(`6713cc3`)](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/commit/6713cc3375741fc9e482b90812ac31995b3afe08?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio) to head [(`687ff2c`)](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/commit/687ff2c430e555a1985970455e7f4a75f90e4d3f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio).

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##             main     #529   +/-   ##
=======================================
  Coverage   78.53%   78.53%           
=======================================
  Files          73       73           
  Lines        5619     5619           
=======================================
  Hits         4413     4413           
  Misses        913      913           
  Partials      293      293           
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/honeycombio/terraform-provider-honeycombio/pull/529?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=honeycombio).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89a185d..03769e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,34 @@
+# 0.26.0 (Aug 12, 2024)
+
+NOTES:
+
+This release deprecates `r/msteams_recipient` in favor of the new `r/msteams_workflow_recipient` in line with Microsoft's deprecation of O365 Connectors.
+New instances of `r/msteams_recipient` can no longer be created and we recommend you migrate your integration to the Workflow-based solution as soon as possible.
+
+ENHANCEMENTS:
+
+* feat(client): V2 API client ratelimit improvements (#519)
+* chore(r/query): add doc note about using latest derived column definition (#521)
+* r/msteams_workflow_recipient: new resource for managing MS Teams Workflow integrations (#524)
+* chore(client): improve V2 API error reporting (#526)
+
+BUGFIXES:
+
+* fix: temporarily disable broken r/query test (#510)
+* fix: allow auto ('0') granularity (#514)
+* fix(limits): separately test min-max vs header+jitter cases (#520)
+* fix: environments data source test flake (#525)
+
+HOUSEKEEPING:
+
+* chore(ci): limit integration test concurrency (#513)
+* maint(deps): bump golangci/golangci-lint-action from 6.0.1 to 6.1.0 (#515)
+* chore(ci): add recipients sweeper (#516)
+* chore(ci): display test summary output (#517)
+* chore(ci): add environment sweeper (#522)
+* maint(deps): bump github.com/hashicorp/terraform-plugin-framework from 1.10.0 to 1.11.0 (#523)
+* maint(deps): bump github.com/hashicorp/terraform-plugin-testing from 1.9.0 to 1.10.0 (#527)
+
 # 0.25.0 (Jul 25, 2024)
 
 NOTES:
diff --git a/README.md b/README.md
index eab6e1b..f960986 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ terraform {
   required_providers {
     honeycombio = {
       source  = "honeycombio/honeycombio"
-      version = "~> 0.25.0"
+      version = "~> 0.26.0"
     }
   }
 }
diff --git a/client/recipient.go b/client/recipient.go
index 66e27b2..7d3a06c 100644
--- a/client/recipient.go
+++ b/client/recipient.go
@@ -75,6 +75,10 @@ type NotificationRecipientDetails struct {
 // RecipientType holds all the possible recipient types.
 type RecipientType string
 
+func (t RecipientType) String() string {
+	return string(t)
+}
+
 // Declaration of recipient types
 const (
 	RecipientTypeEmail     RecipientType = "email"
@@ -82,7 +86,9 @@ const (
 	RecipientTypeSlack     RecipientType = "slack"
 	RecipientTypeWebhook   RecipientType = "webhook"
 	RecipientTypeMarker    RecipientType = "marker"
-	RecipientTypeMSTeams   RecipientType = "msteams"
+	// Deprecated: new recipients must use RecipientTypeMSTeamsWorkflow instead
+	RecipientTypeMSTeams         RecipientType = "msteams"
+	RecipientTypeMSTeamsWorkflow RecipientType = "msteams_workflow"
 )
 
 // PagerDutySeverity holds all the possible PD Severity types
@@ -111,6 +117,7 @@ func RecipientTypes() []RecipientType {
 		RecipientTypeSlack,
 		RecipientTypeWebhook,
 		RecipientTypeMSTeams,
+		RecipientTypeMSTeamsWorkflow,
 	}
 }
 
diff --git a/docs/data-sources/recipient.md b/docs/data-sources/recipient.md
index a739c99..34e6c16 100644
--- a/docs/data-sources/recipient.md
+++ b/docs/data-sources/recipient.md
@@ -54,19 +54,20 @@ resource "honeycombio_trigger" "example" {
 
 The following arguments are supported:
 
-* `type` - (Required) The type of recipient, allowed types are `email`, `pagerduty`, `msteams`, `slack` and `webhook`.
+* `type` - (Required) The type of recipient, allowed types are `email`, `pagerduty`, `msteams`, `msteams_workflow`, `slack` and `webhook`.
 * `dataset` - (Optional) Deprecated: recipients are now a Team-level construct. Any provided value will be ignored.
 * `detail_filter` - (Optional) a block to further filter recipients as described below.
 * `target` - (Optional) Deprecated: use `detail_filter` instead. The target of the recipient, this has another meaning depending on the type of recipient (see the table below).
 
-Type      | Target
-----------|-------------------------
-email     | an email address
-marker    | name of the marker
-msteams   | name of the integration
-pagerduty | _N/A_
-slack     | name of the channel
-webhook   | name of the webhook
+Type             | Target
+-----------------|-------------------------
+email            | an email address
+marker           | name of the marker
+msteams          | name of the integration
+msteams_workflow | name of the integration
+pagerduty        | _N/A_
+slack            | name of the channel
+webhook          | name of the webhook
 
 To further filter the recipient results, a `detail_filter` block can be provided which accepts the following arguments:
 
@@ -85,6 +86,6 @@ In addition to all arguments above, the following attributes are exported:
 * `channel` - The Slack recipient's channel -- if of type `slack`.
 * `name` - The webhook recipient's name -- if of type `webhook` or `msteams`.
 * `secret` - (Sensitive) The webhook recipient's secret -- if of type `webhook`.
-* `url` - The webhook recipient's URL - if of type `webhook` or `msteams`.
+* `url` - The webhook recipient's URL - if of type `webhook`, `msteams` or `msteams_workflow`.
 * `integration_key` - (Sensitive) The PagerDuty recipient's integration key -- if of type `pagerduty`.
 * `integration_name` - The PagerDuty recipient's inregration name -- if of type `pagerduty`.
diff --git a/docs/data-sources/recipients.md b/docs/data-sources/recipients.md
index 46a387b..b5599f0 100644
--- a/docs/data-sources/recipients.md
+++ b/docs/data-sources/recipients.md
@@ -25,7 +25,7 @@ data "honeycombio_recipients" "example-dot-com" {
 
 The following arguments are supported:
 
-* `type` - (Optional) The type of recipient, allowed types are `email`, `pagerduty`, `msteams`, `slack` and `webhook`.
+* `type` - (Optional) The type of recipient, allowed types are `email`, `pagerduty`, `msteams`, `msteams_workflow`, `slack` and `webhook`.
 * `detail_filter` - (Optional) a block to further filter recipients as described below. `name` must be set when providing a filter.
 
 To further filter the recipient results, a `detail_filter` block can be provided which accepts the following arguments:
diff --git a/docs/index.md b/docs/index.md
index 436015d..8b91262 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -14,7 +14,7 @@ terraform {
   required_providers {
     honeycombio = {
       source  = "honeycombio/honeycombio"
-      version = "~> 0.25.0"
+      version = "~> 0.26.0"
     }
   }
 }
diff --git a/docs/resources/msteams_recipient.md b/docs/resources/msteams_recipient.md
index 7655596..581916c 100644
--- a/docs/resources/msteams_recipient.md
+++ b/docs/resources/msteams_recipient.md
@@ -2,6 +2,10 @@
 
 `honeycombio_msteams_recipient` allows you to define and manage an MSTeams recipient that can be used by Triggers or BurnAlerts notifications.
 
+-> **NOTE** Microsoft has deprecated Office 365 Connectors.
+  This resource will no longer allow creation of new recipients.
+  It is recommended you recreate your Teams recipients with the `honeycombio_msteams_workflow_recipient` resource.
+
 ## Example Usage
 
 ```hcl
diff --git a/docs/resources/msteams_workflow_recipient.md b/docs/resources/msteams_workflow_recipient.md
new file mode 100644
index 0000000..027e73a
--- /dev/null
+++ b/docs/resources/msteams_workflow_recipient.md
@@ -0,0 +1,33 @@
+# Resource: honeycombio_msteams_workflow_recipient
+
+`honeycombio_msteams_workflow_recipient` allows you to define and manage an MSTeams Workflows recipient that can be used by Triggers or BurnAlerts notifications.
+
+## Example Usage
+
+```hcl
+resource "honeycombio_msteams_workflow_recipient" "prod" {
+  name = "Production Alerts"
+  url  = "https://mycorp.westus.logic.azure.com/workflows/123456"
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `name` - (Required) The name of the recipient.
+* `url` - (Required) The MSTeams Workflow URL to send the notification to.
+
+## Attribute Reference
+
+In addition to all arguments above, the following attributes are exported:
+
+* `id` - The ID of the recipient.
+
+## Import
+
+MSTeams Workflow Recipients can be imported by their ID, e.g.
+
+```
+$ terraform import honeycombio_msteams_workflow_recipient.my_recipient nx2zsefB1cX
+```
diff --git a/honeycombio/data_source_recipient.go b/honeycombio/data_source_recipient.go
index cf6a8c3..984eb73 100644
--- a/honeycombio/data_source_recipient.go
+++ b/honeycombio/data_source_recipient.go
@@ -175,7 +175,7 @@ func dataSourceHoneycombioRecipientRead(ctx context.Context, d *schema.ResourceD
 		d.Set("address", rcpt.Details.EmailAddress)
 	case honeycombio.RecipientTypeSlack:
 		d.Set("channel", rcpt.Details.SlackChannel)
-	case honeycombio.RecipientTypeMSTeams:
+	case honeycombio.RecipientTypeMSTeams, honeycombio.RecipientTypeMSTeamsWorkflow: //nolint:staticcheck
 		d.Set("name", rcpt.Details.WebhookName)
 		d.Set("url", rcpt.Details.WebhookURL)
 	case honeycombio.RecipientTypeWebhook:
diff --git a/honeycombio/provider.go b/honeycombio/provider.go
index bfa89d5..e3087db 100644
--- a/honeycombio/provider.go
+++ b/honeycombio/provider.go
@@ -60,20 +60,21 @@ func Provider(version string) *schema.Provider {
 			"honeycombio_recipients":        dataSourceHoneycombioRecipients(),
 		},
 		ResourcesMap: map[string]*schema.Resource{
-			"honeycombio_board":               newBoard(),
-			"honeycombio_column":              newColumn(),
-			"honeycombio_dataset":             newDataset(),
-			"honeycombio_dataset_definition":  newDatasetDefinition(),
-			"honeycombio_derived_column":      newDerivedColumn(),
-			"honeycombio_marker":              newMarker(),
-			"honeycombio_marker_setting":      newMarkerSetting(),
-			"honeycombio_query_annotation":    newQueryAnnotation(),
-			"honeycombio_email_recipient":     newEmailRecipient(),
-			"honeycombio_pagerduty_recipient": newPDRecipient(),
-			"honeycombio_msteams_recipient":   newMSTeamsRecipient(),
-			"honeycombio_slack_recipient":     newSlackRecipient(),
-			"honeycombio_webhook_recipient":   newWebhookRecipient(),
-			"honeycombio_slo":                 newSLO(),
+			"honeycombio_board":                      newBoard(),
+			"honeycombio_column":                     newColumn(),
+			"honeycombio_dataset":                    newDataset(),
+			"honeycombio_dataset_definition":         newDatasetDefinition(),
+			"honeycombio_derived_column":             newDerivedColumn(),
+			"honeycombio_marker":                     newMarker(),
+			"honeycombio_marker_setting":             newMarkerSetting(),
+			"honeycombio_query_annotation":           newQueryAnnotation(),
+			"honeycombio_email_recipient":            newEmailRecipient(),
+			"honeycombio_pagerduty_recipient":        newPDRecipient(),
+			"honeycombio_msteams_recipient":          newMSTeamsRecipient(), // deprecated
+			"honeycombio_msteams_workflow_recipient": newMSTeamsWorkflowRecipient(),
+			"honeycombio_slack_recipient":            newSlackRecipient(),
+			"honeycombio_webhook_recipient":          newWebhookRecipient(),
+			"honeycombio_slo":                        newSLO(),
 		},
 	}
 
diff --git a/honeycombio/resource_msteams_recipient.go b/honeycombio/resource_msteams_recipient.go
index 56fac47..0e4279a 100644
--- a/honeycombio/resource_msteams_recipient.go
+++ b/honeycombio/resource_msteams_recipient.go
@@ -10,6 +10,7 @@ import (
 	honeycombio "github.com/honeycombio/terraform-provider-honeycombio/client"
 )
 
+// Deprecated: MSTeams Recipient is deprecated, and does not allow creation of new recipients.
 func newMSTeamsRecipient() *schema.Resource {
 	return &schema.Resource{
 		CreateContext: resourceMSTeamsRecipientCreate,
@@ -19,13 +20,16 @@ func newMSTeamsRecipient() *schema.Resource {
 		Importer: &schema.ResourceImporter{
 			StateContext: schema.ImportStatePassthroughContext,
 		},
+		DeprecationMessage: "MSTeams Recipient is deprecated. " +
+			"Creating new MSTeams recipients is no longer possible." +
+			"Please use the `honeycombio_msteams_workflow_recipient` resource instead. ",
 		Description: "Honeycomb MSTeams Recipient allows you to define and manage an MSTeams recipient that can be used by Triggers or BurnAlerts notifications.",
 
 		Schema: map[string]*schema.Schema{
 			"name": {
 				Type:        schema.TypeString,
 				Required:    true,
-				Description: "The name of the MSTeams Integration to create",
+				Description: "The name of the recipient.",
 			},
 			"url": {
 				Type:         schema.TypeString,
@@ -38,14 +42,22 @@ func newMSTeamsRecipient() *schema.Resource {
 }
 
 func resourceMSTeamsRecipientCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
-	return createRecipient(ctx, d, meta, honeycombio.RecipientTypeMSTeams)
+	return diag.Diagnostics{diag.Diagnostic{
+		Severity: diag.Error,
+		Summary:  "Creating new MSTeams recipients is no longer possible.",
+		Detail: "Microsoft has deprecated the Incoming Webhook feature, and as a result, " +
+			" we are no longer able to create new MSTeams recipients. " +
+			"Use the `honeycombio_msteams_workflow_recipient` resource instead.",
+	}}
 }
 
 func resourceMSTeamsRecipientRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	//nolint:staticcheck
 	return readRecipient(ctx, d, meta, honeycombio.RecipientTypeMSTeams)
 }
 
 func resourceMSTeamsRecipientUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	//nolint:staticcheck
 	return updateRecipient(ctx, d, meta, honeycombio.RecipientTypeMSTeams)
 }
 
diff --git a/honeycombio/resource_msteams_workflow_recipient.go b/honeycombio/resource_msteams_workflow_recipient.go
new file mode 100644
index 0000000..a553c63
--- /dev/null
+++ b/honeycombio/resource_msteams_workflow_recipient.go
@@ -0,0 +1,54 @@
+package honeycombio
+
+import (
+	"context"
+
+	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
+
+	honeycombio "github.com/honeycombio/terraform-provider-honeycombio/client"
+)
+
+func newMSTeamsWorkflowRecipient() *schema.Resource {
+	return &schema.Resource{
+		CreateContext: resourceMSTeamsWorkflowRecipientCreate,
+		ReadContext:   resourceMSTeamsWorkflowRecipientRead,
+		UpdateContext: resourceMSTeamsWorkflowRecipientUpdate,
+		DeleteContext: resourceMSTeamsWorkflowRecipientDelete,
+		Importer: &schema.ResourceImporter{
+			StateContext: schema.ImportStatePassthroughContext,
+		},
+		Description: "Honeycomb MSTeams Workflow Recipient allows you to define and manage an MSTeams Workflows recipient that can be used by Triggers or BurnAlerts notifications.",
+
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:        schema.TypeString,
+				Required:    true,
+				Description: "The name of the recipient.",
+			},
+			"url": {
+				Type:         schema.TypeString,
+				Required:     true,
+				Description:  "The Teams Workflow URL to send the notification to.",
+				ValidateFunc: validation.IsURLWithHTTPorHTTPS,
+			},
+		},
+	}
+}
+
+func resourceMSTeamsWorkflowRecipientCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	return createRecipient(ctx, d, meta, honeycombio.RecipientTypeMSTeamsWorkflow)
+}
+
+func resourceMSTeamsWorkflowRecipientRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	return readRecipient(ctx, d, meta, honeycombio.RecipientTypeMSTeamsWorkflow)
+}
+
+func resourceMSTeamsWorkflowRecipientUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	return updateRecipient(ctx, d, meta, honeycombio.RecipientTypeMSTeamsWorkflow)
+}
+
+func resourceMSTeamsWorkflowRecipientDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
+	return deleteRecipient(ctx, d, meta)
+}
diff --git a/honeycombio/type_helpers.go b/honeycombio/type_helpers.go
index c8acce2..cbfefb3 100644
--- a/honeycombio/type_helpers.go
+++ b/honeycombio/type_helpers.go
@@ -43,7 +43,7 @@ func expandRecipient(t honeycombio.RecipientType, d *schema.ResourceData) (*hone
 		r.Details.PDIntegrationName = d.Get("integration_name").(string)
 	case honeycombio.RecipientTypeSlack:
 		r.Details.SlackChannel = d.Get("channel").(string)
-	case honeycombio.RecipientTypeMSTeams:
+	case honeycombio.RecipientTypeMSTeams, honeycombio.RecipientTypeMSTeamsWorkflow: //nolint:staticcheck
 		r.Details.WebhookName = d.Get("name").(string)
 		r.Details.WebhookURL = d.Get("url").(string)
 	case honeycombio.RecipientTypeWebhook:
@@ -104,7 +104,7 @@ func readRecipient(ctx context.Context, d *schema.ResourceData, meta interface{}
 		d.Set("integration_name", r.Details.PDIntegrationName)
 	case honeycombio.RecipientTypeSlack:
 		d.Set("channel", r.Details.SlackChannel)
-	case honeycombio.RecipientTypeMSTeams:
+	case honeycombio.RecipientTypeMSTeams, honeycombio.RecipientTypeMSTeamsWorkflow: //nolint:staticcheck
 		d.Set("name", r.Details.WebhookName)
 		d.Set("url", r.Details.WebhookURL)
 	case honeycombio.RecipientTypeWebhook:
@@ -201,7 +201,9 @@ func (f *recipientFilter) IsMatch(r honeycombio.Recipient) bool {
 			return f.ValueRegex.MatchString(r.Details.SlackChannel)
 		case honeycombio.RecipientTypePagerDuty:
 			return f.ValueRegex.MatchString(r.Details.PDIntegrationName)
-		case honeycombio.RecipientTypeWebhook, honeycombio.RecipientTypeMSTeams:
+		case honeycombio.RecipientTypeWebhook,
+			honeycombio.RecipientTypeMSTeams, //nolint:staticcheck
+			honeycombio.RecipientTypeMSTeamsWorkflow:
 			return f.ValueRegex.MatchString(r.Details.WebhookName) || f.ValueRegex.MatchString(r.Details.WebhookURL)
 		}
 	} else if f.Value != nil {
@@ -212,7 +214,9 @@ func (f *recipientFilter) IsMatch(r honeycombio.Recipient) bool {
 			return (r.Details.SlackChannel == *f.Value)
 		case honeycombio.RecipientTypePagerDuty:
 			return (r.Details.PDIntegrationName == *f.Value)
-		case honeycombio.RecipientTypeWebhook, honeycombio.RecipientTypeMSTeams:
+		case honeycombio.RecipientTypeWebhook,
+			honeycombio.RecipientTypeMSTeams, //nolint:staticcheck
+			honeycombio.RecipientTypeMSTeamsWorkflow:
 			return (r.Details.WebhookName == *f.Value) || (r.Details.WebhookURL == *f.Value)
 		}
 	}
@@ -242,10 +246,16 @@ func diagFromDetailedErr(err honeycombio.DetailedError) diag.Diagnostics {
 	diags := make(diag.Diagnostics, 0, len(err.Details)+1)
 	if len(err.Details) > 0 {
 		for _, d := range err.Details {
+			detail := d.Code + " - "
+			if d.Field != "" {
+				detail += d.Field + " "
+			}
+			detail += d.Description
+
 			diags = append(diags, diag.Diagnostic{
 				Severity: diag.Error,
 				Summary:  err.Title,
-				Detail:   d.Code + " - " + d.Description,
+				Detail:   detail,
 			})
 		}
 	} else {


Test patch:
diff --git a/client/recipient_test.go b/client/recipient_test.go
index eecd1d4..0487dc1 100644
--- a/client/recipient_test.go
+++ b/client/recipient_test.go
@@ -86,37 +86,61 @@ func TestRecipientsWebhooksandMSTeams(t *testing.T) {
 	ctx := context.Background()
 	c := newTestClient(t)
 
-	testRcpts := []client.Recipient{
+	testCases := []struct {
+		rcpt      client.Recipient
+		expectErr bool
+	}{
 		{
-			Type: client.RecipientTypeWebhook,
-			Details: client.RecipientDetails{
-				WebhookName:   test.RandomStringWithPrefix("test.", 10),
-				WebhookURL:    "https://example.com",
-				WebhookSecret: "secret",
+			rcpt: client.Recipient{
+				Type: client.RecipientTypeWebhook,
+				Details: client.RecipientDetails{
+					WebhookName:   test.RandomStringWithPrefix("test.", 10),
+					WebhookURL:    "https://example.com",
+					WebhookSecret: "secret",
+				},
 			},
 		},
 		{
-			Type: client.RecipientTypeMSTeams,
-			Details: client.RecipientDetails{
-				WebhookName: test.RandomStringWithPrefix("test.", 10),
-				WebhookURL:  "https://corp.office.com/webhook",
+			rcpt: client.Recipient{
+				Type: client.RecipientTypeMSTeams,
+				Details: client.RecipientDetails{
+					WebhookName: test.RandomStringWithPrefix("test.", 10),
+					WebhookURL:  "https://corp.office.com/webhook",
+				},
+			},
+			expectErr: true, // creation of new MSTeams recipients is not allowed
+		},
+		{
+			rcpt: client.Recipient{
+				Type: client.RecipientTypeMSTeamsWorkflow,
+				Details: client.RecipientDetails{
+					WebhookName: test.RandomStringWithPrefix("test.", 10),
+					WebhookURL:  "https://mycorp.westus.logic.azure.com/workflows/12345",
+				},
 			},
 		},
 	}
 
-	for _, tr := range testRcpts {
-		r, err := c.Recipients.Create(ctx, &tr)
-		require.NoError(t, err)
-		t.Cleanup(func() {
-			_ = c.Recipients.Delete(ctx, r.ID)
+	for _, tc := range testCases {
+		tr := tc.rcpt
+		t.Run(tr.Type.String(), func(t *testing.T) {
+			r, err := c.Recipients.Create(ctx, &tr)
+			t.Cleanup(func() {
+				_ = c.Recipients.Delete(ctx, r.ID)
+			})
+
+			if tc.expectErr {
+				require.Error(t, err, "expected error creating %s recipient", tr.Type)
+				return
+			}
+			require.NoError(t, err, "failed to create %s recipient", tr.Type)
+			r, err = c.Recipients.Get(ctx, r.ID)
+			require.NoError(t, err)
+
+			assert.Equal(t, tr.Type, r.Type)
+			assert.Equal(t, tr.Details.WebhookName, r.Details.WebhookName)
+			assert.Equal(t, tr.Details.WebhookURL, r.Details.WebhookURL)
+			assert.Equal(t, tr.Details.WebhookSecret, r.Details.WebhookSecret)
 		})
-
-		r, err = c.Recipients.Get(ctx, r.ID)
-		require.NoError(t, err)
-
-		assert.Equal(t, tr.Type, r.Type)
-		assert.Equal(t, tr.Details.WebhookName, r.Details.WebhookName)
-		assert.Equal(t, tr.Details.WebhookURL, r.Details.WebhookURL)
-		assert.Equal(t, tr.Details.WebhookSecret, r.Details.WebhookSecret)
 	}
 }
diff --git a/honeycombio/data_source_recipient_test.go b/honeycombio/data_source_recipient_test.go
index 7f3ec9d..a8a2333 100644
--- a/honeycombio/data_source_recipient_test.go
+++ b/honeycombio/data_source_recipient_test.go
@@ -66,10 +66,10 @@ func TestAccDataSourceHoneycombioRecipient_basic(t *testing.T) {
 			},
 		},
 		{
-			Type: honeycombio.RecipientTypeMSTeams,
+			Type: honeycombio.RecipientTypeMSTeamsWorkflow,
 			Details: honeycombio.RecipientDetails{
 				WebhookName: test.RandomStringWithPrefix("test.", 16),
-				WebhookURL:  "https://outlook.office.com/webhook/12345",
+				WebhookURL:  "https://mycorp.westus.logic.azure.com/workflows/12345",
 			},
 		},
 	}
@@ -131,7 +131,7 @@ func TestAccDataSourceHoneycombioRecipient_basic(t *testing.T) {
 				Config: testAccRecipientWithFilterValue("msteams", "name", testRecipients[7].Details.WebhookName),
 				Check: resource.ComposeAggregateTestCheckFunc(
 					resource.TestCheckResourceAttr("data.honeycombio_recipient.test", "name", testRecipients[7].Details.WebhookName),
-					resource.TestCheckResourceAttr("data.honeycombio_recipient.test", "url", "https://outlook.office.com/webhook/12345"),
+					resource.TestCheckResourceAttr("data.honeycombio_recipient.test", "url", "https://mycorp.westus.logic.azure.com/workflows/12345"),
 				),
 			},
 			{
diff --git a/honeycombio/recipients_test.go b/honeycombio/recipients_test.go
new file mode 100644
index 0000000..3880fc9
--- /dev/null
+++ b/honeycombio/recipients_test.go
@@ -0,0 +1,49 @@
+package honeycombio
+
+import (
+	"fmt"
+	"regexp"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+
+	"github.com/honeycombio/terraform-provider-honeycombio/internal/helper/test"
+)
+
+// TestAccHoneycombMSTeamsRecipient tests the creation
+// and validation of the original Honeycomb MSTeams recipient
+// and the new Honeycomb MSTeams Workflow recipient.
+func TestAccHoneycombMSTeamsRecipient(t *testing.T) {
+	t.Run("workflow recipient works", func(t *testing.T) {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 testAccPreCheck(t),
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactory,
+			Steps: []resource.TestStep{
+				{
+					Config: fmt.Sprintf(`
+resource "honeycombio_msteams_workflow_recipient" "test" {
+  name = "%s"
+  url  = "https://example.com"
+}`, test.RandomStringWithPrefix("test.", 10)),
+				},
+			},
+		})
+	})
+
+	t.Run("new webhook recipient fails creation", func(t *testing.T) {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 testAccPreCheck(t),
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactory,
+			Steps: []resource.TestStep{
+				{
+					Config: `
+resource "honeycombio_msteams_recipient" "test" {
+  name = "test"
+  url  = "https://example.com"
+}`,
+					ExpectError: regexp.MustCompile(`Creating new MSTeams recipients is no longer possible`),
+				},
+			},
+		})
+	})
+}
diff --git a/internal/provider/honeycombio_sweeper_test.go b/internal/provider/honeycombio_sweeper_test.go
index b67c79d..164532b 100644
--- a/internal/provider/honeycombio_sweeper_test.go
+++ b/internal/provider/honeycombio_sweeper_test.go
@@ -98,7 +98,9 @@ func getRecipientSweeper(name string) *resource.Sweeper {
 					name = r.Details.SlackChannel
 				case client.RecipientTypePagerDuty:
 					name = r.Details.PDIntegrationName
-				case client.RecipientTypeWebhook, client.RecipientTypeMSTeams:
+				case client.RecipientTypeWebhook,
+					client.RecipientTypeMSTeams, //nolint:staticcheck
+					client.RecipientTypeMSTeamsWorkflow:
 					name = r.Details.WebhookName
 				default:
 					log.Printf("[ERROR] unknown recipient type: %s", r.Type)