package terraform import ( "github.com/hashicorp/terraform/dag" ) // NodePlannableResource represents a resource that is "plannable": // it is ready to be planned in order to create a diff. type NodePlannableResource struct { *NodeAbstractCountResource } // GraphNodeDynamicExpandable func (n *NodePlannableResource) DynamicExpand(ctx EvalContext) (*Graph, error) { // Grab the state which we read state, lock := ctx.State() lock.RLock() defer lock.RUnlock() // Expand the resource count which must be available by now from EvalTree count, err := n.Config.Count() if err != nil { return nil, err } // The concrete resource factory we'll use concreteResource := func(a *NodeAbstractResource) dag.Vertex { // Add the config and state since we don't do that via transforms a.Config = n.Config a.ResolvedProvider = n.ResolvedProvider return &NodePlannableResourceInstance{ NodeAbstractResource: a, } } // The concrete resource factory we'll use for oprhans concreteResourceOrphan := func(a *NodeAbstractResource) dag.Vertex { // Add the config and state since we don't do that via transforms a.Config = n.Config a.ResolvedProvider = n.ResolvedProvider return &NodePlannableResourceOrphan{ NodeAbstractResource: a, } } // Start creating the steps steps := []GraphTransformer{ // Expand the count. &ResourceCountTransformer{ Concrete: concreteResource, Count: count, Addr: n.ResourceAddr(), }, // Add the count orphans &OrphanResourceCountTransformer{ Concrete: concreteResourceOrphan, Count: count, Addr: n.ResourceAddr(), State: state, }, // Attach the state &AttachStateTransformer{State: state}, // Targeting &TargetsTransformer{ParsedTargets: n.Targets}, // Connect references so ordering is correct &ReferenceTransformer{}, // Make sure there is a single root &RootTransformer{}, } // Build the graph b := &BasicGraphBuilder{ Steps: steps, Validate: true, Name: "NodePlannableResource", } return b.Build(ctx.Path()) }