Skip to content

CLI option: -g/--generate-mapping-file to generate resource mapping file #240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ In batch mode, instead of interactively specifying the mapping from Azurem resou

```json
{
"<AZURE RESOURCE ID1 IN UPPERCASE>": {
"<Azure resource id1>": {
"resource_type" : "<terraform resource type>",
"resource_name" : "<terraform resource name>",
"resource_id" : "<terraform resource id>"
},
"<AZURE RESOURCE ID2 IN UPPERCASE>": {
"<Azure resource id2>": {
"resource_type" : "<terraform resource type>",
"resource_name" : "<terraform resource name>",
"resource_id" : "<terraform resource id>"
Expand All @@ -170,17 +170,17 @@ Example:

```json
{
"/SUBSCRIPTIONS/0000/RESOURCEGROUPS/AZTFY-VMDISK": {
"/subscriptions/0000/resourceGroups/aztfy-vmdisk": {
"resource_id": "/subscriptions/0000/resourceGroups/aztfy-vmdisk",
"resource_type": "azurerm_resource_group",
"resource_name": "res-1"
},
"/SUBSCRIPTIONS/0000/RESOURCEGROUPS/AZTFY-VMDISK/PROVIDERS/MICROSOFT.COMPUTE/DISKS/AZTFY-TEST-TEST": {
"/subscriptions/0000/resourceGroups/aztfy-vmdisk/providers/Microsoft.Compute/disks/aztfy-test-test": {
"resource_id": "/subscriptions/0000/resourceGroups/aztfy-vmdisk/providers/Microsoft.Compute/disks/aztfy-test-test",
"resource_type": "azurerm_managed_disk",
"resource_name": "res-2"
},
"/SUBSCRIPTIONS/0000/RESOURCEGROUPS/AZTFY-VMDISK/PROVIDERS/MICROSOFT.COMPUTE/VIRTUALMACHINES/AZTFY-TEST-TEST": {
"/subscriptions/0000/resourceGroups/aztfy-vmdisk/providers/Microsoft.Compute/virtualMachines/aztfy-test-test": {
"resource_id": "/subscriptions/0000/resourceGroups/aztfy-vmdisk/providers/Microsoft.Compute/virtualMachines/aztfy-test-test",
"resource_type": "azurerm_linux_virtual_machine",
"resource_name": "res-3"
Expand Down
23 changes: 12 additions & 11 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ type Config interface {
}

type CommonConfig struct {
SubscriptionId string
OutputDir string
Overwrite bool
Append bool
DevProvider bool
BatchMode bool
BackendType string
BackendConfig []string
FullConfig bool
Parallelism int
PlainUI bool
SubscriptionId string
OutputDir string
Overwrite bool
Append bool
DevProvider bool
BatchMode bool
BackendType string
BackendConfig []string
FullConfig bool
Parallelism int
PlainUI bool
GenerateMappingFile bool
}

type GroupConfig struct {
Expand Down
26 changes: 26 additions & 0 deletions internal/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"os"
Expand All @@ -13,6 +14,7 @@ import (

"github.com/Azure/aztfy/internal/client"
"github.com/Azure/aztfy/internal/config"
"github.com/Azure/aztfy/internal/resmap"
"github.com/Azure/aztfy/internal/utils"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/hashicorp/hcl/v2"
Expand All @@ -30,6 +32,7 @@ type meta interface {
Import(item *ImportItem)
CleanTFState(addr string)
GenerateCfg(ImportList) error
ExportResourceMapping(ImportList) error
}

var _ meta = &Meta{}
Expand Down Expand Up @@ -215,6 +218,29 @@ func (meta Meta) GenerateCfg(l ImportList) error {
return meta.generateCfg(l, meta.lifecycleAddon, meta.addDependency)
}

func (meta Meta) ExportResourceMapping(l ImportList) error {
m := resmap.ResourceMapping{}
for _, item := range l {
if item.Skip() {
continue
}
m[item.AzureResourceID.String()] = resmap.ResourceMapEntity{
ResourceId: item.TFResourceId,
ResourceType: item.TFAddr.Type,
ResourceName: item.TFAddr.Name,
}
}
output := filepath.Join(meta.Workspace(), ResourceMappingFileName)
b, err := json.MarshalIndent(m, "", "\t")
if err != nil {
return fmt.Errorf("JSON marshalling the resource mapping: %v", err)
}
if err := os.WriteFile(output, b, 0644); err != nil {
return fmt.Errorf("writing the resource mapping to %s: %v", output, err)
}
return nil
}

func (meta Meta) generateCfg(l ImportList, cfgTrans ...TFConfigTransformer) error {
ctx := context.TODO()

Expand Down
5 changes: 2 additions & 3 deletions internal/meta/meta_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ import (
"github.com/Azure/aztfy/internal/config"
)

const ResourceMappingFileName = ".aztfyResourceMapping.json"
const SkippedResourcesFileName = ".aztfySkippedResources.txt"
const ResourceMappingFileName = "aztfyResourceMapping.json"
const SkippedResourcesFileName = "aztfySkippedResources.txt"

type GroupMeta interface {
meta
ScopeName() string
ListResource() (ImportList, error)
ExportResourceMapping(l ImportList) error
ExportSkippedResources(l ImportList) error
}

Expand Down
33 changes: 7 additions & 26 deletions internal/meta/meta_group_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package meta

import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -106,8 +105,13 @@ func (meta *MetaGroupImpl) ListResource() (ImportList, error) {
item.Recommendations = []string{res.TFType}
}

if len(meta.resourceMapping) != 0 {
if entity, ok := meta.resourceMapping[strings.ToUpper(res.AzureId.String())]; ok {
m := resmap.ResourceMapping{}
for k, v := range meta.resourceMapping {
m[strings.ToUpper(k)] = v
}

if len(m) != 0 {
if entity, ok := m[strings.ToUpper(res.AzureId.String())]; ok {
item.TFResourceId = entity.ResourceId
item.TFAddr = tfaddr.TFAddr{
Type: entity.ResourceType,
Expand All @@ -126,29 +130,6 @@ func (meta *MetaGroupImpl) ListResource() (ImportList, error) {
return l, nil
}

func (meta MetaGroupImpl) ExportResourceMapping(l ImportList) error {
m := resmap.ResourceMapping{}
for _, item := range l {
if item.Skip() {
continue
}
m[strings.ToUpper(item.AzureResourceID.String())] = resmap.ResourceMapEntity{
ResourceId: item.TFResourceId,
ResourceType: item.TFAddr.Type,
ResourceName: item.TFAddr.Name,
}
}
output := filepath.Join(meta.Workspace(), ResourceMappingFileName)
b, err := json.MarshalIndent(m, "", "\t")
if err != nil {
return fmt.Errorf("JSON marshalling the resource mapping: %v", err)
}
if err := os.WriteFile(output, b, 0644); err != nil {
return fmt.Errorf("writing the resource mapping to %s: %v", output, err)
}
return nil
}

func (meta MetaGroupImpl) ExportSkippedResources(l ImportList) error {
var sl []string
for _, item := range l {
Expand Down
51 changes: 34 additions & 17 deletions internal/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func ResourceImport(ctx context.Context, cfg config.ResConfig) error {
rl := resourceSet.ToTFResources()

var l meta.ImportList
for i, res := range rl {
for _, res := range rl {
item := meta.ImportItem{
AzureResourceID: res.AzureId,
TFResourceId: res.TFId, // this might be empty if have multiple matches in aztft
Expand All @@ -65,18 +65,30 @@ func ResourceImport(ctx context.Context, cfg config.ResConfig) error {

// Some special Azure resource is missing the essential property that is used by aztft to detect their TF resource type.
// In this case, users can use the `--type` option to manually specify the TF resource type.
if i == 0 && c.ResourceType != "" {
tfid, err := c.QueryResourceId(c.ResourceType)
if err != nil {
return err
if c.ResourceType != "" {
if c.AzureId.Equal(res.AzureId) {
tfid, err := c.QueryResourceId(c.ResourceType)
if err != nil {
return err
}
item.TFResourceId = tfid
item.TFAddr.Type = c.ResourceType
}
item.TFResourceId = tfid
item.TFAddr.Type = c.ResourceType
}

l = append(l, item)
}

msg.SetStatus("Exporting Resource Mapping file...")
if err := c.ExportResourceMapping(l); err != nil {
return fmt.Errorf("exporting Resource Mapping file: %v", err)
}

// Return early if only generating mapping file
if cfg.GenerateMappingFile {
return nil
}

msgs := []string{}
for _, item := range l {
msgs = append(msgs, fmt.Sprintf(`Resource Address: %s
Expand Down Expand Up @@ -133,6 +145,21 @@ func BatchImport(cfg config.GroupConfig, continueOnError bool) error {
return err
}

msg.SetStatus("Exporting Skipped Resource file...")
if err := c.ExportSkippedResources(list); err != nil {
return fmt.Errorf("exporting Skipped Resource file: %v", err)
}

msg.SetStatus("Exporting Resource Mapping file...")
if err := c.ExportResourceMapping(list); err != nil {
return fmt.Errorf("exporting Resource Mapping file: %v", err)
}

// Return early if only generating mapping file
if cfg.GenerateMappingFile {
return nil
}

msg.SetStatus("Importing resources...")
for i := range list {
if list[i].Skip() {
Expand All @@ -151,16 +178,6 @@ func BatchImport(cfg config.GroupConfig, continueOnError bool) error {
}
}

msg.SetStatus("Exporting Resource Mapping file...")
if err := c.ExportResourceMapping(list); err != nil {
return fmt.Errorf("exporting Resource Mapping file: %v", err)
}

msg.SetStatus("Exporting Skipped Resource file...")
if err := c.ExportSkippedResources(list); err != nil {
return fmt.Errorf("exporting Skipped Resource file: %v", err)
}

msg.SetStatus("Generating Terraform configurations...")
if err := c.GenerateCfg(list); err != nil {
return fmt.Errorf("generating Terraform configuration: %v", err)
Expand Down
6 changes: 3 additions & 3 deletions internal/test/cases/case_applicationinsight_webtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ XML

func (CaseApplicationInsightWebTest) ResourceMapping(d test.Data) (resmap.ResourceMapping, error) {
return test.ResourceMapping(fmt.Sprintf(`{
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s" | Quote }}: {
"resource_type": "azurerm_resource_group",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s"
},
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.insights/components/test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.insights/components/test-%[3]s" | Quote }}: {
"resource_type": "azurerm_application_insights",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Insights/components/test-%[3]s"
},
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.insights/webtests/test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.insights/webtests/test-%[3]s" | Quote }}: {
"resource_type": "azurerm_application_insights_web_test",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Insights/webTests/test-%[3]s"
Expand Down
14 changes: 7 additions & 7 deletions internal/test/cases/case_compute_vm_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,43 +90,43 @@ resource "azurerm_virtual_machine_data_disk_attachment" "test" {

func (CaseComputeVMDisk) ResourceMapping(d test.Data) (resmap.ResourceMapping, error) {
return test.ResourceMapping(fmt.Sprintf(`{
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s" | Quote }}: {
"resource_type": "azurerm_resource_group",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.compute/disks/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.compute/disks/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_managed_disk",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Compute/disks/aztfy-test-%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.compute/virtualmachines/aztfy-test-%[3]s/datadisks/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.compute/virtualmachines/aztfy-test-%[3]s/datadisks/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_virtual_machine_data_disk_attachment",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Compute/virtualMachines/aztfy-test-%[3]s/dataDisks/aztfy-test-%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.compute/virtualmachines/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.compute/virtualmachines/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_linux_virtual_machine",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Compute/virtualMachines/aztfy-test-%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.network/networkinterfaces/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.network/networkinterfaces/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_network_interface",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Network/networkInterfaces/aztfy-test-%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.network/virtualnetworks/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.network/virtualnetworks/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_virtual_network",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Network/virtualNetworks/aztfy-test-%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.network/virtualnetworks/aztfy-test-%[3]s/subnets/internal" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.network/virtualnetworks/aztfy-test-%[3]s/subnets/internal" | Quote }}: {
"resource_type": "azurerm_subnet",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Network/virtualNetworks/aztfy-test-%[3]s/subnets/internal"
Expand Down
10 changes: 5 additions & 5 deletions internal/test/cases/case_function_app_slot.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,31 +61,31 @@ resource "azurerm_windows_function_app_slot" "test" {

func (CaseFunctionAppSlot) ResourceMapping(d test.Data) (resmap.ResourceMapping, error) {
return test.ResourceMapping(fmt.Sprintf(`{
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s" | Quote }}: {
"resource_type": "azurerm_resource_group",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.storage/storageaccounts/aztfytest%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.storage/storageaccounts/aztfytest%[3]s" | Quote }}: {
"resource_type": "azurerm_storage_account",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Storage/storageAccounts/aztfytest%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.web/serverfarms/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.web/serverfarms/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_service_plan",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Web/serverfarms/aztfy-test-%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.web/sites/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.web/sites/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_windows_function_app",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Web/sites/aztfy-test-%[3]s"
},

{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.web/sites/aztfy-test-%[3]s/slots/aztfy-test-%[3]s" | ToUpper | Quote }}: {
{{ "/subscriptions/%[1]s/resourcegroups/%[2]s/providers/microsoft.web/sites/aztfy-test-%[3]s/slots/aztfy-test-%[3]s" | Quote }}: {
"resource_type": "azurerm_windows_function_app_slot",
"resource_name": "test",
"resource_id": "/subscriptions/%[1]s/resourceGroups/%[2]s/providers/Microsoft.Web/sites/aztfy-test-%[3]s/slots/aztfy-test-%[3]s"
Expand Down
Loading