Skip to content

Commit 81e2d24

Browse files
authored
Add support for setting Fluid on vercel_project resource (#288)
* Add support for setting Fluid on vercel_project resource * Fix lint failure
1 parent b3fd40e commit 81e2d24

8 files changed

+160
-7
lines changed

client/project.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ type ProjectResponse struct {
204204
GitComments *GitComments `json:"gitComments"`
205205
Security *Security `json:"security"`
206206
DeploymentExpiration *DeploymentExpiration `json:"deploymentExpiration"`
207-
ResourceConfig *ResourceConfig `json:"resourceConfig"`
207+
ResourceConfig *ResourceConfigResponse `json:"resourceConfig"`
208208
NodeVersion string `json:"nodeVersion"`
209209
}
210210

@@ -217,9 +217,16 @@ type Security struct {
217217
AttackModeEnabled bool `json:"attackModeEnabled"`
218218
}
219219

220+
type ResourceConfigResponse struct {
221+
FunctionDefaultMemoryType *string `json:"functionDefaultMemoryType"`
222+
FunctionDefaultTimeout *int64 `json:"functionDefaultTimeout"`
223+
Fluid bool `json:"fluid"`
224+
}
225+
220226
type ResourceConfig struct {
221227
FunctionDefaultMemoryType *string `json:"functionDefaultMemoryType,omitempty"`
222228
FunctionDefaultTimeout *int64 `json:"functionDefaultTimeout,omitempty"`
229+
Fluid *bool `json:"fluid,omitempty"`
223230
}
224231

225232
// GetProject retrieves information about an existing project from Vercel.

docs/data-sources/project.md

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ Read-Only:
158158

159159
Read-Only:
160160

161+
- `fluid` (Boolean) Enable fluid compute for your Vercel Functions to automatically manage concurrency and optimize performance. Vercel will handle the defaults to ensure the best experience for your workload.
161162
- `function_default_cpu_type` (String) The amount of CPU available to your Serverless Functions. Should be one of 'standard_legacy' (0.6vCPU), 'standard' (1vCPU) or 'performance' (1.7vCPUs).
162163
- `function_default_timeout` (Number) The default timeout for Serverless Functions.
163164

docs/resources/project.md

+1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ Required:
193193

194194
Optional:
195195

196+
- `fluid` (Boolean) Enable fluid compute for your Vercel Functions to automatically manage concurrency and optimize performance. Vercel will handle the defaults to ensure the best experience for your workload.
196197
- `function_default_cpu_type` (String) The amount of CPU available to your Serverless Functions. Should be one of 'standard_legacy' (0.6vCPU), 'standard' (1vCPU) or 'performance' (1.7vCPUs).
197198
- `function_default_timeout` (Number) The default timeout for Serverless Functions.
198199

vercel/data_source_project.go

+4
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ For more detailed information, please see the [Vercel documentation](https://ver
373373
Description: "The default timeout for Serverless Functions.",
374374
Computed: true,
375375
},
376+
"fluid": schema.BoolAttribute{
377+
Description: "Enable fluid compute for your Vercel Functions to automatically manage concurrency and optimize performance. Vercel will handle the defaults to ensure the best experience for your workload.",
378+
Computed: true,
379+
},
376380
},
377381
},
378382
},

vercel/resource_dns_record.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ import (
2020
)
2121

2222
var (
23-
_ resource.Resource = &dnsRecordResource{}
24-
_ resource.ResourceWithConfigure = &dnsRecordResource{}
23+
_ resource.Resource = &dnsRecordResource{}
24+
_ resource.ResourceWithConfigure = &dnsRecordResource{}
25+
_ resource.ResourceWithValidateConfig = &dnsRecordResource{}
2526
)
2627

2728
func newDNSRecordResource() resource.Resource {

vercel/resource_project.go

+23-4
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ import (
3030
)
3131

3232
var (
33-
_ resource.Resource = &projectResource{}
34-
_ resource.ResourceWithConfigure = &projectResource{}
35-
_ resource.ResourceWithImportState = &projectResource{}
36-
_ resource.ResourceWithModifyPlan = &projectResource{}
33+
_ resource.Resource = &projectResource{}
34+
_ resource.ResourceWithConfigure = &projectResource{}
35+
_ resource.ResourceWithImportState = &projectResource{}
36+
_ resource.ResourceWithModifyPlan = &projectResource{}
37+
_ resource.ResourceWithConfigValidators = &projectResource{}
3738
)
3839

3940
func newProjectResource() resource.Resource {
@@ -543,12 +544,24 @@ At this time you cannot use a Vercel Project resource with in-line ` + "`environ
543544
},
544545
PlanModifiers: []planmodifier.Int64{int64planmodifier.UseStateForUnknown()},
545546
},
547+
"fluid": schema.BoolAttribute{
548+
Description: "Enable fluid compute for your Vercel Functions to automatically manage concurrency and optimize performance. Vercel will handle the defaults to ensure the best experience for your workload.",
549+
Optional: true,
550+
Computed: true,
551+
PlanModifiers: []planmodifier.Bool{boolplanmodifier.UseStateForUnknown()},
552+
},
546553
},
547554
},
548555
},
549556
}
550557
}
551558

559+
func (r *projectResource) ConfigValidators(ctx context.Context) []resource.ConfigValidator {
560+
return []resource.ConfigValidator{
561+
&fluidComputeBasicCPUValidator{},
562+
}
563+
}
564+
552565
// Project reflects the state terraform stores internally for a project.
553566
type Project struct {
554567
BuildCommand types.String `tfsdk:"build_command"`
@@ -1003,12 +1016,14 @@ var resourceConfigAttrType = types.ObjectType{
10031016
AttrTypes: map[string]attr.Type{
10041017
"function_default_cpu_type": types.StringType,
10051018
"function_default_timeout": types.Int64Type,
1019+
"fluid": types.BoolType,
10061020
},
10071021
}
10081022

10091023
type ResourceConfig struct {
10101024
FunctionDefaultCPUType types.String `tfsdk:"function_default_cpu_type"`
10111025
FunctionDefaultTimeout types.Int64 `tfsdk:"function_default_timeout"`
1026+
Fluid types.Bool `tfsdk:"fluid"`
10121027
}
10131028

10141029
func (p *Project) resourceConfig(ctx context.Context) (rc *ResourceConfig, diags diag.Diagnostics) {
@@ -1031,6 +1046,9 @@ func (r *ResourceConfig) toClientResourceConfig() *client.ResourceConfig {
10311046
if !r.FunctionDefaultTimeout.IsUnknown() {
10321047
resourceConfig.FunctionDefaultTimeout = r.FunctionDefaultTimeout.ValueInt64Pointer()
10331048
}
1049+
if !r.Fluid.IsUnknown() {
1050+
resourceConfig.Fluid = r.Fluid.ValueBoolPointer()
1051+
}
10341052
return resourceConfig
10351053
}
10361054

@@ -1253,6 +1271,7 @@ func convertResponseToProject(ctx context.Context, response client.ProjectRespon
12531271
resourceConfig = types.ObjectValueMust(resourceConfigAttrType.AttrTypes, map[string]attr.Value{
12541272
"function_default_cpu_type": types.StringPointerValue(response.ResourceConfig.FunctionDefaultMemoryType),
12551273
"function_default_timeout": types.Int64PointerValue(response.ResourceConfig.FunctionDefaultTimeout),
1274+
"fluid": types.BoolValue(response.ResourceConfig.Fluid),
12561275
})
12571276
}
12581277

vercel/resource_project_test.go

+73
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"regexp"
7+
"strings"
78
"testing"
89

910
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
@@ -103,6 +104,78 @@ func TestAcc_Project(t *testing.T) {
103104
})
104105
}
105106

107+
func TestAcc_ProjectFluidCompute(t *testing.T) {
108+
projectSuffix := acctest.RandString(16)
109+
110+
resource.Test(t, resource.TestCase{
111+
PreCheck: func() { testAccPreCheck(t) },
112+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
113+
CheckDestroy: testAccProjectDestroy("vercel_project.test", testTeam()),
114+
Steps: []resource.TestStep{
115+
{
116+
// check we get a sensible error if fluid + invalid CPU combination.
117+
Config: `
118+
resource "vercel_project" "test" {
119+
name = "foo"
120+
resource_config = {
121+
fluid = true
122+
function_default_cpu_type = "standard_legacy"
123+
}
124+
}
125+
`,
126+
ExpectError: regexp.MustCompile(strings.ReplaceAll("Fluid compute is only supported with the standard or performance CPU types.", " ", `\s*`)),
127+
},
128+
{
129+
// check creating a project with Fluid
130+
Config: fmt.Sprintf(`
131+
resource "vercel_project" "test" {
132+
name = "test-acc-fluid-%[1]s"
133+
%[2]s
134+
135+
resource_config = {
136+
fluid = true
137+
}
138+
}
139+
`, projectSuffix, teamIDConfig()),
140+
Check: resource.ComposeAggregateTestCheckFunc(
141+
resource.TestCheckResourceAttr("vercel_project.test", "name", fmt.Sprintf("test-acc-fluid-%s", projectSuffix)),
142+
resource.TestCheckResourceAttr("vercel_project.test", "resource_config.fluid", "true"),
143+
),
144+
},
145+
{
146+
// check updating Fluid on a project
147+
Config: fmt.Sprintf(`
148+
resource "vercel_project" "test" {
149+
name = "test-acc-fluid-%[1]s"
150+
%[2]s
151+
152+
resource_config = {
153+
fluid = false
154+
}
155+
}
156+
`, projectSuffix, teamIDConfig()),
157+
Check: resource.ComposeAggregateTestCheckFunc(
158+
resource.TestCheckResourceAttr("vercel_project.test", "name", fmt.Sprintf("test-acc-fluid-%s", projectSuffix)),
159+
resource.TestCheckResourceAttr("vercel_project.test", "resource_config.fluid", "false"),
160+
),
161+
},
162+
{
163+
// check new projects without fluid specified shows fluid as false
164+
Config: fmt.Sprintf(`
165+
resource "vercel_project" "test" {
166+
name = "test-acc-fluid-disabled-%[1]s"
167+
%[2]s
168+
}
169+
`, projectSuffix, teamIDConfig()),
170+
Check: resource.ComposeAggregateTestCheckFunc(
171+
resource.TestCheckResourceAttr("vercel_project.test", "name", fmt.Sprintf("test-acc-fluid-disabled-%s", projectSuffix)),
172+
resource.TestCheckResourceAttr("vercel_project.test", "resource_config.fluid", "false"),
173+
),
174+
},
175+
},
176+
})
177+
}
178+
106179
func TestAcc_ProjectAddingEnvAfterInitialCreation(t *testing.T) {
107180
projectSuffix := acctest.RandString(16)
108181
resource.Test(t, resource.TestCase{

vercel/resource_project_validators.go

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package vercel
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/resource"
7+
)
8+
9+
var _ resource.ConfigValidator = &fluidComputeBasicCPUValidator{}
10+
11+
type fluidComputeBasicCPUValidator struct{}
12+
13+
func (v *fluidComputeBasicCPUValidator) Description(ctx context.Context) string {
14+
return "Validates that the CPU type is one of the allowed values for Vercel fluid compute."
15+
}
16+
17+
func (v *fluidComputeBasicCPUValidator) MarkdownDescription(ctx context.Context) string {
18+
return v.Description(ctx)
19+
}
20+
21+
func (v *fluidComputeBasicCPUValidator) ValidateResource(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {
22+
var project Project
23+
diags := req.Config.Get(ctx, &project)
24+
resp.Diagnostics.Append(diags...)
25+
if resp.Diagnostics.HasError() {
26+
return
27+
}
28+
resourceConfig, diags := project.resourceConfig(ctx)
29+
if diags.HasError() {
30+
resp.Diagnostics.Append(diags...)
31+
return
32+
}
33+
if resourceConfig == nil {
34+
return
35+
}
36+
if !resourceConfig.Fluid.ValueBool() {
37+
return
38+
}
39+
if resourceConfig.FunctionDefaultCPUType.ValueString() != "standard_legacy" {
40+
return
41+
}
42+
43+
resp.Diagnostics.AddError(
44+
"Error validating project fluid compute configuration",
45+
"Fluid compute is only supported with the standard or performance CPU types.",
46+
)
47+
}

0 commit comments

Comments
 (0)