diff --git a/azurerm/azurerm_sweeper_test.go b/azurerm/azurerm_sweeper_test.go index 0dbc318b7ffc..881bf9d13538 100644 --- a/azurerm/azurerm_sweeper_test.go +++ b/azurerm/azurerm_sweeper_test.go @@ -46,7 +46,7 @@ func buildConfigForSweepers() (*ArmClient, error) { return nil, fmt.Errorf("Error building ARM Client: %+v", err) } - return getArmClient(config, false) + return getArmClient(config, false, "") } func shouldSweepAcceptanceTestResource(name string, resourceLocation string, region string) bool { diff --git a/azurerm/config.go b/azurerm/config.go index 37ce1ef47220..f7d38161ca39 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -84,6 +84,7 @@ type ArmClient struct { clientId string tenantId string subscriptionId string + partnerId string usingServicePrincipal bool environment az.Environment skipProviderRegistration bool @@ -349,7 +350,7 @@ func clientRequestID() string { } func (c *ArmClient) configureClient(client *autorest.Client, auth autorest.Authorizer) { - setUserAgent(client) + setUserAgent(client, c.partnerId) client.Authorizer = auth //client.RequestInspector = azure.WithClientID(clientRequestID()) client.Sender = azure.BuildSender() @@ -357,7 +358,7 @@ func (c *ArmClient) configureClient(client *autorest.Client, auth autorest.Autho client.PollingDuration = 60 * time.Minute } -func setUserAgent(client *autorest.Client) { +func setUserAgent(client *autorest.Client, partnerID string) { // TODO: This is the SDK version not the CLI version, once we are on 0.12, should revisit tfUserAgent := httpclient.UserAgentString() @@ -370,12 +371,16 @@ func setUserAgent(client *autorest.Client) { client.UserAgent = fmt.Sprintf("%s %s", client.UserAgent, azureAgent) } + if partnerID != "" { + client.UserAgent = fmt.Sprintf("%s pid-%s", client.UserAgent, partnerID) + } + log.Printf("[DEBUG] AzureRM Client User Agent: %s\n", client.UserAgent) } // getArmClient is a helper method which returns a fully instantiated // *ArmClient based on the Config's current settings. -func getArmClient(c *authentication.Config, skipProviderRegistration bool) (*ArmClient, error) { +func getArmClient(c *authentication.Config, skipProviderRegistration bool, partnerId string) (*ArmClient, error) { env, err := authentication.DetermineEnvironment(c.Environment) if err != nil { return nil, err @@ -386,6 +391,7 @@ func getArmClient(c *authentication.Config, skipProviderRegistration bool) (*Arm clientId: c.ClientID, tenantId: c.TenantID, subscriptionId: c.SubscriptionID, + partnerId: partnerId, environment: *env, usingServicePrincipal: c.AuthenticatedAsAServicePrincipal, skipProviderRegistration: skipProviderRegistration, @@ -726,7 +732,7 @@ func (c *ArmClient) registerDatabases(endpoint, subscriptionId string, auth auto c.sqlDatabasesClient = sqlDBClient sqlDTDPClient := sql.NewDatabaseThreatDetectionPoliciesClientWithBaseURI(endpoint, subscriptionId) - setUserAgent(&sqlDTDPClient.Client) + setUserAgent(&sqlDTDPClient.Client, "") sqlDTDPClient.Authorizer = auth sqlDTDPClient.Sender = sender sqlDTDPClient.SkipResourceProviderRegistration = c.skipProviderRegistration diff --git a/azurerm/provider.go b/azurerm/provider.go index fef6c219c678..c3bee25a8d14 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" ) // Provider returns a terraform.ResourceProvider. @@ -74,6 +75,14 @@ func Provider() terraform.ResourceProvider { DefaultFunc: schema.EnvDefaultFunc("ARM_MSI_ENDPOINT", ""), }, + // Managed Tracking GUID for User-agent + "partner_id": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("ARM_PARTNER_ID", ""), + ValidateFunc: validate.UUID, + }, + // Advanced feature flags "skip_credentials_validation": { Type: schema.TypeBool, @@ -366,8 +375,10 @@ func providerConfigure(p *schema.Provider) schema.ConfigureFunc { return nil, fmt.Errorf("Error building AzureRM Client: %s", err) } + partnerId := d.Get("partner_id").(string) skipProviderRegistration := d.Get("skip_provider_registration").(bool) - client, err := getArmClient(config, skipProviderRegistration) + client, err := getArmClient(config, skipProviderRegistration, partnerId) + if err != nil { return nil, err } diff --git a/azurerm/required_resource_providers_test.go b/azurerm/required_resource_providers_test.go index aac7fed6047e..f273243f7ae2 100644 --- a/azurerm/required_resource_providers_test.go +++ b/azurerm/required_resource_providers_test.go @@ -14,7 +14,7 @@ func TestAccAzureRMEnsureRequiredResourceProvidersAreRegistered(t *testing.T) { } // this test intentionally checks all the RP's are registered - so this is intentional - armClient, err := getArmClient(config, true) + armClient, err := getArmClient(config, true, "") if err != nil { t.Fatalf("Error building ARM Client: %+v", err) } diff --git a/azurerm/resource_arm_container_registry_migrate_test.go b/azurerm/resource_arm_container_registry_migrate_test.go index 6e24d9035965..4d2b32d20d86 100644 --- a/azurerm/resource_arm_container_registry_migrate_test.go +++ b/azurerm/resource_arm_container_registry_migrate_test.go @@ -19,7 +19,7 @@ func TestAccAzureRMContainerRegistryMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false) + client, err := getArmClient(config, false, "") if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_data_lake_store_file_migration_test.go b/azurerm/resource_arm_data_lake_store_file_migration_test.go index ff0ad9109e43..d0bfb71e9f32 100644 --- a/azurerm/resource_arm_data_lake_store_file_migration_test.go +++ b/azurerm/resource_arm_data_lake_store_file_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMDataLakeStoreFileMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false) + client, err := getArmClient(config, false, "") if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_storage_blob_migration_test.go b/azurerm/resource_arm_storage_blob_migration_test.go index 51bf13cbb758..bb21ddc25578 100644 --- a/azurerm/resource_arm_storage_blob_migration_test.go +++ b/azurerm/resource_arm_storage_blob_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMStorageBlobMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false) + client, err := getArmClient(config, false, "") if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_storage_container_migration_test.go b/azurerm/resource_arm_storage_container_migration_test.go index 8b1e0cba40c3..a638f4e6c907 100644 --- a/azurerm/resource_arm_storage_container_migration_test.go +++ b/azurerm/resource_arm_storage_container_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMStorageContainerMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false) + client, err := getArmClient(config, false, "") if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_storage_queue_migration_test.go b/azurerm/resource_arm_storage_queue_migration_test.go index b01b075dc395..8c9c32ccaef0 100644 --- a/azurerm/resource_arm_storage_queue_migration_test.go +++ b/azurerm/resource_arm_storage_queue_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMStorageQueueMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false) + client, err := getArmClient(config, false, "") if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/azurerm/resource_arm_storage_table_migration_test.go b/azurerm/resource_arm_storage_table_migration_test.go index 67f2236ad615..9122cb3b5643 100644 --- a/azurerm/resource_arm_storage_table_migration_test.go +++ b/azurerm/resource_arm_storage_table_migration_test.go @@ -16,7 +16,7 @@ func TestAccAzureRMStorageTableMigrateState(t *testing.T) { return } - client, err := getArmClient(config, false) + client, err := getArmClient(config, false, "") if err != nil { t.Fatal(fmt.Errorf("Error building ARM Client: %+v", err)) return diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index e5843dbb884e..e8bf3e43bc48 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -126,6 +126,8 @@ More information on [how to configure a Service Principal using Managed Service For some advanced scenarios, such as where more granular permissions are necessary - the following properties can be set: +* `partner_id` - (Optional) A GUID/UUID provided by Microsoft that is added to the user agent to facilitate partner resource usage data collection. This can also be sourced from the `ARM_PARTNER_ID` Environment Variable. + * `skip_credentials_validation` - (Optional) Should the AzureRM Provider skip verifying the credentials being used are valid? This can also be sourced from the `ARM_SKIP_CREDENTIALS_VALIDATION` Environment Variable. Defaults to `false`. * `skip_provider_registration` - (Optional) Should the AzureRM Provider skip registering any required Resource Providers? This can also be sourced from the `ARM_SKIP_PROVIDER_REGISTRATION` Environment Variable. Defaults to `false`.