Merge pull request #7211 from riezebosch/master

arm-builder: specify zone resilient image from config
This commit is contained in:
Paul Meyer 2019-03-19 08:59:29 -07:00 committed by GitHub
commit e4bea87a20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 109 additions and 0 deletions

View File

@ -151,6 +151,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook) (packer.Artifact, error) {
b.config.Location = *group.Location
}
b.config.validateLocationZoneResiliency(ui.Say)
if b.config.StorageAccount != "" {
account, err := b.getBlobAccount(ctx, azureClient, b.config.ResourceGroupName, b.config.StorageAccount)
if err != nil {

View File

@ -107,6 +107,7 @@ type Config struct {
ManagedImageOSDiskSnapshotName string `mapstructure:"managed_image_os_disk_snapshot_name"`
ManagedImageDataDiskSnapshotPrefix string `mapstructure:"managed_image_data_disk_snapshot_prefix"`
manageImageLocation string
ManagedImageZoneResilient bool `mapstructure:"managed_image_zone_resilient"`
// Deployment
AzureTags map[string]*string `mapstructure:"azure_tags"`
@ -196,6 +197,9 @@ func (c *Config) toImageParameters() *compute.Image {
SourceVirtualMachine: &compute.SubResource{
ID: to.StringPtr(c.toVMID()),
},
StorageProfile: &compute.ImageStorageProfile{
ZoneResilient: to.BoolPtr(c.ManagedImageZoneResilient),
},
},
Location: to.StringPtr(c.Location),
Tags: c.AzureTags,
@ -721,3 +725,23 @@ func isValidAzureName(re *regexp.Regexp, rgn string) bool {
!strings.HasSuffix(rgn, ".") &&
!strings.HasSuffix(rgn, "-")
}
func (c *Config) validateLocationZoneResiliency(say func(s string)) {
// Docs on regions that support Availibility Zones:
// https://docs.microsoft.com/en-us/azure/availability-zones/az-overview#regions-that-support-availability-zones
// Query technical names for locations:
// az account list-locations --query '[].name' -o tsv
var zones = make(map[string]struct{})
zones["westeurope"] = struct{}{}
zones["centralus"] = struct{}{}
zones["eastus2"] = struct{}{}
zones["francecentral"] = struct{}{}
zones["northeurope"] = struct{}{}
zones["southeastasia"] = struct{}{}
zones["westus2"] = struct{}{}
if _, ok := zones[c.Location]; !ok {
say(fmt.Sprintf("WARNING: Zone resiliency may not be supported in %s, checkout the docs at https://docs.microsoft.com/en-us/azure/availability-zones/", c.Location))
}
}

View File

@ -794,6 +794,51 @@ func TestConfigShouldRejectExcessiveTagValueLength(t *testing.T) {
}
}
func TestConfigZoneResilientShouldDefaultToFalse(t *testing.T) {
config := map[string]interface{}{
"managed_image_name": "ignore",
"managed_image_resource_group_name": "ignore",
"build_resource_group_name": "ignore",
"image_publisher": "igore",
"image_offer": "ignore",
"image_sku": "ignore",
"os_type": "linux",
}
c, _, err := newConfig(config, getPackerConfiguration())
if err != nil {
t.Fatal(err)
}
p := c.toImageParameters()
if *p.ImageProperties.StorageProfile.ZoneResilient {
t.Fatal("expected zone resilient default to be false")
}
}
func TestConfigZoneResilientSetFromConfig(t *testing.T) {
config := map[string]interface{}{
"managed_image_name": "ignore",
"managed_image_resource_group_name": "ignore",
"build_resource_group_name": "ignore",
"image_publisher": "igore",
"image_offer": "ignore",
"image_sku": "ignore",
"os_type": "linux",
"managed_image_zone_resilient": true,
}
c, _, err := newConfig(config, getPackerConfiguration())
if err != nil {
t.Fatal(err)
}
p := c.toImageParameters()
if *p.ImageProperties.StorageProfile.ZoneResilient == false {
t.Fatal("expected managed image zone resilient to be true from config")
}
}
func TestConfigShouldRejectMissingCustomDataFile(t *testing.T) {
config := map[string]interface{}{
"capture_name_prefix": "ignore",
@ -1636,7 +1681,42 @@ func TestConfigShouldRejectSharedImageGalleryWithVhdTarget(t *testing.T) {
if err != nil {
t.Log("expected an error if Shared Image Gallery source is used with VHD target", err)
}
}
func Test_GivenZoneNotSupportingResiliency_ConfigValidate_ShouldWarn(t *testing.T) {
builderValues := getArmBuilderConfiguration()
builderValues["managed_image_zone_resilient"] = "true"
builderValues["location"] = "ukwest"
c, _, err := newConfig(builderValues, getPackerConfiguration())
if err != nil {
t.Errorf("newConfig failed with %q", err)
}
var m = ""
c.validateLocationZoneResiliency(func(s string) { m = s })
if m != "WARNING: Zone resiliency may not be supported in ukwest, checkout the docs at https://docs.microsoft.com/en-us/azure/availability-zones/" {
t.Errorf("warning message not as expected: %s", m)
}
}
func Test_GivenZoneSupportingResiliency_ConfigValidate_ShouldNotWarn(t *testing.T) {
builderValues := getArmBuilderConfiguration()
builderValues["managed_image_zone_resilient"] = "true"
builderValues["location"] = "westeurope"
c, _, err := newConfig(builderValues, getPackerConfiguration())
if err != nil {
t.Errorf("newConfig failed with %q", err)
}
var m = ""
c.validateLocationZoneResiliency(func(s string) { m = s })
if m != "" {
t.Errorf("warning message not as expected: %s", m)
}
}
func getArmBuilderConfiguration() map[string]string {

View File

@ -334,6 +334,9 @@ Providing `temp_resource_group_name` or `location` in combination with
disk(s) is created with the same prefix as this value before the VM is
captured.
- `managed_image_zone_resilient` (bool) Store the image in zone-resilient storage. You need to create it
in a region that supports [availability zones](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview).
## Basic Example
Here is a basic example for Azure.