terraform: don't process outputs when all we did was destroy
This commit is contained in:
parent
af482381aa
commit
3af16c8faf
|
@ -112,8 +112,11 @@ func (c *Context) Apply() (*State, error) {
|
||||||
// Walk
|
// Walk
|
||||||
err = g.Walk(c.applyWalkFn())
|
err = g.Walk(c.applyWalkFn())
|
||||||
|
|
||||||
|
// Prune the state so that we have as clean a state as possible
|
||||||
|
c.state.prune()
|
||||||
|
|
||||||
// If we have no errors, then calculate the outputs if we have any
|
// If we have no errors, then calculate the outputs if we have any
|
||||||
if err == nil && len(c.config.Outputs) > 0 {
|
if err == nil && len(c.config.Outputs) > 0 && len(c.state.Resources) > 0 {
|
||||||
c.state.Outputs = make(map[string]string)
|
c.state.Outputs = make(map[string]string)
|
||||||
for _, o := range c.config.Outputs {
|
for _, o := range c.config.Outputs {
|
||||||
if err = c.computeVars(o.RawConfig); err != nil {
|
if err = c.computeVars(o.RawConfig); err != nil {
|
||||||
|
|
|
@ -557,6 +557,46 @@ func TestContextApply_destroy(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContextApply_destroyOutputs(t *testing.T) {
|
||||||
|
c := testConfig(t, "apply-destroy-outputs")
|
||||||
|
h := new(HookRecordApplyOrder)
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.ApplyFn = testApplyFn
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Hooks: []Hook{h},
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// First plan and apply a create operation
|
||||||
|
if _, err := ctx.Plan(nil); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := ctx.Apply(); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, plan and apply a destroy operation
|
||||||
|
if _, err := ctx.Plan(&PlanOpts{Destroy: true}); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Active = true
|
||||||
|
|
||||||
|
state, err := ctx.Apply()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(state.Resources) > 0 {
|
||||||
|
t.Fatalf("bad: %#v", state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContextApply_destroyOrphan(t *testing.T) {
|
func TestContextApply_destroyOrphan(t *testing.T) {
|
||||||
c := testConfig(t, "apply-error")
|
c := testConfig(t, "apply-error")
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
|
|
|
@ -40,6 +40,16 @@ func (s *State) deepcopy() *State {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prune is a helper that removes any empty IDs from the state
|
||||||
|
// and cleans it up in general.
|
||||||
|
func (s *State) prune() {
|
||||||
|
for k, v := range s.Resources {
|
||||||
|
if v.ID == "" {
|
||||||
|
delete(s.Resources, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Orphans returns a list of keys of resources that are in the State
|
// Orphans returns a list of keys of resources that are in the State
|
||||||
// but aren't present in the configuration itself. Hence, these keys
|
// but aren't present in the configuration itself. Hence, these keys
|
||||||
// represent the state of resources that are orphans.
|
// represent the state of resources that are orphans.
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
resource "aws_instance" "foo" {
|
||||||
|
id = "foo"
|
||||||
|
num = "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "bar" {
|
||||||
|
id = "bar"
|
||||||
|
foo = "{aws_instance.foo.num}"
|
||||||
|
dep = "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "foo" {
|
||||||
|
value = "${aws_instance.foo.id}"
|
||||||
|
}
|
Loading…
Reference in New Issue