Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions infrastructure/modules/policy/policy-assignments/main.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Configure a policy assignment for a specific resource
resource "azurerm_resource_policy_assignment" "res_assignment" {
count = var.resource_id != "" && local.resource_id_type == "resource" ? 1 : 0
count = var.resource_id != null && local.resource_id_type == "resource" ? 1 : 0

name = var.assignment_name
resource_id = var.resource_id
Expand All @@ -19,7 +19,7 @@ resource "azurerm_resource_policy_assignment" "res_assignment" {

# Configure a policy assignment for a specific resource group
resource "azurerm_resource_group_policy_assignment" "rg_assignment" {
count = var.resource_id != "" && local.resource_id_type == "resource-group" ? 1 : 0
count = var.resource_id != null && local.resource_id_type == "resource-group" ? 1 : 0

name = var.assignment_name
resource_group_id = var.resource_id
Expand All @@ -38,14 +38,16 @@ resource "azurerm_resource_group_policy_assignment" "rg_assignment" {

# Configure a policy assignment for a specific resource group
resource "azurerm_subscription_policy_assignment" "sub_assignment" {
count = var.resource_id != "" && local.resource_id_type == "subscription" ? 1 : 0
count = var.resource_id != null && local.resource_id_type == "subscription" ? 1 : 0

name = var.assignment_name
subscription_id = var.resource_id
policy_definition_id = var.policy_definition_id
enforce = var.enforce_policy
location = var.policy_location

parameters = var.parameters != null ? jsonencode(var.parameters) : null

dynamic "identity" {
for_each = var.requires_identity ? [1] : []
content {
Expand All @@ -59,7 +61,7 @@ resource "azurerm_role_assignment" "role" {
count = var.create_remediator_role ? 1 : 0

scope = var.policy_assignment_scope
principal_id = var.policy_assignment_principal_id
principal_id = var.policy_assignment_principal_id != null ? var.policy_assignment_principal_id : local.principal_id
role_definition_name = "Resource Policy Contributor"

condition = <<EOT
Expand All @@ -81,11 +83,14 @@ resource "azurerm_role_assignment" "role" {

# Configure diagnostic settings for the resource (group) policy assignment
module "policy_assignment_logs" {
count = local.resource_id_type != "subscription" ? 1 : 0

source = "../../diagnostic-settings"
name = "policy-logs"
target_resource_id = local.assignment_id
log_analytics_workspace_id = var.log_analytics_wks_id
enabled_log = var.enabled_log
enabled_metric = var.enabled_metric
}

locals {
Expand Down
157 changes: 157 additions & 0 deletions infrastructure/modules/policy/policy-assignments/tfdocs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Module documentation

## Required Inputs

The following input variables are required:

### <a name="input_assignment_name"></a> [assignment\_name](#input\_assignment\_name)

Description: A short name for this policy assignment

Type: `string`

### <a name="input_display_name"></a> [display\_name](#input\_display\_name)

Description: Policy assignment display name.

Type: `string`

### <a name="input_policy_assignment_scope"></a> [policy\_assignment\_scope](#input\_policy\_assignment\_scope)

Description: The scope at which this assignment is assigned

Type: `string`

### <a name="input_policy_definition_id"></a> [policy\_definition\_id](#input\_policy\_definition\_id)

Description: An identifier of a policy definition to assign.

Type: `string`

## Optional Inputs

The following input variables are optional (have default values):

### <a name="input_create_remediator_role"></a> [create\_remediator\_role](#input\_create\_remediator\_role)

Description: True to create an associated Policy Contributor role, false otherwise

Type: `bool`

Default: `false`

### <a name="input_description"></a> [description](#input\_description)

Description: Description of the policy assignment.

Type: `string`

Default: `""`

### <a name="input_enabled_log"></a> [enabled\_log](#input\_enabled\_log)

Description: Collection of logs to capture

Type: `list(string)`

Default: `[]`

### <a name="input_enabled_metric"></a> [enabled\_metric](#input\_enabled\_metric)

Description: Collection of metrics to capture

Type: `list(string)`

Default: `[]`

### <a name="input_enforce_policy"></a> [enforce\_policy](#input\_enforce\_policy)

Description: True if this policy should be enforced, false otherwise

Type: `bool`

Default: `true`

### <a name="input_log_analytics_wks_id"></a> [log\_analytics\_wks\_id](#input\_log\_analytics\_wks\_id)

Description: An identifier of a specific Log Analytics Workspace instance to use

Type: `string`

Default: `null`

### <a name="input_parameters"></a> [parameters](#input\_parameters)

Description: Parameters for the policy assignment.

Type: `map(any)`

Default: `{}`

### <a name="input_policy_assignment_principal_id"></a> [policy\_assignment\_principal\_id](#input\_policy\_assignment\_principal\_id)

Description: The identifier of a specific service principal to use for the policy assignment

Type: `string`

Default: `null`

### <a name="input_policy_identities"></a> [policy\_identities](#input\_policy\_identities)

Description: A collection of principal identifiers assigned to this policy. Only required if the identity type is 'UserAssigned'

Type: `list(string)`

Default: `[]`

### <a name="input_policy_location"></a> [policy\_location](#input\_policy\_location)

Description: Defines where the policy will be deployed to. Required if identify is provided.

Type: `string`

Default: `"uksouth"`

### <a name="input_requires_identity"></a> [requires\_identity](#input\_requires\_identity)

Description: True if the policy requires a managed identity, false otherwise

Type: `bool`

Default: `false`

### <a name="input_resource_id"></a> [resource\_id](#input\_resource\_id)

Description: An identifier of a specific resource to apply this policy onto

Type: `string`

Default: `null`
## Modules

The following Modules are called:

### <a name="module_policy_assignment_logs"></a> [policy\_assignment\_logs](#module\_policy\_assignment\_logs)

Source: ../../diagnostic-settings

Version:
## Outputs

The following outputs are exported:

### <a name="output_policy_assignment_id"></a> [policy\_assignment\_id](#output\_policy\_assignment\_id)

Description: ID of the policy assignment.

### <a name="output_policy_principal_id"></a> [policy\_principal\_id](#output\_policy\_principal\_id)

Description: Principal ID of the system-assigned identity (if created)
## Resources

The following resources are used by this module:

- [azurerm_resource_group_policy_assignment.rg_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group_policy_assignment) (resource)
- [azurerm_resource_policy_assignment.res_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_policy_assignment) (resource)
- [azurerm_role_assignment.role](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
- [azurerm_subscription_policy_assignment.sub_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subscription_policy_assignment) (resource)
10 changes: 7 additions & 3 deletions infrastructure/modules/policy/policy-assignments/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ variable "enabled_log" {
default = []
}

variable "enabled_metric" {
type = list(string)
description = "Collection of metrics to capture"
default = []
}

variable "log_analytics_wks_id" {
type = string
description = "An identifier of a specific Log Analytics Workspace instance to use"
Expand All @@ -49,7 +55,6 @@ variable "parameters" {
description = "Parameters for the policy assignment."
}


variable "policy_assignment_scope" {
type = string
description = "The scope at which this assignment is assigned"
Expand All @@ -58,6 +63,7 @@ variable "policy_assignment_scope" {
variable "policy_assignment_principal_id" {
type = string
description = "The identifier of a specific service principal to use for the policy assignment"
default = null
}

variable "policy_identities" {
Expand Down Expand Up @@ -87,5 +93,3 @@ variable "requires_identity" {
description = "True if the policy requires a managed identity, false otherwise"
default = false
}


5 changes: 2 additions & 3 deletions infrastructure/modules/policy/policy-definition/main.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
resource "azurerm_policy_definition" "item" {
resource "azurerm_policy_definition" "definition" {
name = var.name
policy_type = coalesce(var.policy_type, "custom")
mode = coalesce(var.mode, "all")
Expand All @@ -10,11 +10,10 @@ resource "azurerm_policy_definition" "item" {
"owner" : "security-team@nhs.net"
},
var.metadata)))
parameters = try(length(var.parameters) > 0 ? jsonencode(var.parameters) : null, null)
parameters = var.parameters != null ? jsonencode(var.parameters) : null
policy_rule = jsonencode(var.policy_rule)
}

locals {
requires_identity = contains(["deployIfNotExists", "modify", "append"], var.policy_rule.then.effect)
}

2 changes: 1 addition & 1 deletion infrastructure/modules/policy/policy-definition/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
output "policy_definition_id" {
value = azurerm_policy_definition.item.id
value = azurerm_policy_definition.definition.id
description = "The ID of the created policy definition."
}

Expand Down
103 changes: 103 additions & 0 deletions infrastructure/modules/policy/policy-definition/tfdocs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Module documentation

## Required Inputs

The following input variables are required:

### <a name="input_display_name"></a> [display\_name](#input\_display\_name)

Description: Display name for the policy.

Type: `string`

### <a name="input_name"></a> [name](#input\_name)

Description: Policy definition name.

Type: `string`

### <a name="input_policy_rule"></a> [policy\_rule](#input\_policy\_rule)

Description: Azure Policy Rule object. Must follow Microsoft schema:
{
"if": {
<condition> | <logical operator> | nested conditions
},
"then": {
"effect": "deny | audit | modify | denyAction | append | auditIfNotExists | deployIfNotExists | disabled"
"details": <policy details>
}
}

Type:

```hcl
object({
if = any
then = object({
effect = string
details = optional(any)
})
})
```

## Optional Inputs

The following input variables are optional (have default values):

### <a name="input_description"></a> [description](#input\_description)

Description: Description of the policy.

Type: `string`

Default: `""`

### <a name="input_metadata"></a> [metadata](#input\_metadata)

Description: Metadata for the policy.

Type: `map(any)`

Default: `{}`

### <a name="input_mode"></a> [mode](#input\_mode)

Description: Determines which resource types are evaluated for a policy definition

Type: `string`

Default: `"All"`

### <a name="input_parameters"></a> [parameters](#input\_parameters)

Description: Policy parameters.

Type: `map(any)`

Default: `{}`

### <a name="input_policy_type"></a> [policy\_type](#input\_policy\_type)

Description: Type of policy.

Type: `string`

Default: `"Custom"`

## Outputs

The following outputs are exported:

### <a name="output_policy_definition_id"></a> [policy\_definition\_id](#output\_policy\_definition\_id)

Description: The ID of the created policy definition.

### <a name="output_policy_requires_identity"></a> [policy\_requires\_identity](#output\_policy\_requires\_identity)

Description: True if this policy must be assigned a managed identity, false otherwise
## Resources

The following resources are used by this module:

- [azurerm_policy_definition.definition](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/policy_definition) (resource)
Loading