mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-26 00:41:27 -06:00
terraform: re-diff on apply
This commit is contained in:
parent
84cf644a30
commit
92ffbf2880
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/terraform/config"
|
||||
@ -29,7 +30,15 @@ func (s *State) init() {
|
||||
func (s *State) String() string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
for k, rs := range s.Resources {
|
||||
names := make([]string, 0, len(s.Resources))
|
||||
for name, _ := range s.Resources {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
for _, k := range names {
|
||||
rs := s.Resources[k]
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s:\n", k))
|
||||
buf.WriteString(fmt.Sprintf(" ID = %s\n", rs.ID))
|
||||
|
||||
|
@ -136,7 +136,13 @@ func (t *Terraform) applyWalkFn(
|
||||
result.init()
|
||||
|
||||
cb := func(r *Resource) (map[string]string, error) {
|
||||
rs, err := r.Provider.Apply(r.State, r.Diff)
|
||||
// Get the latest diff since there are no computed values anymore
|
||||
diff, err := r.Provider.Diff(r.State, r.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rs, err := r.Provider.Apply(r.State, diff)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package terraform
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -228,6 +229,33 @@ func TestTerraformApply(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTerraformApply_compute(t *testing.T) {
|
||||
// This tests that computed variables are properly re-diffed
|
||||
// to get the value prior to application (Apply).
|
||||
tf := testTerraform(t, "apply-compute")
|
||||
|
||||
s := &State{}
|
||||
p, err := tf.Plan(s)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Set meta to change behavior so that computed variables are filled
|
||||
testProviderMock(testProvider(tf, "aws_instance.foo")).Meta =
|
||||
"compute"
|
||||
|
||||
state, err := tf.Apply(p)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(state.String())
|
||||
expected := strings.TrimSpace(testTerraformApplyComputeStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad: \n%s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTerraformPlan(t *testing.T) {
|
||||
tf := testTerraform(t, "plan-good")
|
||||
|
||||
@ -324,6 +352,8 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
|
||||
}
|
||||
|
||||
return func() (ResourceProvider, error) {
|
||||
p := &MockResourceProvider{Meta: n}
|
||||
|
||||
applyFn := func(
|
||||
s *ResourceState,
|
||||
d *ResourceDiff) (*ResourceState, error) {
|
||||
@ -361,11 +391,20 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
|
||||
}
|
||||
|
||||
if k == "compute" {
|
||||
diff.Attributes[v.(string)] = &ResourceAttrDiff{
|
||||
attrDiff := &ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "",
|
||||
NewComputed: true,
|
||||
}
|
||||
|
||||
// If the value of Meta turns into "compute", then we
|
||||
// fill the computed values.
|
||||
if mv, ok := p.Meta.(string); ok && mv == "compute" {
|
||||
attrDiff.NewComputed = false
|
||||
attrDiff.New = fmt.Sprintf("computed_%s", v.(string))
|
||||
}
|
||||
|
||||
diff.Attributes[v.(string)] = attrDiff
|
||||
continue
|
||||
}
|
||||
|
||||
@ -408,15 +447,12 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
result := &MockResourceProvider{
|
||||
Meta: n,
|
||||
ApplyFn: applyFn,
|
||||
DiffFn: diffFn,
|
||||
RefreshFn: refreshFn,
|
||||
ResourcesReturn: resources,
|
||||
}
|
||||
p.ApplyFn = applyFn
|
||||
p.DiffFn = diffFn
|
||||
p.RefreshFn = refreshFn
|
||||
p.ResourcesReturn = resources
|
||||
|
||||
return result, nil
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,6 +538,18 @@ aws_instance.foo:
|
||||
num = 2
|
||||
`
|
||||
|
||||
const testTerraformApplyComputeStr = `
|
||||
aws_instance.bar:
|
||||
ID = foo
|
||||
type = aws_instance
|
||||
foo = computed_id
|
||||
aws_instance.foo:
|
||||
ID = foo
|
||||
type = aws_instance
|
||||
num = 2
|
||||
id = computed_id
|
||||
`
|
||||
|
||||
const testTerraformPlanStr = `
|
||||
UPDATE: aws_instance.bar
|
||||
foo: "" => "2"
|
||||
|
8
terraform/test-fixtures/apply-compute/main.tf
Normal file
8
terraform/test-fixtures/apply-compute/main.tf
Normal file
@ -0,0 +1,8 @@
|
||||
resource "aws_instance" "foo" {
|
||||
num = "2"
|
||||
compute = "id"
|
||||
}
|
||||
|
||||
resource "aws_instance" "bar" {
|
||||
foo = "${aws_instance.foo.id}"
|
||||
}
|
Loading…
Reference in New Issue
Block a user