don't send an invalid config to a provisioner
The config diagnostics weren't checked before sending to the provisioner, and may have contained invalid values.
This commit is contained in:
parent
72f9385285
commit
102c575f04
|
@ -2018,6 +2018,72 @@ aws_instance.foo:
|
|||
`)
|
||||
}
|
||||
|
||||
// for_each values cannot be used in the provisioner during destroy.
|
||||
// There may be a way to handle this, but for now make sure we print an error
|
||||
// rather than crashing with an invalid config.
|
||||
func TestContext2Apply_provisionerDestroyForEach(t *testing.T) {
|
||||
m := testModule(t, "apply-provisioner-each")
|
||||
p := testProvider("aws")
|
||||
pr := testProvisioner()
|
||||
p.DiffFn = testDiffFn
|
||||
p.ApplyFn = testApplyFn
|
||||
|
||||
s := &states.State{
|
||||
Modules: map[string]*states.Module{
|
||||
"": &states.Module{
|
||||
Resources: map[string]*states.Resource{
|
||||
"aws_instance.bar": &states.Resource{
|
||||
Addr: addrs.Resource{Mode: 77, Type: "aws_instance", Name: "bar"},
|
||||
EachMode: states.EachMap,
|
||||
Instances: map[addrs.InstanceKey]*states.ResourceInstance{
|
||||
addrs.StringKey("a"): &states.ResourceInstance{
|
||||
Current: &states.ResourceInstanceObjectSrc{
|
||||
AttrsJSON: []byte(`{"foo":"bar","id":"foo"}`),
|
||||
},
|
||||
},
|
||||
addrs.StringKey("b"): &states.ResourceInstance{
|
||||
Current: &states.ResourceInstanceObjectSrc{
|
||||
AttrsJSON: []byte(`{"foo":"bar","id":"foo"}`),
|
||||
},
|
||||
},
|
||||
},
|
||||
ProviderConfig: addrs.AbsProviderConfig{
|
||||
Module: addrs.ModuleInstance(nil),
|
||||
ProviderConfig: addrs.ProviderConfig{Type: "aws", Alias: ""},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Config: m,
|
||||
ProviderResolver: providers.ResolverFixed(
|
||||
map[string]providers.Factory{
|
||||
"aws": testProviderFuncFixed(p),
|
||||
},
|
||||
),
|
||||
Provisioners: map[string]ProvisionerFactory{
|
||||
"shell": testProvisionerFuncFixed(pr),
|
||||
},
|
||||
State: s,
|
||||
Destroy: true,
|
||||
})
|
||||
|
||||
if _, diags := ctx.Plan(); diags.HasErrors() {
|
||||
t.Fatalf("plan errors: %s", diags.Err())
|
||||
}
|
||||
|
||||
_, diags := ctx.Apply()
|
||||
if diags == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
if !strings.Contains(diags.Err().Error(), `Reference to "each" in context without for_each`) {
|
||||
t.Fatal("unexpected error:", diags.Err())
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Apply_cancelProvisioner(t *testing.T) {
|
||||
m := testModule(t, "apply-cancel-provisioner")
|
||||
p := testProvider("aws")
|
||||
|
|
|
@ -557,6 +557,11 @@ func (n *EvalApplyProvisioners) apply(ctx EvalContext, provs []*configs.Provisio
|
|||
config, _, configDiags := ctx.EvaluateBlock(prov.Config, schema, instanceAddr, keyData)
|
||||
diags = diags.Append(configDiags)
|
||||
|
||||
// we can't apply the provisioner if the config has errors
|
||||
if diags.HasErrors() {
|
||||
return diags.Err()
|
||||
}
|
||||
|
||||
// If the provisioner block contains a connection block of its own then
|
||||
// it can override the base connection configuration, if any.
|
||||
var localConn hcl.Body
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
resource "aws_instance" "bar" {
|
||||
for_each = toset(["a"])
|
||||
provisioner "shell" {
|
||||
when = "destroy"
|
||||
command = "echo ${each.value}"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue