in resource/context.go [119:259]
func (c *Context) AddAzapiDefinition(input types.AzapiDefinition) error {
logrus.Debugf("adding azapi definition: \n%v", input)
if c.azapiAddingMap[input.Identifier()] {
return fmt.Errorf("azapi definition already added: %v", input.Identifier())
}
c.azapiAddingMap[input.Identifier()] = true
defer func() {
c.azapiAddingMap[input.Identifier()] = false
}()
def := input.DeepCopy()
// find all id placeholders from def
placeHolders := make([]types.PropertyDependencyMapping, 0)
rootFields := []string{"parent_id", "resource_id"}
for _, field := range rootFields {
if value, ok := def.AdditionalFields[field]; ok {
if literalValue, ok := value.(types.StringLiteralValue); ok {
placeHolders = append(placeHolders, types.PropertyDependencyMapping{
ValuePath: field,
LiteralValue: literalValue.Literal,
})
}
}
}
if def.Body != nil {
mappings := GetKeyValueMappings(def.Body, "")
for _, mapping := range mappings {
if utils.IsResourceId(mapping.LiteralValue) {
placeHolders = append(placeHolders, mapping)
}
}
}
logrus.Debugf("found %d id placeholders", len(placeHolders))
// find all dependencies that match the id placeholders
for i, placeHolder := range placeHolders {
logrus.Debugf("processing id placeholder: %s", placeHolder.LiteralValue)
if utils.IsAction(placeHolder.LiteralValue) {
logrus.Debugf("skip action: %s", placeHolder.LiteralValue)
continue
}
pattern := dependency.NewPattern(placeHolder.LiteralValue)
for _, resolver := range c.ReferenceResolvers {
result, err := resolver.Resolve(pattern)
if err != nil {
return err
}
if result == nil {
continue
}
logrus.Debugf("found dependency by resolver: %T", resolver)
switch {
case result.Reference.IsKnown():
placeHolders[i].Reference = result.Reference
logrus.Debugf("dependency resolved, ref: %v", result.Reference)
case result.HclToAdd != "":
logrus.Debugf("found dependency:\n %v", result.HclToAdd)
ref, err := c.AddHcl(result.HclToAdd, true)
if err != nil {
logrus.Warnf("failed to add hcl as a dependency, will continue to try other dependency resolvers: %v", err)
continue
}
c.KnownPatternMap[pattern.String()] = *ref
placeHolders[i].Reference = ref
logrus.Debugf("dependency resolved, ref: %v", ref)
case result.AzapiDefinitionToAdd != nil:
logrus.Debugf("found dependency:\n %v", result.AzapiDefinitionToAdd)
err = c.AddAzapiDefinition(*result.AzapiDefinitionToAdd)
if err != nil {
logrus.Warnf("failed to add azapi definition as a dependency, will continue to try other dependency resolvers: %v", err)
continue
}
ref := c.KnownPatternMap[pattern.String()]
if !ref.IsKnown() {
return fmt.Errorf("resource type address not found: %v after adding azapi definition to the context, azapi def: %v", pattern, result.AzapiDefinitionToAdd)
}
placeHolders[i].Reference = &ref
logrus.Debugf("dependency resolved, ref: %v", ref)
}
break
}
}
// replace the id placeholders with the dependency address
logrus.Debugf("replacing id placeholders with dependency address...")
for _, filed := range rootFields {
for _, placeHolder := range placeHolders {
if placeHolder.ValuePath == filed && placeHolder.Reference.IsKnown() {
def.AdditionalFields[filed] = types.NewReferenceValue(placeHolder.Reference.String())
break
}
}
}
if def.Body != nil {
replacements := make(map[string]string)
for _, placeHolder := range placeHolders {
if !placeHolder.Reference.IsKnown() {
continue
}
valuePath := placeHolder.ValuePath
if placeHolder.IsKey {
valuePath = fmt.Sprintf("key:%s", placeHolder.ValuePath)
}
replacements[valuePath] = fmt.Sprintf(`${%s}`, placeHolder.Reference)
}
def.Body = utils.UpdatedBody(def.Body, replacements, "")
}
// add extra dependencies
if def.ResourceName == "azapi_resource_list" {
logrus.Debugf("adding extra dependencies for azapi_resource_list...")
var ref *types.Reference
for pattern, r := range c.KnownPatternMap {
if strings.HasSuffix(pattern, strings.ToLower(":"+def.AzureResourceType)) {
ref = &r
break
}
}
if ref.IsKnown() {
addr := fmt.Sprintf(`%s.%s`, ref.Name, ref.Label)
if ref.Kind == "data" {
addr = fmt.Sprintf(`data.%s.%s`, ref.Name, ref.Label)
}
def.AdditionalFields["depends_on"] = types.NewRawValue(fmt.Sprintf(`[%s]`, addr))
} else {
logrus.Debugf("no `depends_on` dependency found for azapi_resource_list: %v", def)
}
}
ref, err := c.AddHcl(def.String(), false)
if err != nil {
return err
}
if def.AdditionalFields["action"] == nil && def.ResourceName != "azapi_resource_list" {
pattern := dependency.NewPattern(def.Id)
c.KnownPatternMap[pattern.String()] = *ref
logrus.Debugf("adding known pattern: %s, ref: %s", pattern, *ref)
}
return nil
}