azure: support storage account for managed images

Closes #5202
This commit is contained in:
Christopher Boumenot 2017-08-13 01:45:04 -07:00
parent 7da52e1f77
commit 0780667b4d
9 changed files with 103 additions and 12 deletions

View File

@ -74,9 +74,11 @@ type Config struct {
Location string `mapstructure:"location"`
VMSize string `mapstructure:"vm_size"`
ManagedImageResourceGroupName string `mapstructure:"managed_image_resource_group_name"`
ManagedImageName string `mapstructure:"managed_image_name"`
manageImageLocation string
ManagedImageResourceGroupName string `mapstructure:"managed_image_resource_group_name"`
ManagedImageName string `mapstructure:"managed_image_name"`
ManagedImageStorageAccountType string `mapstructure:"managed_image_storage_account_type"`
managedImageStorageAccountType compute.StorageAccountTypes
manageImageLocation string
// Deployment
AzureTags map[string]*string `mapstructure:"azure_tags"`
@ -405,6 +407,10 @@ func provideDefaultValues(c *Config) {
c.VMSize = DefaultVMSize
}
if c.ManagedImageStorageAccountType == "" {
c.managedImageStorageAccountType = compute.StandardLRS
}
if c.ImagePublisher != "" && c.ImageVersion == "" {
c.ImageVersion = DefaultImageVersion
}
@ -598,4 +604,13 @@ func assertRequiredParametersSet(c *Config, errs *packer.MultiError) {
} else {
errs = packer.MultiErrorAppend(errs, fmt.Errorf("The os_type %q is invalid", c.OSType))
}
switch c.ManagedImageStorageAccountType {
case "", string(compute.StandardLRS):
c.managedImageStorageAccountType = compute.StandardLRS
case string(compute.PremiumLRS):
c.managedImageStorageAccountType = compute.PremiumLRS
default:
errs = packer.MultiErrorAppend(errs, fmt.Errorf("The managed_image_storage_account_type %q is invalid", c.ManagedImageStorageAccountType))
}
}

View File

@ -9,6 +9,7 @@ import (
"testing"
"time"
"github.com/Azure/azure-sdk-for-go/arm/compute"
"github.com/hashicorp/packer/builder/azure/common/constants"
"github.com/hashicorp/packer/packer"
)
@ -48,6 +49,10 @@ func TestConfigShouldProvideReasonableDefaultValues(t *testing.T) {
if c.ObjectID != "" {
t.Errorf("Expected 'ObjectID' to be nil, but it was '%s'!", c.ObjectID)
}
if c.managedImageStorageAccountType == "" {
t.Errorf("Expected 'managedImageStorageAccountType' to be populated, but it was empty!")
}
}
func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
@ -56,6 +61,7 @@ func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
builderValues["ssh_username"] = "override_username"
builderValues["vm_size"] = "override_vm_size"
builderValues["communicator"] = "ssh"
builderValues["managed_image_storage_account_type"] = "Premium_LRS"
c, _, err := newConfig(builderValues, getPackerConfiguration())
@ -64,23 +70,27 @@ func TestConfigShouldBeAbleToOverrideDefaultedValues(t *testing.T) {
}
if c.Password != "override_password" {
t.Errorf("Expected 'Password' to be set to 'override_password', but found '%s'!", c.Password)
t.Errorf("Expected 'Password' to be set to 'override_password', but found %q!", c.Password)
}
if c.Comm.SSHPassword != "override_password" {
t.Errorf("Expected 'c.Comm.SSHPassword' to be set to 'override_password', but found '%s'!", c.Comm.SSHPassword)
t.Errorf("Expected 'c.Comm.SSHPassword' to be set to 'override_password', but found %q!", c.Comm.SSHPassword)
}
if c.UserName != "override_username" {
t.Errorf("Expected 'UserName' to be set to 'override_username', but found '%s'!", c.UserName)
t.Errorf("Expected 'UserName' to be set to 'override_username', but found %q!", c.UserName)
}
if c.Comm.SSHUsername != "override_username" {
t.Errorf("Expected 'c.Comm.SSHUsername' to be set to 'override_username', but found '%s'!", c.Comm.SSHUsername)
t.Errorf("Expected 'c.Comm.SSHUsername' to be set to 'override_username', but found %q!", c.Comm.SSHUsername)
}
if c.VMSize != "override_vm_size" {
t.Errorf("Expected 'vm_size' to be set to 'override_vm_size', but found '%s'!", c.VMSize)
t.Errorf("Expected 'vm_size' to be set to 'override_vm_size', but found %q!", c.VMSize)
}
if c.managedImageStorageAccountType != compute.PremiumLRS {
t.Errorf("Expected 'managed_image_storage_account_type' to be set to 'Premium_LRS', but found %q!", c.managedImageStorageAccountType)
}
}
@ -826,6 +836,52 @@ func TestConfigShouldRejectCustomAndImageUrlForManagedImageBuild(t *testing.T) {
}
}
func TestConfigShouldRejectMalformedManageImageStorageAccountTypes(t *testing.T) {
config := map[string]interface{}{
"custom_managed_image_resource_group_name": "ignore",
"custom_managed_image_name": "ignore",
"location": "ignore",
"subscription_id": "ignore",
"communicator": "none",
"managed_image_resource_group_name": "ignore",
"managed_image_name": "ignore",
"managed_image_storage_account_type": "--invalid--",
// Does not matter for this test case, just pick one.
"os_type": constants.Target_Linux,
}
_, _, err := newConfig(config, getPackerConfiguration())
if err == nil {
t.Fatal("expected config to reject custom and platform input for a managed image build")
}
}
func TestConfigShouldAcceptManagedImageStorageAccountTypes(t *testing.T) {
config := map[string]interface{}{
"custom_managed_image_resource_group_name": "ignore",
"custom_managed_image_name": "ignore",
"location": "ignore",
"subscription_id": "ignore",
"communicator": "none",
"managed_image_resource_group_name": "ignore",
"managed_image_name": "ignore",
// Does not matter for this test case, just pick one.
"os_type": constants.Target_Linux,
}
storage_account_types := []string{"Premium_LRS", "Standard_LRS"}
for _, x := range storage_account_types {
config["managed_image_storage_account_type"] = x
_, _, err := newConfig(config, getPackerConfiguration())
if err != nil {
t.Fatalf("expected config to accept a managed_image_storage_account_type of %q", x)
}
}
}
func getArmBuilderConfiguration() map[string]string {
m := make(map[string]string)
for _, v := range requiredConfigValues {

View File

@ -53,7 +53,7 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error)
if config.ImageUrl != "" {
builder.SetImageUrl(config.ImageUrl, osType)
} else if config.CustomManagedImageName != "" {
builder.SetManagedDiskUrl(config.customManagedImageID)
builder.SetManagedDiskUrl(config.customManagedImageID, config.managedImageStorageAccountType)
} else if config.ManagedImageName != "" && config.ImagePublisher != "" {
imageID := fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/locations/%s/publishers/%s/ArtifactTypes/vmimage/offers/%s/skus/%s/versions/%s",
config.SubscriptionID,
@ -63,7 +63,7 @@ func GetVirtualMachineDeployment(config *Config) (*resources.Deployment, error)
config.ImageSku,
config.ImageVersion)
builder.SetManagedMarketplaceImage(config.Location, config.ImagePublisher, config.ImageOffer, config.ImageSku, config.ImageVersion, imageID)
builder.SetManagedMarketplaceImage(config.Location, config.ImagePublisher, config.ImageOffer, config.ImageSku, config.ImageVersion, imageID, config.managedImageStorageAccountType)
} else {
builder.SetMarketPlaceImage(config.ImagePublisher, config.ImageOffer, config.ImageSku, config.ImageVersion)
}

View File

@ -129,6 +129,9 @@
"osDisk": {
"caching": "ReadWrite",
"createOption": "fromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
},
"name": "osdisk",
"osType": "Linux"
}

View File

@ -132,6 +132,9 @@
"osDisk": {
"caching": "ReadWrite",
"createOption": "fromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
},
"name": "osdisk",
"osType": "Linux"
}

View File

@ -110,6 +110,9 @@
"osDisk": {
"caching": "ReadWrite",
"createOption": "fromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
},
"name": "osdisk",
"osType": "Linux"
}

View File

@ -45,6 +45,7 @@ type OSDiskUnion struct {
Caching compute.CachingTypes `json:"caching,omitempty"`
CreateOption compute.DiskCreateOptionTypes `json:"createOption,omitempty"`
DiskSizeGB *int32 `json:"diskSizeGB,omitempty"`
ManagedDisk *compute.ManagedDiskParameters `json:"managedDisk,omitempty"`
}
// Union of the StorageProfile and ImageStorageProfile types.

View File

@ -101,7 +101,7 @@ func (s *TemplateBuilder) BuildWindows(keyVaultName, winRMCertificateUrl string)
return nil
}
func (s *TemplateBuilder) SetManagedDiskUrl(managedImageId string) error {
func (s *TemplateBuilder) SetManagedDiskUrl(managedImageId string, storageAccountType compute.StorageAccountTypes) error {
resource, err := s.getResourceByType(resourceVirtualMachine)
if err != nil {
return err
@ -115,11 +115,14 @@ func (s *TemplateBuilder) SetManagedDiskUrl(managedImageId string) error {
profile.OsDisk.OsType = s.osType
profile.OsDisk.CreateOption = compute.FromImage
profile.OsDisk.Vhd = nil
profile.OsDisk.ManagedDisk = &compute.ManagedDiskParameters{
StorageAccountType: storageAccountType,
}
return nil
}
func (s *TemplateBuilder) SetManagedMarketplaceImage(location, publisher, offer, sku, version, imageID string) error {
func (s *TemplateBuilder) SetManagedMarketplaceImage(location, publisher, offer, sku, version, imageID string, storageAccountType compute.StorageAccountTypes) error {
resource, err := s.getResourceByType(resourceVirtualMachine)
if err != nil {
return err
@ -137,6 +140,9 @@ func (s *TemplateBuilder) SetManagedMarketplaceImage(location, publisher, offer,
profile.OsDisk.OsType = s.osType
profile.OsDisk.CreateOption = compute.FromImage
profile.OsDisk.Vhd = nil
profile.OsDisk.ManagedDisk = &compute.ManagedDiskParameters{
StorageAccountType: storageAccountType,
}
return nil
}

View File

@ -107,6 +107,10 @@ When creating a managed image the following two options are required.
- `image_url` (string) Specify a custom VHD to use. If this value is set, do not set image\_publisher, image\_offer,
image\_sku, or image\_version.
- `managed_image_storage_account_type` (string) Specify the storage
account type for a managed image. Valid values are Standard_LRS
and Premium\_LRS. The default is Standard\_LRS.
- `object_id` (string) Specify an OAuth Object ID to protect WinRM certificates
created at runtime. This variable is required when creating images based on