Files
hunfabric/modules/secret-manager
Hemanand eaa420534b Add agent engine BYOC support (#3885)
* feat(agent-engine): add support for container and custom image specs

- Add container_config to deployment_files.
- Add image_spec with build_args to source_config.
- Make agent_framework optional and document supported values.
- Implement dynamic specs for container and source deployments.
- Add examples and automated tests for new deployment types.

* chore: update Google provider version to 7.28.0 across modules

Mechanical update of versions.tf and versions.tofu files using tools/versions.py.

* feat(agent-engine): refactor for container deployments and API alignment

- Group deployment settings under 'deployment_config' (renamed from 'deployment_files').
- Support container-based deployments via 'container_config' and 'image_spec'.
- Refactor 'source_files_config' (renamed from 'source_config') to include mutually exclusive 'python_spec' and 'image_spec'.
- Support 'developer_connect_config' as a source code type.
- Group engine settings (framework, env, secrets) under 'agent_engine_config'.
- Add support for 'memory_bank_config' persistent memory.
- Overhaul reasoning engine resources with dynamic blocks to match provider schema.
- Update all documentation examples, add TOC, and refresh test inventories.

* Update dynamic python_spec block and related example yamls

* Ignore changes setting for developer_connect_source under lifecycle management

* fixing review comments for `try` and default path for `source_path`

---------

Co-authored-by: Hemanand <hemr@google.com>
Co-authored-by: Julio Castillo <jccb@google.com>
2026-04-21 17:46:20 +00:00
..
2025-09-10 11:47:35 +00:00
2025-09-10 11:47:35 +00:00

Google Secret Manager

This module allows managing one or more secrets with versions and IAM bindings. For global secrets, this module optionally supports write-only attributes for versions, which do not save data in state. Write-only attributes are not yet supported in OpenTofu, so this module is only compatible with Terraform until OpenTofu support has been released.

Global Secrets

Secrets are created as global by default, with auto replication policy. For auto managed replication secrets the kms_key attribute can be used to configure CMEK via a global key.

To configure a secret for user managed replication configure the global_replica_locations attribute. Non-auto secrets ignore the kms_key attribute, but use each element of the locations map to configure keys.

module "secret-manager" {
  source     = "./fabric/modules/secret-manager"
  project_id = var.project_id
  secrets = {
    test-auto = {}
    test-auto-cmek = {
      kms_key = "projects/test-0/locations/global/keyRings/test-g/cryptoKeys/sec"
    }
    test-user = {
      global_replica_locations = {
        europe-west1 = null
        europe-west3 = null
      }
    }
    test-user-cmek = {
      global_replica_locations = {
        europe-west1 = "projects/test-0/locations/europe-west1/keyRings/test-g/cryptoKeys/sec-ew1"
        europe-west3 = "projects/test-0/locations/europe-west3/keyRings/test-g/cryptoKeys/sec-ew3"
      }
    }
  }
}
# tftest modules=1 resources=4 inventory=secret.yaml skip-tofu

Regional Secrets

Regional secrets are identified by having the location attribute defined, and share the same interface with a few exceptions: the global_replica_locations is of course ignored, and versions only support a subset of attributes and can't use write-only attributes.

module "secret-manager" {
  source     = "./fabric/modules/secret-manager"
  project_id = var.project_id
  secrets = {
    test = {
      location = "europe-west1"
    }
    test-cmek = {
      location = "europe-west1"
      kms_key  = "projects/test-0/locations/global/keyRings/test-g/cryptoKeys/sec"
    }
  }
}
# tftest modules=1 resources=2 inventory=secret-regional.yaml skip-tofu

IAM Bindings

This module supports the same IAM interface as all other modules in this repository. IAM bindings are defined per secret, if you need cross-secret IAM bindings use project-level ones.

module "secret-manager" {
  source     = "./fabric/modules/secret-manager"
  project_id = var.project_id
  secrets = {
    test = {
      iam = {
        "roles/secretmanager.admin" = [
          "user:test-0@example.com"
        ]
      }
      iam_bindings = {
        test = {
          role = "roles/secretmanager.secretAccessor"
          members = [
            "user:test-1@example.com"
          ]
          condition = {
            title      = "Test."
            expression = "resource.matchTag('1234567890/environment', 'test')"
          }
        }
      }
      iam_bindings_additive = {
        test = {
          role   = "roles/secretmanager.viewer"
          member = "user:test-2@example.com"
        }
      }
    }
  }
}
# tftest modules=1 resources=4 inventory=iam.yaml skip-tofu

Secret Versions

Versions are defined per secret via the versions attribute, and by default they accept string data which is stored in state. The data_config attributes allow configuring each secret:

  • data_config.is_file instructs the module to read version data from a file (data is then used as the file path)
  • data_config.is_base64 instructs the provider to treat data as Base64
  • data_config.write_only_version instructs the module to use write-only attributes so that data is not set in state, each time the write-only version is changed data is reuploaded to the secret version

As mentioned before write-only attributes are only available for global secrets. Regional secrets still use the potentially insecure way of storing data.

module "secret-manager" {
  source     = "./fabric/modules/secret-manager"
  project_id = var.project_id
  secrets = {
    test = {
      versions = {
        a = {
          # potentially unsafe
          data = "foo"
        }
        b = {
          # potentially unsafe, reads from file
          data = "test-data/secret-b.txt"
          data_config = {
            is_file = true
          }
        }
        c = {
          # uses safer write-only attribute
          data = "bar"
          data_config = {
            # bump this version when data needs updating
            write_only_version = 1
          }
        }
      }
    }
  }
}
# tftest files=0 modules=1 resources=4 inventory=versions.yaml skip-tofu
foo-secret
# tftest-file id=0 path=test-data/secret-b.txt

Context Interpolations

Similarly to other core modules in this repository, this module also supports context-based interpolations, which are populated via the context variable.

This is a summary table of the available contexts, which can be used whenever an attribute expects the relevant information. Refer to the project factory module for more details on context replacements.

  • $custom_roles:my_role
  • $iam_principals:my_principal
  • $kms_keys:my_key
  • $locations:my_location
  • $project_ids:my_project
  • $tag_keys:my_key
  • $tag_values:my_value
  • custom template variables used in IAM conditions

This is a simple example that uses context interpolation.

module "secret-manager" {
  source = "./fabric/modules/secret-manager"
  context = {
    iam_principals = {
      mysa   = "serviceAccount:test@foo-prod-test-0.iam.gserviceaccount.com"
      myuser = "user:test@example.com"
    }
    kms_keys = {
      primary   = "projects/test-0/locations/europe-west1/keyRings/test-g/cryptoKeys/sec-ew1"
      secondary = "projects/test-0/locations/europe-west3/keyRings/test-g/cryptoKeys/sec-ew3"
    }
    locations = {
      primary   = "europe-west1"
      secondary = "europe-west3"
    }
    project_ids = {
      test = "foo-prod-test-0"
    }
  }
  project_id = "$project_ids:test"
  secrets = {
    test-user-cmek = {
      global_replica_locations = {
        "$locations:primary"   = "$kms_keys:primary"
        "$locations:secondary" = "$kms_keys:secondary"
      }
      iam = {
        "roles/secretmanager.viewer" = [
          "$iam_principals:mysa", "$iam_principals:myuser"
        ]
      }
    }
  }
}
# tftest modules=1 resources=2 inventory=context.yaml skip-tofu

Variables

name description type required default
project_id Project id where the keyring will be created. string
context Context-specific interpolations. object({…}) {}
project_number Project number of var.project_id. Set this to avoid permadiffs when creating tag bindings. string null
secrets Map of secrets to manage. Defaults to global secrets unless region is set. map(object({…})) {}

Outputs

name description sensitive
ids Fully qualified secret ids.
secrets Secret resources.
version_ids Fully qualified version ids.
version_versions Version versions.
versions Version resources.

Requirements

These sections describe requirements for using this module.

IAM

The following roles must be used to provision the resources of this module:

  • Cloud KMS Admin: roles/cloudkms.admin or
  • Owner: roles/owner

APIs

A project with the following APIs enabled must be used to host the resources of this module:

  • Google Cloud Key Management Service: cloudkms.googleapis.com