Skip to content

Commit

Permalink
Add support for Azure MSI authentication
Browse files Browse the repository at this point in the history
Changed the authentication code fall back to the default environment
based Azure SDK authentication mechanism, as described here:
https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization#use-environment-based-authentication

This will in the last step use Azure Managed Service Identities if
available.
  • Loading branch information
ne-msft committed Jun 13, 2019
1 parent 8aba54d commit 004ae6d
Showing 1 changed file with 28 additions and 19 deletions.
47 changes: 28 additions & 19 deletions provider/azure/azure_discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import (

"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2015-06-15/network"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/adal"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/azure/auth"
)

type Provider struct {
Expand Down Expand Up @@ -40,6 +39,10 @@ func (p *Provider) Help() string {
export ARM_CLIENT_ID for client
export ARM_CLIENT_SECRET for secret access key
If none of those options are given, the Azure SDK is using the default environment based authentication outlined
here https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization#use-environment-based-authentication
This will fallback to MSI if nothing is explicitly specified.
Use these configuration parameters when using tags:
tag_name: The name of the tag to filter on
Expand All @@ -60,13 +63,15 @@ func (p *Provider) Help() string {

// argsOrEnv allows you to pick an environmental variable for a setting if the arg is not set
func argsOrEnv(args map[string]string, key, env string) string {
if value, ok := args[key]; ok {
return value
}
return os.Getenv(env)
if value, ok := args[key]; ok {
return value
}
return os.Getenv(env)
}

func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error) {
var authorizer autorest.Authorizer

if args["provider"] != "azure" {
return nil, fmt.Errorf("discover-azure: invalid provider " + args["provider"])
}
Expand All @@ -81,6 +86,22 @@ func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error
subscriptionID := argsOrEnv(args, "subscription_id", "ARM_SUBSCRIPTION_ID")
secretKey := argsOrEnv(args, "secret_access_key", "ARM_CLIENT_SECRET")

// Try to use the argument and environment provided arguments first, if this fails fall back to the Azure
// SDK provided methods
if tenantID != "" && clientID != "" && secretKey != "" {
var err error
authorizer, err = auth.NewClientCredentialsConfig(clientID, secretKey, tenantID).Authorizer()
if err != nil {
return nil, fmt.Errorf("discover-azure (ClientCredentials): %s", err)
}
} else {
var err error
authorizer, err = auth.NewAuthorizerFromEnvironment()
if err != nil {
return nil, fmt.Errorf("discover-azure (EnvironmentCredentials): %s", err)
}
}

// Use tags if using network interfaces
tagName := args["tag_name"]
tagValue := args["tag_value"]
Expand All @@ -89,22 +110,10 @@ func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error
resourceGroup := args["resource_group"]
vmScaleSet := args["vm_scale_set"]

// Only works for the Azure PublicCLoud for now; no ability to test other Environment
oauthConfig, err := adal.NewOAuthConfig(azure.PublicCloud.ActiveDirectoryEndpoint, tenantID)
if err != nil {
return nil, fmt.Errorf("discover-azure: %s", err)
}

// Get the ServicePrincipalToken for use searching the NetworkInterfaces
sbt, err := adal.NewServicePrincipalToken(*oauthConfig, clientID, secretKey, azure.PublicCloud.ResourceManagerEndpoint)
if err != nil {
return nil, fmt.Errorf("discover-azure: %s", err)
}

// Setup the client using autorest; followed the structure from Terraform
vmnet := network.NewInterfacesClient(subscriptionID)
vmnet.Sender = autorest.CreateSender(autorest.WithLogging(l))
vmnet.Authorizer = autorest.NewBearerAuthorizer(sbt)
vmnet.Authorizer = authorizer

if p.userAgent != "" {
vmnet.Client.UserAgent = p.userAgent
Expand Down

0 comments on commit 004ae6d

Please sign in to comment.