terraform: add Dependencies to ResourceState
This commit is contained in:
parent
b3de33cc69
commit
521b432728
|
@ -16,8 +16,7 @@ import (
|
||||||
// can use to keep track of what real world resources it is actually
|
// can use to keep track of what real world resources it is actually
|
||||||
// managing.
|
// managing.
|
||||||
type State struct {
|
type State struct {
|
||||||
Dependencies map[string][][]string
|
Resources map[string]*ResourceState
|
||||||
Resources map[string]*ResourceState
|
|
||||||
|
|
||||||
once sync.Once
|
once sync.Once
|
||||||
}
|
}
|
||||||
|
@ -75,6 +74,13 @@ func (s *State) String() string {
|
||||||
for ak, av := range rs.Attributes {
|
for ak, av := range rs.Attributes {
|
||||||
buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av))
|
buf.WriteString(fmt.Sprintf(" %s = %s\n", ak, av))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(rs.Dependencies) > 0 {
|
||||||
|
buf.WriteString(fmt.Sprintf("\n Dependencies:\n"))
|
||||||
|
for _, dep := range rs.Dependencies {
|
||||||
|
buf.WriteString(fmt.Sprintf(" %s\n", dep.ID))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf.String()
|
return buf.String()
|
||||||
|
@ -135,10 +141,43 @@ func WriteState(d *State, dst io.Writer) error {
|
||||||
// Extra is just extra data that a provider can return that we store
|
// Extra is just extra data that a provider can return that we store
|
||||||
// for later, but is not exposed in any way to the user.
|
// for later, but is not exposed in any way to the user.
|
||||||
type ResourceState struct {
|
type ResourceState struct {
|
||||||
ID string
|
// This is filled in and managed by Terraform, and is the resource
|
||||||
Type string
|
// type itself such as "mycloud_instance". If a resource provider sets
|
||||||
|
// this value, it won't be persisted.
|
||||||
|
Type string
|
||||||
|
|
||||||
|
// The attributes below are all meant to be filled in by the
|
||||||
|
// resource providers themselves. Documentation for each are above
|
||||||
|
// each element.
|
||||||
|
|
||||||
|
// A unique ID for this resource. This is opaque to Terraform
|
||||||
|
// and is only meant as a lookup mechanism for the providers.
|
||||||
|
ID string
|
||||||
|
|
||||||
|
// Attributes are basic information about the resource. Any keys here
|
||||||
|
// are accessible in variable format within Terraform configurations:
|
||||||
|
// ${resourcetype.name.attribute}.
|
||||||
Attributes map[string]string
|
Attributes map[string]string
|
||||||
Extra map[string]interface{}
|
|
||||||
|
// Extra information that the provider can store about a resource.
|
||||||
|
// This data is opaque, never shown to the user, and is sent back to
|
||||||
|
// the provider as-is for whatever purpose appropriate.
|
||||||
|
Extra map[string]interface{}
|
||||||
|
|
||||||
|
// Dependencies are a list of things that this resource relies on
|
||||||
|
// existing to remain intact. For example: an AWS instance might
|
||||||
|
// depend on a subnet (which itself might depend on a VPC, and so
|
||||||
|
// on).
|
||||||
|
//
|
||||||
|
// Terraform uses this information to build valid destruction
|
||||||
|
// orders and to warn the user if they're destroying a resource that
|
||||||
|
// another resource depends on.
|
||||||
|
//
|
||||||
|
// Things can be put into this list that may not be managed by
|
||||||
|
// Terraform. If Terraform doesn't find a matching ID in the
|
||||||
|
// overall state, then it assumes it isn't managed and doesn't
|
||||||
|
// worry about it.
|
||||||
|
Dependencies []ResourceDependency
|
||||||
}
|
}
|
||||||
|
|
||||||
// MergeDiff takes a ResourceDiff and merges the attributes into
|
// MergeDiff takes a ResourceDiff and merges the attributes into
|
||||||
|
@ -174,3 +213,11 @@ func (s *ResourceState) MergeDiff(d *ResourceDiff) *ResourceState {
|
||||||
|
|
||||||
return &result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ResourceDependency maps a resource to another resource that it
|
||||||
|
// depends on to remain intact and uncorrupted.
|
||||||
|
type ResourceDependency struct {
|
||||||
|
// ID of the resource that we depend on. This ID should map
|
||||||
|
// directly to another ResourceState's ID.
|
||||||
|
ID string
|
||||||
|
}
|
||||||
|
|
|
@ -104,6 +104,10 @@ func (t *Terraform) apply(
|
||||||
p *Plan) (*State, error) {
|
p *Plan) (*State, error) {
|
||||||
s := new(State)
|
s := new(State)
|
||||||
err := g.Walk(t.applyWalkFn(s, p))
|
err := g.Walk(t.applyWalkFn(s, p))
|
||||||
|
|
||||||
|
// Now that we've built the state and have the graph, re-calculate
|
||||||
|
// the dependencies for our state based on what we did.
|
||||||
|
|
||||||
return s, err
|
return s, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -492,15 +492,27 @@ func testProviderFunc(n string, rs []string) ResourceProviderFactory {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id := "foo"
|
||||||
|
if idAttr, ok := d.Attributes["id"]; ok {
|
||||||
|
id = idAttr.New
|
||||||
|
}
|
||||||
|
|
||||||
result := &ResourceState{
|
result := &ResourceState{
|
||||||
ID: "foo",
|
ID: id,
|
||||||
Attributes: make(map[string]string),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if d != nil {
|
if d != nil {
|
||||||
result = result.MergeDiff(d)
|
result = result.MergeDiff(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if depAttr, ok := d.Attributes["dep"]; ok {
|
||||||
|
result.Dependencies = []ResourceDependency{
|
||||||
|
ResourceDependency{
|
||||||
|
ID: depAttr.New,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
resource "aws_instance" "foo" {
|
resource "aws_instance" "foo" {
|
||||||
|
id = "foo"
|
||||||
num = "2"
|
num = "2"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_instance" "bar" {
|
resource "aws_instance" "bar" {
|
||||||
|
id = "bar"
|
||||||
foo = "{aws_instance.foo.num}"
|
foo = "{aws_instance.foo.num}"
|
||||||
|
dep = "foo"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue