Files
hunfabric/fast/stages/2-secops
Ludovico Magnocavallo 68955ff809 Improve context support in vpc-sc module and stage / new FAST stages small fixes (#3305)
* improve context support in vpc-sc module and stage

* fix stage env files

* fix stage env files

* fix FAST variables comments

* tfdoc

* fix locations order

* fix tests
2025-09-07 14:59:46 +02:00
..
2025-04-18 15:57:29 +02:00
2025-04-18 15:57:29 +02:00
2025-09-06 09:15:41 +00:00
2025-04-18 15:57:29 +02:00
2025-04-18 15:57:29 +02:00
2025-04-18 15:57:29 +02:00

SecOps Stage

This stage sets up an area dedicated to hosting SecOps projects in the Google Cloud organization.

The design of this stage is fairly simple, as it is only responsible for creating GCP projects that will be linked to SecOps instances as per the following documentation.

After creating the projects please refer to your Google Cloud Security representative for instructions on how to bind your Google SecOps instance to the Google Cloud project/s created in this stage.

The following diagram illustrates the high-level design of resources managed here:

Security diagram

Design overview and choices

This stage will deploy 1 SecOps project for each environment available from the 0-globals input variables, of course such a behaviour might be updated to either deploy a single production instance or different number of environments with respect to the foundations ones.

IAM for day to day operations is already assigned at the folder level to the secops team by the previous stage, but more granularity can be added here at the project level, to grant control of separate services across environments to different actors as well as in the later 3-secops-dev/prod stages.

Workforce Identity Federation

This stage supports configuration of Workforce Identity Federation which lets an external identity provider (IdP) to authenticate and authorize a group of users (usually employees) using IAM, so that the users can access Google Cloud services.

The following example shows an example on how to define a Workforce Identity pool for the organization.

# stage 2 secops wif tfvars
workforce_identity_providers = {
  test = {
    issuer       = "azuread"
    display_name = "wif-provider"
    description  = "Workforce Identity pool"
    saml         = {
      idp_metadata_xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>..."
    }
  }
}
# tftest skip

How to run this stage

This stage is meant to be executed after the bootstrap stage has run, as it leverages the automation service account and bucket created there, and additional resources configured there.

It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements.

Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration.

Provider and Terraform variables

As all other FAST stages, the mechanism used to pass variable values and pre-built provider files from one stage to the next is also leveraged here.

The commands to link or copy the provider and terraform variable files can be easily derived from the fast-links.sh script in the FAST stages folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run.

../fast-links.sh ~/fast-config

# File linking commands for security stage

# provider file
ln -s ~/fast-config/fast-test-00/providers/2-secops-providers.tf ./

# input files from other stages
ln -s ~/fast-config/fast-test-00/tfvars/0-globals.auto.tfvars.json ./
ln -s ~/fast-config/fast-test-00/tfvars/0-org-setup.auto.tfvars.json ./
ln -s ~/fast-config/fast-test-00/tfvars/1-resman.auto.tfvars.json ./

# conventional place for stage tfvars (manually created)
ln -s ~/fast-config/fast-test-00/2-secops.auto.tfvars ./
../fast-links.sh gs://xxx-prod-iac-core-outputs-0

# File linking commands for security stage

# provider file
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/providers/2-secops-providers.tf ./

# input files from other stages
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-globals.auto.tfvars.json ./
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-org-setup.auto.tfvars.json ./
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./

# conventional place for stage tfvars (manually created)
gcloud storage cp gs://xxx-prod-iac-core-outputs-0/2-secops.auto.tfvars ./

Impersonating the automation service account

The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The gcp-devops and organization-admins groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups.

Variable configuration

Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets:

  • variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the 0-globals.auto.tfvars.json file linked or copied above
  • variables which refer to resources managed by previous stages, which are prepopulated here via the 0-org-setup.auto.tfvars.json and 1-resman.auto.tfvars.json files linked or copied above
  • and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom terraform.tfvars file

The latter set is explained in the Customization sections below, and the full list can be found in the Variables table at the bottom of this document.

Note that the outputs_location variable is disabled by default, you need to explicitly set it in your terraform.tfvars file if you want output files to be generated by this stage. This is a sample terraform.tfvars that configures it, refer to the bootstrap stage documentation for more details:

outputs_location = "~/fast-config"

Using delayed billing association for projects

This configuration is possible but unsupported and only exists for development purposes, use at your own risk:

  • temporarily switch billing_account.id to null in 0-globals.auto.tfvars.json
  • for each project resources in the project modules used in this stage (dev, prod)
    • apply using -target, for example terraform apply -target 'module.project["dev"].google_project.project[0]'
    • untaint the project resource after applying, for example terraform untaint 'module.project["dev"].google_project.project[0]'
  • go through the process to associate the billing account with the two projects
  • switch billing_account.id back to the real billing account id
  • resume applying normally

Running the stage

Once provider and variable values are in place and the correct user is configured, the stage can be run:

terraform init
terraform apply

Customizations

Workforce Identity Federation

This is a minimal configuration that creates a Workforce Identity pool at organization level.

workforce_identity_providers = {
  test = {
    issuer       = "azuread"
    display_name = "wif-provider"
    description  = "Workforce Identity pool"
    saml         = {
      idp_metadata_xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>..."
    }
  }
}

Files

name description modules resources
identity-providers-defs.tf Workforce Identity provider definitions.
identity-providers.tf Workforce Identity Federation provider definitions. google_iam_workforce_pool · google_iam_workforce_pool_provider
main.tf Module-level locals and resources. folder · project
outputs.tf Module outputs. google_storage_bucket_object · local_file
variables-fast.tf None
variables.tf Module variables.

Variables

name description type required default producer
automation Automation resources created by the bootstrap stage. object({…}) 0-org-setup
billing_account Billing account id. If billing account is not part of the same org set is_org_level to false. object({…}) 0-org-setup
environments Environment names. map(object({…})) 0-globals
folder_ids Folder name => id mappings, the 'security' folder name must exist. object({…}) 1-resman
organization Organization details. object({…}) 0-org-setup
prefix Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. string 0-org-setup
custom_roles Custom roles defined at the org level, in key => id format. object({…}) null 0-org-setup
essential_contacts Email used for essential contacts, unset if null. string null
outputs_location Path where providers, tfvars files, and lists for the following stages are written. Leave empty to disable. string null
stage_config FAST stage configuration. object({…}) {} 1-resman
tag_values Root-level tag values. map(string) {} 1-resman
workforce_identity_providers Workforce Identity Federation pools. map(object({…})) {}

Outputs

name description sensitive consumers
federated_identity_pool Workforce Identity Federation pool.
secops_project_ids SecOps project IDs.
tfvars Terraform variable files for the following stages.