Skip to content

Commit

Permalink
feat: assign permissions override (#168)
Browse files Browse the repository at this point in the history
* feat: add definition assign permissions override

* feat: add assign permissions default

* feat: alz provider 0.17

* docs: make docs

* feat: add authorization failed retry

* chore: simplify provider constraint

* fix: review comments
  • Loading branch information
matt-FFFFFF authored Jan 20, 2025
1 parent b4c6d5e commit 182c20a
Show file tree
Hide file tree
Showing 6 changed files with 500 additions and 16 deletions.
256 changes: 248 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ The following requirements are needed by this module:

- <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) (~> 1.8)

- <a name="requirement_alz"></a> [alz](#requirement\_alz) (~> 0.16, >= 0.16.2)
- <a name="requirement_alz"></a> [alz](#requirement\_alz) (~> 0.17)

- <a name="requirement_azapi"></a> [azapi](#requirement\_azapi) (~> 2.0, >= 2.2)
- <a name="requirement_azapi"></a> [azapi](#requirement\_azapi) (~> 2.2)

- <a name="requirement_modtm"></a> [modtm](#requirement\_modtm) (~> 0.3)

Expand Down Expand Up @@ -260,6 +260,235 @@ object({

Default: `null`

### <a name="input_override_policy_definition_parameter_assign_permissions_set"></a> [override\_policy\_definition\_parameter\_assign\_permissions\_set](#input\_override\_policy\_definition\_parameter\_assign\_permissions\_set)

Description: This list of objects allows you to set the [`assignPermissions` metadata property](https://learn.microsoft.com/azure/governance/policy/concepts/definition-structure-parameters#parameter-properties) of the supplied definition and parameter names.
This allows you to correct policies that haven't been authored correctly and means that the provider can generate the correct policy role assignments.

The value is a list of objects with the following attributes:

- `definition_name` - (Required) The name of the policy definition, ***for built-in policies this us a UUID***.
- `parameter_name` - (Required) The name of the parameter to set the assignPermissions property for.

The default value has been populated with the Azure Landing Zones policies that are assigned by default, but do not have the correct parameter metadata.

Type:

```hcl
set(object({
definition_name = string
parameter_name = string
}))
```

Default:

```json
[
{
"definition_name": "04754ef9-9ae3-4477-bf17-86ef50026304",
"parameter_name": "userWorkspaceResourceId"
},
{
"definition_name": "09963c90-6ee7-4215-8d26-1cc660a1682f",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "09a1f130-7697-42bc-8d84-8a9ea17e5192",
"parameter_name": "dcrResourceId"
},
{
"definition_name": "0b026355-49cb-467b-8ac4-f777874e175a",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "1142b015-2bd7-41e0-8645-a531afe09a1e",
"parameter_name": "dcrResourceId"
},
{
"definition_name": "1e5ed725-f16c-478b-bd4b-7bfa2f7940b9",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "2227e1f1-23dd-4c3a-85a9-7024a401d8b2",
"parameter_name": "dcrResourceId"
},
{
"definition_name": "34804460-d88b-4922-a7ca-537165e060e",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "4485d24b-a9d3-4206-b691-1fad83bc5007",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "4ec38ebc-381f-45ee-81a4-acbc4be878f8",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "516187d4-ef64-4a1b-ad6b-a7348502976c",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "56d0ed2b-60fc-44bf-af81-a78c851b5fe1",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "59c3d93f-900b-4827-a8bd-562e7b956e7c",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "637125fd-7c39-4b94-bb0a-d331faf333a9",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "63d03cbd-47fd-4ee1-8a1c-9ddf07303de0",
"parameter_name": "userWorkspaceResourceId"
},
{
"definition_name": "6a4e6f44-f2af-4082-9702-033c9e88b9f8",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "6dd01e4f-1be1-4e80-9d0b-d109e04cb064",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "7590a335-57cf-4c95-babd-ecbc8fafeb1f",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "7a860e27-9ca2-4fc6-822d-c2d248c300df",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "86cd96e1-1745-420d-94d4-d3f2fe415aa4",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "8fd85785-1547-4a4a-bf90-d5483c9571c5",
"parameter_name": "dcrResourceId"
},
{
"definition_name": "9427df23-0f42-4e1e-bf99-a6133d841c4a",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "942bd215-1a66-44be-af65-6a1c0318dbe2",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "98569e20-8f32-4f31-bf34-0e91590ae9d3",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "a63cc0bd-cda4-4178-b705-37dc439d3e0f",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "aaa64d2d-2fa3-45e5-b332-0b031b9b30e8",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "ad1eeff9-20d7-4c82-a04e-903acab0bfc1",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "ae8a10e6-19d6-44a3-a02d-a2bdfc707742",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "b0e86710-7fb7-4a6c-a064-32e9b829509e",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "b318f84a-b872-429b-ac6d-a01b96814452",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "b6faa975-0add-4f35-8d1c-70bba45c4424",
"parameter_name": "dcrResourceId"
},
{
"definition_name": "b73e81f3-6303-48ad-9822-b69fc00c15ef",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "baf19753-7502-405f-8745-370519b20483",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "c99ce9c1-ced7-4c3e-aca0-10e69ce0cb02",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "d367bd60-64ca-4364-98ea-276775bddd94",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "d389df0a-e0d7-4607-833c-75a6fdac2c2d",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "d627d7c6-ded5-481a-8f2e-7e16b1e6faf6",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "ddca0ddc-4e9d-4bbb-92a1-f7c4dd7ef7ce",
"parameter_name": "dcrResourceId"
},
{
"definition_name": "e016b22b-e0eb-436d-8fd7-160c4eaed6e2",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "ed66d4f5-8220-45dc-ab4a-20d1749c74e6",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "ee40564d-486e-4f68-a5ca-7a621edae0fb",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "ef9fe2ce-a588-4edd-829c-6247069dcfdb",
"parameter_name": "dcrResourceId"
},
{
"definition_name": "f0fcf93c-c063-4071-9668-c47474bd3564",
"parameter_name": "privateDnsZoneId"
},
{
"definition_name": "f91991d1-5383-4c95-8ee5-5ac423dd8bb1",
"parameter_name": "userAssignedIdentityResourceId"
},
{
"definition_name": "fbc14a67-53e4-4932-abcc-2049c6706009",
"parameter_name": "privateDnsZoneId"
}
]
```

### <a name="input_override_policy_definition_parameter_assign_permissions_unset"></a> [override\_policy\_definition\_parameter\_assign\_permissions\_unset](#input\_override\_policy\_definition\_parameter\_assign\_permissions\_unset)

Description: This list of objects allows you to unset the [`assignPermissions` metadata property](https://learn.microsoft.com/azure/governance/policy/concepts/definition-structure-parameters#parameter-properties) of the supplied definition and parameter names.
This allows you to correct policies that haven't been authored correctly, or prevent permissions being assigned for policies that are disabled in a policy set. The provider can then generate the correct policy role assignments.

The value is a list of objects with the following attributes:

- `definition_name` - (Required) The name of the policy definition, ***for built-in policies this us a UUID***.
- `parameter_name` - (Required) The name of the parameter to unset the assignPermissions property for.

Type:

```hcl
set(object({
definition_name = string
parameter_name = string
}))
```

Default: `null`

### <a name="input_partner_id"></a> [partner\_id](#input\_partner\_id)

Description: A value to be included in the telemetry tag. Requires the `enable_telemetry` variable to be set to `true`. The must be in the following format:
Expand Down Expand Up @@ -366,36 +595,44 @@ Type:
object({
management_groups = optional(object({
error_message_regex = optional(list(string), [
"AuthorizationFailed" # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
"AuthorizationFailed", # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
"Permission to Microsoft.Management/managementGroups on resources of type 'Write' is required on the management group or its ancestors."
])
interval_seconds = optional(number, null)
max_interval_seconds = optional(number, null)
multiplier = optional(number, null)
randomization_factor = optional(number, null)
}), {})
role_definitions = optional(object({
error_message_regex = optional(list(string), null)
error_message_regex = optional(list(string), [
"AuthorizationFailed" # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
])
interval_seconds = optional(number, null)
max_interval_seconds = optional(number, null)
multiplier = optional(number, null)
randomization_factor = optional(number, null)
}), {})
policy_definitions = optional(object({
error_message_regex = optional(list(string), null)
error_message_regex = optional(list(string), [
"AuthorizationFailed" # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
])
interval_seconds = optional(number, null)
max_interval_seconds = optional(number, null)
multiplier = optional(number, null)
randomization_factor = optional(number, null)
}), {})
policy_set_definitions = optional(object({
error_message_regex = optional(list(string), null)
error_message_regex = optional(list(string), [
"AuthorizationFailed" # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
])
interval_seconds = optional(number, null)
max_interval_seconds = optional(number, null)
multiplier = optional(number, null)
randomization_factor = optional(number, null)
}), {})
policy_assignments = optional(object({
error_message_regex = optional(list(string), [
"AuthorizationFailed", # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
"The policy definition specified in policy assignment '.+' is out of scope" # If assignment is created soon after a policy definition has been created then the assignment will fail with this error.
])
interval_seconds = optional(number, 5)
Expand All @@ -405,7 +642,8 @@ object({
}), {})
policy_role_assignments = optional(object({
error_message_regex = optional(list(string), [
"ResourceNotFound", # If the resource has just been created, retry until it is available.
"AuthorizationFailed", # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
"ResourceNotFound", # If the resource has just been created, retry until it is available.
])
interval_seconds = optional(number, null)
max_interval_seconds = optional(number, null)
Expand All @@ -420,7 +658,9 @@ object({
randomization_factor = optional(number, null)
}), {})
subscription_placement = optional(object({
error_message_regex = optional(list(string), null)
error_message_regex = optional(list(string), [
"AuthorizationFailed", # Avoids a eventual consistency issue where a recently created management group is not yet available for a GET operation.
])
interval_seconds = optional(number, null)
max_interval_seconds = optional(number, null)
multiplier = optional(number, null)
Expand Down
2 changes: 2 additions & 0 deletions examples/default/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ The following requirements are needed by this module:

- <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) (~> 1.8)

- <a name="requirement_alz"></a> [alz](#requirement\_alz) (~> 0.17)

- <a name="requirement_azapi"></a> [azapi](#requirement\_azapi) (~> 2.0, >= 2.0.1)

## Resources
Expand Down
11 changes: 11 additions & 0 deletions examples/default/terraform.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
terraform {
required_version = "~> 1.8"
required_providers {
alz = {
source = "azure/alz"
version = "~> 0.17"
}
azapi = {
source = "azure/azapi"
version = "~> 2.0, >= 2.0.1"
}
}
}

provider "alz" {
library_references = [{
path = "platform/alz"
ref = "2025.01.0"
}]
}
3 changes: 3 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ data "alz_architecture" "this" {
location = var.location
policy_assignments_to_modify = var.policy_assignments_to_modify
policy_default_values = var.policy_default_values

override_policy_definition_parameter_assign_permissions_set = var.override_policy_definition_parameter_assign_permissions_set
override_policy_definition_parameter_assign_permissions_unset = var.override_policy_definition_parameter_assign_permissions_unset
}
4 changes: 2 additions & 2 deletions terraform.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ terraform {
required_providers {
alz = {
source = "azure/alz"
version = "~> 0.16, >= 0.16.2"
version = "~> 0.17"
}
azapi = {
source = "azure/azapi"
version = "~> 2.0, >= 2.2"
version = "~> 2.2"
}
modtm = {
source = "azure/modtm"
Expand Down
Loading

0 comments on commit 182c20a

Please sign in to comment.