Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add use_shallow_replication field for Compute Gallery/SIG builds, fix replica count type #337

Merged
merged 6 commits into from
Oct 17, 2023
14 changes: 10 additions & 4 deletions .web-docs/components/builder/arm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,9 @@ Providing `temp_resource_group_name` or `location` in combination with
- `shared_gallery_image_version_end_of_life_date` (string) - The end of life date (2006-01-02T15:04:05.99Z) of the gallery Image Version. This property
can be used for decommissioning purposes.

- `shared_image_gallery_replica_count` (int32) - The number of replicas of the Image Version to be created per region. This
property would take effect for a region when regionalReplicaCount is not specified.
- `shared_image_gallery_replica_count` (int64) - The number of replicas of the Image Version to be created per region.
Replica count must be between 1 and 100, but 50 replicas should be sufficient for most use cases.
When using shallow replication `use_shallow_replication=true` the value can only be 1.

- `shared_gallery_image_version_exclude_from_latest` (bool) - If set to true, Virtual Machines deployed from the latest version of the
Image Definition won't use this Image Version.
Expand Down Expand Up @@ -335,9 +335,11 @@ Providing `temp_resource_group_name` or `location` in combination with

- `build_resource_group_name` (string) - Specify an existing resource group to run the build in.

- `build_key_vault_name` (string) - Specify an existing key vault to use for uploading certificates to the
- `build_key_vault_name` (string) - Specify an existing key vault to use for uploading the certificate for the
instance to connect.

- `build_key_vault_secret_name` (string) - Specify the secret name to use for the certificate created in the key vault.

- `build_key_vault_sku` (string) - Specify the KeyVault SKU to create during the build. Valid values are
standard or premium. The default value is standard.

Expand Down Expand Up @@ -638,13 +640,17 @@ The shared_image_gallery_destination block is available for publishing a new ima

- `image_version` (string) - Sig Destination Image Version

- `replication_regions` ([]string) - Sig Destination Replication Regions
- `replication_regions` ([]string) - A list of regions to replicate the image version in, by default the build location will be used as a replication region (the build location is either set in the location field, or the location of the resource group used in `build_resource_group_name` will be included.
Can not contain any region but the build region when using shallow replication

- `storage_account_type` (string) - Specify a storage account type for the Shared Image Gallery Image Version.
Defaults to `Standard_LRS`. Accepted values are `Standard_LRS`, `Standard_ZRS` and `Premium_LRS`

- `specialized` (bool) - Set to true if publishing to a Specialized Gallery, this skips a call to set the build VM's OS state as Generalized

- `use_shallow_replication` (bool) - Setting a `shared_image_gallery_replica_count` or any `replication_regions` is unnecessary for shallow builds, as they can only replicate to the build region and must have a replica count of 1
Refer to [Shallow Replication](https://learn.microsoft.com/en-us/azure/virtual-machines/shared-image-galleries?tabs=azure-cli#shallow-replication) for details on when to use shallow replication mode.

<!-- End of code generated from the comments of the SharedImageGalleryDestination struct in builder/azure/arm/config.go; -->


Expand Down
18 changes: 14 additions & 4 deletions builder/azure/arm/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,21 +213,30 @@ func (b *Builder) Run(ctx context.Context, ui packersdk.Ui, hook packersdk.Hook)
return nil, fmt.Errorf("a gallery image version for image name:version %s:%s already exists in gallery %s", b.config.SharedGalleryDestination.SigDestinationImageName, b.config.SharedGalleryDestination.SigDestinationImageVersion, b.config.SharedGalleryDestination.SigDestinationGalleryName)
}

// SIG requires that replication regions include the region in which the Managed Image resides
managedImageLocation := normalizeAzureRegion(b.stateBag.Get(constants.ArmLocation).(string))
// SIG requires that replication regions include the region in which the created image version resides
buildLocation := normalizeAzureRegion(b.stateBag.Get(constants.ArmLocation).(string))
foundMandatoryReplicationRegion := false
var normalizedReplicationRegions []string
for _, region := range b.config.SharedGalleryDestination.SigDestinationReplicationRegions {
// change region to lower-case and strip spaces
normalizedRegion := normalizeAzureRegion(region)
normalizedReplicationRegions = append(normalizedReplicationRegions, normalizedRegion)
if strings.EqualFold(normalizedRegion, managedImageLocation) {
if strings.EqualFold(normalizedRegion, buildLocation) {
foundMandatoryReplicationRegion = true
continue
}
}
if foundMandatoryReplicationRegion == false {
b.config.SharedGalleryDestination.SigDestinationReplicationRegions = append(normalizedReplicationRegions, managedImageLocation)
b.config.SharedGalleryDestination.SigDestinationReplicationRegions = append(normalizedReplicationRegions, buildLocation)
}
// TODO It would be better if validation could be handled in a central location
// Currently we rely on the build Resource Group being queried if used to get the build location
// So we have to do this validation afterwards
// We should remove this logic builder and handle this logic via the `Step` pattern
if b.config.SharedGalleryDestination.SigDestinationUseShallowReplicationMode {
if len(b.config.SharedGalleryDestination.SigDestinationReplicationRegions) != 1 {
return nil, fmt.Errorf("when `use_shallow_replication` is enabled the value of `replicated_regions` must match the build region specified by `location` or match the region of `build_resource_group_name`.")
}
}
b.stateBag.Put(constants.ArmManagedImageSharedGalleryReplicationRegions, b.config.SharedGalleryDestination.SigDestinationReplicationRegions)
}
Expand Down Expand Up @@ -532,6 +541,7 @@ func (b *Builder) configureStateBag(stateBag multistep.StateBag) {
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersion, b.config.SharedGalleryDestination.SigDestinationImageVersion)
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersionStorageAccountType, b.config.SharedGalleryDestination.SigDestinationStorageAccountType)
stateBag.Put(constants.ArmSharedImageGalleryDestinationSpecialized, b.config.SharedGalleryDestination.SigDestinationSpecialized)
stateBag.Put(constants.ArmSharedImageGalleryDestinationShallowReplication, b.config.SharedGalleryDestination.SigDestinationUseShallowReplicationMode)
stateBag.Put(constants.ArmManagedImageSubscription, b.config.ClientConfig.SubscriptionID)
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersionEndOfLifeDate, b.config.SharedGalleryImageVersionEndOfLifeDate)
stateBag.Put(constants.ArmManagedImageSharedGalleryImageVersionReplicaCount, b.config.SharedGalleryImageVersionReplicaCount)
Expand Down
32 changes: 24 additions & 8 deletions builder/azure/arm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,24 @@ type SharedImageGallery struct {
}

type SharedImageGalleryDestination struct {
SigDestinationSubscription string `mapstructure:"subscription"`
SigDestinationResourceGroup string `mapstructure:"resource_group"`
SigDestinationGalleryName string `mapstructure:"gallery_name"`
SigDestinationImageName string `mapstructure:"image_name"`
SigDestinationImageVersion string `mapstructure:"image_version"`
SigDestinationSubscription string `mapstructure:"subscription"`
SigDestinationResourceGroup string `mapstructure:"resource_group"`
SigDestinationGalleryName string `mapstructure:"gallery_name"`
SigDestinationImageName string `mapstructure:"image_name"`
SigDestinationImageVersion string `mapstructure:"image_version"`
// A list of regions to replicate the image version in, by default the build location will be used as a replication region (the build location is either set in the location field, or the location of the resource group used in `build_resource_group_name` will be included.
// Can not contain any region but the build region when using shallow replication
SigDestinationReplicationRegions []string `mapstructure:"replication_regions"`
// Specify a storage account type for the Shared Image Gallery Image Version.
// Defaults to `Standard_LRS`. Accepted values are `Standard_LRS`, `Standard_ZRS` and `Premium_LRS`
SigDestinationStorageAccountType string `mapstructure:"storage_account_type"`
// Set to true if publishing to a Specialized Gallery, this skips a call to set the build VM's OS state as Generalized
SigDestinationSpecialized bool `mapstructure:"specialized"`
// Set to true to use shallow replication mode, which will publish the image version without replication. This option results in a faster build, but the image version's replication count and regions are not modifiable builds with shallow replication enabled.

// Setting a `shared_image_gallery_replica_count` or any `replication_regions` is unnecessary for shallow builds, as they can only replicate to the build region and must have a replica count of 1
// Refer to [Shallow Replication](https://learn.microsoft.com/en-us/azure/virtual-machines/shared-image-galleries?tabs=azure-cli#shallow-replication) for details on when to use shallow replication mode.
SigDestinationUseShallowReplicationMode bool `mapstructure:"use_shallow_replication" required:"false"`
}

type Spot struct {
Expand Down Expand Up @@ -212,10 +219,10 @@ type Config struct {
// The end of life date (2006-01-02T15:04:05.99Z) of the gallery Image Version. This property
// can be used for decommissioning purposes.
SharedGalleryImageVersionEndOfLifeDate string `mapstructure:"shared_gallery_image_version_end_of_life_date" required:"false"`
// The number of replicas of the Image Version to be created per region. This
// property would take effect for a region when regionalReplicaCount is not specified.
// The number of replicas of the Image Version to be created per region.
// Replica count must be between 1 and 100, but 50 replicas should be sufficient for most use cases.
SharedGalleryImageVersionReplicaCount int32 `mapstructure:"shared_image_gallery_replica_count" required:"false"`
// When using shallow replication `use_shallow_replication=true` the value can only be 1.
SharedGalleryImageVersionReplicaCount int64 `mapstructure:"shared_image_gallery_replica_count" required:"false"`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the new SDK this value is an int64, because this was being parsed as an int32, stored in the state bag, and then in step_publish_to_shared_image_gallery it was retrieved as an int64, this int would be incorrectly registered, leading to #341

// If set to true, Virtual Machines deployed from the latest version of the
// Image Definition won't use this Image Version.
SharedGalleryImageVersionExcludeFromLatest bool `mapstructure:"shared_gallery_image_version_exclude_from_latest" required:"false"`
Expand Down Expand Up @@ -1256,6 +1263,15 @@ func assertRequiredParametersSet(c *Config, errs *packersdk.MultiError) {
if c.SharedGalleryDestination.SigDestinationSubscription == "" {
c.SharedGalleryDestination.SigDestinationSubscription = c.ClientConfig.SubscriptionID
}
if c.SharedGalleryDestination.SigDestinationUseShallowReplicationMode {
if c.SharedGalleryImageVersionReplicaCount == 0 {
c.SharedGalleryImageVersionReplicaCount = 1
}

if c.SharedGalleryImageVersionReplicaCount != 1 {
errs = packersdk.MultiErrorAppend(errs, fmt.Errorf("When using shallow replication the replica count can only be 1, leaving this value unset will default to 1"))
}
}
}
if c.SharedGalleryTimeout == 0 {
// default to a one-hour timeout. In the sdk, the default is 15 m.
Expand Down
36 changes: 19 additions & 17 deletions builder/azure/arm/config.hcl2spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading