func()

in cmd/migrate_command.go [103:192]


func (c *MigrateCommand) MigrateResources(terraform *tf.Terraform, resources []types.AzureResource) {
	if len(resources) == 0 {
		return
	}

	workingDirectory := terraform.GetWorkingDirectory()
	// write empty config to temp dir for import
	tempDir := filepath.Join(workingDirectory, tempFolderName)
	if err := os.MkdirAll(tempDir, 0750); err != nil {
		log.Fatalf("creating temp workspace %q: %+v", tempDir, err)
	}
	if err := os.RemoveAll(path.Join(tempDir, "terraform.tfstate")); err != nil {
		log.Printf("[WARN] removing temp workspace %q: %+v", tempDir, err)
	}
	defer func() {
		err := os.RemoveAll(path.Join(tempDir, "terraform.tfstate"))
		if err != nil {
			log.Printf("[ERROR] removing temp workspace %q: %+v", tempDir, err)
		}
	}()
	tempTerraform, err := tf.NewTerraform(tempDir, c.Verbose)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("[INFO] generating import config...")
	config := ImportConfig(resources, helper.FindHclBlock(workingDirectory, "terraform", nil))
	if err = os.WriteFile(filepath.Join(tempDir, filenameImport), []byte(config), 0600); err != nil {
		log.Fatal(err)
	}

	log.Printf("[INFO] migrating resources...")
	for _, r := range resources {
		log.Printf("[INFO] generating new config for resource %s...", r.OldAddress(nil))
		if err := r.GenerateNewConfig(tempTerraform); err != nil {
			log.Printf("[ERROR] %+v", err)
		}
	}

	log.Printf("[INFO] updating config...")
	updateResources := make([]types.AzapiUpdateResource, 0)
	for _, r := range resources {
		if updateResource, ok := r.(*types.AzapiUpdateResource); ok {
			updateResources = append(updateResources, *updateResource)
		}
	}
	if err := types.UpdateMigratedResourceBlock(workingDirectory, updateResources); err != nil {
		log.Fatal(err)
	}

	// migrate depends_on, lifecycle, provisioner
	for _, r := range resources {
		if existingBlock, err := types.GetResourceBlock(workingDirectory, r.OldAddress(nil)); err == nil && existingBlock != nil {
			migratedBlock := r.MigratedBlock()
			if attr := existingBlock.Body().GetAttribute("depends_on"); attr != nil {
				migratedBlock.Body().SetAttributeRaw("depends_on", attr.Expr().BuildTokens(nil))
			}
			for _, block := range existingBlock.Body().Blocks() {
				if block.Type() == "lifecycle" || block.Type() == "provisioner" {
					migratedBlock.Body().AppendBlock(block)
				}
			}
		}
	}

	// remove from config
	for _, r := range resources {
		if r.IsMigrated() {
			log.Printf("[INFO] removing %s from config", r.OldAddress(nil))
			stateUpdateBlocks := r.StateUpdateBlocks()
			newBlocks := make([]*hclwrite.Block, 0)
			newBlocks = append(newBlocks, stateUpdateBlocks...)
			newBlocks = append(newBlocks, r.MigratedBlock())
			if err := types.ReplaceResourceBlock(workingDirectory, r.OldAddress(nil), newBlocks); err != nil {
				log.Printf("[ERROR] error removing %s from state: %+v", r.OldAddress(nil), err)
			}
		}
	}

	log.Printf("[INFO] replacing references with migrated resource...")
	outputs := make([]types.Output, 0)
	for _, r := range resources {
		if r.IsMigrated() {
			outputs = append(outputs, r.Outputs()...)
		}
	}
	if err := types.ReplaceGenericOutputs(workingDirectory, outputs); err != nil {
		log.Printf("[ERROR] replacing outputs: %+v", err)
	}
}