From affa711922b3ebd779cdb749378c454da014df30 Mon Sep 17 00:00:00 2001 From: Douglas Harcourt Parsons Date: Fri, 12 Apr 2024 15:48:47 +0100 Subject: [PATCH] Add support for creating Edge Config --- client/edge_config.go | 70 +++++ docs/data-sources/edge_config.md | 31 +++ docs/resources/edge_config.md | 53 ++++ .../vercel_dns_record/data-source.tf | 3 + .../resources/vercel_edge_config/import.sh | 9 + .../resources/vercel_edge_config/resource.tf | 3 + vercel/data_source_edge_config.go | 113 ++++++++ vercel/data_source_edge_config_test.go | 39 +++ vercel/provider.go | 2 + vercel/resource_edge_config.go | 253 ++++++++++++++++++ vercel/resource_edge_config_test.go | 79 ++++++ 11 files changed, 655 insertions(+) create mode 100644 client/edge_config.go create mode 100644 docs/data-sources/edge_config.md create mode 100644 docs/resources/edge_config.md create mode 100644 examples/data-sources/vercel_dns_record/data-source.tf create mode 100644 examples/resources/vercel_edge_config/import.sh create mode 100644 examples/resources/vercel_edge_config/resource.tf create mode 100644 vercel/data_source_edge_config.go create mode 100644 vercel/data_source_edge_config_test.go create mode 100644 vercel/resource_edge_config.go create mode 100644 vercel/resource_edge_config_test.go diff --git a/client/edge_config.go b/client/edge_config.go new file mode 100644 index 00000000..a230b513 --- /dev/null +++ b/client/edge_config.go @@ -0,0 +1,70 @@ +package client + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +type EdgeConfig struct { + Slug string `json:"slug"` + ID string `json:"id"` + TeamID string `json:"ownerId"` +} + +type CreateEdgeConfigRequest struct { + Name string `json:"slug"` + TeamID string `json:"-"` +} + +func (c *Client) CreateEdgeConfig(ctx context.Context, request CreateEdgeConfigRequest) (e *EdgeConfig, err error) { + url := fmt.Sprintf("%s/v1/edge-config", c.baseURL) + if c.teamID(request.TeamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID)) + } + payload := string(mustMarshal(request)) + tflog.Trace(ctx, "creating edge config", map[string]interface{}{ + "url": url, + "payload": payload, + }) + err = c.doRequest(clientRequest{ + ctx: ctx, + method: "POST", + url: url, + body: payload, + }, &e) + return e, err +} + +func (c *Client) GetEdgeConfig(ctx context.Context, id, teamID string) (e *EdgeConfig, err error) { + url := fmt.Sprintf("%s/v1/edge-config/%s", c.baseURL, id) + if c.teamID(teamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) + } + tflog.Trace(ctx, "reading edge config", map[string]interface{}{ + "url": url, + }) + err = c.doRequest(clientRequest{ + ctx: ctx, + method: "GET", + url: url, + }, &e) + return e, err +} + +func (c *Client) DeleteEdgeConfig(ctx context.Context, id, teamID string) error { + url := fmt.Sprintf("%s/v1/edge-config/%s", c.baseURL, id) + if c.teamID(teamID) != "" { + url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID)) + } + tflog.Trace(ctx, "deleting edge config", map[string]interface{}{ + "url": url, + }) + + return c.doRequest(clientRequest{ + ctx: ctx, + method: "DELETE", + url: url, + }, nil) +} diff --git a/docs/data-sources/edge_config.md b/docs/data-sources/edge_config.md new file mode 100644 index 00000000..d362a930 --- /dev/null +++ b/docs/data-sources/edge_config.md @@ -0,0 +1,31 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "vercel_edge_config Data Source - terraform-provider-vercel" +subcategory: "" +description: |- + Provides information about an existing Edge Config resource. + An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more. +--- + +# vercel_edge_config (Data Source) + +Provides information about an existing Edge Config resource. + +An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more. + + + + +## Schema + +### Required + +- `id` (String) The Edge Config ID to be retrieved. This can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`. + +### Optional + +- `team_id` (String) The ID of the team the Edge Config should exist under. Required when configuring a team resource if a default team has not been set in the provider. + +### Read-Only + +- `name` (String) The name/slug of the Edge Config. diff --git a/docs/resources/edge_config.md b/docs/resources/edge_config.md new file mode 100644 index 00000000..c3658fcc --- /dev/null +++ b/docs/resources/edge_config.md @@ -0,0 +1,53 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "vercel_edge_config Resource - terraform-provider-vercel" +subcategory: "" +description: |- + Provides an Edge Config resource. + An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more. +--- + +# vercel_edge_config (Resource) + +Provides an Edge Config resource. + +An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more. + +## Example Usage + +```terraform +resource "vercel_edge_config" "example" { + name = "my-edge-config" +} +``` + + +## Schema + +### Required + +- `name` (String) The name/slug of the Edge Config. + +### Optional + +- `team_id` (String) The ID of the team the Edge Config should exist under. Required when configuring a team resource if a default team has not been set in the provider. + +### Read-Only + +- `id` (String) The ID of this resource. + +## Import + +Import is supported using the following syntax: + +```shell +# If importing into a personal account, or with a team configured on +# the provider, simply use the edge config id. +# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`. +terraform import vercel_edge_config.example ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx + +# Alternatively, you can import via the team_id and edge_config_id. +# - team_id can be found in the team `settings` tab in the Vercel UI. +# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`. +terraform import vercel_edge_config.example team_xxxxxxxxxxxxxxxxxxxxxxxx/ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` diff --git a/examples/data-sources/vercel_dns_record/data-source.tf b/examples/data-sources/vercel_dns_record/data-source.tf new file mode 100644 index 00000000..fc500881 --- /dev/null +++ b/examples/data-sources/vercel_dns_record/data-source.tf @@ -0,0 +1,3 @@ +data "vercel_edge_config" "example" { + id = "ecfg_xxxxxxxxxxxxxxxxxxxxxxxx" +} diff --git a/examples/resources/vercel_edge_config/import.sh b/examples/resources/vercel_edge_config/import.sh new file mode 100644 index 00000000..4d46d25e --- /dev/null +++ b/examples/resources/vercel_edge_config/import.sh @@ -0,0 +1,9 @@ +# If importing into a personal account, or with a team configured on +# the provider, simply use the edge config id. +# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`. +terraform import vercel_edge_config.example ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx + +# Alternatively, you can import via the team_id and edge_config_id. +# - team_id can be found in the team `settings` tab in the Vercel UI. +# - edge_config_id is hard to find, but can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`. +terraform import vercel_edge_config.example team_xxxxxxxxxxxxxxxxxxxxxxxx/ecfg_xxxxxxxxxxxxxxxxxxxxxxxxxxxx diff --git a/examples/resources/vercel_edge_config/resource.tf b/examples/resources/vercel_edge_config/resource.tf new file mode 100644 index 00000000..4bf9cb4d --- /dev/null +++ b/examples/resources/vercel_edge_config/resource.tf @@ -0,0 +1,3 @@ +resource "vercel_edge_config" "example" { + name = "my-edge-config" +} diff --git a/vercel/data_source_edge_config.go b/vercel/data_source_edge_config.go new file mode 100644 index 00000000..be9aa39f --- /dev/null +++ b/vercel/data_source_edge_config.go @@ -0,0 +1,113 @@ +package vercel + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/vercel/terraform-provider-vercel/client" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ datasource.DataSource = &edgeConfigDataSource{} + _ datasource.DataSourceWithConfigure = &edgeConfigDataSource{} +) + +func newEdgeConfigDataSource() datasource.DataSource { + return &edgeConfigDataSource{} +} + +type edgeConfigDataSource struct { + client *client.Client +} + +func (d *edgeConfigDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_edge_config" +} + +func (d *edgeConfigDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*client.Client) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.client = client +} + +// Schema returns the schema information for an edgeConfig data source +func (r *edgeConfigDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Description: ` +Provides information about an existing Edge Config resource. + +An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more.`, + Attributes: map[string]schema.Attribute{ + "team_id": schema.StringAttribute{ + Optional: true, + Computed: true, + Description: "The ID of the team the Edge Config should exist under. Required when configuring a team resource if a default team has not been set in the provider.", + }, + "id": schema.StringAttribute{ + Required: true, + Description: "The Edge Config ID to be retrieved. This can be found by navigating to the Edge Config in the Vercel UI and looking at the URL. It should begin with `ecfg_`.", + }, + "name": schema.StringAttribute{ + Computed: true, + Description: "The name/slug of the Edge Config.", + }, + }, + } +} + +// Read will read the edgeConfig information by requesting it from the Vercel API, and will update terraform +// with this information. +// It is called by the provider whenever data source values should be read to update state. +func (d *edgeConfigDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var config EdgeConfig + diags := req.Config.Get(ctx, &config) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + out, err := d.client.GetEdgeConfig(ctx, config.ID.ValueString(), config.TeamID.ValueString()) + if client.NotFound(err) { + resp.State.RemoveResource(ctx) + return + } + if err != nil { + resp.Diagnostics.AddError( + "Error reading EdgeConfig", + fmt.Sprintf("Could not get Edge Config %s %s, unexpected error: %s", + config.TeamID.ValueString(), + config.ID.ValueString(), + err, + ), + ) + return + } + + result := responseToEdgeConfig(out) + tflog.Trace(ctx, "read edge config", map[string]interface{}{ + "team_id": result.TeamID.ValueString(), + "edge_config_id": result.ID.ValueString(), + }) + + diags = resp.State.Set(ctx, result) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} diff --git a/vercel/data_source_edge_config_test.go b/vercel/data_source_edge_config_test.go new file mode 100644 index 00000000..2fbc0ea6 --- /dev/null +++ b/vercel/data_source_edge_config_test.go @@ -0,0 +1,39 @@ +package vercel_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAcc_EdgeConfigDataSource(t *testing.T) { + name := acctest.RandString(16) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccEdgeConfigDataSourceConfig(name, teamIDConfig()), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.vercel_edge_config.test", "name", name), + ), + }, + }, + }) +} + +func testAccEdgeConfigDataSourceConfig(name, teamID string) string { + return fmt.Sprintf(` +resource "vercel_edge_config" "test" { + name = "%[1]s" + %[2]s +} + +data "vercel_edge_config" "test" { + id = vercel_edge_config.test.id + %[2]s +} +`, name, teamID) +} diff --git a/vercel/provider.go b/vercel/provider.go index de2735f1..06239170 100644 --- a/vercel/provider.go +++ b/vercel/provider.go @@ -57,6 +57,7 @@ func (p *vercelProvider) Resources(_ context.Context) []func() resource.Resource newProjectDomainResource, newProjectEnvironmentVariableResource, newSharedEnvironmentVariableResource, + newEdgeConfigResource, } } @@ -68,6 +69,7 @@ func (p *vercelProvider) DataSources(_ context.Context) []func() datasource.Data newProjectDataSource, newProjectDirectoryDataSource, newSharedEnvironmentVariableDataSource, + newEdgeConfigDataSource, } } diff --git a/vercel/resource_edge_config.go b/vercel/resource_edge_config.go new file mode 100644 index 00000000..100098b1 --- /dev/null +++ b/vercel/resource_edge_config.go @@ -0,0 +1,253 @@ +package vercel + +import ( + "context" + "fmt" + "regexp" + + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/vercel/terraform-provider-vercel/client" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ resource.Resource = &edgeConfigResource{} + _ resource.ResourceWithConfigure = &edgeConfigResource{} + _ resource.ResourceWithImportState = &edgeConfigResource{} +) + +func newEdgeConfigResource() resource.Resource { + return &edgeConfigResource{} +} + +type edgeConfigResource struct { + client *client.Client +} + +func (r *edgeConfigResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_edge_config" +} + +func (r *edgeConfigResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*client.Client) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + r.client = client +} + +// Schema returns the schema information for an edgeConfig resource. +func (r *edgeConfigResource) Schema(_ context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Description: ` +Provides an Edge Config resource. + +An Edge Config is a global data store that enables experimentation with feature flags, A/B testing, critical redirects, and more.`, + Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Description: "The name/slug of the Edge Config.", + Required: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, + Validators: []validator.String{ + stringRegex( + regexp.MustCompile(`^[a-z0-9\_\-]{0,32}$`), + "The name of an Edge Config can only contain up to 32 alphanumeric lowercase characters, hyphens and underscores.", + ), + }, + }, + "team_id": schema.StringAttribute{ + Optional: true, + Computed: true, + Description: "The ID of the team the Edge Config should exist under. Required when configuring a team resource if a default team has not been set in the provider.", + PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplaceIfConfigured()}, + }, + "id": schema.StringAttribute{ + Computed: true, + }, + }, + } +} + +type EdgeConfig struct { + Name types.String `tfsdk:"name"` + ID types.String `tfsdk:"id"` + TeamID types.String `tfsdk:"team_id"` +} + +func responseToEdgeConfig(out *client.EdgeConfig) EdgeConfig { + return EdgeConfig{ + Name: types.StringValue(out.Slug), + ID: types.StringValue(out.ID), + TeamID: toTeamID(out.TeamID), + } +} + +// Create will create an edgeConfig within Vercel. +// This is called automatically by the provider when a new resource should be created. +func (r *edgeConfigResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan EdgeConfig + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + out, err := r.client.CreateEdgeConfig(ctx, client.CreateEdgeConfigRequest{ + Name: plan.Name.ValueString(), + TeamID: plan.TeamID.ValueString(), + }) + if err != nil { + resp.Diagnostics.AddError( + "Error creating Edge Config", + "Could not create Edge Config, unexpected error: "+err.Error(), + ) + return + } + + result := responseToEdgeConfig(out) + tflog.Trace(ctx, "created Edge Config", map[string]interface{}{ + "team_id": plan.TeamID.ValueString(), + "edge_config_id": result.ID.ValueString(), + }) + + diags = resp.State.Set(ctx, result) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +// Read will read edgeConfig information by requesting it from the Vercel API, and will update terraform +// with this information. +func (r *edgeConfigResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state EdgeConfig + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + out, err := r.client.GetEdgeConfig(ctx, state.ID.ValueString(), state.TeamID.ValueString()) + if client.NotFound(err) { + resp.State.RemoveResource(ctx) + return + } + if err != nil { + resp.Diagnostics.AddError( + "Error reading EdgeConfig", + fmt.Sprintf("Could not get Edge Config %s %s, unexpected error: %s", + state.TeamID.ValueString(), + state.ID.ValueString(), + err, + ), + ) + return + } + + result := responseToEdgeConfig(out) + tflog.Trace(ctx, "read edge config", map[string]interface{}{ + "team_id": result.TeamID.ValueString(), + "edge_config_id": result.ID.ValueString(), + }) + + diags = resp.State.Set(ctx, result) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +// Update does nothing. +func (r *edgeConfigResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + resp.Diagnostics.AddError( + "Updating an Edge Config is not supported", + "Updating an Edge Config is not supported", + ) +} + +// Delete deletes an Edge Config. +func (r *edgeConfigResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state EdgeConfig + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + err := r.client.DeleteEdgeConfig(ctx, state.ID.ValueString(), state.TeamID.ValueString()) + if client.NotFound(err) { + return + } + if err != nil { + resp.Diagnostics.AddError( + "Error deleting edgeConfig", + fmt.Sprintf( + "Could not delete Edge Config %s %s, unexpected error: %s", + state.TeamID.ValueString(), + state.ID.ValueString(), + err, + ), + ) + return + } + + tflog.Trace(ctx, "deleted Edge Config", map[string]interface{}{ + "team_id": state.TeamID.ValueString(), + "edge_config_id": state.ID.ValueString(), + }) +} + +func (r *edgeConfigResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + teamID, id, ok := splitID(req.ID) + if !ok { + resp.Diagnostics.AddError( + "Error importing edge config", + fmt.Sprintf("Invalid id '%s' specified. should be in format \"team_id/edge_config_id\" or \"edge_config_id\"", req.ID), + ) + } + + out, err := r.client.GetEdgeConfig(ctx, id, teamID) + if client.NotFound(err) { + resp.State.RemoveResource(ctx) + return + } + if err != nil { + resp.Diagnostics.AddError( + "Error reading EdgeConfig", + fmt.Sprintf("Could not get Edge Config %s %s, unexpected error: %s", + teamID, + id, + err, + ), + ) + return + } + + result := responseToEdgeConfig(out) + tflog.Trace(ctx, "import edge config", map[string]interface{}{ + "team_id": result.TeamID.ValueString(), + "edge_config_id": result.ID.ValueString(), + }) + + diags := resp.State.Set(ctx, result) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} diff --git a/vercel/resource_edge_config_test.go b/vercel/resource_edge_config_test.go new file mode 100644 index 00000000..861b2941 --- /dev/null +++ b/vercel/resource_edge_config_test.go @@ -0,0 +1,79 @@ +package vercel_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/vercel/terraform-provider-vercel/client" +) + +func testCheckEdgeConfigExists(teamID, n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("no ID is set") + } + + _, err := testClient().GetEdgeConfig(context.TODO(), rs.Primary.ID, teamID) + return err + } +} + +func testCheckEdgeConfigDeleted(n, teamID string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("no ID is set") + } + + _, err := testClient().GetEdgeConfig(context.TODO(), rs.Primary.ID, teamID) + if err == nil { + return fmt.Errorf("expected not_found error, but got no error") + } + if !client.NotFound(err) { + return fmt.Errorf("Unexpected error checking for deleted project: %s", err) + } + + return nil + } +} + +func TestAcc_EdgeConfigResource(t *testing.T) { + name := acctest.RandString(16) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + CheckDestroy: testCheckEdgeConfigDeleted("vercel_edge_config.test", testTeam()), + Steps: []resource.TestStep{ + { + Config: testAccResourceEdgeConfig(name, teamIDConfig()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckEdgeConfigExists(testTeam(), "vercel_edge_config.test"), + resource.TestCheckResourceAttr("vercel_edge_config.test", "name", name), + resource.TestCheckResourceAttrSet("vercel_edge_config.test", "id"), + ), + }, + }, + }) +} + +func testAccResourceEdgeConfig(name, team string) string { + return fmt.Sprintf(` +resource "vercel_edge_config" "test" { + name = "%[1]s" + %[2]s +} +`, name, team) +}