From 84be665172b21220938ee702c4654e1a0cd0a584 Mon Sep 17 00:00:00 2001 From: lcaggio Date: Tue, 17 Jan 2023 08:49:04 +0100 Subject: [PATCH] First commit. --- .../data-solutions/shielded-folder/README.md | 1 + .../data/firewall-policies/cidrs.yaml | 15 ++ .../hierarchical-policy-rules.yaml | 50 ++++++ .../data/org-policies/compute.yaml | 73 ++++++++ .../data/org-policies/iam.yaml | 12 ++ .../data/org-policies/serverless.yaml | 26 +++ .../data/org-policies/sql.yaml | 9 + .../data/org-policies/storage.yaml | 6 + .../data-solutions/shielded-folder/maint.tf | 79 +++++++++ .../shielded-folder/variables.tf | 159 ++++++++++++++++++ 10 files changed, 430 insertions(+) create mode 100644 blueprints/data-solutions/shielded-folder/README.md create mode 100644 blueprints/data-solutions/shielded-folder/data/firewall-policies/cidrs.yaml create mode 100644 blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-policy-rules.yaml create mode 100644 blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml create mode 100644 blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml create mode 100644 blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml create mode 100644 blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml create mode 100644 blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml create mode 100644 blueprints/data-solutions/shielded-folder/maint.tf create mode 100644 blueprints/data-solutions/shielded-folder/variables.tf diff --git a/blueprints/data-solutions/shielded-folder/README.md b/blueprints/data-solutions/shielded-folder/README.md new file mode 100644 index 000000000..503fa1da0 --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/README.md @@ -0,0 +1 @@ +#TODO \ No newline at end of file diff --git a/blueprints/data-solutions/shielded-folder/data/firewall-policies/cidrs.yaml b/blueprints/data-solutions/shielded-folder/data/firewall-policies/cidrs.yaml new file mode 100644 index 000000000..90dabfb6a --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/firewall-policies/cidrs.yaml @@ -0,0 +1,15 @@ +# skip boilerplate check + +healthchecks: + - 35.191.0.0/16 + - 130.211.0.0/22 + - 209.85.152.0/22 + - 209.85.204.0/22 + +rfc1918: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + +onprem_probes: + - 10.255.255.254/32 \ No newline at end of file diff --git a/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-policy-rules.yaml b/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-policy-rules.yaml new file mode 100644 index 000000000..6a3b31335 --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/firewall-policies/hierarchical-policy-rules.yaml @@ -0,0 +1,50 @@ +# skip boilerplate check + +allow-admins: + description: Access from the admin subnet to all subnets + direction: INGRESS + action: allow + priority: 1000 + ranges: + - $rfc1918 + ports: + all: [] + target_resources: null + enable_logging: false + +allow-healthchecks: + description: Enable HTTP and HTTPS healthchecks + direction: INGRESS + action: allow + priority: 1001 + ranges: + - $healthchecks + ports: + tcp: ["80", "443"] + target_resources: null + enable_logging: false + +allow-ssh-from-iap: + description: Enable SSH from IAP + direction: INGRESS + action: allow + priority: 1002 + ranges: + - 35.235.240.0/20 + ports: + tcp: ["22"] + target_resources: null + enable_logging: false + +allow-icmp: + description: Enable ICMP + direction: INGRESS + action: allow + priority: 1003 + ranges: + - 0.0.0.0/0 + ports: + icmp: [] + target_resources: null + enable_logging: false + \ No newline at end of file diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml new file mode 100644 index 000000000..0d27ac426 --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml @@ -0,0 +1,73 @@ +# skip boilerplate check +# +# sample subset of useful organization policies, edit to suit requirements + +compute.disableGuestAttributesAccess: + enforce: true + +compute.requireOsLogin: + enforce: true + +compute.restrictLoadBalancerCreationForTypes: + allow: + values: + - in:INTERNAL + +compute.skipDefaultNetworkCreation: + enforce: true + +compute.vmExternalIpAccess: + deny: + all: true + + +# compute.disableInternetNetworkEndpointGroup: +# enforce: true + +# compute.disableNestedVirtualization: +# enforce: true + +# compute.disableSerialPortAccess: +# enforce: true + +# compute.restrictCloudNATUsage: +# deny: +# all: true + +# compute.restrictDedicatedInterconnectUsage: +# deny: +# all: true + +# compute.restrictPartnerInterconnectUsage: +# deny: +# all: true + +# compute.restrictProtocolForwardingCreationForTypes: +# deny: +# all: true + +# compute.restrictSharedVpcHostProjects: +# deny: +# all: true + +# compute.restrictSharedVpcSubnetworks: +# deny: +# all: true + +# compute.restrictVpcPeering: +# deny: +# all: true + +# compute.restrictVpnPeerIPs: +# deny: +# all: true + +# compute.restrictXpnProjectLienRemoval: +# enforce: true + +# compute.setNewProjectDefaultToZonalDNSOnly: +# enforce: true + +# compute.vmCanIpForward: +# deny: +# all: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml new file mode 100644 index 000000000..4d83f827f --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml @@ -0,0 +1,12 @@ +# skip boilerplate check +# +# sample subset of useful organization policies, edit to suit requirements + +iam.automaticIamGrantsForDefaultServiceAccounts: + enforce: true + +iam.disableServiceAccountKeyCreation: + enforce: true + +iam.disableServiceAccountKeyUpload: + enforce: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml new file mode 100644 index 000000000..de62e6c70 --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml @@ -0,0 +1,26 @@ +# skip boilerplate check +# +# sample subset of useful organization policies, edit to suit requirements + +run.allowedIngress: + allow: + values: + - is:internal + +# run.allowedVPCEgress: +# allow: +# values: +# - is:private-ranges-only + +# cloudfunctions.allowedIngressSettings: +# allow: +# values: +# - is:ALLOW_INTERNAL_ONLY + +# cloudfunctions.allowedVpcConnectorEgressSettings: +# allow: +# values: +# - is:PRIVATE_RANGES_ONLY + +# cloudfunctions.requireVPCConnector: +# enforce: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml new file mode 100644 index 000000000..88b84d9d5 --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml @@ -0,0 +1,9 @@ +# skip boilerplate check +# +# sample subset of useful organization policies, edit to suit requirements + +sql.restrictAuthorizedNetworks: + enforce: true + +sql.restrictPublicIp: + enforce: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml new file mode 100644 index 000000000..6c0a673f3 --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml @@ -0,0 +1,6 @@ +# skip boilerplate check +# +# sample subset of useful organization policies, edit to suit requirements + +storage.uniformBucketLevelAccess: + enforce: true diff --git a/blueprints/data-solutions/shielded-folder/maint.tf b/blueprints/data-solutions/shielded-folder/maint.tf new file mode 100644 index 000000000..33774d43b --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/maint.tf @@ -0,0 +1,79 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# tfdoc:file:description Folder resources. + +locals { + groups = { + for k, v in var.groups : k => "${v}@${var.organization_domain}" + } + groups_iam = { + for k, v in local.groups : k => "group:${v}" + } + group_iam = { + (local.groups.data-engineers) = [ + "roles/editor", + ] + } + + vpc_sc_resources = [ + for k, v in data.google_projects.folder-projects.projects : format("projects/%s", v.number) + ] + +} + +module "folder" { + source = "../../../modules/folder" + folder_create = var.folder_create != null + parent = try(var.folder_create.parent, null) + name = try(var.folder_create.display_name, null) + id = var.folder_id + group_iam = local.group_iam + org_policies_data_path = "${var.data_dir}/org-policies" + firewall_policy_factory = { + cidr_file = "${var.data_dir}/firewall-policies/cidrs.yaml" + policy_name = "hierarchical-policy" + rules_file = "${var.data_dir}/firewall-policies/hierarchical-policy-rules.yaml" + } + #TODO logsink +} + +#TODO VPCSC +data "google_projects" "folder-projects" { + filter = "parent.id:${split("/", module.folder.id)[1]}" +} + +module "vpc-sc" { + source = "../../../modules/vpc-sc" + access_policy = var.access_policy + access_policy_create = var.access_policy_create + access_levels = var.vpc_sc_access_levels + egress_policies = var.vpc_sc_egress_policies + ingress_policies = var.vpc_sc_ingress_policies + service_perimeters_regular = { + shielded = { + status = { + access_levels = keys(var.vpc_sc_access_levels) + resources = local.vpc_sc_resources + restricted_services = var.vpc_sc_restricted_services + egress_policies = keys(var.vpc_sc_egress_policies) + ingress_policies = keys(var.vpc_sc_ingress_policies) + vpc_accessible_services = { + allowed_services = var.vpc_sc_accessible_services + enable_restriction = true + } + } + } + } +} diff --git a/blueprints/data-solutions/shielded-folder/variables.tf b/blueprints/data-solutions/shielded-folder/variables.tf new file mode 100644 index 000000000..4990abfad --- /dev/null +++ b/blueprints/data-solutions/shielded-folder/variables.tf @@ -0,0 +1,159 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# tfdoc:file:description Folder resources. + +variable "access_policy" { + description = "Access Policy name, set to null if creating one." + type = string + +} + +variable "access_policy_create" { + description = "Access Policy configuration, fill in to create. Parent is in 'organizations/123456' format." + type = object({ + parent = string + title = string + }) + default = null +} + +variable "data_dir" { + description = "Relative path for the folder storing configuration data." + type = string + default = "data" +} + +variable "folder_create" { + description = "Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format." + type = object({ + display_name = string + parent = string + }) + default = null +} + +variable "folder_id" { + description = "Folder ID in case you use folder_create=null." + type = string + default = null +} + +variable "groups" { + description = "User groups." + type = map(string) + default = { + #TODO data-analysts = "gcp-data-analysts" + data-engineers = "gcp-data-engineers" + #TODO data-security = "gcp-data-security" + } +} + +variable "organization_domain" { + description = "Organization domain." + type = string +} + +variable "vpc_sc_access_levels" { + description = "VPC SC access level definitions." + type = map(object({ + combining_function = optional(string) + conditions = optional(list(object({ + device_policy = optional(object({ + allowed_device_management_levels = optional(list(string)) + allowed_encryption_statuses = optional(list(string)) + require_admin_approval = bool + require_corp_owned = bool + require_screen_lock = optional(bool) + os_constraints = optional(list(object({ + os_type = string + minimum_version = optional(string) + require_verified_chrome_os = optional(bool) + }))) + })) + ip_subnetworks = optional(list(string), []) + members = optional(list(string), []) + negate = optional(bool) + regions = optional(list(string), []) + required_access_levels = optional(list(string), []) + })), []) + description = optional(string) + })) + default = {} + nullable = false +} + +variable "vpc_sc_accessible_services" { + description = "VPC SC accessible services." + type = list(string) + default = ["storage.googleapis.com"] +} + +variable "vpc_sc_restricted_services" { + description = "VPC SC restricted services." + type = list(string) + default = ["storage.googleapis.com"] +} + +variable "vpc_sc_egress_policies" { + description = "VPC SC egress policy defnitions." + type = map(object({ + from = object({ + identity_type = optional(string, "ANY_IDENTITY") + identities = optional(list(string)) + }) + to = object({ + operations = optional(list(object({ + method_selectors = optional(list(string)) + service_name = string + })), []) + resources = optional(list(string)) + resource_type_external = optional(bool, false) + }) + })) + default = {} + nullable = false +} + +variable "vpc_sc_ingress_policies" { + description = "VPC SC ingress policy defnitions." + type = map(object({ + from = object({ + access_levels = optional(list(string), []) + identity_type = optional(string) + identities = optional(list(string)) + resources = optional(list(string), []) + }) + to = object({ + operations = optional(list(object({ + method_selectors = optional(list(string)) + service_name = string + })), []) + resources = optional(list(string)) + }) + })) + default = {} + nullable = false +} + +variable "vpc_sc_perimeters" { + description = "VPC SC regular perimeter definitions for shielded folder. All projects in the perimeter will be added." + type = object({ + access_levels = optional(list(string), []) + egress_policies = optional(list(string), []) + ingress_policies = optional(list(string), []) + }) + default = {} + nullable = false +}