12 | Click to expand!
13 |
14 |
15 | ```hcl
16 | locals {
17 | name_no_params = "example_NP_Audit"
18 | subscription_name_no_params = "example"
19 | management_group_no_params = ""
20 | enforcement_mode_no_params = false
21 | policy_ids_no_params = [
22 | # -----------------------------------------------------------------------------------------------------------------
23 | # Key Vault
24 | # -----------------------------------------------------------------------------------------------------------------
25 | "c39ba22d-4428-4149-b981-70acb31fc383", # Azure Key Vault Managed HSM should have purge protection enabled
26 | "0b60c0b2-2dc2-4e1c-b5c9-abbed971de53", # Key vaults should have purge protection enabled
27 | "1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d", # Key vaults should have soft delete enabled
28 | "55615ac9-af46-4a59-874e-391cc3dfb490", # Firewall should be enabled on Key Vault
29 | "152b15f7-8e1f-4c1f-ab71-8c010ba5dbc0", # Key Vault keys should have an expiration date
30 | "98728c90-32c7-4049-8429-847dc0f4fe37", # Key Vault secrets should have an expiration date
31 | "587c79fe-dd04-4a5e-9d0b-f89598c7261b", # Keys should be backed by a hardware security module (HSM)
32 | "5f0bc445-3935-4915-9981-011aa2b46147", # Private endpoint should be configured for Key Vault
33 | "75262d3e-ba4a-4f43-85f8-9f72c090e5e3", # Secrets should have content type set
34 |
35 | ]
36 | }
37 |
38 | # ---------------------------------------------------------------------------------------------------------------------
39 | # Azure Policy name lookups:
40 | # Because the policies are built-in, we can just look up their IDs by their names.
41 | # ---------------------------------------------------------------------------------------------------------------------
42 | data "azurerm_policy_definition" "no_params" {
43 | count = length(local.policy_ids_no_params)
44 | name = element(local.policy_ids_no_params, count.index)
45 | }
46 |
47 | locals {
48 | no_params_policy_definitions = flatten([tolist([
49 | for definition in data.azurerm_policy_definition.no_params.*.id :
50 | map("policyDefinitionId", definition)
51 | ])
52 | ])
53 | }
54 |
55 | # ---------------------------------------------------------------------------------------------------------------------
56 | # Conditional data lookups: If the user supplies management group, look up the ID of the management group
57 | # ---------------------------------------------------------------------------------------------------------------------
58 | data "azurerm_management_group" "no_params" {
59 | count = local.management_group_no_params != "" ? 1 : 0
60 | display_name = local.management_group_no_params
61 | }
62 |
63 | ### If the user supplies subscription, look up the ID of the subscription
64 | data "azurerm_subscriptions" "no_params" {
65 | count = local.subscription_name_no_params != "" ? 1 : 0
66 | display_name_contains = local.subscription_name_no_params
67 | }
68 |
69 | locals {
70 | no_params_scope = local.management_group_no_params != "" ? data.azurerm_management_group.no_params[0].id : element(data.azurerm_subscriptions.no_params[0].subscriptions.*.id, 0)
71 | }
72 |
73 | # ---------------------------------------------------------------------------------------------------------------------
74 | # Policy Initiative
75 | # ---------------------------------------------------------------------------------------------------------------------
76 | resource "azurerm_policy_set_definition" "no_params" {
77 | name = local.name_no_params
78 | policy_type = "Custom"
79 | display_name = local.name_no_params
80 | description = local.name_no_params
81 | management_group_name = local.management_group_no_params == "" ? null : local.management_group_no_params
82 | policy_definitions = tostring(jsonencode(local.no_params_policy_definitions))
83 | metadata = tostring(jsonencode({
84 | category = local.name_no_params
85 | }))
86 | }
87 |
88 | # ---------------------------------------------------------------------------------------------------------------------
89 | # Azure Policy Assignments
90 | # Apply the Policy Initiative to the specified scope
91 | # ---------------------------------------------------------------------------------------------------------------------
92 | resource "azurerm_policy_assignment" "no_params" {
93 | name = local.name_no_params
94 | policy_definition_id = azurerm_policy_set_definition.no_params.id
95 | scope = local.no_params_scope
96 | enforcement_mode = local.enforcement_mode_no_params
97 | }
98 |
99 | # ---------------------------------------------------------------------------------------------------------------------
100 | # Outputs
101 | # ---------------------------------------------------------------------------------------------------------------------
102 | output "no_params_policy_assignment_ids" {
103 | value = azurerm_policy_assignment.no_params.id
104 | description = "The IDs of the Policy Assignments."
105 | }
106 |
107 | output "no_params_scope" {
108 | value = local.no_params_scope
109 | description = "The target scope - either the management group or subscription, depending on which parameters were supplied"
110 | }
111 |
112 | output "no_params_policy_set_definition_id" {
113 | value = azurerm_policy_set_definition.no_params.id
114 | description = "The ID of the Policy Set Definition."
115 | }
116 |
117 | output "no_params_count_of_policies_applied" {
118 | description = "The number of Policies applied as part of the Policy Initiative"
119 | value = length(local.policy_ids_no_params)
120 | }
121 | ```
122 |
123 |
--------------------------------------------------------------------------------
/docs/tutorials/parameters-required.md:
--------------------------------------------------------------------------------
1 | # Advanced: Parameters Required
2 |
3 |
--------------------------------------------------------------------------------
/examples/parameters-config-example.yml:
--------------------------------------------------------------------------------
1 | # ---------------------------------------------------------------------------------------------------------------------
2 | # API Management
3 | # ---------------------------------------------------------------------------------------------------------------------
4 | API Management:
5 | API Management service should use a SKU that supports virtual networks:
6 | effect: Deny # Audit, Deny, Disabled. Default: Audit
7 | listOfAllowedSKUs: # Developer, Basic, Standard, Premium, Isolated, Consumption
8 | - Developer
9 | - Premium
10 | - Isolated
11 | # ---------------------------------------------------------------------------------------------------------------------
12 | #
13 | # ---------------------------------------------------------------------------------------------------------------------
14 | Kubernetes:
15 | Kubernetes cluster containers CPU and memory resource limits should not exceed the specified limits:
16 | effect: Audit # Audit, Deny, Disabled
17 | excludedNamespaces:
18 | - kube-system
19 | - gatekeeper-system
20 | - azure-arc
21 | namespaces: []
22 | labelSelector: {}
23 | cpuLimit: "200m"
24 | memoryLimit: "1Gi"
25 | Kubernetes cluster containers should not share host process ID or host IPC namespace:
26 | effect: Audit # Audit, Deny, Disabled
27 | excludedNamespaces:
28 | - kube-system
29 | - gatekeeper-system
30 | - azure-arc
31 | namespaces: [ ]
32 | labelSelector: {}
33 | Kubernetes cluster containers should not use forbidden sysctl interfaces:
34 | effect: Audit # Audit, Deny, Disabled
35 | excludedNamespaces:
36 | - kube-system
37 | - gatekeeper-system
38 | - azure-arc
39 | namespaces: [ ]
40 | labelSelector: {}
41 | forbiddenSysctls: [ ]
42 | # Kubernetes cluster containers should only listen on allowed ports
43 | # Kubernetes cluster containers should only use allowed AppArmor profiles
44 | # Kubernetes cluster containers should only use allowed ProcMountType
45 | # Kubernetes cluster containers should only use allowed capabilities
46 | # Kubernetes cluster containers should only use allowed images
47 | # Kubernetes cluster containers should only use allowed seccomp profiles
48 | # Kubernetes cluster containers should run with a read only root file system
49 | # Kubernetes cluster pod FlexVolume volumes should only use allowed drivers
50 | # Kubernetes cluster pod hostPath volumes should only use allowed host paths
51 | # Kubernetes cluster pods and containers should only run with approved user and group
52 | # IDs
53 | # Kubernetes cluster pods and containers should only use allowed SELinux options
54 | # Kubernetes cluster pods should only use allowed volume types
55 | # Kubernetes cluster pods should only use approved host network and port range
56 | # Kubernetes cluster pods should use specified labels
57 | # Kubernetes cluster services should listen only on allowed ports
58 | # Kubernetes cluster should not allow privileged containers
59 | # Kubernetes clusters should be accessible only over HTTPS
60 | # Kubernetes clusters should not allow container privilege escalation
61 | # Kubernetes clusters should use internal load balancers
62 | # '[Preview]: Kubernetes cluster services should only use allowed external IPs'
63 | # '[Preview]: Kubernetes clusters should disable automounting API credentials'
64 | # '[Preview]: Kubernetes clusters should not grant CAP_SYS_ADMIN security capabilities'
65 | # '[Preview]: Kubernetes clusters should not use specific security capabilities'
66 | # '[Preview]: Kubernetes clusters should not use the default namespace'
--------------------------------------------------------------------------------
/examples/terraform-demo-no-params/NP-all-table.csv:
--------------------------------------------------------------------------------
1 | Service,Policy Definition,Parameter Requirements,Audit Only,Azure Security Benchmark,CIS,CCMC L3,ISO 27001,NIST SP 800-53 R4,NIST SP 800-171 R2,HIPAA HITRUST 9.2,New Zealand ISM,Parameters,Link,ID
2 | Compute,Audit VMs that do not use managed disks,None,Yes,,7.1,,A.9.1.2,,,,,,https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Compute/VMRequireManagedDisk_Audit.json,06a78e20-9358-41c9-923c-fb736d382a4d
3 | Compute,Audit virtual machines without disaster recovery configured,None,Yes,,,,,CP-7,,1638.12b2Organizational.345 - 12.b,ESS-3,,https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Compute/RecoveryServices_DisasterRecovery_Audit.json,0015ea4d-51ff-4ce3-8d8c-f3f8f0179a56
4 | Compute,Require automatic OS image patching on Virtual Machine Scale Sets,None,No,,,,,,,,,,https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Compute/VMSSOSUpgradeHealthCheck_Deny.json,465f0161-0087-490a-9ad9-ad6217f4f43a
5 | Data Lake,Require encryption on Data Lake Store accounts,None,No,,,,,,,0304.09o3Organizational.1 - 09.o,,,https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Data%20Lake/DataLakeStoreEncryption_Deny.json,a7ff3161-0087-490a-9ad9-ad6217f4f43a
6 | General,Audit resource location matches resource group location,None,Yes,,,,,,,,,,https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/General/ResourcesInResourceGroupLocation_Audit.json,0a914e76-4921-4c19-b460-a2d36003525a
7 | Network,Gateway subnets should not be configured with a network security group,None,No,,,,,,,0894.01m2Organizational.7 - 01.m,,,https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Network/NetworkSecurityGroupOnGatewaySubnet_Deny.json,35f9c03a-cc27-418e-9c0c-539ff999d010
8 | Network,Network interfaces should disable IP forwarding,None,No,,,,,,,,,,https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Network/NetworkIPForwardingNic_Deny.json,88c0b9da-ce96-4b03-9635-f29a937e2900
9 | Network,Network interfaces should not have public IPs,None,No,,,,,,,,,,https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Network/NetworkPublicIPNic_Deny.json,83a86a26-fd1f-447c-b59d-e51f44264114
10 |
--------------------------------------------------------------------------------
/examples/terraform-demo-no-params/NP-all-table.md:
--------------------------------------------------------------------------------
1 | | Service | Policy Definition | Parameter Requirements | Audit Only | Azure Security Benchmark | CIS | CCMC L3 | ISO 27001 | NIST SP 800-171 R2 | NIST SP 800-53 R4 | HIPAA HITRUST 9.2 | New Zealand ISM | Parameters | Link | ID |
2 | |-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------|--------------|----------------------------|-------|-----------|-------------|----------------------|---------------------|------------------------------------|-------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|
3 | | Compute | [Audit VMs that do not use managed disks](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Compute/VMRequireManagedDisk_Audit.json) | None | Yes | | 7.1 | | A.9.1.2 | | | | | | https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Compute/VMRequireManagedDisk_Audit.json | 06a78e20-9358-41c9-923c-fb736d382a4d |
4 | | Compute | [Audit virtual machines without disaster recovery configured](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Compute/RecoveryServices_DisasterRecovery_Audit.json) | None | Yes | | | | | | CP-7 | 1638.12b2Organizational.345 - 12.b | ESS-3 | | https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Compute/RecoveryServices_DisasterRecovery_Audit.json | 0015ea4d-51ff-4ce3-8d8c-f3f8f0179a56 |
5 | | Compute | [Require automatic OS image patching on Virtual Machine Scale Sets](https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Compute/VMSSOSUpgradeHealthCheck_Deny.json) | None | No | | | | | | | | | | https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Compute/VMSSOSUpgradeHealthCheck_Deny.json | 465f0161-0087-490a-9ad9-ad6217f4f43a |
6 | | Data Lake | [Require encryption on Data Lake Store accounts](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Data%20Lake/DataLakeStoreEncryption_Deny.json) | None | No | | | | | | | 0304.09o3Organizational.1 - 09.o | | | https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Data%20Lake/DataLakeStoreEncryption_Deny.json | a7ff3161-0087-490a-9ad9-ad6217f4f43a |
7 | | General | [Audit resource location matches resource group location](https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/General/ResourcesInResourceGroupLocation_Audit.json) | None | Yes | | | | | | | | | | https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/General/ResourcesInResourceGroupLocation_Audit.json | 0a914e76-4921-4c19-b460-a2d36003525a |
8 | | Network | [Gateway subnets should not be configured with a network security group](https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Network/NetworkSecurityGroupOnGatewaySubnet_Deny.json) | None | No | | | | | | | 0894.01m2Organizational.7 - 01.m | | | https://github.com/Azure/azure-policy/blob/master/built-in-policies/policyDefinitions/Network/NetworkSecurityGroupOnGatewaySubnet_Deny.json | 35f9c03a-cc27-418e-9c0c-539ff999d010 |
9 | | Network | [Network interfaces should disable IP forwarding](https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Network/NetworkIPForwardingNic_Deny.json) | None | No | | | | | | | | | | https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Network/NetworkIPForwardingNic_Deny.json | 88c0b9da-ce96-4b03-9635-f29a937e2900 |
10 | | Network | [Network interfaces should not have public IPs](https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Network/NetworkPublicIPNic_Deny.json) | None | No | | | | | | | | | | https://github.com/Azure/azure-policy/tree/master/built-in-policies/policyDefinitions/Network/NetworkPublicIPNic_Deny.json | 83a86a26-fd1f-447c-b59d-e51f44264114 |
--------------------------------------------------------------------------------
/examples/terraform-demo-no-params/no_params.tf:
--------------------------------------------------------------------------------
1 | locals {
2 | name_no_params = "example_NP_Audit"
3 | subscription_name_no_params = "example"
4 | management_group_no_params = ""
5 | enforcement_mode_no_params = false
6 | policy_ids_no_params = [
7 | # -----------------------------------------------------------------------------------------------------------------
8 | # Compute
9 | # -----------------------------------------------------------------------------------------------------------------
10 | "06a78e20-9358-41c9-923c-fb736d382a4d", # Audit VMs that do not use managed disks
11 | "0015ea4d-51ff-4ce3-8d8c-f3f8f0179a56", # Audit virtual machines without disaster recovery configured
12 | "465f0161-0087-490a-9ad9-ad6217f4f43a", # Require automatic OS image patching on Virtual Machine Scale Sets
13 |
14 | # -----------------------------------------------------------------------------------------------------------------
15 | # Data Lake
16 | # -----------------------------------------------------------------------------------------------------------------
17 | "a7ff3161-0087-490a-9ad9-ad6217f4f43a", # Require encryption on Data Lake Store accounts
18 |
19 | # -----------------------------------------------------------------------------------------------------------------
20 | # General
21 | # -----------------------------------------------------------------------------------------------------------------
22 | "0a914e76-4921-4c19-b460-a2d36003525a", # Audit resource location matches resource group location
23 |
24 | # -----------------------------------------------------------------------------------------------------------------
25 | # Network
26 | # -----------------------------------------------------------------------------------------------------------------
27 | "35f9c03a-cc27-418e-9c0c-539ff999d010", # Gateway subnets should not be configured with a network security group
28 | "88c0b9da-ce96-4b03-9635-f29a937e2900", # Network interfaces should disable IP forwarding
29 | "83a86a26-fd1f-447c-b59d-e51f44264114", # Network interfaces should not have public IPs
30 |
31 | ]
32 | }
33 |
34 | # ---------------------------------------------------------------------------------------------------------------------
35 | # Azure Policy name lookups:
36 | # Because the policies are built-in, we can just look up their IDs by their names.
37 | # ---------------------------------------------------------------------------------------------------------------------
38 | data "azurerm_policy_definition" "no_params" {
39 | count = length(local.policy_ids_no_params)
40 | name = element(local.policy_ids_no_params, count.index)
41 | }
42 |
43 | locals {
44 | no_params_policy_definitions = flatten([tolist([
45 | for definition in data.azurerm_policy_definition.no_params.*.id :
46 | map("policyDefinitionId", definition)
47 | ])
48 | ])
49 | }
50 |
51 | # ---------------------------------------------------------------------------------------------------------------------
52 | # Conditional data lookups: If the user supplies management group, look up the ID of the management group
53 | # ---------------------------------------------------------------------------------------------------------------------
54 | data "azurerm_management_group" "no_params" {
55 | count = local.management_group_no_params != "" ? 1 : 0
56 | display_name = local.management_group_no_params
57 | }
58 |
59 | ### If the user supplies subscription, look up the ID of the subscription
60 | data "azurerm_subscriptions" "no_params" {
61 | count = local.subscription_name_no_params != "" ? 1 : 0
62 | display_name_contains = local.subscription_name_no_params
63 | }
64 |
65 | locals {
66 | no_params_scope = local.management_group_no_params != "" ? data.azurerm_management_group.no_params[0].id : element(data.azurerm_subscriptions.no_params[0].subscriptions.*.id, 0)
67 | }
68 |
69 | # ---------------------------------------------------------------------------------------------------------------------
70 | # Policy Initiative
71 | # ---------------------------------------------------------------------------------------------------------------------
72 | resource "azurerm_policy_set_definition" "no_params" {
73 | name = local.name_no_params
74 | policy_type = "Custom"
75 | display_name = local.name_no_params
76 | description = local.name_no_params
77 | management_group_name = local.management_group_no_params == "" ? null : local.management_group_no_params
78 | policy_definitions = tostring(jsonencode(local.no_params_policy_definitions))
79 | metadata = tostring(jsonencode({
80 | category = local.name_no_params
81 | }))
82 | }
83 |
84 | # ---------------------------------------------------------------------------------------------------------------------
85 | # Azure Policy Assignments
86 | # Apply the Policy Initiative to the specified scope
87 | # ---------------------------------------------------------------------------------------------------------------------
88 | resource "azurerm_policy_assignment" "no_params" {
89 | name = local.name_no_params
90 | policy_definition_id = azurerm_policy_set_definition.no_params.id
91 | scope = local.no_params_scope
92 | enforcement_mode = local.enforcement_mode_no_params
93 | }
94 |
95 | # ---------------------------------------------------------------------------------------------------------------------
96 | # Outputs
97 | # ---------------------------------------------------------------------------------------------------------------------
98 | output "no_params_policy_assignment_ids" {
99 | value = azurerm_policy_assignment.no_params.id
100 | description = "The IDs of the Policy Assignments."
101 | }
102 |
103 | output "no_params_scope" {
104 | value = local.no_params_scope
105 | description = "The target scope - either the management group or subscription, depending on which parameters were supplied"
106 | }
107 |
108 | output "no_params_policy_set_definition_id" {
109 | value = azurerm_policy_set_definition.no_params.id
110 | description = "The ID of the Policy Set Definition."
111 | }
112 |
113 | output "no_params_count_of_policies_applied" {
114 | description = "The number of Policies applied as part of the Policy Initiative"
115 | value = length(local.policy_ids_no_params)
116 | }
--------------------------------------------------------------------------------
/examples/terraform-demo-no-params/provider.tf:
--------------------------------------------------------------------------------
1 | provider "azurerm" {
2 | version = "=2.56.0"
3 | features {}
4 | }
--------------------------------------------------------------------------------
/examples/terraform-demo-no-params/terraform.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.12.0"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/terraform-demo-params-optional/provider.tf:
--------------------------------------------------------------------------------
1 | provider "azurerm" {
2 | version = "=2.56.0"
3 | features {}
4 | }
--------------------------------------------------------------------------------
/examples/terraform-demo-params-optional/terraform.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.12.0"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/terraform-demo-params-required/provider.tf:
--------------------------------------------------------------------------------
1 | provider "azurerm" {
2 | version = "=2.56.0"
3 | features {}
4 | }
--------------------------------------------------------------------------------
/examples/terraform-demo-params-required/terraform.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.12.0"
3 | }
4 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: Cloud Guardrails
2 | site_url: https://cloud-guardrails.readthedocs.io/
3 | repo_url: https://github.com/salesforce/cloud-guardrails/
4 | theme: material
5 | use_directory_urls: true
6 | markdown_extensions:
7 | - codehilite
8 | - tables
9 | - pymdownx.superfences
10 | - admonition
11 | - pymdownx.details
12 | plugins:
13 | - search
14 | - table-reader:
15 | data_path: "docs"
16 | - mkdocstrings:
17 | default_handler: python
18 | handlers:
19 | python:
20 | rendering:
21 | show_source: true
22 | watch:
23 | - cloud_guardrails/
24 | extra_css:
25 | - custom.css
26 |
27 | nav:
28 | - Home: 'index.md'
29 | - Installation: 'installation.md'
30 | - Cheatsheet: 'cheatsheet.md'
31 |
32 | - "