terraform: apply diff before apply

This commit is contained in:
Mitchell Hashimoto 2014-06-30 19:29:07 -07:00
parent 2d72164c6a
commit d026d4207e
4 changed files with 38 additions and 23 deletions

View File

@ -1,5 +1,9 @@
package terraform
import (
"fmt"
)
// Resource encapsulates a resource, its configuration, its provider,
// its current state, and potentially a desired diff from the state it
// wants to reach.
@ -10,3 +14,17 @@ type Resource struct {
Provider ResourceProvider
State *ResourceState
}
// TODO: test
func (r *Resource) Vars() map[string]string {
if r.State == nil {
return nil
}
vars := make(map[string]string)
for ak, av := range r.State.Attributes {
vars[fmt.Sprintf("%s.%s", r.Id, ak)] = av
}
return vars
}

View File

@ -102,6 +102,13 @@ func (t *Terraform) Refresh(c *config.Config, s *State) (*State, error) {
func (t *Terraform) apply(
g *depgraph.Graph,
p *Plan) (*State, error) {
if err := GraphAddDiff(g, p.Diff); err != nil {
return nil, err
}
if err := g.Validate(); err != nil {
return nil, err
}
s := new(State)
err := g.Walk(t.applyWalkFn(s, p))
return s, err
@ -170,11 +177,9 @@ func (t *Terraform) applyWalkFn(
result.init()
cb := func(r *Resource) (map[string]string, error) {
diff, ok := p.Diff.Resources[r.Id]
if !ok {
// Skip if there is no diff for a resource
log.Printf("[DEBUG] No diff for %s, skipping.", r.Id)
return nil, nil
diff := r.Diff
if diff.Empty() {
return r.Vars(), nil
}
if !diff.Destroy {
@ -229,23 +234,21 @@ func (t *Terraform) applyWalkFn(
result.Resources[r.Id] = rs
l.Unlock()
// Update the state for the resource itself
r.State = rs
for _, h := range t.hooks {
// TODO: return value
h.PostApply(r.Id, r.State)
}
// Determine the new state and update variables
vars := make(map[string]string)
for ak, av := range rs.Attributes {
vars[fmt.Sprintf("%s.%s", r.Id, ak)] = av
}
err = nil
if len(errs) > 0 {
err = &MultiError{Errors: errs}
}
return vars, err
return r.Vars(), err
}
return t.genericWalkFn(p.Vars, cb)
@ -298,17 +301,11 @@ func (t *Terraform) planWalkFn(result *Plan, opts *PlanOpts) depgraph.WalkFunc {
}
// Determine the new state and update variables
vars := make(map[string]string)
if !diff.Empty() {
r.State = r.State.MergeDiff(diff)
}
if r.State != nil {
for ak, av := range r.State.Attributes {
vars[fmt.Sprintf("%s.%s", r.Id, ak)] = av
}
}
return vars, nil
return r.Vars(), nil
}
return t.genericWalkFn(opts.Vars, cb)

View File

@ -493,7 +493,7 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
}
id := "foo"
if idAttr, ok := d.Attributes["id"]; ok {
if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed {
id = idAttr.New
}
@ -687,12 +687,12 @@ const testTerraformApplyComputeStr = `
aws_instance.bar:
ID = foo
type = aws_instance
foo = computed_id
foo = computed_dynamical
aws_instance.foo:
ID = foo
type = aws_instance
num = 2
id = computed_id
dynamical = computed_dynamical
`
const testTerraformApplyDestroyStr = `

View File

@ -1,9 +1,9 @@
resource "aws_instance" "foo" {
num = "2"
compute = "id"
compute = "dynamical"
compute_value = "${var.value}"
}
resource "aws_instance" "bar" {
foo = "${aws_instance.foo.id}"
foo = "${aws_instance.foo.dynamical}"
}