in internal/meta/config_info.go [145:195]
func (cfgs ConfigInfos) addReferenceDependency() error {
// TF resource id to Azure resource ids.
// Typically, one TF resource id maps to one Azure resource id. However, there are cases that one one TF resource id maps to multiple Azure resource ids.
// E.g. A parent and child resources have the same TF id. Or the association resource's TF id is the same as the master resource's.
m := map[string][]armid.ResourceId{}
for _, cfg := range cfgs {
m[cfg.TFResourceId] = append(m[cfg.TFResourceId], cfg.AzureResourceID)
}
for i, cfg := range cfgs {
file, err := hclsyntax.ParseConfig(cfg.hcl.Bytes(), "main.tf", hcl.InitialPos)
if err != nil {
return fmt.Errorf("parsing hcl for %s: %v", cfg.AzureResourceID, err)
}
hclsyntax.VisitAll(file.Body.(*hclsyntax.Body), func(node hclsyntax.Node) hcl.Diagnostics {
expr, ok := node.(*hclsyntax.LiteralValueExpr)
if !ok {
return nil
}
val := expr.Val
if !expr.Val.IsKnown() || !val.Type().Equals(cty.String) {
return nil
}
maybeTFId := val.AsString()
// This is safe to match case sensitively given the TF id are consistent across the provider. Otherwise, it is a provider bug.
dependingResourceIds, ok := m[maybeTFId]
if !ok {
return nil
}
var dependingResourceIdsWithoutSelf []string
for _, id := range dependingResourceIds[:] {
if id.String() == cfg.AzureResourceID.String() {
continue
}
// if cfg is parent of `id` resource, we should skip, or it will cause circular dependency, so skip parent depends on sub resources
if cfg.AzureResourceID.Equal(id.Parent()) {
continue
}
dependingResourceIdsWithoutSelf = append(dependingResourceIdsWithoutSelf, id.String())
}
if len(dependingResourceIdsWithoutSelf) != 0 {
cfg.DependsOn = append(cfg.DependsOn, Dependency{Candidates: dependingResourceIdsWithoutSelf})
}
return nil
})
cfgs[i] = cfg
}
return nil
}