mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-27 17:06:27 -06:00
terraform: Unmark provisioner arguments
If provisioner configuration or connection info includes sensitive values, we need to unmark them before calling the provisioner. Failing to do so causes serialization to error. Unlike resources, we do not need to capture marked paths here, so we just discard the marks.
This commit is contained in:
parent
31033001a8
commit
9c580335e3
@ -12052,3 +12052,58 @@ output "out" {
|
||||
t.Fatalf("wrong result\ngot: %#v\nwant: %#v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Apply_provisionerSensitive(t *testing.T) {
|
||||
m := testModule(t, "apply-provisioner-sensitive")
|
||||
p := testProvider("aws")
|
||||
pr := testProvisioner()
|
||||
pr.ProvisionResourceFn = func(req provisioners.ProvisionResourceRequest) (resp provisioners.ProvisionResourceResponse) {
|
||||
if req.Config.ContainsMarked() {
|
||||
t.Fatalf("unexpectedly marked config value: %#v", req.Config)
|
||||
}
|
||||
command := req.Config.GetAttr("command")
|
||||
if command.IsMarked() {
|
||||
t.Fatalf("unexpectedly marked command argument: %#v", command.Marks())
|
||||
}
|
||||
return
|
||||
}
|
||||
p.ApplyResourceChangeFn = testApplyFn
|
||||
p.PlanResourceChangeFn = testDiffFn
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Config: m,
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
|
||||
},
|
||||
Provisioners: map[string]ProvisionerFactory{
|
||||
"shell": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
Variables: InputValues{
|
||||
"password": &InputValue{
|
||||
Value: cty.StringVal("secret"),
|
||||
SourceType: ValueFromCaller,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
||||
logDiagnostics(t, diags)
|
||||
t.Fatal("plan failed")
|
||||
}
|
||||
|
||||
state, diags := ctx.Apply()
|
||||
if diags.HasErrors() {
|
||||
logDiagnostics(t, diags)
|
||||
t.Fatal("apply failed")
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(state.String())
|
||||
expected := strings.TrimSpace(testTerraformApplyProvisionerSensitiveStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected)
|
||||
}
|
||||
|
||||
// Verify apply was invoked
|
||||
if !pr.ProvisionResourceCalled {
|
||||
t.Fatalf("provisioner was not called on apply")
|
||||
}
|
||||
}
|
||||
|
@ -683,10 +683,17 @@ func (n *EvalApplyProvisioners) apply(ctx EvalContext, provs []*configs.Provisio
|
||||
})
|
||||
}
|
||||
|
||||
// If our config or connection info contains any marked values, ensure
|
||||
// those are stripped out before sending to the provisioner. Unlike
|
||||
// resources, we have no need to capture the marked paths and reapply
|
||||
// later.
|
||||
unmarkedConfig, _ := config.UnmarkDeep()
|
||||
unmarkedConnInfo, _ := connInfo.UnmarkDeep()
|
||||
|
||||
output := CallbackUIOutput{OutputFn: outputFn}
|
||||
resp := provisioner.ProvisionResource(provisioners.ProvisionResourceRequest{
|
||||
Config: config,
|
||||
Connection: connInfo,
|
||||
Config: unmarkedConfig,
|
||||
Connection: unmarkedConnInfo,
|
||||
UIOutput: &output,
|
||||
})
|
||||
applyDiags := resp.Diagnostics.InConfigBody(prov.Config)
|
||||
|
@ -866,6 +866,13 @@ aws_instance.bar:
|
||||
type = aws_instance
|
||||
`
|
||||
|
||||
const testTerraformApplyProvisionerSensitiveStr = `
|
||||
aws_instance.foo:
|
||||
ID = foo
|
||||
provider = provider["registry.terraform.io/hashicorp/aws"]
|
||||
type = aws_instance
|
||||
`
|
||||
|
||||
const testTerraformApplyDestroyStr = `
|
||||
<no state>
|
||||
`
|
||||
|
18
terraform/testdata/apply-provisioner-sensitive/main.tf
vendored
Normal file
18
terraform/testdata/apply-provisioner-sensitive/main.tf
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
variable "password" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
resource "aws_instance" "foo" {
|
||||
connection {
|
||||
host = "localhost"
|
||||
type = "telnet"
|
||||
user = "superuser"
|
||||
port = 2222
|
||||
password = var.password
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
command = "echo ${var.password} > secrets"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user