Skip to content

Commit 32ed0f7

Browse files
committed
lang: stabilise ephemeral values experiment
Stabilise the ephemeral values experiment and ephemeralasnull experimental function.
1 parent 64d1b07 commit 32ed0f7

File tree

6 files changed

+19
-101
lines changed

6 files changed

+19
-101
lines changed

internal/configs/experiments.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -207,29 +207,5 @@ func checkModuleExperiments(m *Module) hcl.Diagnostics {
207207
}
208208
}
209209
*/
210-
211-
if !m.ActiveExperiments.Has(experiments.EphemeralValues) {
212-
for _, oc := range m.Outputs {
213-
if oc.EphemeralSet {
214-
diags = append(diags, &hcl.Diagnostic{
215-
Severity: hcl.DiagError,
216-
Summary: "Ephemeral values are experimental",
217-
Detail: "This feature is currently an opt-in experiment, subject to change in future releases based on feedback.\n\nActivate the feature for this module by adding ephemeral_values to the list of active experiments.",
218-
Subject: oc.DeclRange.Ptr(),
219-
})
220-
}
221-
}
222-
for _, vc := range m.Variables {
223-
if vc.EphemeralSet {
224-
diags = append(diags, &hcl.Diagnostic{
225-
Severity: hcl.DiagError,
226-
Summary: "Ephemeral values are experimental",
227-
Detail: "This feature is currently an opt-in experiment, subject to change in future releases based on feedback.\n\nActivate the feature for this module by adding ephemeral_values to the list of active experiments.",
228-
Subject: vc.DeclRange.Ptr(),
229-
})
230-
}
231-
}
232-
}
233-
234210
return diags
235211
}

internal/lang/functions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (s *Scope) Functions() map[string]function.Function {
8989
"distinct": stdlib.DistinctFunc,
9090
"element": stdlib.ElementFunc,
9191
"endswith": funcs.EndsWithFunc,
92-
"ephemeralasnull": s.experimentalFunction(experiments.EphemeralValues, funcs.EphemeralAsNullFunc),
92+
"ephemeralasnull": funcs.EphemeralAsNullFunc,
9393
"chunklist": stdlib.ChunklistFunc,
9494
"file": funcs.MakeFileFunc(s.BaseDir, false),
9595
"fileexists": funcs.MakeFileExistsFunc(s.BaseDir),

internal/lang/functions_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,6 @@ func TestFunctions(t *testing.T) {
12421242
}
12431243

12441244
experimentalFuncs := map[string]experiments.Experiment{}
1245-
experimentalFuncs["ephemeralasnull"] = experiments.EphemeralValues
12461245

12471246
// We'll also register a few "external functions" so that we can
12481247
// verify that registering these works. The functions actually

internal/terraform/context_apply2_test.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3019,11 +3019,6 @@ func TestContext2Apply_applyingFlag(t *testing.T) {
30193019
source = "terraform.io/builtin/test"
30203020
}
30213021
}
3022-
3023-
# If this experimental feature becomes stablized and this test
3024-
# is still relevant, consider just removing this opt-in while
3025-
# retaining the rest.
3026-
experiments = [ephemeral_values]
30273022
}
30283023
30293024
provider "test" {
@@ -3102,13 +3097,6 @@ func TestContext2Apply_applyingFlag(t *testing.T) {
31023097
func TestContext2Apply_applyTimeVariables(t *testing.T) {
31033098
m := testModuleInline(t, map[string]string{
31043099
"main.tf": `
3105-
# If this experimental feature becomes stablized and this test
3106-
# is still relevant, consider just removing this opt-in while
3107-
# retaining the rest.
3108-
terraform {
3109-
experiments = [ephemeral_values]
3110-
}
3111-
31123100
variable "e" {
31133101
type = string
31143102
default = null

internal/terraform/context_plan2_test.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5499,11 +5499,6 @@ func TestContext2Plan_ephemeralInResource(t *testing.T) {
54995499
m := testModuleInline(t, map[string]string{
55005500
"main.tf": `
55015501
terraform {
5502-
# Ephemeral values are currently experimental. Remove this
5503-
# argument if the feature gets stablized and this test otherwise
5504-
# still makes sense for what was stabilized.
5505-
experiments = [ephemeral_values]
5506-
55075502
required_providers {
55085503
beep = {
55095504
source = "terraform.io/builtin/beep"
@@ -5555,10 +5550,10 @@ func TestContext2Plan_ephemeralInResource(t *testing.T) {
55555550
Subject: &hcl.Range{
55565551
Filename: filepath.Join(m.Module.SourceDir, "main.tf"),
55575552
Start: hcl.Pos{
5558-
Line: 21, Column: 10, Byte: 442,
5553+
Line: 16, Column: 10, Byte: 223,
55595554
},
55605555
End: hcl.Pos{
5561-
Line: 21, Column: 16, Byte: 448,
5556+
Line: 16, Column: 16, Byte: 229,
55625557
},
55635558
},
55645559
})
@@ -5569,10 +5564,10 @@ func TestContext2Plan_ephemeralInResource(t *testing.T) {
55695564
Subject: &hcl.Range{
55705565
Filename: filepath.Join(m.Module.SourceDir, "main.tf"),
55715566
Start: hcl.Pos{
5572-
Line: 25, Column: 10, Byte: 488,
5567+
Line: 20, Column: 10, Byte: 269,
55735568
},
55745569
End: hcl.Pos{
5575-
Line: 25, Column: 16, Byte: 494,
5570+
Line: 20, Column: 16, Byte: 275,
55765571
},
55775572
},
55785573
})
@@ -5602,11 +5597,6 @@ func TestContext2Plan_ephemeralInProviderConfig(t *testing.T) {
56025597
m := testModuleInline(t, map[string]string{
56035598
"main.tf": `
56045599
terraform {
5605-
# Ephemeral values are currently experimental. Remove this
5606-
# argument if the feature gets stablized and this test otherwise
5607-
# still makes sense for what was stabilized.
5608-
experiments = [ephemeral_values]
5609-
56105600
required_providers {
56115601
beep = {
56125602
source = "terraform.io/builtin/beep"

internal/terraform/evaluate_data.go

Lines changed: 14 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313

1414
"github.com/hashicorp/terraform/internal/addrs"
1515
"github.com/hashicorp/terraform/internal/didyoumean"
16-
"github.com/hashicorp/terraform/internal/experiments"
1716
"github.com/hashicorp/terraform/internal/lang/marks"
1817
"github.com/hashicorp/terraform/internal/tfdiags"
1918
)
@@ -101,69 +100,35 @@ func (d *evaluationData) GetPathAttr(addr addrs.PathAttr, rng tfdiags.SourceRang
101100
// GetTerraformAttr implements lang.Data.
102101
func (d *evaluationData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.SourceRange) (cty.Value, tfdiags.Diagnostics) {
103102
var diags tfdiags.Diagnostics
103+
switch addr.Name {
104104

105-
// terraform.applying is an ephemeral boolean value that's set to true
106-
// during an apply walk or false in any other situation. This is
107-
// intended to allow, for example, using a more privileged auth role
108-
// in a provider configuration during the apply phase but a more
109-
// constrained role for other situations.
110-
//
111-
// Since this produces an ephemeral value, and ephemeral values are
112-
// currently experimental, this is available only in modules that
113-
// have opted in to the experiment. If this experiment gets stabilized,
114-
// it'll probably be best to incorporate this into the normal codepath
115-
// below, but it's currently handled separately up here so it'll be easier
116-
// to remove if the experiment is unsuccessful.
117-
if addr.Name == "applying" {
118-
modCfg := d.Evaluator.Config.Descendent(d.Module)
119-
if modCfg != nil && modCfg.Module.ActiveExperiments.Has(experiments.EphemeralValues) {
120-
return cty.BoolVal(d.Evaluator.Operation == walkApply).Mark(marks.Ephemeral), nil
121-
}
122-
// If the experiment isn't active then we just fall out to the other
123-
// code below, which will treat this situation just like any other
124-
// invalid attribute name.
125-
//
126-
// If you're here to stabilize the experiment, note also that some
127-
// of the error messages below assume that terraform.workspace is
128-
// the only currently-valid attribute and so will probably need revising
129-
// once terraform.applying is also valid.
130-
}
131-
132-
if d.Evaluator.Meta == nil || d.Evaluator.Meta.Env == "" {
133-
// The absense of an "env" (really: workspace) name suggests that
105+
case "workspace":
106+
// The absence of an "env" (really: workspace) name suggests that
134107
// we're running in a non-workspace context, such as in a component
135108
// of a stack. terraform.workspace is a legacy thing from workspaces
136109
// mode that isn't carried forward to stacks, because stack
137110
// configurations can instead vary their behavior based on input
138111
// variables provided in the deployment configuration.
139-
switch addr.Name {
140-
case "workspace":
112+
if d.Evaluator.Meta == nil || d.Evaluator.Meta.Env == "" {
141113
diags = diags.Append(&hcl.Diagnostic{
142114
Severity: hcl.DiagError,
143115
Summary: `Invalid reference`,
144116
Detail: `The terraform.workspace attribute is only available for modules used in Terraform workspaces. Use input variables instead to create variations between different instances of this module.`,
145117
Subject: rng.ToHCL().Ptr(),
146118
})
147-
default:
148-
// A more generic error for any other attribute name, since no
149-
// others are valid anyway but it would be confusing to mention
150-
// terraform.workspace here.
151-
diags = diags.Append(&hcl.Diagnostic{
152-
Severity: hcl.DiagError,
153-
Summary: `Invalid reference`,
154-
Detail: `The "terraform" object is only available for modules used in Terraform workspaces.`,
155-
Subject: rng.ToHCL().Ptr(),
156-
})
119+
return cty.DynamicVal, diags
157120
}
158-
return cty.DynamicVal, diags
159-
}
160-
161-
switch addr.Name {
162-
163-
case "workspace":
164121
workspaceName := d.Evaluator.Meta.Env
165122
return cty.StringVal(workspaceName), diags
166123

124+
// terraform.applying is an ephemeral boolean value that's set to true
125+
// during an apply walk or false in any other situation. This is
126+
// intended to allow, for example, using a more privileged auth role
127+
// in a provider configuration during the apply phase but a more
128+
// constrained role for other situations.
129+
case "applying":
130+
return cty.BoolVal(d.Evaluator.Operation == walkApply).Mark(marks.Ephemeral), nil
131+
167132
case "env":
168133
// Prior to Terraform 0.12 there was an attribute "env", which was
169134
// an alias name for "workspace". This was deprecated and is now
@@ -180,7 +145,7 @@ func (d *evaluationData) GetTerraformAttr(addr addrs.TerraformAttr, rng tfdiags.
180145
diags = diags.Append(&hcl.Diagnostic{
181146
Severity: hcl.DiagError,
182147
Summary: `Invalid "terraform" attribute`,
183-
Detail: fmt.Sprintf(`The "terraform" object does not have an attribute named %q. The only supported attribute is terraform.workspace, the name of the currently-selected workspace.`, addr.Name),
148+
Detail: fmt.Sprintf(`The "terraform" object does not have an attribute named %q. The only supported attributes are terraform.workspace, the name of the currently-selected workspace, and terraform.applying, a boolean which is true only during apply.`, addr.Name),
184149
Subject: rng.ToHCL().Ptr(),
185150
})
186151
return cty.DynamicVal, diags

0 commit comments

Comments
 (0)