diff --git a/provisioner/terraform/tfparse/tfparse.go b/provisioner/terraform/tfparse/tfparse.go index 3807c518cbb73..0eb6a0094e505 100644 --- a/provisioner/terraform/tfparse/tfparse.go +++ b/provisioner/terraform/tfparse/tfparse.go @@ -172,7 +172,7 @@ func (p *Parser) WorkspaceTagDefaults(ctx context.Context) (map[string]string, e if err != nil { return nil, xerrors.Errorf("load variable defaults: %w", err) } - paramsDefaults, err := p.CoderParameterDefaults(ctx) + paramsDefaults, err := p.CoderParameterDefaults(ctx, varsDefaults) if err != nil { return nil, xerrors.Errorf("load parameter defaults: %w", err) } @@ -268,7 +268,7 @@ func (p *Parser) VariableDefaults(ctx context.Context) (map[string]string, error // CoderParameterDefaults returns the default values of all coder_parameter data sources // in the parsed module. -func (p *Parser) CoderParameterDefaults(ctx context.Context) (map[string]string, error) { +func (p *Parser) CoderParameterDefaults(ctx context.Context, varsDefaults map[string]string) (map[string]string, error) { defaultsM := make(map[string]string) var ( skipped []string @@ -316,6 +316,7 @@ func (p *Parser) CoderParameterDefaults(ctx context.Context) (map[string]string, } if _, ok := resContent.Attributes["default"]; !ok { + p.logger.Warn(ctx, "coder_parameter data source does not have a default value", slog.F("name", dataResource.Name)) defaultsM[dataResource.Name] = "" } else { expr := resContent.Attributes["default"].Expr @@ -323,7 +324,20 @@ func (p *Parser) CoderParameterDefaults(ctx context.Context) (map[string]string, if err != nil { return nil, xerrors.Errorf("can't preview the resource file: %v", err) } - defaultsM[dataResource.Name] = strings.Trim(value, `"`) + // Issue #15795: the "default" value could also be an expression we need + // to evaluate. + // TODO: should we support coder_parameter default values that reference other coder_parameter data sources? + evalCtx := buildEvalContext(varsDefaults, nil) + val, diags := expr.Value(evalCtx) + if diags.HasErrors() { + return nil, xerrors.Errorf("failed to evaluate coder_parameter %q default value %q: %s", dataResource.Name, value, diags.Error()) + } + // Do not use "val.AsString()" as it can panic + strVal, err := ctyValueString(val) + if err != nil { + return nil, xerrors.Errorf("failed to marshal coder_parameter %q default value %q as string: %s", dataResource.Name, value, err) + } + defaultsM[dataResource.Name] = strings.Trim(strVal, `"`) } } } diff --git a/provisioner/terraform/tfparse/tfparse_test.go b/provisioner/terraform/tfparse/tfparse_test.go index 8436d99e67d03..9d9bcc4526584 100644 --- a/provisioner/terraform/tfparse/tfparse_test.go +++ b/provisioner/terraform/tfparse/tfparse_test.go @@ -114,6 +114,73 @@ func Test_WorkspaceTagDefaultsFromFile(t *testing.T) { expectTags: map[string]string{"platform": "kubernetes", "cluster": "developers", "region": "us", "az": "a"}, expectError: "", }, + { + name: "main.tf with parameter that has default value from dynamic value", + files: map[string]string{ + "main.tf": ` + provider "foo" {} + resource "foo_bar" "baz" {} + variable "region" { + type = string + default = "us" + } + variable "az" { + type = string + default = "${""}${"a"}" + } + data "base" "ours" { + all = true + } + data "coder_parameter" "az" { + name = "az" + type = "string" + default = var.az + } + data "coder_workspace_tags" "tags" { + tags = { + "platform" = "kubernetes", + "cluster" = "${"devel"}${"opers"}" + "region" = var.region + "az" = data.coder_parameter.az.value + } + }`, + }, + expectTags: map[string]string{"platform": "kubernetes", "cluster": "developers", "region": "us", "az": "a"}, + expectError: "", + }, + { + name: "main.tf with parameter that has default value from another parameter", + files: map[string]string{ + "main.tf": ` + provider "foo" {} + resource "foo_bar" "baz" {} + variable "region" { + type = string + default = "us" + } + data "base" "ours" { + all = true + } + data "coder_parameter" "az" { + type = string + default = "${""}${"a"}" + } + data "coder_parameter" "az2" { + name = "az" + type = "string" + default = data.coder_parameter.az.value + } + data "coder_workspace_tags" "tags" { + tags = { + "platform" = "kubernetes", + "cluster" = "${"devel"}${"opers"}" + "region" = var.region + "az" = data.coder_parameter.az2.value + } + }`, + }, + expectError: "Unknown variable; There is no variable named \"data\".", + }, { name: "main.tf with multiple valid workspace tags", files: map[string]string{
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: