diff --git a/config/config.msft.yaml b/config/config.msft.yaml index a16d39c97..6e219352b 100644 --- a/config/config.msft.yaml +++ b/config/config.msft.yaml @@ -10,6 +10,7 @@ defaults: subscription: hcp-{{ .ctx.region }} manageTokenCustomRole: false region: uksouth + drRegion: ukwest # (TODO): change to actual region we want to use globalMSIName: "global-ev2-identity" # General AKS config diff --git a/config/config.schema.json b/config/config.schema.json index 071ec9dab..6469fcee9 100644 --- a/config/config.schema.json +++ b/config/config.schema.json @@ -184,6 +184,9 @@ "region": { "type": "string" }, + "drRegion": { + "type": "string" + }, "globalMSIName": { "type": "string", "description": "The name of the MSI that will be used for ev2" @@ -193,7 +196,8 @@ "rg", "subscription", "manageTokenCustomRole", - "region" + "region", + "drRegion" ] }, "hypershift": { diff --git a/config/config.yaml b/config/config.yaml index da3d3c365..0978ff9cd 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -8,6 +8,7 @@ defaults: subscription: ARO Hosted Control Planes (EA Subscription 1) manageTokenCustomRole: true region: westus3 + drRegion: eastus2 # (TODO): change to actual region we want to use globalMSIName: "global-rollout-identity" # General AKS config diff --git a/config/public-cloud-cs-pr.json b/config/public-cloud-cs-pr.json index 5e56e7ed0..665e0beb7 100644 --- a/config/public-cloud-cs-pr.json +++ b/config/public-cloud-cs-pr.json @@ -40,6 +40,7 @@ "imageTag": "" }, "global": { + "drRegion": "eastus2", "globalMSIName": "global-rollout-identity", "manageTokenCustomRole": true, "region": "westus3", diff --git a/config/public-cloud-dev.json b/config/public-cloud-dev.json index 15f4ad119..b2c5c76d5 100644 --- a/config/public-cloud-dev.json +++ b/config/public-cloud-dev.json @@ -40,6 +40,7 @@ "imageTag": "" }, "global": { + "drRegion": "eastus2", "globalMSIName": "global-rollout-identity", "manageTokenCustomRole": true, "region": "westus3", diff --git a/config/public-cloud-msft-int.json b/config/public-cloud-msft-int.json index 5a07c2ce0..25d46fa48 100644 --- a/config/public-cloud-msft-int.json +++ b/config/public-cloud-msft-int.json @@ -39,6 +39,7 @@ "imageTag": "0b3c08f" }, "global": { + "drRegion": "ukwest", "globalMSIName": "global-ev2-identity", "manageTokenCustomRole": false, "region": "uksouth", diff --git a/config/public-cloud-personal-dev.json b/config/public-cloud-personal-dev.json index 9f845c5e7..a8736a6d8 100644 --- a/config/public-cloud-personal-dev.json +++ b/config/public-cloud-personal-dev.json @@ -40,6 +40,7 @@ "imageTag": "" }, "global": { + "drRegion": "eastus2", "globalMSIName": "global-rollout-identity", "manageTokenCustomRole": true, "region": "westus3", diff --git a/dev-infrastructure/configurations/global-acr.tmpl.bicepparam b/dev-infrastructure/configurations/global-acr.tmpl.bicepparam index 879a2976c..f24852c58 100644 --- a/dev-infrastructure/configurations/global-acr.tmpl.bicepparam +++ b/dev-infrastructure/configurations/global-acr.tmpl.bicepparam @@ -7,3 +7,5 @@ param ocpAcrName = '{{ .ocpAcrName }}' param ocpAcrSku = 'Premium' param location = '{{ .global.region }}' +param replicaLocation = '{{ .global.drRegion }}' + diff --git a/dev-infrastructure/modules/acr/acr.bicep b/dev-infrastructure/modules/acr/acr.bicep index 864562e39..d80663bf2 100644 --- a/dev-infrastructure/modules/acr/acr.bicep +++ b/dev-infrastructure/modules/acr/acr.bicep @@ -6,6 +6,9 @@ param acrName string @description('Location of the registry.') param location string = resourceGroup().location +@description('Location of the registry\'s replica.') +param replicaLocation string = '' + @description('Service tier of the Azure Container Registry.') param acrSku string @@ -39,6 +42,13 @@ resource acrResource 'Microsoft.ContainerRegistry/registries@2023-11-01-preview' } } +resource acrReplicaResource 'Microsoft.ContainerRegistry/registries/replications@2023-11-01-preview' = if (replicaLocation != '') { + parent: acrResource + name: '${acrName}-replica' + location: replicaLocation + properties: {} +} + // Assign the AcrPull Role to the ${acrName}-pull-identity var acrPullRoleId = '7f951dda-4ed3-4680-a7ca-43fe172d538d' diff --git a/dev-infrastructure/templates/global-acr.bicep b/dev-infrastructure/templates/global-acr.bicep index 3c9a0bc05..4aeaa3b6a 100644 --- a/dev-infrastructure/templates/global-acr.bicep +++ b/dev-infrastructure/templates/global-acr.bicep @@ -9,6 +9,7 @@ param svcAcrName string param svcAcrSku string param location string +param replicaLocation string module ocpAcr '../modules/acr/acr.bicep' = { name: ocpAcrName @@ -16,6 +17,7 @@ module ocpAcr '../modules/acr/acr.bicep' = { acrName: ocpAcrName acrSku: ocpAcrSku location: location + replicaLocation: replicaLocation } } @@ -25,5 +27,6 @@ module svcAcr '../modules/acr/acr.bicep' = { acrName: svcAcrName acrSku: svcAcrSku location: location + replicaLocation: replicaLocation } } diff --git a/tooling/templatize/cmd/generate/options_test.go b/tooling/templatize/cmd/generate/options_test.go index 0d518f460..0058414bb 100644 --- a/tooling/templatize/cmd/generate/options_test.go +++ b/tooling/templatize/cmd/generate/options_test.go @@ -17,6 +17,7 @@ func TestRawOptions(t *testing.T) { opts := &RawGenerationOptions{ RolloutOptions: &options.RawRolloutOptions{ Region: "uksouth", + DrRegion: "ukwest", RegionShort: "abcde", Stamp: "fghij", BaseOptions: &options.RawOptions{ diff --git a/tooling/templatize/cmd/pipeline/inspect/options.go b/tooling/templatize/cmd/pipeline/inspect/options.go index 774a43e18..0b7083db0 100644 --- a/tooling/templatize/cmd/pipeline/inspect/options.go +++ b/tooling/templatize/cmd/pipeline/inspect/options.go @@ -105,6 +105,7 @@ func (o *InspectOptions) RunInspect(ctx context.Context) error { rolloutOptions.Region, config.NewConfigReplacements( rolloutOptions.Region, + rolloutOptions.DrRegion, rolloutOptions.RegionShort, rolloutOptions.Stamp, ), diff --git a/tooling/templatize/cmd/pipeline/run/options.go b/tooling/templatize/cmd/pipeline/run/options.go index 5a866f37c..1818fa2be 100644 --- a/tooling/templatize/cmd/pipeline/run/options.go +++ b/tooling/templatize/cmd/pipeline/run/options.go @@ -93,6 +93,7 @@ func (o *RunOptions) RunPipeline(ctx context.Context) error { rolloutOptions.Region, config.NewConfigReplacements( rolloutOptions.Region, + rolloutOptions.DrRegion, rolloutOptions.RegionShort, rolloutOptions.Stamp, ), diff --git a/tooling/templatize/cmd/rolloutoptions.go b/tooling/templatize/cmd/rolloutoptions.go index c5bd75091..8540068a5 100644 --- a/tooling/templatize/cmd/rolloutoptions.go +++ b/tooling/templatize/cmd/rolloutoptions.go @@ -25,6 +25,7 @@ func NewRolloutOptions(config config.Variables) *RolloutOptions { func EV2RolloutOptions() *RawRolloutOptions { return &RawRolloutOptions{ Region: "$location()", + DrRegion: "$(drRegion)", RegionShort: "$(regionShort)", Stamp: "$stamp()", } @@ -36,6 +37,7 @@ func BindRolloutOptions(opts *RawRolloutOptions, cmd *cobra.Command) error { return fmt.Errorf("failed to bind options: %w", err) } cmd.Flags().StringVar(&opts.Region, "region", opts.Region, "resources location") + cmd.Flags().StringVar(&opts.Region, "dr-region", opts.DrRegion, "disaster recovery location") cmd.Flags().StringVar(&opts.RegionShort, "region-short", opts.RegionShort, "short region string") cmd.Flags().StringVar(&opts.Stamp, "stamp", opts.Stamp, "stamp") cmd.Flags().StringToStringVar(&opts.ExtraVars, "extra-args", opts.ExtraVars, "Extra arguments to be used config templating") @@ -45,6 +47,7 @@ func BindRolloutOptions(opts *RawRolloutOptions, cmd *cobra.Command) error { // RawRolloutOptions holds input values. type RawRolloutOptions struct { Region string + DrRegion string RegionShort string Stamp string ExtraVars map[string]string @@ -93,7 +96,7 @@ func (o *ValidatedRolloutOptions) Complete() (*RolloutOptions, error) { return nil, err } - variables, err := completed.ConfigProvider.GetVariables(o.Cloud, o.DeployEnv, o.Region, config.NewConfigReplacements(o.Region, o.RegionShort, o.Stamp)) + variables, err := completed.ConfigProvider.GetVariables(o.Cloud, o.DeployEnv, o.Region, config.NewConfigReplacements(o.Region, o.DrRegion, o.RegionShort, o.Stamp)) if err != nil { return nil, fmt.Errorf("failed to get variables: %w", err) } diff --git a/tooling/templatize/pkg/config/config.go b/tooling/templatize/pkg/config/config.go index 1ea492b53..9bbc881b0 100644 --- a/tooling/templatize/pkg/config/config.go +++ b/tooling/templatize/pkg/config/config.go @@ -13,12 +13,13 @@ import ( ) func DefaultConfigReplacements() *ConfigReplacements { - return NewConfigReplacements("", "", "") + return NewConfigReplacements("", "", "", "") } -func NewConfigReplacements(regionReplacement, regionShortReplacement, stampReplacement string) *ConfigReplacements { +func NewConfigReplacements(regionReplacement, drRegionReplacement, regionShortReplacement, stampReplacement string) *ConfigReplacements { return &ConfigReplacements{ RegionReplacement: regionReplacement, + DrRegionReplacement: drRegionReplacement, RegionShortReplacement: regionShortReplacement, StampReplacement: stampReplacement, } @@ -26,6 +27,7 @@ func NewConfigReplacements(regionReplacement, regionShortReplacement, stampRepla type ConfigReplacements struct { RegionReplacement string + DrRegionReplacement string RegionShortReplacement string StampReplacement string } @@ -34,6 +36,7 @@ func (c *ConfigReplacements) AsMap() map[string]interface{} { return map[string]interface{}{ "ctx": map[string]interface{}{ "region": c.RegionReplacement, + "drRegion": c.DrRegionReplacement, "regionShort": c.RegionShortReplacement, "stamp": c.StampReplacement, }, diff --git a/tooling/templatize/pkg/config/config_test.go b/tooling/templatize/pkg/config/config_test.go index e999ec7db..3617bbdf4 100644 --- a/tooling/templatize/pkg/config/config_test.go +++ b/tooling/templatize/pkg/config/config_test.go @@ -12,12 +12,13 @@ import ( func TestConfigProvider(t *testing.T) { region := "uksouth" + drRegion := "ukwest" regionShort := "uks" stamp := "1" configProvider := NewConfigProvider("../../testdata/config.yaml") - variables, err := configProvider.GetVariables("public", "int", region, NewConfigReplacements(region, regionShort, stamp)) + variables, err := configProvider.GetVariables("public", "int", region, NewConfigReplacements(region, drRegion, regionShort, stamp)) assert.NoError(t, err) assert.NotNil(t, variables) diff --git a/tooling/templatize/pkg/ev2/utils.go b/tooling/templatize/pkg/ev2/utils.go index 5b4e74c7b..8de15b608 100644 --- a/tooling/templatize/pkg/ev2/utils.go +++ b/tooling/templatize/pkg/ev2/utils.go @@ -13,6 +13,7 @@ import ( func NewEv2ConfigReplacements() *config.ConfigReplacements { return config.NewConfigReplacements( "$location()", + "$(drRegion)", "$(regionShortName)", "$stamp()", ) diff --git a/tooling/templatize/pkg/pipeline/common_test.go b/tooling/templatize/pkg/pipeline/common_test.go index 7b5d15b65..284fa3b77 100644 --- a/tooling/templatize/pkg/pipeline/common_test.go +++ b/tooling/templatize/pkg/pipeline/common_test.go @@ -13,7 +13,7 @@ import ( func TestDeepCopy(t *testing.T) { configProvider := config.NewConfigProvider("../../testdata/config.yaml") - vars, err := configProvider.GetVariables("public", "int", "", config.NewConfigReplacements("r", "sr", "s")) + vars, err := configProvider.GetVariables("public", "int", "", config.NewConfigReplacements("r", "dr", "sr", "s")) if err != nil { t.Errorf("failed to get variables: %v", err) } @@ -38,7 +38,7 @@ func TestDeepCopy(t *testing.T) { func TestAbsoluteFilePath(t *testing.T) { configProvider := config.NewConfigProvider("../../testdata/config.yaml") - vars, err := configProvider.GetVariables("public", "int", "", config.NewConfigReplacements("r", "sr", "s")) + vars, err := configProvider.GetVariables("public", "int", "", config.NewConfigReplacements("r", "dr", "sr", "s")) if err != nil { t.Errorf("failed to get variables: %v", err) }