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)
}
}