github.com/GoogleCloudPlatform/terraformer@v0.8.18/providers/azure/azure_provider.go (about)

     1  // Copyright 2019 The Terraformer Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package azure
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  	"os"
    21  	"strings"
    22  
    23  	"github.com/Azure/go-autorest/autorest"
    24  	"github.com/hashicorp/go-azure-helpers/authentication"
    25  	"github.com/hashicorp/go-azure-helpers/sender"
    26  
    27  	"github.com/GoogleCloudPlatform/terraformer/terraformutils"
    28  	"github.com/GoogleCloudPlatform/terraformer/terraformutils/providerwrapper"
    29  )
    30  
    31  type AzureProvider struct { //nolint
    32  	terraformutils.Provider
    33  	config        authentication.Config
    34  	authorizer    autorest.Authorizer
    35  	resourceGroup string
    36  }
    37  
    38  func (p *AzureProvider) setEnvConfig() error {
    39  	subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID")
    40  	if subscriptionID == "" {
    41  		return errors.New("set ARM_SUBSCRIPTION_ID env var")
    42  	}
    43  	builder := &authentication.Builder{
    44  		ClientID:                 os.Getenv("ARM_CLIENT_ID"),
    45  		SubscriptionID:           subscriptionID,
    46  		TenantID:                 os.Getenv("ARM_TENANT_ID"),
    47  		Environment:              os.Getenv("ARM_ENVIRONMENT"),
    48  		ClientSecret:             os.Getenv("ARM_CLIENT_SECRET"),
    49  		SupportsAzureCliToken:    true,
    50  		SupportsClientSecretAuth: true,
    51  		SupportsClientCertAuth:   true,
    52  		ClientCertPath:           os.Getenv("ARM_CLIENT_CERTIFICATE_PATH"),
    53  		ClientCertPassword:       os.Getenv("ARM_CLIENT_CERTIFICATE_PASSWORD"),
    54  
    55  		/*
    56  		   // Managed Service Identity Auth
    57  		   SupportsManagedServiceIdentity bool
    58  		   MsiEndpoint                    string
    59  		*/
    60  	}
    61  
    62  	if builder.Environment == "" {
    63  		builder.Environment = "public"
    64  	}
    65  	config, err := builder.Build()
    66  	if err != nil {
    67  		return nil
    68  	}
    69  	p.config = *config
    70  
    71  	return nil
    72  }
    73  
    74  func (p *AzureProvider) getAuthorizer() (autorest.Authorizer, error) {
    75  	env, err := authentication.DetermineEnvironment(p.config.Environment)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	oauthConfig, err := p.config.BuildOAuthConfig(env.ActiveDirectoryEndpoint)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	if oauthConfig == nil {
    86  		return nil, fmt.Errorf("Unable to configure OAuthConfig for tenant %s", p.config.TenantID)
    87  	}
    88  
    89  	sender := sender.BuildSender("AzureRM")
    90  
    91  	auth, err := p.config.GetAuthorizationToken(sender, oauthConfig, env.ResourceManagerEndpoint)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	return auth, nil
    97  }
    98  
    99  func (p *AzureProvider) Init(args []string) error {
   100  	err := p.setEnvConfig()
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	authorizer, err := p.getAuthorizer()
   106  	if err != nil {
   107  		return err
   108  	}
   109  	p.authorizer = authorizer
   110  	p.resourceGroup = args[0]
   111  
   112  	return nil
   113  }
   114  
   115  func (p *AzureProvider) GetName() string {
   116  	return "azurerm"
   117  }
   118  
   119  func (p *AzureProvider) GetProviderData(arg ...string) map[string]interface{} {
   120  	version := providerwrapper.GetProviderVersion(p.GetName())
   121  	if strings.Contains(version, "v2.") {
   122  		return map[string]interface{}{
   123  			"provider": map[string]interface{}{
   124  				"azurerm": map[string]interface{}{
   125  					// NOTE:
   126  					// Workaround for azurerm v2 provider changes
   127  					// Tested with azurerm_resource_group under v2.17.0
   128  					// https://github.com/terraform-providers/terraform-provider-azurerm/issues/5866#issuecomment-594239342
   129  					// https://github.com/hashicorp/terraform/issues/24200#issuecomment-594745861
   130  					"features": map[string]interface{}{},
   131  				},
   132  			},
   133  		}
   134  	}
   135  	return map[string]interface{}{
   136  		"provider": map[string]interface{}{
   137  			"azurerm": map[string]interface{}{
   138  				"version": version,
   139  			},
   140  		},
   141  	}
   142  }
   143  
   144  func (AzureProvider) GetResourceConnections() map[string]map[string][]string {
   145  	return map[string]map[string][]string{
   146  		"analysis": {
   147  			"resource_group": []string{"resource_group_name", "name"},
   148  		},
   149  		"app_service": {
   150  			"resource_group": []string{"resource_group_name", "name"},
   151  		},
   152  		"cosmosdb": {
   153  			"resource_group": []string{
   154  				"resource_group_name", "name",
   155  				"location", "location",
   156  			},
   157  		},
   158  		"container": {
   159  			"resource_group": []string{
   160  				"resource_group_name", "name",
   161  				"location", "location",
   162  			},
   163  		},
   164  		"database": {
   165  			"resource_group": []string{
   166  				"resource_group_name", "name",
   167  				"location", "location",
   168  			},
   169  		},
   170  		"databricks": {
   171  			"resource_group": []string{
   172  				"resource_group_name", "name",
   173  				"managed_resource_group_name", "name",
   174  				"location", "location",
   175  			},
   176  			"storage_account": []string{"storage_account_name", "name"},
   177  			"subnet": []string{
   178  				"public_subnet_name", "name",
   179  				"private_subnet_name", "name",
   180  			},
   181  			"virtual_network": []string{"virtual_network_id", "id"},
   182  		},
   183  		"data_factory": {
   184  			"resource_group": []string{
   185  				"resource_group_name", "name",
   186  				"location", "location",
   187  			},
   188  			"data_factory": []string{
   189  				"data_factory_name", "name",
   190  				"data_factory_id", "id",
   191  				"linked_service_name", "name",
   192  				"integration_runtime_name", "name",
   193  			},
   194  			"databricks":      []string{"existing_cluster_id", "id"},
   195  			"keyvault":        []string{"keyvault_id", "id"},
   196  			"storage_account": []string{"storage_account_id", "id"},
   197  		},
   198  		"disk": {
   199  			"resource_group": []string{"resource_group_name", "name"},
   200  		},
   201  		"dns": {
   202  			"resource_group": []string{"resource_group_name", "name"},
   203  		},
   204  		"eventhub": {
   205  			"resource_group": []string{"resource_group_name", "name"},
   206  			"eventhub": []string{
   207  				"eventhub_name", "name",
   208  				"namespace_name", "name",
   209  			},
   210  		},
   211  		"keyvault": {
   212  			"resource_group": []string{
   213  				"resource_group_name", "name",
   214  				"location", "location",
   215  			},
   216  		},
   217  		"load_balancer": {
   218  			"resource_group": []string{"resource_group_name", "name"},
   219  		},
   220  		"network_interface": {
   221  			"resource_group": []string{
   222  				"resource_group_name", "name",
   223  				"location", "location",
   224  			},
   225  			"subnet": []string{"subnet_id", "id"},
   226  		},
   227  		"network_security_group": {
   228  			"resource_group": []string{
   229  				"resource_group_name", "name",
   230  				"location", "location",
   231  			},
   232  			"network_security_group": []string{"network_security_group_name", "name"},
   233  		},
   234  		"network_watcher": {
   235  			"resource_group": []string{
   236  				"resource_group_name", "name",
   237  				"location", "location",
   238  			},
   239  			"network_watcher": []string{"network_watcher_name", "name"},
   240  			"storage_account": []string{"storage_account_id", "id"},
   241  		},
   242  		"private_dns": {
   243  			"resource_group":  []string{"resource_group_name", "name"},
   244  			"virtual_network": []string{"virtual_network_id", "id"},
   245  			"private_dns": []string{
   246  				"zone_name", "name",
   247  				"private_dns_zone_name", "name",
   248  			},
   249  		},
   250  		"private_endpoint": {
   251  			"resource_group": []string{
   252  				"resource_group_name", "name",
   253  				"location", "location",
   254  			},
   255  			"subnet": []string{"subnet_id", "id"},
   256  		},
   257  		"public_ip": {
   258  			"resource_group": []string{
   259  				"resource_group_name", "name",
   260  				"location", "location",
   261  			},
   262  		},
   263  		"purview": {
   264  			"resource_group": []string{"resource_group_name", "name"},
   265  		},
   266  		"redis": {
   267  			"resource_group": []string{"resource_group_name", "name"},
   268  		},
   269  		"route_table": {
   270  			"resource_group": []string{
   271  				"resource_group_name", "name",
   272  				"location", "location",
   273  			},
   274  			"route_table": []string{"route_table_name", "name"},
   275  		},
   276  		"scaleset": {
   277  			"resource_group": []string{"resource_group_name", "name"},
   278  		},
   279  		"ssh_public_key": {
   280  			"resource_group": []string{
   281  				"resource_group_name", "name",
   282  				"location", "location",
   283  			},
   284  		},
   285  		"storage_account": {
   286  			"resource_group": []string{
   287  				"resource_group_name", "name",
   288  				"location", "location",
   289  			},
   290  			"virtual_network": []string{"virtual_network_subnet_ids", "id"},
   291  		},
   292  		"storage_blob": {
   293  			"storage_account":   []string{"storage_account_name", "name"},
   294  			"storage_container": []string{"storage_container_name", "name"},
   295  		},
   296  		"storage_container": {
   297  			"storage_account": []string{"storage_account_name", "name"},
   298  		},
   299  		"synapse": {
   300  			"resource_group": []string{
   301  				"resource_group_name", "name",
   302  				"managed_resource_group_name", "name",
   303  			},
   304  			"synapse": []string{"synapse_workspace_id", "id"},
   305  		},
   306  		"subnet": {
   307  			"resource_group":         []string{"resource_group_name", "name"},
   308  			"virtual_network":        []string{"virtual_network_name", "name"},
   309  			"network_security_group": []string{"network_security_group_id", "id"},
   310  			"route_table":            []string{"route_table_id", "id"},
   311  			"subnet":                 []string{"subnet_id", "id"},
   312  		},
   313  		"virtual_machine": {
   314  			"resource_group": []string{
   315  				"resource_group_name", "name",
   316  				"location", "location",
   317  			},
   318  			"network_interface": []string{"network_interface_ids", "id"},
   319  		},
   320  		"virtual_network": {
   321  			"resource_group": []string{"resource_group_name", "name"},
   322  		},
   323  	}
   324  }
   325  
   326  func (p *AzureProvider) GetSupportedService() map[string]terraformutils.ServiceGenerator {
   327  	return map[string]terraformutils.ServiceGenerator{
   328  		"analysis":                             &AnalysisGenerator{},
   329  		"app_service":                          &AppServiceGenerator{},
   330  		"cosmosdb":                             &CosmosDBGenerator{},
   331  		"container":                            &ContainerGenerator{},
   332  		"database":                             &DatabasesGenerator{},
   333  		"databricks":                           &DatabricksGenerator{},
   334  		"data_factory":                         &DataFactoryGenerator{},
   335  		"disk":                                 &DiskGenerator{},
   336  		"dns":                                  &DNSGenerator{},
   337  		"eventhub":                             &EventHubGenerator{},
   338  		"keyvault":                             &KeyVaultGenerator{},
   339  		"load_balancer":                        &LoadBalancerGenerator{},
   340  		"management_lock":                      &ManagementLockGenerator{},
   341  		"network_interface":                    &NetworkInterfaceGenerator{},
   342  		"network_security_group":               &NetworkSecurityGroupGenerator{},
   343  		"network_watcher":                      &NetworkWatcherGenerator{},
   344  		"private_dns":                          &PrivateDNSGenerator{},
   345  		"private_endpoint":                     &PrivateEndpointGenerator{},
   346  		"public_ip":                            &PublicIPGenerator{},
   347  		"purview":                              &PurviewGenerator{},
   348  		"redis":                                &RedisGenerator{},
   349  		"resource_group":                       &ResourceGroupGenerator{},
   350  		"route_table":                          &RouteTableGenerator{},
   351  		"scaleset":                             &ScaleSetGenerator{},
   352  		"security_center_contact":              &SecurityCenterContactGenerator{},
   353  		"security_center_subscription_pricing": &SecurityCenterSubscriptionPricingGenerator{},
   354  		"ssh_public_key":                       &SSHPublicKeyGenerator{},
   355  		"storage_account":                      &StorageAccountGenerator{},
   356  		"storage_blob":                         &StorageBlobGenerator{},
   357  		"storage_container":                    &StorageContainerGenerator{},
   358  		"synapse":                              &SynapseGenerator{},
   359  		"subnet":                               &SubnetGenerator{},
   360  		"virtual_machine":                      &VirtualMachineGenerator{},
   361  		"virtual_network":                      &VirtualNetworkGenerator{},
   362  	}
   363  }
   364  
   365  func (p *AzureProvider) InitService(serviceName string, verbose bool) error {
   366  	var isSupported bool
   367  	if _, isSupported = p.GetSupportedService()[serviceName]; !isSupported {
   368  		return errors.New("azurerm: " + serviceName + " not supported service")
   369  	}
   370  	p.Service = p.GetSupportedService()[serviceName]
   371  	p.Service.SetName(serviceName)
   372  	p.Service.SetVerbose(verbose)
   373  	p.Service.SetProviderName(p.GetName())
   374  	p.Service.SetArgs(map[string]interface{}{
   375  		"config":         p.config,
   376  		"authorizer":     p.authorizer,
   377  		"resource_group": p.resourceGroup,
   378  	})
   379  	return nil
   380  }