Skip to content

Commit

Permalink
feat: new org policies (#791)
Browse files Browse the repository at this point in the history
* new org policies

* inverting the logic for os login constraint enablement

* removing unnecessary commnets

* Adjusting org policiest location on file definition + other small changes

* Adding dynamic allow list length to restricted contacts

* Changing essential contacts to use email domains

* Removing wrong default value for essential contacts

* APplying missing generate docs

* removing the need to ask the user to put "@" in front of essential contacts

* fixing wrong local placement

* wrong locals typing

* Adding list of boolean type policy orgs

* removing flag for enable os login constraint

* changing org policies local var from map to set
  • Loading branch information
mauro-cit committed Sep 9, 2022
1 parent c6f12e2 commit 878da45
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 118 deletions.
4 changes: 0 additions & 4 deletions 1-org/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ You can change the filters & sinks by modifying the configuration in `envs/share

**Note:** Currently, this module does not enable [bucket policy retention](https://cloud.google.com/storage/docs/bucket-lock) for organization logs, please, enable it if needed.

**Note:** It is possible to enable an organization policy for [OS Login](https://cloud.google.com/compute/docs/oslogin/manage-oslogin-in-an-org) with this module.
OS Login has some [limitations](https://cloud.google.com/compute/docs/instances/managing-instance-access#limitations).
If those limitations do not apply to your workload/environment, you can choose to enable the OS Login policy by setting variable `enable_os_login_policy` to `true`.

**Note:** You need to set variable `enable_hub_and_spoke` to `true` to be able to use the **Hub-and-Spoke** architecture detailed in the **Networking** section of the [Google Cloud security foundations guide](https://cloud.google.com/architecture/security-foundations/networking#hub-and-spoke).

**Note:** If you are using MacOS, replace `cp -RT` with `cp -R` in the relevant
Expand Down
2 changes: 1 addition & 1 deletion 1-org/envs/shared/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
| dns\_hub\_project\_budget\_amount | The amount to use as the budget for the DNS hub project. | `number` | `1000` | no |
| domains\_to\_allow | The list of domains to allow users from in IAM. Used by Domain Restricted Sharing Organization Policy. Must include the domain of the organization you are deploying the foundation. To add other domains you must also grant access to these domains to the terraform service account used in the deploy. | `list(string)` | n/a | yes |
| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no |
| enable\_os\_login\_policy | Enable OS Login Organization Policy. | `bool` | `false` | no |
| essential\_contacts\_domains\_to\_allow | The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes |
| essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no |
| gcp\_audit\_viewer | Google Workspace or Cloud Identity group that members are part of an audit team and view audit logs in the logging project. | `string` | `null` | no |
| gcp\_billing\_admin\_user | Identity that has billing administrator permissions. | `string` | `null` | no |
Expand Down
153 changes: 46 additions & 107 deletions 1-org/envs/shared/org_policy.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,42 @@ locals {
organization_id = local.parent_folder != "" ? null : local.org_id
folder_id = local.parent_folder != "" ? local.parent_folder : null
policy_for = local.parent_folder != "" ? "folder" : "organization"
essential_contacts_domains_to_allow = concat(
[for domain in var.essential_contacts_domains_to_allow : "${domain}" if can(regex("^@.*$", domain)) == true],
[for domain in var.essential_contacts_domains_to_allow : "@${domain}" if can(regex("^@.*$", domain)) == false]
)
boolean_type_organization_policies = toset([
"compute.disableNestedVirtualization",
"compute.disableSerialPortAccess",
"compute.disableGuestAttributesAccess",
"compute.skipDefaultNetworkCreation",
"compute.restrictXpnProjectLienRemoval",
"compute.disableVpcExternalIpv6",
"compute.setNewProjectDefaultToZonalDNSOnly",
"compute.requireOsLogin",
"sql.restrictPublicIp",
"iam.disableServiceAccountKeyCreation",
"iam.automaticIamGrantsForDefaultServiceAccounts",
"iam.disableServiceAccountKeyUpload",
"storage.uniformBucketLevelAccess"
])
}


/******************************************
Compute org policies
*******************************************/

module "org_disable_nested_virtualization" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/compute.disableNestedVirtualization"
}

module "org_disable_serial_port_access" {
module "organization_policies_type_boolean" {
for_each = local.boolean_type_organization_policies
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/compute.disableSerialPortAccess"
constraint = "constraints/${each.value}"
}

module "org_compute_disable_guest_attributes_access" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/compute.disableGuestAttributesAccess"
}
/******************************************
Compute org policies
*******************************************/

module "org_vm_external_ip_access" {
source = "terraform-google-modules/org-policy/google"
Expand All @@ -69,53 +66,16 @@ module "org_vm_external_ip_access" {
constraint = "constraints/compute.vmExternalIpAccess"
}

module "org_skip_default_network" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/compute.skipDefaultNetworkCreation"
}

module "org_shared_vpc_lien_removal" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/compute.restrictXpnProjectLienRemoval"
}

module "org_shared_require_os_login" {
source = "terraform-google-modules/org-policy/google"
count = var.enable_os_login_policy ? 1 : 0
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/compute.requireOsLogin"
}

/******************************************
Cloud SQL
*******************************************/

module "org_cloudsql_external_ip_access" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/sql.restrictPublicIp"
module "restrict_protocol_fowarding" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "list"
allow = ["INTERNAL"]
allow_list_length = 1
constraint = "constraints/compute.restrictProtocolForwardingCreationForTypes"
}

/******************************************
Expand All @@ -131,41 +91,20 @@ module "org_domain_restricted_sharing" {
domains_to_allow = var.domains_to_allow
}

module "org_disable_sa_key_creation" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/iam.disableServiceAccountKeyCreation"
}

module "org_disable_automatic_iam_grants_on_default_service_accounts" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/iam.automaticIamGrantsForDefaultServiceAccounts"
}

/******************************************
Storage
Essential Contacts
*******************************************/

module "org_enforce_bucket_level_access" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "boolean"
enforce = "true"
constraint = "constraints/storage.uniformBucketLevelAccess"
module "domain_restricted_contacts" {
source = "terraform-google-modules/org-policy/google"
version = "~> 5.1"
organization_id = local.organization_id
folder_id = local.folder_id
policy_for = local.policy_for
policy_type = "list"
allow_list_length = length(local.essential_contacts_domains_to_allow)
allow = local.essential_contacts_domains_to_allow
constraint = "constraints/essentialcontacts.allowedContactDomains"
}

/******************************************
Expand Down
2 changes: 2 additions & 0 deletions 1-org/envs/shared/terraform.example.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
// Must include the domain of the organization you are deploying the foundation.
domains_to_allow = ["example.com"]

essential_contacts_domains_to_allow = ["@example.com"]

group_org_admins = "gcp-organization-admins@example.com"

group_billing_admins = "gcp-billing-admins@example.com"
Expand Down
11 changes: 5 additions & 6 deletions 1-org/envs/shared/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ variable "domains_to_allow" {
type = list(string)
}

variable "enable_os_login_policy" {
description = "Enable OS Login Organization Policy."
type = bool
default = false
}

variable "audit_logs_table_expiration_days" {
description = "Period before tables expire for all audit logs in milliseconds. Default is 30 days."
type = number
Expand Down Expand Up @@ -323,3 +317,8 @@ variable "backend_bucket" {
description = "Backend bucket to load remote state information from previous steps."
type = string
}

variable "essential_contacts_domains_to_allow" {
description = "The list of domains that email addresses added to Essential Contacts can have."
type = list(string)
}
4 changes: 4 additions & 0 deletions test/setup/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ output "domains_to_allow" {
value = tolist([var.domain_to_allow])
}

output "essential_contacts_domains_to_allow" {
value = tolist(["@${var.domain_to_allow}"])
}

output "target_name_server_addresses" {
value = ["192.168.0.1", "192.168.0.2"]
}
Expand Down

0 comments on commit 878da45

Please sign in to comment.