Skip to content

Commit

Permalink
Add use_shallow_replication field for Compute Gallery/SIG builds, f…
Browse files Browse the repository at this point in the history
…ix replica count type (#337)

* Add `use_shallow_replication` option for SIG image versions & Cast replica count at int64 to fix it being parsed as the wrong number

Fix sig replica count - use shallow replication in acc test - fix units

Make generate

Add tests

Update docs-partials/builder/azure/arm/SharedImageGalleryDestination-not-required.mdx

Co-authored-by: Wilken Rivera <[email protected]>

Update builder/azure/arm/step_publish_to_shared_image_gallery.go

Co-authored-by: Wilken Rivera <[email protected]>

Implement the rest of Wilken's suggested changes

Add validation, fix acceptance tests with new name for shallow replication field

make generate

Fix make generate

Fix make generate after rebasing on main

Add comments and tests

* Apply suggestions from code review

Co-authored-by: Wilken Rivera <[email protected]>

* Update builder/azure/arm/step_publish_to_shared_image_gallery.go

Co-authored-by: Wilken Rivera <[email protected]>

* Fix brackets after code review, gofmt config file, and make generate

* Fix replica count check should only happen when using shallow replication

* Shallow Replication region check didn't work so I changed it to be a bit simpler, be stricter about requiring replica count = 1 rather than > 1 for shallow replication

---------

Co-authored-by: Wilken Rivera <[email protected]>
  • Loading branch information
JenGoldstrich and nywilken authored Oct 17, 2023
1 parent 55fc16b commit d042ec9
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 82 deletions.
10 changes: 7 additions & 3 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 @@ -640,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 @@ -534,6 +543,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"`
// 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

0 comments on commit d042ec9

Please sign in to comment.