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 }