Skip to content

Commit

Permalink
[FAST] Add basic NGFW enterprise stage (#2410)
Browse files Browse the repository at this point in the history
  • Loading branch information
LucaPrete authored Aug 1, 2024
1 parent 1d508d2 commit 80f9ce6
Show file tree
Hide file tree
Showing 53 changed files with 1,119 additions and 125 deletions.
15 changes: 15 additions & 0 deletions fast/stage-links.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ case $STAGE_NAME in
tenants/$TENANT/tfvars/1-resman.auto.tfvars.json"
fi
;;
"3-network-security"*)
if [[ -z "$TENANT" ]]; then
echo "# if this is a tenant stage, set a \$TENANT variable with the tenant shortname and run the command again"
PROVIDER="providers/3-netsec-providers.tf"
TFVARS="tfvars/0-bootstrap.auto.tfvars.json
tfvars/1-resman.auto.tfvars.json
tfvars/2-networking.auto.tfvars.json"
else
unset GLOBALS
PROVIDER="tenants/$TENANT/providers/3-netsec-providers.tf"
TFVARS="tenants/$TENANT/tfvars/0-bootstrap-tenant.auto.tfvars.json
tenants/$TENANT/tfvars/1-resman.auto.tfvars.json
tenants/$TENANT/tfvars/2-networking.auto.tfvars.json"
fi
;;
*)
# check for a "dev" stage 3
echo "no stage found, trying for parent stage 3..."
Expand Down
1 change: 1 addition & 0 deletions fast/stages/0-bootstrap/automation.tf
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ module "automation-project" {
"essentialcontacts.googleapis.com",
"iam.googleapis.com",
"iamcredentials.googleapis.com",
"networksecurity.googleapis.com",
"orgpolicy.googleapis.com",
"pubsub.googleapis.com",
"servicenetworking.googleapis.com",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 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.

name: networkFirewallPoliciesAdmin
includedPermissions:
- compute.networks.setFirewallPolicy
- networksecurity.firewallEndpointAssociations.create
- networksecurity.firewallEndpointAssociations.delete
- networksecurity.firewallEndpointAssociations.get
- networksecurity.firewallEndpointAssociations.list
- networksecurity.firewallEndpointAssociations.update
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 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.

name: ngfwEnterpriseAdmin
includedPermissions:
- networksecurity.firewallEndpoints.create
- networksecurity.firewallEndpoints.delete
- networksecurity.firewallEndpoints.get
- networksecurity.firewallEndpoints.list
- networksecurity.firewallEndpoints.update
- networksecurity.firewallEndpoints.use
- networksecurity.locations.get
- networksecurity.locations.list
- networksecurity.operations.cancel
- networksecurity.operations.delete
- networksecurity.operations.get
- networksecurity.operations.list
- networksecurity.securityProfileGroups.create
- networksecurity.securityProfileGroups.delete
- networksecurity.securityProfileGroups.get
- networksecurity.securityProfileGroups.list
- networksecurity.securityProfileGroups.update
- networksecurity.securityProfileGroups.use
- networksecurity.securityProfiles.create
- networksecurity.securityProfiles.delete
- networksecurity.securityProfiles.get
- networksecurity.securityProfiles.list
- networksecurity.securityProfiles.update
- networksecurity.securityProfiles.use
2 changes: 1 addition & 1 deletion fast/stages/0-bootstrap/organization-iam.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* 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.
Expand Down
39 changes: 26 additions & 13 deletions fast/stages/0-bootstrap/organization.tf
Original file line number Diff line number Diff line change
Expand Up @@ -163,23 +163,36 @@ module "organization" {
# delegated role grant for resource manager service account
iam_bindings = merge(
{
organization_ngfw_enterprise_admin = {
members = [local.principals.gcp-network-admins]
role = module.organization.custom_role_id["ngfw_enterprise_admin"]
}
organization_iam_admin_conditional = {
members = [module.automation-tf-resman-sa.iam_email]
role = module.organization.custom_role_id["organization_iam_admin"]
condition = {
expression = format(
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])",
join(",", formatlist("'%s'", [
"roles/accesscontextmanager.policyAdmin",
"roles/cloudasset.viewer",
"roles/compute.orgFirewallPolicyAdmin",
"roles/compute.xpnAdmin",
"roles/orgpolicy.policyAdmin",
"roles/orgpolicy.policyViewer",
"roles/resourcemanager.organizationViewer",
module.organization.custom_role_id["service_project_network_admin"],
module.organization.custom_role_id["tenant_network_admin"],
]))
expression = (
format(
<<-EOT
api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])
|| api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly([%s])
EOT
, join(",", formatlist("'%s'", [
"roles/accesscontextmanager.policyAdmin",
"roles/cloudasset.viewer",
"roles/compute.orgFirewallPolicyAdmin",
"roles/compute.xpnAdmin",
"roles/orgpolicy.policyAdmin",
"roles/orgpolicy.policyViewer",
"roles/resourcemanager.organizationViewer"
]))
, join(",", formatlist("'%s'", [
module.organization.custom_role_id["network_firewall_policies_admin"],
module.organization.custom_role_id["ngfw_enterprise_admin"],
module.organization.custom_role_id["service_project_network_admin"],
module.organization.custom_role_id["tenant_network_admin"]
]))
)
)
title = "automation_sa_delegated_grants"
description = "Automation service account delegated grants."
Expand Down
54 changes: 28 additions & 26 deletions fast/stages/1-resman/README.md

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions fast/stages/1-resman/branch-netsec.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* 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.
*/

# tfdoc:file:description Network security stage resources.

# automation service account

module "branch-netsec-sa" {
source = "../../../modules/iam-service-account"
project_id = var.automation.project_id
name = "prod-resman-netsec-0"
display_name = "Terraform resman network security service account."
prefix = var.prefix
service_account_create = var.root_node == null
iam = {
"roles/iam.serviceAccountTokenCreator" = compact([
try(module.branch-netsec-sa-cicd[0].iam_email, null)
])
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectAdmin"]
}
}

# automation read-only service account

module "branch-netsec-r-sa" {
source = "../../../modules/iam-service-account"
project_id = var.automation.project_id
name = "prod-resman-netsec-0r"
display_name = "Terraform resman network security service account (read-only)."
prefix = var.prefix
iam = {
"roles/iam.serviceAccountTokenCreator" = compact([
try(module.branch-netsec-r-sa-cicd[0].iam_email, null)
])
}
iam_project_roles = {
(var.automation.project_id) = ["roles/serviceusage.serviceUsageConsumer"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = [var.custom_roles["storage_viewer"]]
}
}

# automation bucket

module "branch-netsec-gcs" {
source = "../../../modules/gcs"
project_id = var.automation.project_id
name = "prod-resman-netsec-0"
prefix = var.prefix
location = var.locations.gcs
storage_class = local.gcs_storage_class
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-netsec-sa.iam_email]
"roles/storage.objectViewer" = [module.branch-netsec-r-sa.iam_email]
}
}
3 changes: 3 additions & 0 deletions fast/stages/1-resman/branch-networking.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ locals {
# read-only (plan) automation service account
"roles/viewer" = [module.branch-network-r-sa.iam_email]
"roles/resourcemanager.folderViewer" = [module.branch-network-r-sa.iam_email]
# netsec service account
"roles/serviceusage.serviceUsageAdmin" = [module.branch-netsec-sa.iam_email]
(var.custom_roles["network_firewall_policies_admin"]) = [module.branch-netsec-sa.iam_email]
}
# deep-merge FAST-specific IAM with user-provided bindings in var.folder_iam
_network_folder_iam = merge(
Expand Down
85 changes: 85 additions & 0 deletions fast/stages/1-resman/cicd-netsec.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* 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.
*/

# tfdoc:file:description CI/CD resources for the networking branch.

# read-write (apply) SA used by CI/CD workflows
# to impersonate netsec automation SA

module "branch-netsec-sa-cicd" {
source = "../../../modules/iam-service-account"
for_each = (
try(local.cicd_repositories.netsec.name, null) != null
? { 0 = local.cicd_repositories.netsec }
: {}
)
project_id = var.automation.project_id
name = "prod-resman-netsec-1"
display_name = "Terraform CI/CD stage 2 network security service account."
prefix = var.prefix
iam = {
"roles/iam.workloadIdentityUser" = [
each.value.branch == null
? format(
local.identity_providers[each.value.identity_provider].principal_repo,
var.automation.federated_identity_pool,
each.value.name
)
: format(
local.identity_providers[each.value.identity_provider].principal_branch,
var.automation.federated_identity_pool,
each.value.name,
each.value.branch
)
]
}
iam_project_roles = {
(var.automation.project_id) = ["roles/logging.logWriter"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
}
}

# read-only (plan) SA used by CI/CD workflows to impersonate netsec automation SA

module "branch-netsec-r-sa-cicd" {
source = "../../../modules/iam-service-account"
for_each = (
try(local.cicd_repositories.netsec.name, null) != null
? { 0 = local.cicd_repositories.netsec }
: {}
)
project_id = var.automation.project_id
name = "prod-resman-netsec-1r"
display_name = "Terraform CI/CD stage 2 network security service account (read-only)."
prefix = var.prefix
iam = {
"roles/iam.workloadIdentityUser" = [
format(
local.identity_providers[each.value.identity_provider].principal_repo,
var.automation.federated_identity_pool,
each.value.name
)
]
}
iam_project_roles = {
(var.automation.project_id) = ["roles/logging.logWriter"]
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.objectViewer"]
}
}
8 changes: 8 additions & 0 deletions fast/stages/1-resman/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ locals {
member = module.branch-network-sa.iam_email
role = "roles/compute.orgFirewallPolicyAdmin"
}
sa_net_netsec_fw_policy_admin = {
member = module.branch-netsec-sa.iam_email
role = "roles/compute.orgFirewallPolicyAdmin"
}
sa_net_netsec_ngfw_enterprise_admin = {
member = module.branch-netsec-sa.iam_email
role = local.custom_roles["ngfw_enterprise_admin"],
}
sa_net_xpn_admin = {
member = module.branch-network-sa.iam_email
role = "roles/compute.xpnAdmin"
Expand Down
27 changes: 26 additions & 1 deletion fast/stages/1-resman/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ locals {
}
tf_var_files = local.cicd_workflow_var_files.stage_3
}
netsec = {
service_accounts = {
apply = try(module.branch-netsec-sa-cicd[0].email, null)
plan = try(module.branch-netsec-r-sa-cicd[0].email, null)
}
tf_providers_files = {
apply = "3-netsec-providers.tf"
plan = "3-netsec-r-providers.tf"
}
tf_var_files = local.cicd_workflow_var_files.stage_3
}
networking = {
service_accounts = {
apply = try(module.branch-network-sa-cicd[0].email, null)
Expand Down Expand Up @@ -198,6 +209,18 @@ locals {
name = "security"
sa = module.branch-security-r-sa.email
})
"3-netsec" = templatefile(local._tpl_providers, {
backend_extra = null
bucket = module.branch-netsec-gcs.name
name = "netsec"
sa = module.branch-netsec-sa.email
})
"3-netsec-r" = templatefile(local._tpl_providers, {
backend_extra = null
bucket = module.branch-network-gcs.name
name = "netsec"
sa = module.branch-netsec-r-sa.email
})
},
{
for k, v in module.top-level-sa :
Expand Down Expand Up @@ -347,6 +370,8 @@ locals {
gke-dev-r = try(module.branch-gke-dev-r-sa[0].email, null)
gke-prod = try(module.branch-gke-prod-sa[0].email, null)
gke-prod-r = try(module.branch-gke-prod-r-sa[0].email, null)
netsec = module.branch-netsec-sa.email
netsec-r = module.branch-netsec-r-sa.email
networking = module.branch-network-sa.email
networking-r = module.branch-network-r-sa.email
project-factory = try(module.branch-pf-sa[0].email, null)
Expand Down Expand Up @@ -480,7 +505,7 @@ output "project_factories" {

# ready to use provider configurations for subsequent stages
output "providers" {
# tfdoc:output:consumers 02-networking 02-security 03-dataplatform
# tfdoc:output:consumers 02-networking 02-security 03-dataplatform 03-netsec
description = "Terraform provider files for this stage and dependent stages."
sensitive = true
value = local.providers
Expand Down
Loading

0 comments on commit 80f9ce6

Please sign in to comment.