Repository: grafana/terraform-provider-grafana
Pull request #2173: Recreate deleted k6 resources
Author: login: fornfrey
Created: 2025-05-14T15:38:43Z | Merged: 2025-05-23T11:15:56Z

* Ensure that k6 resources (Projects, Load Tests) create a Terraform drift instead of raising an error when deleted outside of Terraform.
* Add tests to verify the resources are removed from the state when not found on the backend.
* Update existing tests to generate unique k6 project names.


Diff:
diff --git a/docs/data-sources/k6_projects.md b/docs/data-sources/k6_projects.md
index d33475241..d806509e9 100644
--- a/docs/data-sources/k6_projects.md
+++ b/docs/data-sources/k6_projects.md
@@ -17,18 +17,12 @@ resource "grafana_k6_project" "project" {
   name = "Terraform Test Project"
 }
 
-resource "grafana_k6_project" "project_2" {
-  name = "Terraform Test Project"
-}
-
 data "grafana_k6_projects" "from_name" {
   name = "Terraform Test Project"
 
   depends_on = [
     grafana_k6_project.project,
-    grafana_k6_project.project_2
   ]
-
 }
 ```
 
diff --git a/examples/data-sources/grafana_k6_projects/data-source.tf b/examples/data-sources/grafana_k6_projects/data-source.tf
index 2708f97c9..fc3cdfff0 100644
--- a/examples/data-sources/grafana_k6_projects/data-source.tf
+++ b/examples/data-sources/grafana_k6_projects/data-source.tf
@@ -2,18 +2,12 @@ resource "grafana_k6_project" "project" {
   name = "Terraform Test Project"
 }
 
-resource "grafana_k6_project" "project_2" {
-  name = "Terraform Test Project"
-}
-
 data "grafana_k6_projects" "from_name" {
   name = "Terraform Test Project"
 
   depends_on = [
     grafana_k6_project.project,
-    grafana_k6_project.project_2
   ]
-
 }
 
 
diff --git a/internal/resources/k6/data_source_k6_loadtest_test.go b/internal/resources/k6/data_source_k6_loadtest_test.go
index bedba089c..dda017c87 100644
--- a/internal/resources/k6/data_source_k6_loadtest_test.go
+++ b/internal/resources/k6/data_source_k6_loadtest_test.go
@@ -3,6 +3,7 @@ package k6_test
 import (
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 
 	"github.com/grafana/terraform-provider-grafana/v3/internal/testutils"
@@ -11,11 +12,15 @@ import (
 func TestAccDataSourceK6LoadTest_basic(t *testing.T) {
 	testutils.CheckCloudInstanceTestsEnabled(t)
 
+	projectName := "Terraform Load Test Project " + acctest.RandString(8)
+
 	resource.ParallelTest(t, resource.TestCase{
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "data-sources/grafana_k6_load_test/data-source.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "data-sources/grafana_k6_load_test/data-source.tf", map[string]string{
+					"Terraform Load Test Project": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					resource.TestCheckResourceAttrSet("data.grafana_k6_load_test.from_id", "id"),
 					resource.TestCheckResourceAttr("data.grafana_k6_load_test.from_id", "name", "Terraform Test Load Test"),
diff --git a/internal/resources/k6/data_source_k6_loadtests_test.go b/internal/resources/k6/data_source_k6_loadtests_test.go
index bd708da3f..6e3956ad1 100644
--- a/internal/resources/k6/data_source_k6_loadtests_test.go
+++ b/internal/resources/k6/data_source_k6_loadtests_test.go
@@ -5,6 +5,7 @@ import (
 	"strconv"
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 
 	"github.com/grafana/k6-cloud-openapi-client-go/k6"
@@ -17,6 +18,8 @@ func TestAccDataSourceK6LoadTests_basic(t *testing.T) {
 
 	var project k6.ProjectApiModel
 
+	projectName := "Terraform Load Test Project " + acctest.RandString(8)
+
 	checkProjectIDMatch := func(value string) error {
 		if value != strconv.Itoa(int(project.GetId())) {
 			return fmt.Errorf("project_id does not match the expected value: %s", value)
@@ -28,7 +31,9 @@ func TestAccDataSourceK6LoadTests_basic(t *testing.T) {
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "data-sources/grafana_k6_load_tests/data-source.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "data-sources/grafana_k6_load_tests/data-source.tf", map[string]string{
+					"Terraform Load Test Project": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					projectCheckExists.exists("grafana_k6_project.load_test_project", &project),
 					// from_project_id.0
diff --git a/internal/resources/k6/data_source_k6_project_limits_test.go b/internal/resources/k6/data_source_k6_project_limits_test.go
index 551fd5dcb..1fd5e62cf 100644
--- a/internal/resources/k6/data_source_k6_project_limits_test.go
+++ b/internal/resources/k6/data_source_k6_project_limits_test.go
@@ -3,6 +3,7 @@ package k6_test
 import (
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 
 	"github.com/grafana/terraform-provider-grafana/v3/internal/testutils"
@@ -11,11 +12,15 @@ import (
 func TestAccDataSourceK6ProjectLimits_basic(t *testing.T) {
 	testutils.CheckCloudInstanceTestsEnabled(t)
 
+	projectName := "Terraform Project Test Limits " + acctest.RandString(8)
+
 	resource.ParallelTest(t, resource.TestCase{
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "data-sources/grafana_k6_project_limits/data-source.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "data-sources/grafana_k6_project_limits/data-source.tf", map[string]string{
+					"Terraform Project Test Limits": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					// project_id
 					resource.TestCheckResourceAttr("data.grafana_k6_project_limits.from_project_id", "vuh_max_per_month", "10000"),
diff --git a/internal/resources/k6/data_source_k6_project_test.go b/internal/resources/k6/data_source_k6_project_test.go
index fc85243fc..307f6b96c 100644
--- a/internal/resources/k6/data_source_k6_project_test.go
+++ b/internal/resources/k6/data_source_k6_project_test.go
@@ -3,6 +3,7 @@ package k6_test
 import (
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 
 	"github.com/grafana/terraform-provider-grafana/v3/internal/testutils"
@@ -11,14 +12,18 @@ import (
 func TestAccDataSourceK6Project_basic(t *testing.T) {
 	testutils.CheckCloudInstanceTestsEnabled(t)
 
+	projectName := "Terraform Test Project " + acctest.RandString(8)
+
 	resource.ParallelTest(t, resource.TestCase{
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "data-sources/grafana_k6_project/data-source.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "data-sources/grafana_k6_project/data-source.tf", map[string]string{
+					"Terraform Test Project": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					resource.TestCheckResourceAttrSet("data.grafana_k6_project.from_id", "id"),
-					resource.TestCheckResourceAttr("data.grafana_k6_project.from_id", "name", "Terraform Test Project"),
+					resource.TestCheckResourceAttr("data.grafana_k6_project.from_id", "name", projectName),
 					resource.TestCheckResourceAttrSet("data.grafana_k6_project.from_id", "is_default"),
 					resource.TestCheckResourceAttrSet("data.grafana_k6_project.from_id", "grafana_folder_uid"),
 					resource.TestCheckResourceAttrSet("data.grafana_k6_project.from_id", "created"),
diff --git a/internal/resources/k6/data_source_k6_projects_test.go b/internal/resources/k6/data_source_k6_projects_test.go
index 0ab63d9f2..fefeb7184 100644
--- a/internal/resources/k6/data_source_k6_projects_test.go
+++ b/internal/resources/k6/data_source_k6_projects_test.go
@@ -3,6 +3,7 @@ package k6_test
 import (
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 
 	"github.com/grafana/k6-cloud-openapi-client-go/k6"
@@ -13,33 +14,25 @@ import (
 func TestAccDataSourceK6Projects_basic(t *testing.T) {
 	testutils.CheckCloudInstanceTestsEnabled(t)
 
-	var (
-		project  k6.ProjectApiModel
-		project2 k6.ProjectApiModel
-	)
+	var project k6.ProjectApiModel
+
+	projectName := "Terraform Test Project " + acctest.RandString(8)
 
 	resource.ParallelTest(t, resource.TestCase{
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "data-sources/grafana_k6_projects/data-source.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "data-sources/grafana_k6_projects/data-source.tf", map[string]string{
+					"Terraform Test Project": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					projectCheckExists.exists("grafana_k6_project.project", &project),
-					projectCheckExists.exists("grafana_k6_project.project_2", &project2),
-					// from_name.0
 					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.0.id"),
-					resource.TestCheckResourceAttr("data.grafana_k6_projects.from_name", "projects.0.name", "Terraform Test Project"),
+					resource.TestCheckResourceAttr("data.grafana_k6_projects.from_name", "projects.0.name", projectName),
 					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.0.is_default"),
 					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.0.grafana_folder_uid"),
 					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.0.created"),
 					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.0.updated"),
-					// from_name.1
-					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.1.id"),
-					resource.TestCheckResourceAttr("data.grafana_k6_projects.from_name", "projects.1.name", "Terraform Test Project"),
-					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.1.is_default"),
-					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.1.grafana_folder_uid"),
-					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.1.created"),
-					resource.TestCheckResourceAttrSet("data.grafana_k6_projects.from_name", "projects.1.updated"),
 				),
 			},
 		},
diff --git a/internal/resources/k6/resource_loadtest.go b/internal/resources/k6/resource_loadtest.go
index dc78ebdc7..696770ad6 100644
--- a/internal/resources/k6/resource_loadtest.go
+++ b/internal/resources/k6/resource_loadtest.go
@@ -3,6 +3,7 @@ package k6
 import (
 	"context"
 	"io"
+	"net/http"
 	"strconv"
 	"strings"
 	"time"
@@ -153,8 +154,12 @@ func (r *loadTestResource) Read(ctx context.Context, req resource.ReadRequest, r
 	k6Req := r.client.LoadTestsAPI.LoadTestsRetrieve(ctx, state.ID.ValueInt32()).
 		XStackId(r.config.StackID)
 
-	lt, _, err := k6Req.Execute()
-	if err != nil {
+	lt, httpResp, err := k6Req.Execute()
+
+	if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
+		resp.State.RemoveResource(ctx)
+		return
+	} else if err != nil {
 		resp.Diagnostics.AddError(
 			"Error reading k6 load test",
 			"Could not read k6 load test with id "+strconv.Itoa(int(state.ID.ValueInt32()))+": "+err.Error(),
@@ -166,8 +171,12 @@ func (r *loadTestResource) Read(ctx context.Context, req resource.ReadRequest, r
 	scriptReq := r.client.LoadTestsAPI.LoadTestsScriptRetrieve(ctx, state.ID.ValueInt32()).
 		XStackId(r.config.StackID)
 
-	script, _, err := scriptReq.Execute()
-	if err != nil {
+	script, httpResp, err := scriptReq.Execute()
+
+	if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
+		// 404 response from the script endpoint for an existing test means that the script is undefined
+		script = ""
+	} else if err != nil {
 		resp.Diagnostics.AddError(
 			"Error reading k6 load test script",
 			"Could not read k6 load test script with id "+strconv.Itoa(int(state.ID.ValueInt32()))+": "+err.Error(),
diff --git a/internal/resources/k6/resource_loadtest_test.go b/internal/resources/k6/resource_loadtest_test.go
index 58e508cfe..ae3e7bc2f 100644
--- a/internal/resources/k6/resource_loadtest_test.go
+++ b/internal/resources/k6/resource_loadtest_test.go
@@ -7,6 +7,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
 
@@ -24,6 +25,8 @@ func TestAccLoadTest_basic(t *testing.T) {
 		loadTest k6.LoadTestApiModel
 	)
 
+	projectName := "Terraform Load Test Project " + acctest.RandString(8)
+
 	resource.ParallelTest(t, resource.TestCase{
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		CheckDestroy: resource.ComposeTestCheckFunc(
@@ -32,7 +35,9 @@ func TestAccLoadTest_basic(t *testing.T) {
 		),
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "resources/grafana_k6_load_test/resource.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_load_test/resource.tf", map[string]string{
+					"Terraform Load Test Project": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					projectCheckExists.exists("grafana_k6_project.load_test_project", &project),
 					loadTestCheckExists.exists("grafana_k6_load_test.test_load_test", &loadTest),
@@ -47,9 +52,38 @@ func TestAccLoadTest_basic(t *testing.T) {
 				ImportState:       true,
 				ImportStateVerify: true,
 			},
+			// Delete the load test and check that TF sees a difference
+			{
+				PreConfig: func() {
+					commonClient := testutils.Provider.Meta().(*common.Client)
+					client := commonClient.K6APIClient
+					config := commonClient.K6APIConfig
+
+					ctx := context.WithValue(context.Background(), k6.ContextAccessToken, config.Token)
+					deleteReq := client.LoadTestsAPI.LoadTestsDestroy(ctx, loadTest.Id).XStackId(config.StackID)
+
+					_, err := deleteReq.Execute()
+					if err != nil {
+						t.Fatalf("error deleting load test: %s", err)
+					}
+				},
+				RefreshState:       true,
+				ExpectNonEmptyPlan: true,
+			},
+			// Recreate the test
+			{
+				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_load_test/resource.tf", map[string]string{
+					"Terraform Load Test Project": projectName,
+				}),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					loadTestCheckExists.exists("grafana_k6_load_test.test_load_test", &loadTest),
+					resource.TestCheckResourceAttr("grafana_k6_load_test.test_load_test", "name", "Terraform Test Load Test"),
+				),
+			},
 			// Change the name and script of a load test. This shouldn't recreate the load test.
 			{
 				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_load_test/resource.tf", map[string]string{
+					"Terraform Load Test Project":   projectName,
 					"Terraform Test Load Test":      "Terraform Test Load Test Updated",
 					"console.log('Hello from k6!')": "console.log('Hello from updated k6!')",
 				}),
diff --git a/internal/resources/k6/resource_project.go b/internal/resources/k6/resource_project.go
index 1ab239a4c..d4751a993 100644
--- a/internal/resources/k6/resource_project.go
+++ b/internal/resources/k6/resource_project.go
@@ -2,6 +2,7 @@ package k6
 
 import (
 	"context"
+	"net/http"
 	"strconv"
 	"time"
 
@@ -147,7 +148,13 @@ func (r *projectResource) Read(ctx context.Context, req resource.ReadRequest, re
 	k6Req := r.client.ProjectsAPI.ProjectsRetrieve(ctx, state.ID.ValueInt32()).
 		XStackId(r.config.StackID)
 
-	p, _, err := k6Req.Execute()
+	p, httpResp, err := k6Req.Execute()
+
+	if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
+		resp.State.RemoveResource(ctx)
+		return
+	}
+
 	if err != nil {
 		resp.Diagnostics.AddError(
 			"Error reading k6 project",
diff --git a/internal/resources/k6/resource_project_limits_test.go b/internal/resources/k6/resource_project_limits_test.go
index df71b8ec4..78ec17ed9 100644
--- a/internal/resources/k6/resource_project_limits_test.go
+++ b/internal/resources/k6/resource_project_limits_test.go
@@ -4,6 +4,7 @@ import (
 	"strconv"
 	"testing"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
 
@@ -18,6 +19,8 @@ func TestAccProjectLimits_basic(t *testing.T) {
 	var project k6.ProjectApiModel
 	var projectLimits k6.ProjectLimitsApiModel
 
+	projectName := "Terraform Project Test Limits " + acctest.RandString(8)
+
 	resource.ParallelTest(t, resource.TestCase{
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		CheckDestroy: resource.ComposeTestCheckFunc(
@@ -26,7 +29,9 @@ func TestAccProjectLimits_basic(t *testing.T) {
 		),
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "resources/grafana_k6_project_limits/resource.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_project_limits/resource.tf", map[string]string{
+					"Terraform Project Test Limits": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					projectCheckExists.exists("grafana_k6_project.test_project_limits", &project),
 					projectLimitsCheckExists.exists("grafana_k6_project_limits.test_limits", &projectLimits),
@@ -38,6 +43,7 @@ func TestAccProjectLimits_basic(t *testing.T) {
 			},
 			{
 				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_project_limits/resource.tf", map[string]string{
+					"Terraform Project Test Limits":  projectName,
 					"vuh_max_per_month       = 1000": "vuh_max_per_month       = 2000",
 				}),
 				Check: resource.ComposeTestCheckFunc(
diff --git a/internal/resources/k6/resource_project_test.go b/internal/resources/k6/resource_project_test.go
index f6ad52adb..094c47d14 100644
--- a/internal/resources/k6/resource_project_test.go
+++ b/internal/resources/k6/resource_project_test.go
@@ -8,6 +8,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
 	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
 
@@ -24,6 +25,8 @@ func TestAccProject_basic(t *testing.T) {
 
 	var project k6.ProjectApiModel
 
+	projectName := "Terraform Test Project " + acctest.RandString(8)
+
 	resource.ParallelTest(t, resource.TestCase{
 		ProtoV5ProviderFactories: testutils.ProtoV5ProviderFactories,
 		CheckDestroy: resource.ComposeTestCheckFunc(
@@ -31,11 +34,13 @@ func TestAccProject_basic(t *testing.T) {
 		),
 		Steps: []resource.TestStep{
 			{
-				Config: testutils.TestAccExample(t, "resources/grafana_k6_project/resource.tf"),
+				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_project/resource.tf", map[string]string{
+					"Terraform Test Project": projectName,
+				}),
 				Check: resource.ComposeTestCheckFunc(
 					projectCheckExists.exists("grafana_k6_project.test_project", &project),
 					resource.TestMatchResourceAttr("grafana_k6_project.test_project", "id", defaultIDRegexp),
-					resource.TestCheckResourceAttr("grafana_k6_project.test_project", "name", "Terraform Test Project"),
+					resource.TestCheckResourceAttr("grafana_k6_project.test_project", "name", projectName),
 					resource.TestMatchResourceAttr("grafana_k6_project.test_project", "is_default", regexp.MustCompile(`^(true|false)$`)),
 					resource.TestCheckResourceAttrSet("grafana_k6_project.test_project", "grafana_folder_uid"),
 					testutils.CheckLister("grafana_k6_project.test_project"),
@@ -47,15 +52,43 @@ func TestAccProject_basic(t *testing.T) {
 				ImportStateVerify:       true,
 				ImportStateVerifyIgnore: []string{"grafana_folder_uid"},
 			},
+			// Delete the project and check that TF sees a difference
+			{
+				PreConfig: func() {
+					commonClient := testutils.Provider.Meta().(*common.Client)
+					client := commonClient.K6APIClient
+					config := commonClient.K6APIConfig
+
+					ctx := context.WithValue(context.Background(), k6.ContextAccessToken, config.Token)
+					deleteReq := client.ProjectsAPI.ProjectsDestroy(ctx, project.Id).XStackId(config.StackID)
+
+					_, err := deleteReq.Execute()
+					if err != nil {
+						t.Fatalf("error deleting project: %s", err)
+					}
+				},
+				RefreshState:       true,
+				ExpectNonEmptyPlan: true,
+			},
+			// Recreate the project
+			{
+				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_project/resource.tf", map[string]string{
+					"Terraform Test Project": projectName,
+				}),
+				Check: resource.ComposeAggregateTestCheckFunc(
+					projectCheckExists.exists("grafana_k6_project.test_project", &project),
+					resource.TestCheckResourceAttr("grafana_k6_project.test_project", "name", projectName),
+				),
+			},
 			// Change the title of a project. This shouldn't recreate the project.
 			{
 				Config: testutils.TestAccExampleWithReplace(t, "resources/grafana_k6_project/resource.tf", map[string]string{
-					"Terraform Test Project": "Terraform Test Project Updated",
+					"Terraform Test Project": projectName + " Updated",
 				}),
 				Check: resource.ComposeTestCheckFunc(
 					testAccProjectWasntRecreated("grafana_k6_project.test_project", &project),
 					testAccProjectUnchangedAttr("grafana_k6_project.test_project", "id", func() string { return strconv.Itoa(int(project.GetId())) }),
-					resource.TestCheckResourceAttr("grafana_k6_project.test_project", "name", "Terraform Test Project Updated"),
+					resource.TestCheckResourceAttr("grafana_k6_project.test_project", "name", projectName+" Updated"),
 					testAccProjectUnchangedAttr("grafana_k6_project.test_project", "grafana_folder_uid", project.GetGrafanaFolderUid),
 					testAccProjectUnchangedAttr("grafana_k6_project.test_project", "created", func() string { return project.GetCreated().Truncate(time.Microsecond).Format(time.RFC3339Nano) }),
 				),


Reviews:
user: login: joanlopez
body: Looks good, thanks @fornfrey!

I think it could be a very nice idea to try to write a test that:
- Loads a config directory, with a given resource (and so it creates it)
- Use the Go client/direct HTTP request to remove it.
- Try to reload the configuration, and see how it behaves (no error).

However, I'm not sure how easy that would be, and if there's any similar test for any other resource within the provider. If so, and it's easy to copy and adjust, I'd try it, if not, feel free to merge it as-is! We could look at it later.

Thanks! 🙌🏻 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T09:08:04Z
user: login: joanlopez
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T14:19:18Z
user: login: joanlopez
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T14:20:35Z
user: login: spinillos
body: Thanks for fix the cloud tests 😃 
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-23T10:04:18Z
user: login: vortegatorres
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-23T10:48:42Z
user: login: vortegatorres
state: APPROVED
author_association: NONE
submitted_at: 2025-05-23T10:49:44Z
user: login: fornfrey
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-23T11:41:38Z

Review comments:
diff_hunk: @@ -166,8 +171,12 @@ func (r *loadTestResource) Read(ctx context.Context, req resource.ReadRequest, r
 	scriptReq := r.client.LoadTestsAPI.LoadTestsScriptRetrieve(ctx, state.ID.ValueInt32()).
 		XStackId(r.config.StackID)
 
-	script, _, err := scriptReq.Execute()
-	if err != nil {
+	script, httpResp, err := scriptReq.Execute()
+
+	if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
+		// 404 response from the script endpoin for an existing test means that the script is undefined
path: internal/resources/k6/resource_loadtest.go
user: login: joanlopez
body: ```suggestion
		// 404 response from the script endpoint for an existing test means that the script is undefined
```
created_at: 2025-05-20T14:19:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -153,8 +154,12 @@ func (r *loadTestResource) Read(ctx context.Context, req resource.ReadRequest, r
 	k6Req := r.client.LoadTestsAPI.LoadTestsRetrieve(ctx, state.ID.ValueInt32()).
 		XStackId(r.config.StackID)
 
-	lt, _, err := k6Req.Execute()
-	if err != nil {
+	lt, httpResp, err := k6Req.Execute()
+
+	if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
+		resp.State.RemoveResource(ctx)
path: internal/resources/k6/resource_loadtest.go
user: login: vortegatorres
body: Do you think it make sense to add a warning here?
```
		resp.Diagnostics.AddWarning(
			"Resource not found",
			fmt.Sprintf("The k6 load test with ID %d was not found. It may have been deleted outside of Terraform. Removing from state.", state.ID.ValueInt32()),
		)
```
created_at: 2025-05-23T10:48:42Z
author_association: NONE
diff_hunk: @@ -153,8 +154,12 @@ func (r *loadTestResource) Read(ctx context.Context, req resource.ReadRequest, r
 	k6Req := r.client.LoadTestsAPI.LoadTestsRetrieve(ctx, state.ID.ValueInt32()).
 		XStackId(r.config.StackID)
 
-	lt, _, err := k6Req.Execute()
-	if err != nil {
+	lt, httpResp, err := k6Req.Execute()
+
+	if httpResp != nil && httpResp.StatusCode == http.StatusNotFound {
+		resp.State.RemoveResource(ctx)
path: internal/resources/k6/resource_loadtest.go
user: login: fornfrey
body: Sorry, I missed your message. Most resources in the provider don't log anything when deleted resources are removed from the state. I suggest keeping the k6 resources consistent with the others.
created_at: 2025-05-23T11:41:38Z
author_association: CONTRIBUTOR

PR comments:
user: login: CLAassistant
created_at: 2025-05-14T15:38:51Z
body: [![CLA assistant check](https://cla-assistant.io/pull/badge/signed)](https://cla-assistant.io/grafana/terraform-provider-grafana?pullRequest=2173) <br/>All committers have signed the CLA.
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-14T15:38:58Z
body: <!-- add-pr-comment:add-pr-comment -->

In order to lower resource usage and have a faster runtime, PRs will not run Cloud tests automatically.
To do so, a Grafana Labs employee must trigger the `cloud acceptance tests` workflow manually.
author_association: CONTRIBUTOR