terraform: mark resource as tainted if provisioning fails
This commit is contained in:
parent
808036bf60
commit
192fc1e544
|
@ -554,9 +554,11 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
//
|
||||
// Additionally, we need to be careful to not run this if there
|
||||
// was an error during the provider apply.
|
||||
tainted := false
|
||||
if applyerr == nil && r.State.ID == "" && len(r.Provisioners) > 0 {
|
||||
if err := c.applyProvisioners(r, rs); err != nil {
|
||||
errs = append(errs, err)
|
||||
tainted = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -566,6 +568,10 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc {
|
|||
delete(c.state.Resources, r.Id)
|
||||
} else {
|
||||
c.state.Resources[r.Id] = rs
|
||||
|
||||
if tainted {
|
||||
c.state.Tainted[r.Id] = struct{}{}
|
||||
}
|
||||
}
|
||||
c.sl.Unlock()
|
||||
|
||||
|
|
|
@ -457,14 +457,16 @@ func TestContextApply_Provisioner_compute(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestContextApply_provisionerFail(t *testing.T) {
|
||||
t.Skip()
|
||||
|
||||
c := testConfig(t, "apply-provisioner-fail")
|
||||
p := testProvider("aws")
|
||||
pr := testProvisioner()
|
||||
p.ApplyFn = testApplyFn
|
||||
p.DiffFn = testDiffFn
|
||||
|
||||
pr.ApplyFn = func(*ResourceState, *ResourceConfig) error {
|
||||
return fmt.Errorf("EXPLOSION")
|
||||
}
|
||||
|
||||
ctx := testContext(t, &ContextOpts{
|
||||
Config: c,
|
||||
Providers: map[string]ResourceProviderFactory{
|
||||
|
@ -483,8 +485,8 @@ func TestContextApply_provisionerFail(t *testing.T) {
|
|||
}
|
||||
|
||||
state, err := ctx.Apply()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
if err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(state.String())
|
||||
|
|
|
@ -18,13 +18,20 @@ import (
|
|||
type State struct {
|
||||
Outputs map[string]string
|
||||
Resources map[string]*ResourceState
|
||||
Tainted map[string]struct{}
|
||||
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
func (s *State) init() {
|
||||
s.once.Do(func() {
|
||||
s.Resources = make(map[string]*ResourceState)
|
||||
if s.Resources == nil {
|
||||
s.Resources = make(map[string]*ResourceState)
|
||||
}
|
||||
|
||||
if s.Tainted == nil {
|
||||
s.Tainted = make(map[string]struct{})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -97,7 +104,12 @@ func (s *State) String() string {
|
|||
id = "<not created>"
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s:\n", k))
|
||||
taintStr := ""
|
||||
if _, ok := s.Tainted[k]; ok {
|
||||
taintStr = " (tainted)"
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s:%s\n", k, taintStr))
|
||||
buf.WriteString(fmt.Sprintf(" ID = %s\n", id))
|
||||
|
||||
attrKeys := make([]string, 0, len(rs.Attributes))
|
||||
|
|
|
@ -131,11 +131,10 @@ aws_instance.foo:
|
|||
`
|
||||
|
||||
const testTerraformApplyProvisionerFailStr = `
|
||||
aws_instance.bar:
|
||||
aws_instance.bar: (tainted)
|
||||
ID = foo
|
||||
aws_instance.foo:
|
||||
ID = foo
|
||||
dynamical = computed_dynamical
|
||||
num = 2
|
||||
type = aws_instance
|
||||
`
|
||||
|
|
Loading…
Reference in New Issue