Files
hunfabric/fast/stages/2-security
2026-04-14 08:53:46 +00:00
..
2026-04-14 08:47:07 +00:00
2025-10-28 07:33:15 +01:00

Shared Security Resources

This stage sets up an area dedicated to hosting security resources and configurations which impact the whole organization, or are shared across the hierarchy to other projects and teams.

Like other modern FAST stage, the resource design is defined here via YAML configuration files and implemented via factories to provide maximum flexibility. A sample reference design compatible with legacy FAST is provided in an initial dataset, and can be used as-is or used as a basis for customizations.

The following diagram illustrates the high-level design of resources implemented in the default dataset:

Security diagram

Quickstart

This stage is designed to be applied after stage 0, but as any other FAST stage it can also be used in isolation, provided the required prerequisites are met. This section details the FAST usage, where prerequisited are already in place.

The high-level flow for running this stage is:

  • check the factory data set and do any necessary edits to match your configuration (number of projects, names, KMS keys, CAs, etc.)
  • populate the defaults file with attributes matching your configuration
  • define a simple tfvars file if your dataset is in a non-standard path, and/or you want local output files (recommended for initial setups)
  • bring in or link the prerequisite files generated by the previous stage
  • run terraform init and apply

Factory data set

The default dataset provides two projects, each rooted in a separate folder. I does not define any KMS or CAS resources.

If a different folder or project configuration is needed copy the full dataset to a different path to avoid accidental changes from upstream, then add or remove files in data/folders and data/projects.

A simple KMS keyrin is provided in keyrings folder, use it as an example if more are needed. For CAS too a sample configuration is already present, but the Certificate Authorities factory is disabled by default. If CAS is needed define the factories_config.paths.certificate_authorities variable attribute in your tfvars and set it to the path of the relevant data folder (data/certificate-authorities by default) as shown in this snippet.

factories_config = {
  paths = {
    certificate_authorities = "certificate-authorities"
  }
}

Defaults file

Configurations defaults are stored in the defaults.yaml file in the selected dataset. Relocating the defaults file is good practice to avoid accindetal changes from upstream, this is done via the factories_config.paths.default variable attribute.

Once a suitable place has been found for the file, edit it to match the desired configuration. Several pieces of information coming from the previous stage (prefix, billing account, etc.) are pre-populated in the project defaults so they don't need to be explicitly set. If some of them need to be overridden, the attributes in projects.overrides take precedence as shown in this annotated sample.

context:
  # external definitions can be set here and used in context from YAML files
  # locations.primary is used by the default dataset, and should be defined
  locations:
    primary: europe-west1
    secondary: europe-west3
# defaults and overrides common to security projects should go here
# defining storage_location is required
projects:
  defaults:
    storage_location: eu
  # overrides are optional, and can be used to override some FAST defaults
  overrides:
    # don't do this unless you have a good reason :
    prefix: foo-0

Terraform vars configuration

A tfvars file allows you to control paths for the project factories data, and to enable local output files generation. This example shows how to override all the factory paths while also enabling the CAS factory, and how to enable output files.

factories_config = {
  dataset = "datasets/mydataset"
  paths = {
    certificate_authorities = "certificate-authorities"
    # the following default to relative paths in the dataset
    # defaults                = "defaults.yaml"
    # folders                 = "folders"
    # keyrings                = "keyrings"
    # projects                = "projects"
  }
}
outputs_location = "~/fast-config"

Linking FAST output files

If you enabled local output files in the previous stage, run this command replacing the example path with the one for your output files.

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

# File linking commands for security stage

# provider file
ln -s ~/fast-config/providers/2-security-providers.tf ./

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

# conventional location for this stage terraform.tfvars (manually managed)
ln -s ~/fast-config/2-security.auto.tfvars ./

If you have no local output files, check the previous state's outputs for the name of your GCS outputs bucket and replace it in the example below.

../fast-links.sh gs://myprefix-prod-iac-org-0-iac-outputs

# File linking commands for security stage

# provider file
gcloud storage cp gs://myprefix-prod-iac-org-0-iac-outputs/providers/2-security-providers.tf ./

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

# conventional location for this stage terraform.tfvars (manually managed)
gcloud storage cp gs://myprefix-prod-iac-org-0-iac-outputs/2-security.auto.tfvars ./

Once you have one of the above outputs, copy/paste it in your terminal from within this stage's folder.

Note that the last command in both outputs is optional: this is our recommended best practice to centrally store the tfvars file you created for this stage. If this convention works for you, move the tfvars file created in the previous steps to the path shown in the output, then run the command.

Terraform init/apply cycle

Once everything is set up, simply run the usual init/apply cycle.

terraform init
terraform apply

Design overview and choices

Project-level security resources are grouped into one project per environment. This setup matches requirements we frequently observe in real life and provides enough separation without needlessly complicating operations.

Cloud KMS is configured and designed mainly to encrypt GCP resources with a Customer-managed encryption key but it may be used to create cryptokeys used to encrypt application data and other uses.

A single Certificate Authority Service pool and CA are configured by default, but the setup can be easily extended to support multiple resources in any environment.

IAM for day to day operations is already assigned at the folder level to the security team by the previous stage, but more granularity can be added here to grant control of separate services across environments to different actors.

Cloud KMS

A reference Cloud KMS implementation is part of this stage, to provide a simple way of managing centralized keys, that are then shared and consumed widely across the organization to enable customer-managed encryption. The implementation is also easy to clone and modify to support other services like Secret Manager.

The Cloud KMS configuration allows defining keys by name (typically matching the downstream service that uses them) in different locations. It then takes care internally of provisioning the relevant keyrings and creating keys in the appropriate location.

IAM roles on keys can be configured at the logical level for all locations where a logical key is created. Their management can also be delegated via delegated role grants exposed through a simple variable, to allow other identities to set IAM policies on keys. This is particularly useful in setups like project factories, making it possible to configure IAM bindings during project creation for team groups or service agent accounts (compute, storage, etc.).

Certificate Authority Service (CAS)

A reference Certificate Authority Services (CAS) is also part of this stage, allowing creation of any number of CA pools and authorities. To create custom CAS, the relevant factory variable needs to be configured first as explained above.

Files

name description modules resources
factory-cas.tf None certificate-authority-service
factory-keyrings.tf None kms
factory-projects.tf None project-factory
main.tf Module-level locals and resources.
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
billing_account Billing account id. 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
context Context-specific interpolations. object({…}) {}
custom_roles Custom roles defined at the org level, in key => id format. map(string) {} 0-org-setup
factories_config Configuration for the resource factories or external data. object({…}) {}
folder_ids Folders created in the bootstrap stage. map(string) {} 0-org-setup
iam_principals IAM-format principals. map(string) {} 0-org-setup
perimeters Optional VPC-SC perimeter ids. map(string) {} 1-vpcsc
project_ids Projects created in the bootstrap stage. map(string) {} 0-org-setup
service_accounts Service accounts created in the bootstrap stage. map(string) {} 0-org-setup
storage_buckets Storage buckets created in the bootstrap stage. map(string) {} 0-org-setup
tag_keys FAST-managed resource manager tag keys. map(string) {} 0-org-setup
tag_values FAST-managed resource manager tag values. map(string) {} 0-org-setup
universe GCP universe where to deploy projects. The prefix will be prepended to the project id. object({…}) null 0-org-setup

Outputs

name description sensitive consumers
ca_pools Certificate Authority Service pools and CAs.
kms_keys_ids KMS keys IDs.
tfvars Terraform variable files for the following stages.