Skip to content

Commit 8f1b397

Browse files
authored
azurerm_container_registry: Support azuread_authentication_as_arm_policy_enabled, role_assignment_mode and network_rule_bypass_allowed_for_tasks (#31667)
[ENHANCEMENT] * `azurerm_container_registry` Add support for `azuread_authentication_as_arm_policy_enabled`, `role_assignment_mode` and `network_rule_bypass_allowed_for_tasks` properties
1 parent 306877b commit 8f1b397

3 files changed

Lines changed: 97 additions & 49 deletions

File tree

internal/services/containers/container_registry_resource.go

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414

1515
"github.com/hashicorp/go-azure-helpers/lang/pointer"
1616
"github.com/hashicorp/go-azure-helpers/lang/response"
17-
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
1817
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
1918
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity"
2019
"github.com/hashicorp/go-azure-helpers/resourcemanager/keyvault"
@@ -226,6 +225,12 @@ func resourceContainerRegistry() *pluginsdk.Resource {
226225
Default: true,
227226
},
228227

228+
"azuread_authentication_as_arm_policy_enabled": {
229+
Type: pluginsdk.TypeBool,
230+
Optional: true,
231+
Default: true,
232+
},
233+
229234
"zone_redundancy_enabled": {
230235
Type: pluginsdk.TypeBool,
231236
ForceNew: true,
@@ -261,6 +266,19 @@ func resourceContainerRegistry() *pluginsdk.Resource {
261266
Default: string(registries.NetworkRuleBypassOptionsAzureServices),
262267
},
263268

269+
"network_rule_bypass_for_tasks_enabled": {
270+
Type: pluginsdk.TypeBool,
271+
Optional: true,
272+
Default: false,
273+
},
274+
275+
"role_assignment_mode": {
276+
Type: pluginsdk.TypeString,
277+
Optional: true,
278+
ValidateFunc: validation.StringInSlice(registries.PossibleValuesForRoleAssignmentMode(), false),
279+
Default: registries.RoleAssignmentModeLegacyRegistryPermissions,
280+
},
281+
264282
"tags": commonschema.Tags(),
265283
},
266284

@@ -353,7 +371,6 @@ func resourceContainerRegistry() *pluginsdk.Resource {
353371

354372
func resourceContainerRegistryCreate(d *pluginsdk.ResourceData, meta interface{}) error {
355373
client := meta.(*clients.Client).Containers.ContainerRegistryClient.Registries
356-
registriesClient := meta.(*clients.Client).Containers.ContainerRegistryClient.Registries
357374
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
358375
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
359376
defer cancel()
@@ -373,29 +390,11 @@ func resourceContainerRegistryCreate(d *pluginsdk.ResourceData, meta interface{}
373390
}
374391
}
375392

376-
sId := commonids.NewSubscriptionID(subscriptionId)
377-
availabilityRequest := registries.RegistryNameCheckRequest{
378-
Name: id.RegistryName,
379-
Type: "Microsoft.ContainerRegistry/registries",
380-
}
381-
resp, err := registriesClient.CheckNameAvailability(ctx, sId, availabilityRequest)
382-
if err != nil {
383-
return fmt.Errorf("checking if the name %q was available: %+v", id.RegistryName, err)
384-
}
385-
386-
if resp.Model == nil && resp.Model.NameAvailable == nil {
387-
return fmt.Errorf("checking name availability for %s: model was nil", id)
388-
}
389-
390-
if available := *resp.Model.NameAvailable; !available {
391-
return fmt.Errorf("the name %q used for the Container Registry needs to be globally unique and isn't available: %s", id.RegistryName, *resp.Model.Message)
392-
}
393-
394393
sku := d.Get("sku").(string)
395394

396395
networkRuleSet := expandNetworkRuleSet(d.Get("network_rule_set").([]interface{}))
397396
if networkRuleSet != nil && !strings.EqualFold(sku, string(registries.SkuNamePremium)) {
398-
return fmt.Errorf("`network_rule_set_set` can only be specified for a Premium Sku. If you are reverting from a Premium to Basic SKU please set network_rule_set = []")
397+
return fmt.Errorf("`network_rule_set` can only be specified for a Premium Sku. If you are reverting from a Premium to Basic SKU please set network_rule_set = []")
399398
}
400399

401400
identity, err := identity.ExpandSystemAndUserAssignedMap(d.Get("identity").([]interface{}))
@@ -440,16 +439,19 @@ func resourceContainerRegistryCreate(d *pluginsdk.ResourceData, meta interface{}
440439
Encryption: expandEncryption(d.Get("encryption").([]interface{})),
441440
NetworkRuleSet: networkRuleSet,
442441
Policies: &registries.Policies{
443-
QuarantinePolicy: expandQuarantinePolicy(d.Get("quarantine_policy_enabled").(bool)),
444-
RetentionPolicy: retentionPolicy,
445-
TrustPolicy: trustPolicy,
446-
ExportPolicy: expandExportPolicy(d.Get("export_policy_enabled").(bool)),
442+
QuarantinePolicy: expandQuarantinePolicy(d.Get("quarantine_policy_enabled").(bool)),
443+
RetentionPolicy: retentionPolicy,
444+
TrustPolicy: trustPolicy,
445+
ExportPolicy: expandExportPolicy(d.Get("export_policy_enabled").(bool)),
446+
AzureADAuthenticationAsArmPolicy: expandAadAuthAsArmPolicy(d.Get("azuread_authentication_as_arm_policy_enabled").(bool)),
447447
},
448-
PublicNetworkAccess: &publicNetworkAccess,
449-
ZoneRedundancy: &zoneRedundancy,
450-
AnonymousPullEnabled: pointer.To(d.Get("anonymous_pull_enabled").(bool)),
451-
DataEndpointEnabled: pointer.To(d.Get("data_endpoint_enabled").(bool)),
452-
NetworkRuleBypassOptions: pointer.To(registries.NetworkRuleBypassOptions(d.Get("network_rule_bypass_option").(string))),
448+
PublicNetworkAccess: &publicNetworkAccess,
449+
ZoneRedundancy: &zoneRedundancy,
450+
AnonymousPullEnabled: pointer.To(d.Get("anonymous_pull_enabled").(bool)),
451+
DataEndpointEnabled: pointer.To(d.Get("data_endpoint_enabled").(bool)),
452+
NetworkRuleBypassOptions: pointer.To(registries.NetworkRuleBypassOptions(d.Get("network_rule_bypass_option").(string))),
453+
RoleAssignmentMode: pointer.ToEnum[registries.RoleAssignmentMode](d.Get("role_assignment_mode").(string)),
454+
NetworkRuleBypassAllowedForTasks: pointer.To(d.Get("network_rule_bypass_for_tasks_enabled").(bool)),
453455
},
454456

455457
Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
@@ -509,7 +511,7 @@ func resourceContainerRegistryUpdate(d *pluginsdk.ResourceData, meta interface{}
509511
if d.HasChange("network_rule_set") {
510512
networkRuleSet := expandNetworkRuleSet(d.Get("network_rule_set").([]interface{}))
511513
if networkRuleSet != nil && isBasicSku {
512-
return fmt.Errorf("`network_rule_set_set` can only be specified for a Premium Sku. If you are reverting from a Premium to Basic SKU plese set network_rule_set = []")
514+
return fmt.Errorf("`network_rule_set` can only be specified for a Premium Sku. If you are reverting from a Premium to Basic SKU plese set network_rule_set = []")
513515
}
514516

515517
payload.Properties.NetworkRuleSet = networkRuleSet
@@ -540,6 +542,7 @@ func resourceContainerRegistryUpdate(d *pluginsdk.ResourceData, meta interface{}
540542
policyKeys := []string{
541543
"quarantine_policy_enabled",
542544
"export_policy_enabled",
545+
"azuread_authentication_as_arm_policy_enabled",
543546
}
544547

545548
policyKeys = append(policyKeys, []string{"retention_policy_in_days", "trust_policy_enabled"}...)
@@ -597,6 +600,10 @@ func resourceContainerRegistryUpdate(d *pluginsdk.ResourceData, meta interface{}
597600
}
598601
}
599602

603+
if d.HasChange("azuread_authentication_as_arm_policy_enabled") {
604+
payload.Properties.Policies.AzureADAuthenticationAsArmPolicy = expandAadAuthAsArmPolicy(d.Get("azuread_authentication_as_arm_policy_enabled").(bool))
605+
}
606+
600607
if d.HasChange("admin_enabled") {
601608
payload.Properties.AdminUserEnabled = pointer.To(d.Get("admin_enabled").(bool))
602609
}
@@ -617,6 +624,14 @@ func resourceContainerRegistryUpdate(d *pluginsdk.ResourceData, meta interface{}
617624
payload.Properties.NetworkRuleBypassOptions = pointer.To(registries.NetworkRuleBypassOptions(d.Get("network_rule_bypass_option").(string)))
618625
}
619626

627+
if d.HasChange("role_assignment_mode") {
628+
payload.Properties.RoleAssignmentMode = pointer.ToEnum[registries.RoleAssignmentMode](d.Get("role_assignment_mode").(string))
629+
}
630+
631+
if d.HasChange("network_rule_bypass_for_tasks_enabled") {
632+
payload.Properties.NetworkRuleBypassAllowedForTasks = pointer.To(d.Get("network_rule_bypass_for_tasks_enabled").(bool))
633+
}
634+
620635
if d.HasChange("tags") {
621636
payload.Tags = tags.Expand(d.Get("tags").(map[string]interface{}))
622637
}
@@ -856,6 +871,8 @@ func resourceContainerRegistryRead(d *pluginsdk.ResourceData, meta interface{})
856871
d.Set("data_endpoint_enabled", props.DataEndpointEnabled)
857872
d.Set("data_endpoint_host_names", props.DataEndpointHostNames)
858873
d.Set("network_rule_bypass_option", string(pointer.From(props.NetworkRuleBypassOptions)))
874+
d.Set("role_assignment_mode", string(pointer.From(props.RoleAssignmentMode)))
875+
d.Set("network_rule_bypass_for_tasks_enabled", pointer.From(props.NetworkRuleBypassAllowedForTasks))
859876

860877
if policies := props.Policies; policies != nil {
861878
var retentionInDays int64
@@ -870,6 +887,7 @@ func resourceContainerRegistryRead(d *pluginsdk.ResourceData, meta interface{})
870887
}
871888
d.Set("quarantine_policy_enabled", flattenQuarantinePolicy(props.Policies))
872889
d.Set("export_policy_enabled", flattenExportPolicy(props.Policies))
890+
d.Set("azuread_authentication_as_arm_policy_enabled", flattenAadAuthAsArmPolicy(props.Policies))
873891
}
874892

875893
if *props.AdminUserEnabled {
@@ -995,6 +1013,18 @@ func expandExportPolicy(enabled bool) *registries.ExportPolicy {
9951013
return &exportPolicy
9961014
}
9971015

1016+
func expandAadAuthAsArmPolicy(enabled bool) *registries.AzureADAuthenticationAsArmPolicy {
1017+
policy := registries.AzureADAuthenticationAsArmPolicy{
1018+
Status: pointer.To(registries.AzureADAuthenticationAsArmPolicyStatusDisabled),
1019+
}
1020+
1021+
if enabled {
1022+
policy.Status = pointer.To(registries.AzureADAuthenticationAsArmPolicyStatusEnabled)
1023+
}
1024+
1025+
return &policy
1026+
}
1027+
9981028
func expandReplications(p []interface{}) []replications.Replication {
9991029
reps := make([]replications.Replication, 0)
10001030
if p == nil {
@@ -1091,3 +1121,11 @@ func flattenExportPolicy(p *registries.Policies) bool {
10911121

10921122
return *p.ExportPolicy.Status == registries.ExportPolicyStatusEnabled
10931123
}
1124+
1125+
func flattenAadAuthAsArmPolicy(p *registries.Policies) bool {
1126+
if p.AzureADAuthenticationAsArmPolicy == nil {
1127+
return false
1128+
}
1129+
1130+
return *p.AzureADAuthenticationAsArmPolicy.Status == registries.AzureADAuthenticationAsArmPolicyStatusEnabled
1131+
}

internal/services/containers/container_registry_resource_test.go

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -491,15 +491,17 @@ resource "azurerm_container_registry" "test" {
491491
type = "SystemAssigned"
492492
}
493493
494-
public_network_access_enabled = false
495-
quarantine_policy_enabled = true
496-
retention_policy_in_days = 10
497-
trust_policy_enabled = true
498-
export_policy_enabled = false
499-
anonymous_pull_enabled = true
500-
data_endpoint_enabled = true
501-
502-
network_rule_bypass_option = "None"
494+
public_network_access_enabled = false
495+
quarantine_policy_enabled = true
496+
retention_policy_in_days = 10
497+
trust_policy_enabled = true
498+
export_policy_enabled = false
499+
azuread_authentication_as_arm_policy_enabled = false
500+
anonymous_pull_enabled = true
501+
data_endpoint_enabled = true
502+
network_rule_bypass_option = "None"
503+
network_rule_bypass_for_tasks_enabled = true
504+
role_assignment_mode = "AbacRepositoryPermissions"
503505
504506
tags = {
505507
environment = "production"
@@ -540,15 +542,17 @@ resource "azurerm_container_registry" "test" {
540542
]
541543
}
542544
543-
public_network_access_enabled = true
544-
quarantine_policy_enabled = false
545-
retention_policy_in_days = 15
546-
trust_policy_enabled = false
547-
export_policy_enabled = true
548-
anonymous_pull_enabled = false
549-
data_endpoint_enabled = false
550-
551-
network_rule_bypass_option = "AzureServices"
545+
public_network_access_enabled = true
546+
quarantine_policy_enabled = false
547+
retention_policy_in_days = 15
548+
trust_policy_enabled = false
549+
export_policy_enabled = true
550+
azuread_authentication_as_arm_policy_enabled = true
551+
anonymous_pull_enabled = false
552+
data_endpoint_enabled = false
553+
network_rule_bypass_option = "AzureServices"
554+
network_rule_bypass_for_tasks_enabled = false
555+
role_assignment_mode = "LegacyRegistryPermissions"
552556
553557
tags = {
554558
environment = "production"

website/docs/r/container_registry.html.markdown

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ The following arguments are supported:
168168

169169
* `export_policy_enabled` - (Optional) Boolean value that indicates whether export policy is enabled. Defaults to `true`. In order to set it to `false`, make sure the `public_network_access_enabled` is also set to `false`.
170170

171+
* `azuread_authentication_as_arm_policy_enabled` - (Optional) Whether to use Azure Resource Manager audience token for this Container Registry? Defaults to `true`.
172+
171173
~> **Note:** `quarantine_policy_enabled`, `retention_policy_in_days`, `trust_policy_enabled`, `export_policy_enabled` and `zone_redundancy_enabled` are only supported on resources with the `Premium` SKU.
172174

173175
* `identity` - (Optional) An `identity` block as defined below.
@@ -180,6 +182,10 @@ The following arguments are supported:
180182

181183
* `network_rule_bypass_option` - (Optional) Whether to allow trusted Azure services to access a network-restricted Container Registry? Possible values are `None` and `AzureServices`. Defaults to `AzureServices`.
182184

185+
* `network_rule_bypass_for_tasks_enabled` - (Optional) Whether to allow Container Registry Tasks to access a network-restricted Container Registry? Defaults to `false`.
186+
187+
* `role_assignment_mode` - (Optional) The role assignment mode of this Container Registry. Possible values are `AbacRepositoryPermissions` and `LegacyRegistryPermissions`. Defaults to `LegacyRegistryPermissions`.
188+
183189
---
184190

185191
The `georeplications` block supports the following:

0 commit comments

Comments
 (0)