Skip to content

Commit f5abffa

Browse files
authored
Make shared environment variable project IDs optional (#568)
* Make shared env var project IDs optional * Fix shared env var project ids tests * remove redundant test
1 parent 6ea2df9 commit f5abffa

4 files changed

Lines changed: 57 additions & 22 deletions

File tree

client/shared_environment_variable.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type SharedEnvVarRequest struct {
2828

2929
type SharedEnvironmentVariableRequest struct {
3030
Type string `json:"type"`
31-
ProjectIDs []string `json:"projectId"`
31+
ProjectIDs []string `json:"projectId,omitempty"`
3232
Target []string `json:"target"`
3333
ApplyToAllCustomEnvironments bool `json:"applyToAllCustomEnvironments"`
3434
EnvironmentVariables []SharedEnvVarRequest `json:"evs"`

docs/resources/shared_environment_variable.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ resource "vercel_shared_environment_variable" "example_development" {
6565
### Required
6666

6767
- `key` (String) The name of the Environment Variable.
68-
- `project_ids` (Set of String) The ID of the Vercel project.
6968
- `sensitive` (Boolean) Whether the Environment Variable is sensitive (meaning it cannot be read via the API or Vercel Dashboard once set). This must be explicitly set. If a [team-wide environment variable policy](https://vercel.com/docs/projects/environment-variables/sensitive-environment-variables#environment-variables-policy) is active, environment variables may have to be sensitive. Variables targeting only `development` must set this to `false`. Variables targeting `preview`, `production`, or custom environments may have to set this to `true`. A variable cannot target `development` together with `preview`, `production`, or custom environments while that team policy is enabled.
7069

7170
### Optional
@@ -74,6 +73,7 @@ resource "vercel_shared_environment_variable" "example_development" {
7473
7574
- `apply_to_all_custom_environments` (Boolean) Whether the shared environment variable should be applied to all custom environments in the linked projects.
7675
- `comment` (String) A comment explaining what the environment variable is for.
76+
- `project_ids` (Set of String) The ID of the Vercel project.
7777
- `target` (Set of String) The environments that the Environment Variable should be present on. Valid targets are either `production`, `preview`, or `development`.
7878
- `team_id` (String) The ID of the Vercel team. Shared environment variables require a team.
7979
- `value` (String, Sensitive) (Optional, exactly one of `value` or `value_wo` is required) The value of the Environment Variable.

vercel/resource_shared_environment_variable.go

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ For more detailed information, please see the [Vercel documentation](https://ver
176176
},
177177
},
178178
"project_ids": schema.SetAttribute{
179-
Required: true,
179+
Optional: true,
180180
Description: "The ID of the Vercel project.",
181181
ElementType: types.StringType,
182182
},
@@ -342,10 +342,12 @@ func (e *SharedEnvironmentVariable) toCreateSharedEnvironmentVariableRequest(ctx
342342
}
343343

344344
var projectIDs []string
345-
ds := e.ProjectIDs.ElementsAs(ctx, &projectIDs, false)
346-
diags = append(diags, ds...)
347-
if diags.HasError() {
348-
return req, false
345+
if !e.ProjectIDs.IsNull() && !e.ProjectIDs.IsUnknown() {
346+
ds := e.ProjectIDs.ElementsAs(ctx, &projectIDs, false)
347+
diags = append(diags, ds...)
348+
if diags.HasError() {
349+
return req, false
350+
}
349351
}
350352

351353
var envVariableType string
@@ -391,10 +393,12 @@ func (e *SharedEnvironmentVariable) toUpdateSharedEnvironmentVariableRequest(ctx
391393
}
392394

393395
var projectIDs []string
394-
ds := e.ProjectIDs.ElementsAs(ctx, &projectIDs, false)
395-
diags = append(diags, ds...)
396-
if diags.HasError() {
397-
return req, false
396+
if !e.ProjectIDs.IsNull() && !e.ProjectIDs.IsUnknown() {
397+
ds := e.ProjectIDs.ElementsAs(ctx, &projectIDs, false)
398+
diags = append(diags, ds...)
399+
if diags.HasError() {
400+
return req, false
401+
}
398402
}
399403
var envVariableType string
400404

@@ -422,17 +426,12 @@ func (e *SharedEnvironmentVariable) toUpdateSharedEnvironmentVariableRequest(ctx
422426
// convertResponseToSharedEnvironmentVariable is used to populate terraform state based on an API response.
423427
// Where possible, values from the API response are used to populate state. If not possible,
424428
// values from plan are used.
425-
func convertResponseToSharedEnvironmentVariable(response client.SharedEnvironmentVariableResponse, v types.String) SharedEnvironmentVariable {
429+
func convertResponseToSharedEnvironmentVariable(response client.SharedEnvironmentVariableResponse, v types.String, projectIDs types.Set) SharedEnvironmentVariable {
426430
target := []attr.Value{}
427431
for _, t := range response.Target {
428432
target = append(target, types.StringValue(t))
429433
}
430434

431-
projectIDs := []attr.Value{}
432-
for _, t := range response.ProjectIDs {
433-
projectIDs = append(projectIDs, types.StringValue(t))
434-
}
435-
436435
value := types.StringNull()
437436
if !v.IsNull() {
438437
if response.Type == "sensitive" {
@@ -448,7 +447,7 @@ func convertResponseToSharedEnvironmentVariable(response client.SharedEnvironmen
448447
Key: types.StringValue(response.Key),
449448
Value: value,
450449
ValueWO: types.StringNull(),
451-
ProjectIDs: types.SetValueMust(types.StringType, projectIDs),
450+
ProjectIDs: projectIDs,
452451
TeamID: toTeamID(response.TeamID),
453452
ID: types.StringValue(response.ID),
454453
Sensitive: types.BoolValue(response.Type == "sensitive"),
@@ -485,7 +484,7 @@ func (r *sharedEnvironmentVariableResource) Create(ctx context.Context, req reso
485484
return
486485
}
487486

488-
result := convertResponseToSharedEnvironmentVariable(response, plan.Value)
487+
result := convertResponseToSharedEnvironmentVariable(response, plan.Value, plan.ProjectIDs)
489488

490489
tflog.Info(ctx, "created shared environment variable", map[string]any{
491490
"id": result.ID.ValueString(),
@@ -526,7 +525,7 @@ func (r *sharedEnvironmentVariableResource) Read(ctx context.Context, req resour
526525
return
527526
}
528527

529-
result := convertResponseToSharedEnvironmentVariable(out, state.Value)
528+
result := convertResponseToSharedEnvironmentVariable(out, state.Value, state.ProjectIDs)
530529
tflog.Info(ctx, "read shared environment variable", map[string]any{
531530
"id": result.ID.ValueString(),
532531
"team_id": result.TeamID.ValueString(),
@@ -567,7 +566,7 @@ func (r *sharedEnvironmentVariableResource) Update(ctx context.Context, req reso
567566
return
568567
}
569568

570-
result := convertResponseToSharedEnvironmentVariable(response, plan.Value)
569+
result := convertResponseToSharedEnvironmentVariable(response, plan.Value, plan.ProjectIDs)
571570

572571
tflog.Info(ctx, "updated shared environment variable", map[string]any{
573572
"id": result.ID.ValueString(),
@@ -642,7 +641,12 @@ func (r *sharedEnvironmentVariableResource) ImportState(ctx context.Context, req
642641
value = types.StringValue(out.Value)
643642
}
644643

645-
result := convertResponseToSharedEnvironmentVariable(out, value)
644+
projectIDs := make([]attr.Value, 0, len(out.ProjectIDs))
645+
for _, projectID := range out.ProjectIDs {
646+
projectIDs = append(projectIDs, types.StringValue(projectID))
647+
}
648+
649+
result := convertResponseToSharedEnvironmentVariable(out, value, types.SetValueMust(types.StringType, projectIDs))
646650
tflog.Info(ctx, "imported shared environment variable", map[string]any{
647651
"team_id": result.TeamID.ValueString(),
648652
"env_id": result.ID.ValueString(),

vercel/resource_shared_environment_variable_unit_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,37 @@ func TestSharedEnvironmentVariableResourceSchemaRequiresSensitive(t *testing.T)
2525
assertBoolRequired(t, sensitiveAttr, "sensitive")
2626
}
2727

28+
func TestConvertResponseDoesNotTrackProjectsWhenProjectIDsAreUnconfigured(t *testing.T) {
29+
projectIDs := types.SetNull(types.StringType)
30+
result := convertResponseToSharedEnvironmentVariable(client.SharedEnvironmentVariableResponse{
31+
ID: "env_123",
32+
Key: "EXAMPLE",
33+
ProjectIDs: []string{"prj_123"},
34+
}, types.StringValue("value"), projectIDs)
35+
36+
if !result.ProjectIDs.IsNull() {
37+
t.Errorf("ProjectIDs = %#v, want null", result.ProjectIDs)
38+
}
39+
}
40+
41+
func TestConvertResponseTracksConfiguredProjectIDs(t *testing.T) {
42+
projectIDs := stringSet("prj_123")
43+
result := convertResponseToSharedEnvironmentVariable(client.SharedEnvironmentVariableResponse{
44+
ID: "env_123",
45+
Key: "EXAMPLE",
46+
ProjectIDs: []string{"prj_456"},
47+
}, types.StringValue("value"), projectIDs)
48+
49+
var got []string
50+
diags := result.ProjectIDs.ElementsAs(context.Background(), &got, false)
51+
if diags.HasError() {
52+
t.Fatalf("ProjectIDs.ElementsAs() returned diagnostics: %v", diags)
53+
}
54+
if len(got) != 1 || got[0] != "prj_123" {
55+
t.Errorf("ProjectIDs = %#v, want []string{\"prj_123\"}", got)
56+
}
57+
}
58+
2859
func TestSharedEnvironmentVariableSensitiveSemantics(t *testing.T) {
2960
tests := []struct {
3061
name string

0 commit comments

Comments
 (0)