terraform: apply diff before apply
This commit is contained in:
parent
2d72164c6a
commit
d026d4207e
|
@ -1,5 +1,9 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
// Resource encapsulates a resource, its configuration, its provider,
|
// Resource encapsulates a resource, its configuration, its provider,
|
||||||
// its current state, and potentially a desired diff from the state it
|
// its current state, and potentially a desired diff from the state it
|
||||||
// wants to reach.
|
// wants to reach.
|
||||||
|
@ -10,3 +14,17 @@ type Resource struct {
|
||||||
Provider ResourceProvider
|
Provider ResourceProvider
|
||||||
State *ResourceState
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -102,6 +102,13 @@ func (t *Terraform) Refresh(c *config.Config, s *State) (*State, error) {
|
||||||
func (t *Terraform) apply(
|
func (t *Terraform) apply(
|
||||||
g *depgraph.Graph,
|
g *depgraph.Graph,
|
||||||
p *Plan) (*State, error) {
|
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)
|
s := new(State)
|
||||||
err := g.Walk(t.applyWalkFn(s, p))
|
err := g.Walk(t.applyWalkFn(s, p))
|
||||||
return s, err
|
return s, err
|
||||||
|
@ -170,11 +177,9 @@ func (t *Terraform) applyWalkFn(
|
||||||
result.init()
|
result.init()
|
||||||
|
|
||||||
cb := func(r *Resource) (map[string]string, error) {
|
cb := func(r *Resource) (map[string]string, error) {
|
||||||
diff, ok := p.Diff.Resources[r.Id]
|
diff := r.Diff
|
||||||
if !ok {
|
if diff.Empty() {
|
||||||
// Skip if there is no diff for a resource
|
return r.Vars(), nil
|
||||||
log.Printf("[DEBUG] No diff for %s, skipping.", r.Id)
|
|
||||||
return nil, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !diff.Destroy {
|
if !diff.Destroy {
|
||||||
|
@ -229,23 +234,21 @@ func (t *Terraform) applyWalkFn(
|
||||||
result.Resources[r.Id] = rs
|
result.Resources[r.Id] = rs
|
||||||
l.Unlock()
|
l.Unlock()
|
||||||
|
|
||||||
|
// Update the state for the resource itself
|
||||||
|
r.State = rs
|
||||||
|
|
||||||
for _, h := range t.hooks {
|
for _, h := range t.hooks {
|
||||||
// TODO: return value
|
// TODO: return value
|
||||||
h.PostApply(r.Id, r.State)
|
h.PostApply(r.Id, r.State)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the new state and update variables
|
// 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
|
err = nil
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
err = &MultiError{Errors: errs}
|
err = &MultiError{Errors: errs}
|
||||||
}
|
}
|
||||||
|
|
||||||
return vars, err
|
return r.Vars(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.genericWalkFn(p.Vars, cb)
|
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
|
// Determine the new state and update variables
|
||||||
vars := make(map[string]string)
|
|
||||||
if !diff.Empty() {
|
if !diff.Empty() {
|
||||||
r.State = r.State.MergeDiff(diff)
|
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)
|
return t.genericWalkFn(opts.Vars, cb)
|
||||||
|
|
|
@ -493,7 +493,7 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
id := "foo"
|
id := "foo"
|
||||||
if idAttr, ok := d.Attributes["id"]; ok {
|
if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed {
|
||||||
id = idAttr.New
|
id = idAttr.New
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,12 +687,12 @@ const testTerraformApplyComputeStr = `
|
||||||
aws_instance.bar:
|
aws_instance.bar:
|
||||||
ID = foo
|
ID = foo
|
||||||
type = aws_instance
|
type = aws_instance
|
||||||
foo = computed_id
|
foo = computed_dynamical
|
||||||
aws_instance.foo:
|
aws_instance.foo:
|
||||||
ID = foo
|
ID = foo
|
||||||
type = aws_instance
|
type = aws_instance
|
||||||
num = 2
|
num = 2
|
||||||
id = computed_id
|
dynamical = computed_dynamical
|
||||||
`
|
`
|
||||||
|
|
||||||
const testTerraformApplyDestroyStr = `
|
const testTerraformApplyDestroyStr = `
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
resource "aws_instance" "foo" {
|
resource "aws_instance" "foo" {
|
||||||
num = "2"
|
num = "2"
|
||||||
compute = "id"
|
compute = "dynamical"
|
||||||
compute_value = "${var.value}"
|
compute_value = "${var.value}"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_instance" "bar" {
|
resource "aws_instance" "bar" {
|
||||||
foo = "${aws_instance.foo.id}"
|
foo = "${aws_instance.foo.dynamical}"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue