6 "github.com/hashicorp/terraform/config"
9 // EvalValidateResourceSelfRef is an EvalNode implementation that validates that
10 // a configuration doesn't contain a reference to the resource itself.
12 // This must be done prior to interpolating configuration in order to avoid
13 // any infinite loop scenarios.
14 type EvalValidateResourceSelfRef struct {
15 Addr **ResourceAddress
16 Config **config.RawConfig
19 func (n *EvalValidateResourceSelfRef) Eval(ctx EvalContext) (interface{}, error) {
23 // Go through the variables and find self references
25 for k, raw := range conf.Variables {
26 rv, ok := raw.(*config.ResourceVariable)
31 // Build an address from the variable
32 varAddr := &ResourceAddress{
38 InstanceType: TypePrimary,
41 // If the variable access is a multi-access (*), then we just
42 // match the index so that we'll match our own addr if everything
44 if rv.Multi && rv.Index == -1 {
45 varAddr.Index = addr.Index
48 // This is a weird thing where ResourceAddres has index "-1" when
49 // index isn't set at all. This means index "0" for resource access.
50 // So, if we have this scenario, just set our varAddr to -1 so it
52 if addr.Index == -1 && varAddr.Index == 0 {
56 // If the addresses match, then this is a self reference
57 if varAddr.Equals(addr) && varAddr.Index == addr.Index {
58 errs = append(errs, fmt.Errorf(
59 "%s: self reference not allowed: %q",
64 // If no errors, no errors!
69 // Wrap the errors in the proper wrapper so we can handle validation
70 // formatting properly upstream.
71 return nil, &EvalValidateError{