Merge pull request #6982 from hashicorp/fix_6161
azure builder: allow to auth with managed identities ( MSI )
This commit is contained in:
commit
7643ccc67d
|
@ -31,6 +31,10 @@ func (a *Authenticate) getServicePrincipalTokenWithResource(resource string) (*a
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if a.clientID == "" && a.clientSecret == "" {
|
||||
return adal.NewServicePrincipalTokenFromMSI("http://169.254.169.254/metadata/identity/oauth2/token", resource)
|
||||
}
|
||||
|
||||
spt, err := adal.NewServicePrincipalToken(
|
||||
*oauthConfig,
|
||||
a.clientID,
|
||||
|
|
|
@ -514,17 +514,14 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) {
|
|||
if isUseDeviceLogin(c) {
|
||||
c.useDeviceLogin = true
|
||||
} else {
|
||||
if c.ClientID == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A client_id must be specified"))
|
||||
if c.ClientID == "" && c.ClientSecret != "" || c.ClientID != "" && c.ClientSecret == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A client_id and client_secret must be specified together or not specified at all"))
|
||||
}
|
||||
|
||||
if c.ClientSecret == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A client_secret must be specified"))
|
||||
if c.ClientID != "" && c.SubscriptionID == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A subscription_id must be specified when client_id & client_secret are"))
|
||||
}
|
||||
|
||||
if c.SubscriptionID == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A subscription_id must be specified"))
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
|
|
@ -124,6 +124,87 @@ func TestConfigShouldNotDefaultImageVersionIfCustomImage(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_newConfig_MSI(t *testing.T) {
|
||||
baseConfig := map[string]string{
|
||||
"capture_name_prefix": "ignore",
|
||||
"capture_container_name": "ignore",
|
||||
"location": "ignore",
|
||||
"image_url": "ignore",
|
||||
"storage_account": "ignore",
|
||||
"resource_group_name": "ignore",
|
||||
"os_type": constants.Target_Linux,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args []interface{}
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "no client_id and no client_secret should enable MSI auth",
|
||||
args: []interface{}{
|
||||
baseConfig,
|
||||
getPackerConfiguration(),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "subscription_id is will be taken from MSI",
|
||||
args: []interface{}{
|
||||
baseConfig,
|
||||
map[string]string{
|
||||
"subscription_id": "error",
|
||||
},
|
||||
getPackerConfiguration(),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "client_id without client_secret should error",
|
||||
args: []interface{}{
|
||||
baseConfig,
|
||||
map[string]string{
|
||||
"client_id": "error",
|
||||
},
|
||||
getPackerConfiguration(),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "client_secret without client_id should error",
|
||||
args: []interface{}{
|
||||
baseConfig,
|
||||
map[string]string{
|
||||
"client_secret": "error",
|
||||
},
|
||||
getPackerConfiguration(),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "missing subscription_id",
|
||||
args: []interface{}{
|
||||
baseConfig,
|
||||
map[string]string{
|
||||
"client_id": "ok",
|
||||
"client_secret": "ok",
|
||||
},
|
||||
getPackerConfiguration(),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, _, err := newConfig(tt.args...)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("newConfig() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigShouldNormalizeOSTypeCase(t *testing.T) {
|
||||
config := map[string]string{
|
||||
"capture_name_prefix": "ignore",
|
||||
|
|
|
@ -59,14 +59,30 @@ mode.
|
|||
> Device login mode is for the Public and US Gov clouds only.
|
||||
|
||||
The device login flow asks that you open a web browser, navigate to
|
||||
<http://aka.ms/devicelogin>, and input the supplied code. This authorizes the
|
||||
Packer for Azure application to act on your behalf. An OAuth token will be
|
||||
created, and stored in the user's home directory
|
||||
(~/.azure/packer/oauth-TenantID.json). This token is used if the token file
|
||||
exists, and it is refreshed as necessary. The token file prevents the need to
|
||||
continually execute the device login flow. Packer will ask for two device login
|
||||
auth, one for service management endpoint and another for accessing temp
|
||||
keyvault secrets that it creates.
|
||||
<a href="http://aka.ms/devicelogin" class="uri">http://aka.ms/devicelogin</a>,
|
||||
and input the supplied code. This authorizes the Packer for Azure application
|
||||
to act on your behalf. An OAuth token will be created, and stored in the user's
|
||||
home directory (\~/.azure/packer/oauth-TenantID.json). This token is used if
|
||||
the token file exists, and it is refreshed as necessary. The token file
|
||||
prevents the need to continually execute the device login flow. Packer will ask
|
||||
for two device login auth, one for service management endpoint and another for
|
||||
accessing temp keyvault secrets that it creates.
|
||||
|
||||
## Managed identities for Azure resources
|
||||
|
||||
-> Managed identities for Azure resources is the new name for the service
|
||||
formerly known as Managed Service Identity (MSI).
|
||||
|
||||
Managed identities is an alternative way to authorize in Azure Packer. Managed
|
||||
identities for Azure resources are automatically managed by Azure and enable
|
||||
you to authenticate to services that support Azure AD authentication without
|
||||
needing to insert credentials into your buildfile. Navigate to
|
||||
<a href="https://docs.microsoft.com/en-gb/azure/active-directory/managed-identities-azure-resources/overview"
|
||||
class="uri">managed identities azure resources overview</a> to learn more about
|
||||
this feature.
|
||||
|
||||
This feature will be used when no `subscription_id`, `client_id` or
|
||||
`client_secret` is set in your buildfile.
|
||||
|
||||
## Install the Azure CLI
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ addition to the options listed here, a
|
|||
[communicator](/docs/templates/communicator.html) can be configured for this
|
||||
builder.
|
||||
|
||||
### Required:
|
||||
### Required ( unless instance has [managed identities](/docs/builders/azure-setup.html#managed-identities-for-azure-resources) enabled):
|
||||
|
||||
- `client_id` (string) The Active Directory service principal associated with
|
||||
your builder.
|
||||
|
@ -48,6 +48,8 @@ builder.
|
|||
specified in which case it needs to have owner access to the existing
|
||||
resource group specified in build\_resource\_group\_name parameter.**
|
||||
|
||||
### Required:
|
||||
|
||||
- `image_publisher` (string) PublisherName for your base image. See
|
||||
[documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/)
|
||||
for details.
|
||||
|
@ -250,6 +252,7 @@ Providing `temp_resource_group_name` or `location` in combination with
|
|||
type* - the target must be a *Managed Image*.
|
||||
|
||||
<!-- -->
|
||||
|
||||
"shared_image_gallery": {
|
||||
"subscription": "00000000-0000-0000-0000-00000000000",
|
||||
"resource_group": "ResourceGroup",
|
||||
|
|
Loading…
Reference in New Issue