4-appfactory/modules/app-group-baseline/service_perimeter.tf (313 lines of code) (raw):
/**
* Copyright 2024 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
*
* http://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.
*/
locals {
infra_projects = [for key, value in module.app_infra_project : value.project_id]
hpc_specific_applications = ["hpc-team-a", "hpc-team-b"]
}
###############################################
# EGRESS POLICIES #
###############################################
resource "google_access_context_manager_service_perimeter_egress_policy" "secret_manager_egress_policy" {
count = var.service_perimeter_mode == "ENFORCE" && var.service_perimeter_name != null && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Secret Manager Egress from ${data.google_project.admin_project.project_id} to ${local.secret_project_number}"
egress_from {
identities = ["serviceAccount:service-${data.google_project.admin_project.number}@gcp-sa-cloudbuild.iam.gserviceaccount.com"]
}
egress_to {
resources = ["projects/${local.secret_project_number}"]
operations {
service_name = "secretmanager.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
}
resource "google_access_context_manager_service_perimeter_dry_run_egress_policy" "secret_manager_egress_policy" {
count = var.service_perimeter_mode == "DRY_RUN" && var.service_perimeter_name != null && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Secret Manager Egress from ${data.google_project.admin_project.project_id} to ${local.secret_project_number}"
egress_from {
identities = ["serviceAccount:service-${module.app_admin_project[0].project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com"]
}
egress_to {
resources = ["projects/${local.secret_project_number}"]
operations {
service_name = "secretmanager.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
}
resource "google_access_context_manager_service_perimeter_egress_policy" "cloudbuild_egress_policy" {
count = var.service_perimeter_mode == "ENFORCE" && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Egress from ${data.google_project.admin_project.project_id} to ${data.google_project.workerpool_project.project_id}"
egress_from {
identity_type = "ANY_IDENTITY"
sources {
resource = "projects/${data.google_project.admin_project.number}"
}
source_restriction = "SOURCE_RESTRICTION_ENABLED"
}
egress_to {
resources = ["projects/${data.google_project.workerpool_project.number}"]
operations {
service_name = "cloudbuild.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "clouddeploy.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "logging.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
}
resource "google_access_context_manager_service_perimeter_dry_run_egress_policy" "cloudbuild_egress_policy" {
count = var.service_perimeter_mode == "DRY_RUN" && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Egress from ${data.google_project.admin_project.project_id} to ${data.google_project.workerpool_project.project_id}"
egress_from {
identity_type = "ANY_IDENTITY"
sources {
resource = "projects/${data.google_project.admin_project.number}"
}
source_restriction = "SOURCE_RESTRICTION_ENABLED"
}
egress_to {
resources = ["projects/${data.google_project.workerpool_project.number}"]
operations {
service_name = "cloudbuild.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "clouddeploy.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "logging.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
}
resource "google_access_context_manager_service_perimeter_egress_policy" "clouddeploy_egress_policy" {
count = var.service_perimeter_mode == "ENFORCE" && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Cloud Deploy from ${data.google_project.admin_project.project_id} to ${data.google_project.workerpool_project.project_id}"
egress_from {
identity_type = "ANY_IDENTITY"
dynamic "sources" {
for_each = data.google_project.clusters_projects
content {
resource = "projects/${sources.value.number}"
}
}
source_restriction = "SOURCE_RESTRICTION_ENABLED"
}
egress_to {
resources = ["projects/${data.google_project.workerpool_project.number}"]
operations {
service_name = "clouddeploy.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
}
resource "google_access_context_manager_service_perimeter_egress_policy" "clouddeploy_egress_policy_to_gke_cluster" {
count = var.service_perimeter_mode == "ENFORCE" && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Cloud Deploy from ${data.google_project.admin_project.project_id} to GKE Cluster Projects"
egress_from {
identity_type = "ANY_IDENTITY"
}
egress_to {
resources = [for project in data.google_project.clusters_projects : "projects/${project.number}"]
operations {
service_name = "clouddeploy.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
}
resource "google_access_context_manager_service_perimeter_egress_policy" "service_directory_policy" {
count = var.service_perimeter_mode == "ENFORCE" && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Allow Service Directory from ${data.google_project.admin_project.project_id} to ${data.google_project.workerpool_project.project_id}"
egress_from {
identity_type = "ANY_IDENTITY"
sources {
resource = "projects/${data.google_project.admin_project.number}"
}
source_restriction = "SOURCE_RESTRICTION_ENABLED"
}
egress_to {
resources = ["projects/${data.google_project.workerpool_project.number}"]
operations {
service_name = "servicedirectory.googleapis.com"
method_selectors {
method = "*"
}
}
}
}
resource "google_access_context_manager_service_perimeter_dry_run_egress_policy" "clouddeploy_egress_policy" {
count = var.service_perimeter_mode == "DRY_RUN" && var.create_admin_project ? 1 : 0
perimeter = var.service_perimeter_name
title = "Cloud Deploy Egress from ${join(", ", var.cluster_projects_ids)} to ${data.google_project.workerpool_project.project_id}"
egress_from {
identity_type = "ANY_IDENTITY"
dynamic "sources" {
for_each = data.google_project.clusters_projects
content {
resource = "projects/${sources.value.number}"
}
}
source_restriction = "SOURCE_RESTRICTION_ENABLED"
}
egress_to {
resources = ["projects/${data.google_project.workerpool_project.number}"]
operations {
service_name = "clouddeploy.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
}
resource "google_access_context_manager_service_perimeter_egress_policy" "hpc_allow_infra_projects_to_use_workerpool" {
// Create egress policy only if it is an HPC application (as defined in 'hpc_specific_applications')
count = var.service_perimeter_mode == "ENFORCE" && contains(local.hpc_specific_applications, var.service_name) ? 1 : 0
perimeter = var.service_perimeter_name
title = "HPC - Allow from [${join(", ", local.infra_projects)}] to ${data.google_project.workerpool_project.project_id}"
egress_from {
identity_type = "ANY_IDENTITY"
dynamic "sources" {
for_each = module.app_infra_project
content {
resource = "projects/${sources.value.project_number}"
}
}
source_restriction = "SOURCE_RESTRICTION_ENABLED"
}
egress_to {
resources = ["projects/${data.google_project.workerpool_project.number}"]
operations {
service_name = "cloudbuild.googleapis.com"
method_selectors {
method = "*"
}
}
}
}
###############################################
# INGRESS POLICIES #
###############################################
# This ingress policy configures the necessary permissions for Cloud Deploy and Worker Pool to deploy the workload on the GKE cluster project
resource "google_access_context_manager_service_perimeter_ingress_policy" "ingress_policy" {
count = var.service_perimeter_mode == "ENFORCE" ? 1 : 0
perimeter = var.service_perimeter_name
title = "Ingress from [${data.google_project.admin_project.project_id}, ${data.google_project.workerpool_project.project_id}] to Deployment API's"
ingress_from {
identity_type = "ANY_IDENTITY"
sources {
resource = "projects/${data.google_project.admin_project.number}"
}
sources {
resource = "projects/${data.google_project.workerpool_project.number}"
}
}
ingress_to {
resources = ["*"]
operations {
service_name = "logging.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "artifactregistry.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "storage.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "clouddeploy.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "gkehub.googleapis.com"
method_selectors {
method = "*"
}
}
operations {
service_name = "connectgateway.googleapis.com"
method_selectors {
method = "*"
}
}
}
lifecycle {
create_before_destroy = true
}
depends_on = [google_access_context_manager_service_perimeter_egress_policy.service_directory_policy]
}
resource "google_access_context_manager_access_level_condition" "access-level-conditions" {
count = var.access_level_name != null ? 1 : 0
access_level = var.access_level_name
members = ["serviceAccount:${reverse(split("/", module.tf_cloudbuild_workspace.cloudbuild_sa))[0]}"]
}