-
Notifications
You must be signed in to change notification settings - Fork 255
Adds support for MIC to authenticate with azure using system assigned/user assigned MSI #265
Changes from 16 commits
6068d6f
cf88f36
4761bf4
76ad313
492a15d
70f7bf3
8098604
ebe4a5c
8b25cbe
a9a6d16
b041052
dd3b597
778d72a
8cb37fc
2a8c3bf
38954aa
2495265
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
## Introduction | ||
|
||
The MIC component in aad-pod-identity needs to authenticate with the cloud to assign and remove user assign identities onto | ||
virtual machines (VMAs) or virtual machine scale sets(VMSS). This authentication is performed using either the cluster credentials | ||
obtained from azure.json in AKS/aks-engine clusters or credentials given via environment variables. | ||
|
||
MIC can authenticate using the following options: | ||
1. Service principal | ||
2. System assigned MSI | ||
3. User assigned MSI | ||
|
||
The rest of the README describes the prerequisite role assignments to be performed for using MSI and how to configure MIC to use system assigned/user assigned MSI. | ||
|
||
## Pre-requisites - role assignments | ||
MIC is responsible for performing operations such as assigning user assigned identity to the underlying vm or vmss which makes up the | ||
nodes in the Kubernetes cluster. The system/user assigned MSI needs to have role assignments authorizing such operations on the vms/vmss | ||
and also operations on the user assigned identity. | ||
|
||
After the cluster is created to perform the following steps to obtain the principal id: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After the cluster is created, run these commands to retrieve the principal id There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
for VMAs: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: VMAs -> VMAS There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
||
```bash | ||
az vm identity show -g <resource group> -n <vm name> -o yaml | ||
``` | ||
for VMSS: | ||
```bash | ||
az vmss identity show -g <resource group> -n <vmss scalset name> -o yaml | ||
``` | ||
|
||
The type in the output of the above command will identify the system assigned or user assigned MSI. Please record the corresponding | ||
principal id. | ||
|
||
For creating a role assignment to authorize assignment/removal of user assigned identities on VMS/VMSS, run the following command: | ||
```bash | ||
az role assignment create --role "Contributor" --assignee <principal id from az vm/vmss identity command> --scope /subscriptions/<sub id>/resourcegroups/<resource group name> | ||
``` | ||
|
||
Now to ensure that the operations are allowed on individual identity, perform the following for every identity in use: | ||
```bash | ||
az role assignment create --role "Managed Identity Operator" --assignee <principal id from az vm/vmss identity command> --scope /subscriptions/<subscription id>/resourcegroups/<resource group name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identity name> | ||
``` | ||
|
||
|
||
## Authentication method | ||
In case the azure.json is used, the following keys indicates whether the cluster is configured with system assigned or user assigned identity: | ||
```UseManagedIdentityExtension``` shows that MSI is to be used. If ```UserAssignedIdentityID``` is set, then the user assigned | ||
identity is used, otherwise system assigned identity is used for authentication. | ||
|
||
In case where the azure.json is not used and the environment variables are used, the following variables are used to setup the configuration: | ||
```USE_MSI``` is to setup MSI. If the ```USER_ASSIGNED_MSI_CLIENTID``` is used then user assigned identity is used, otherwise system assigned identity is used. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ import ( | |
"os" | ||
"path" | ||
"regexp" | ||
"strings" | ||
"time" | ||
|
||
config "github.com/Azure/aad-pod-identity/pkg/config" | ||
|
@@ -59,6 +60,8 @@ func NewCloudProvider(configFile string) (c *Client, e error) { | |
azureConfig.SubscriptionID = os.Getenv("SUBSCRIPTION_ID") | ||
azureConfig.ResourceGroupName = os.Getenv("RESOURCE_GROUP") | ||
azureConfig.VMType = os.Getenv("VM_TYPE") | ||
azureConfig.UseManagedIdentityExtension = strings.EqualFold(os.Getenv("USE_MSI"), "True") | ||
azureConfig.UserAssignedIdentityID = os.Getenv("USER_ASSIGNED_MSI_CLIENTID") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should split There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
} | ||
|
||
azureEnv, err := azure.EnvironmentFromName(azureConfig.Cloud) | ||
|
@@ -77,15 +80,42 @@ func NewCloudProvider(configFile string) (c *Client, e error) { | |
glog.Errorf("Create OAuth config error: %+v", err) | ||
return nil, err | ||
} | ||
spt, err := adal.NewServicePrincipalToken( | ||
*oauthConfig, | ||
azureConfig.ClientID, | ||
azureConfig.ClientSecret, | ||
azureEnv.ResourceManagerEndpoint, | ||
) | ||
if err != nil { | ||
glog.Errorf("Get service principle token error: %+v", err) | ||
return nil, err | ||
|
||
var spt *adal.ServicePrincipalToken | ||
if azureConfig.UseManagedIdentityExtension { | ||
// MSI endpoint is required for both types of MSI - system assigned and user assigned. | ||
msiEndpoint, err := adal.GetMSIVMEndpoint() | ||
if err != nil { | ||
glog.Errorf("Failed to get MSI endpoint. Error: %+v", err) | ||
return nil, err | ||
} | ||
// UserAssignedIdentityID is empty, so we are going to use system assigned MSI | ||
if azureConfig.UserAssignedIdentityID == "" { | ||
glog.Infof("MIC using system assigned identity for authentication.") | ||
spt, err = adal.NewServicePrincipalTokenFromMSI(msiEndpoint, azureEnv.ResourceManagerEndpoint) | ||
if err != nil { | ||
glog.Errorf("Get token from system assigned MSI error: %+v", err) | ||
return nil, err | ||
} | ||
} else { // User assigned identity usage. | ||
glog.Infof("MIC using user assigned identity: %s for authentication.", azureConfig.UserAssignedIdentityID) | ||
spt, err = adal.NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, azureEnv.ResourceManagerEndpoint, azureConfig.UserAssignedIdentityID) | ||
if err != nil { | ||
glog.Errorf("Get token from user assigned MSI error: %+v", err) | ||
return nil, err | ||
} | ||
} | ||
} else { // This is the default scenario - use service principal to get the token. | ||
spt, err = adal.NewServicePrincipalToken( | ||
*oauthConfig, | ||
azureConfig.ClientID, | ||
azureConfig.ClientSecret, | ||
azureEnv.ResourceManagerEndpoint, | ||
) | ||
if err != nil { | ||
glog.Errorf("Get service principle token error: %+v", err) | ||
return nil, err | ||
} | ||
} | ||
|
||
extClient := compute.NewVirtualMachineExtensionsClient(azureConfig.SubscriptionID) | ||
|
@@ -166,6 +196,7 @@ func (c *Client) UpdateUserMSI(addUserAssignedMSIIDs []string, removeUserAssigne | |
requiresUpdate = requiresUpdate || addedToList | ||
} | ||
if requiresUpdate { | ||
glog.Infof("Updating user assigned MSIs on %s", node.Name) | ||
timeStarted := time.Now() | ||
if err := updateFunc(); err != nil { | ||
return err | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/user assign/user assigned
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done