refactor: reorganize GitOps control plane
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
bucket = "project-gitops-terraform-state"
|
||||
key = "dev-k3s/vault-core.tfstate"
|
||||
region = "us-east-1"
|
||||
encrypt = true
|
||||
use_lockfile = true
|
||||
@@ -0,0 +1,5 @@
|
||||
bucket = "project-gitops-terraform-state"
|
||||
key = "dev-k3s/vault-database.tfstate"
|
||||
region = "us-east-1"
|
||||
encrypt = true
|
||||
use_lockfile = true
|
||||
@@ -0,0 +1,22 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/vault" {
|
||||
version = "5.7.0"
|
||||
constraints = "~> 5.7.0"
|
||||
hashes = [
|
||||
"h1:Pm0AcUSYmBPZgRahQX/ahiYcjtZODSAEc2rK8r8MQ18=",
|
||||
"zh:1dd9ab6d23f61a5e522efcb462f1fd6f4a210c77b9038c8e12fa5fa663b45d01",
|
||||
"zh:3c98d37ead857c980f7b9285f8c3e1eb7a8fd6d6799275c311c6997973389cc9",
|
||||
"zh:3df895fbaed383e3748ba1b50f5f1046f75503483bc3d783992059f85c85ba31",
|
||||
"zh:3e9faaa0a85c6f03c7fd7f8b7008bb3fbb8777f26c001875947cafa47f91c657",
|
||||
"zh:52a057d0c6cde7cbfd9ceb78a3781dcfc81cf108c533f454530ea6bb87a9bea8",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:8521c3825254a5f7fbff8f42ca57cabf052366f0420f5f239ebebf8292c03d0e",
|
||||
"zh:953563d429e40087eb34faf22f28e781e50eee27cfc9ac1ad04308ba592a647f",
|
||||
"zh:a52dd76bb7f5b86cb8de7380d2e68b47ec4445782c16ee205e6a013be35a57b6",
|
||||
"zh:bdad38c95a14c8cce1eeadcc539cf9bf74902ce7c662b79105ad993bb48ec073",
|
||||
"zh:d3c676d7d12c15b58518fa3ee7fc398a13893b4057fe9bf4bc1fe635f3fb995a",
|
||||
"zh:f8673b6c06da80e912c9e32dd4853f07bfca386968d5b33c9fceb6f68b519959",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
terraform {
|
||||
required_version = ">= 1.11.0"
|
||||
|
||||
required_providers {
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "~> 5.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
backend "s3" {}
|
||||
}
|
||||
|
||||
provider "vault" {
|
||||
address = var.vault_addr
|
||||
skip_child_token = true
|
||||
token = var.vault_token
|
||||
}
|
||||
|
||||
locals {
|
||||
policy_dir = "${path.module}/../../../../../policies/vault/dev-k3s"
|
||||
|
||||
workload_policies = {
|
||||
auth-server-dev = file("${local.policy_dir}/auth-server-dev.hcl")
|
||||
auth-db-migration-dev = file("${local.policy_dir}/auth-db-migration-dev.hcl")
|
||||
postgres-dev = file("${local.policy_dir}/postgres-dev.hcl")
|
||||
keycloak-dev = file("${local.policy_dir}/keycloak-dev.hcl")
|
||||
keycloak-client-sync-dev = file("${local.policy_dir}/keycloak-client-sync-dev.hcl")
|
||||
postgres-operator-dev = file("${local.policy_dir}/postgres-operator-dev.hcl")
|
||||
keycloak-operator-dev = file("${local.policy_dir}/keycloak-operator-dev.hcl")
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_mount" "kv" {
|
||||
path = var.kv_mount_path
|
||||
type = "kv"
|
||||
options = {
|
||||
version = "2"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
prevent_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_mount" "database" {
|
||||
path = var.database_mount_path
|
||||
type = "database"
|
||||
|
||||
lifecycle {
|
||||
prevent_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_mount" "transit" {
|
||||
path = var.transit_mount_path
|
||||
type = "transit"
|
||||
|
||||
lifecycle {
|
||||
prevent_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_auth_backend" "kubernetes" {
|
||||
path = var.kubernetes_auth_path
|
||||
type = "kubernetes"
|
||||
}
|
||||
|
||||
resource "vault_kubernetes_auth_backend_config" "cluster" {
|
||||
backend = vault_auth_backend.kubernetes.path
|
||||
disable_iss_validation = true
|
||||
disable_local_ca_jwt = false
|
||||
kubernetes_host = var.kubernetes_host
|
||||
}
|
||||
|
||||
resource "vault_transit_secret_backend_key" "project_auth_jwt" {
|
||||
backend = vault_mount.transit.path
|
||||
name = var.jwt_transit_key_name
|
||||
type = "rsa-2048"
|
||||
}
|
||||
|
||||
resource "vault_policy" "platform_admin" {
|
||||
name = var.platform_admin_policy_name
|
||||
policy = file("${local.policy_dir}/platform-admin-dev.hcl")
|
||||
}
|
||||
|
||||
resource "vault_policy" "database_automation" {
|
||||
name = var.database_automation_policy_name
|
||||
policy = file("${local.policy_dir}/vault-database-automation-dev.hcl")
|
||||
}
|
||||
|
||||
module "workload_policies" {
|
||||
source = "../../../modules/vault-policy-set"
|
||||
|
||||
policies = local.workload_policies
|
||||
}
|
||||
|
||||
resource "vault_kubernetes_auth_backend_role" "operator" {
|
||||
audience = var.kubernetes_token_audience
|
||||
backend = vault_auth_backend.kubernetes.path
|
||||
bound_service_account_names = [var.operator_service_account_name]
|
||||
bound_service_account_namespaces = [var.operator_service_account_namespace]
|
||||
role_name = var.operator_role_name
|
||||
token_policies = [vault_policy.platform_admin.name]
|
||||
token_ttl = var.operator_token_ttl_seconds
|
||||
}
|
||||
|
||||
module "workload_roles" {
|
||||
source = "../../../modules/vault-kubernetes-roles"
|
||||
|
||||
backend = vault_auth_backend.kubernetes.path
|
||||
roles = {
|
||||
auth-server-dev = {
|
||||
audiences = [var.kubernetes_token_audience]
|
||||
service_account_names = ["auth-server"]
|
||||
service_account_namespaces = ["auth-dev"]
|
||||
token_policies = [module.workload_policies.names["auth-server-dev"]]
|
||||
token_ttl = var.kubernetes_role_ttl_seconds
|
||||
}
|
||||
auth-db-migration-dev = {
|
||||
audiences = [var.kubernetes_token_audience]
|
||||
service_account_names = ["auth-db-migration"]
|
||||
service_account_namespaces = ["auth-dev"]
|
||||
token_policies = [module.workload_policies.names["auth-db-migration-dev"]]
|
||||
token_ttl = var.kubernetes_role_ttl_seconds
|
||||
}
|
||||
postgres-dev = {
|
||||
audiences = [var.kubernetes_token_audience]
|
||||
service_account_names = ["postgres"]
|
||||
service_account_namespaces = ["platform"]
|
||||
token_policies = [module.workload_policies.names["postgres-dev"]]
|
||||
token_ttl = var.kubernetes_role_ttl_seconds
|
||||
}
|
||||
keycloak-dev = {
|
||||
audiences = [var.kubernetes_token_audience]
|
||||
service_account_names = ["keycloak"]
|
||||
service_account_namespaces = ["platform"]
|
||||
token_policies = [module.workload_policies.names["keycloak-dev"]]
|
||||
token_ttl = var.kubernetes_role_ttl_seconds
|
||||
}
|
||||
keycloak-client-sync-dev = {
|
||||
audiences = [var.kubernetes_token_audience]
|
||||
service_account_names = ["keycloak-client-sync"]
|
||||
service_account_namespaces = ["platform"]
|
||||
token_policies = [module.workload_policies.names["keycloak-client-sync-dev"]]
|
||||
token_ttl = var.kubernetes_role_ttl_seconds
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_jwt_auth_backend" "ci" {
|
||||
count = var.ci_jwt_oidc_discovery_url == null ? 0 : 1
|
||||
|
||||
bound_issuer = var.ci_jwt_bound_issuer
|
||||
oidc_discovery_url = var.ci_jwt_oidc_discovery_url
|
||||
path = var.ci_jwt_auth_path
|
||||
}
|
||||
|
||||
resource "vault_jwt_auth_backend_role" "ci" {
|
||||
count = var.ci_jwt_oidc_discovery_url == null ? 0 : 1
|
||||
|
||||
backend = vault_jwt_auth_backend.ci[0].path
|
||||
bound_audiences = var.ci_jwt_bound_audiences
|
||||
bound_claims = var.ci_jwt_bound_claims
|
||||
bound_claims_type = "glob"
|
||||
role_name = var.ci_jwt_role_name
|
||||
role_type = "jwt"
|
||||
token_explicit_max_ttl = var.ci_token_ttl_seconds
|
||||
token_policies = [vault_policy.database_automation.name]
|
||||
user_claim = var.ci_jwt_user_claim
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
variable "database_automation_policy_name" {
|
||||
description = "Least-privilege policy used by the approved Vault database runner."
|
||||
type = string
|
||||
default = "vault-database-automation-dev"
|
||||
}
|
||||
|
||||
variable "ci_jwt_auth_path" {
|
||||
description = "JWT auth mount used by external CI."
|
||||
type = string
|
||||
default = "jwt-ci"
|
||||
}
|
||||
|
||||
variable "ci_jwt_bound_audiences" {
|
||||
description = "Accepted CI JWT audiences."
|
||||
type = set(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "ci_jwt_bound_claims" {
|
||||
description = "Claims that bind CI JWTs to the canonical repository and protected branch."
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "ci_jwt_bound_issuer" {
|
||||
description = "Expected issuer for CI JWTs."
|
||||
type = string
|
||||
default = null
|
||||
nullable = true
|
||||
}
|
||||
|
||||
variable "ci_jwt_oidc_discovery_url" {
|
||||
description = "CI OIDC discovery URL. Null keeps JWT auth disabled until the issuer is confirmed."
|
||||
type = string
|
||||
default = null
|
||||
nullable = true
|
||||
}
|
||||
|
||||
variable "ci_jwt_role_name" {
|
||||
description = "Vault role used by the GitOps configuration workflow."
|
||||
type = string
|
||||
default = "project-gitops-dev"
|
||||
}
|
||||
|
||||
variable "ci_jwt_user_claim" {
|
||||
description = "JWT claim used as the Vault identity alias."
|
||||
type = string
|
||||
default = "sub"
|
||||
}
|
||||
|
||||
variable "ci_token_ttl_seconds" {
|
||||
description = "Maximum lifetime for a CI Vault token."
|
||||
type = number
|
||||
default = 3600
|
||||
}
|
||||
|
||||
variable "database_mount_path" {
|
||||
description = "Workload Vault database secrets mount path."
|
||||
type = string
|
||||
default = "database"
|
||||
}
|
||||
|
||||
variable "jwt_transit_key_name" {
|
||||
description = "Transit key used for application JWT signing."
|
||||
type = string
|
||||
default = "project-auth-jwt"
|
||||
}
|
||||
|
||||
variable "kubernetes_auth_path" {
|
||||
description = "Kubernetes auth backend path."
|
||||
type = string
|
||||
default = "kubernetes"
|
||||
}
|
||||
|
||||
variable "kubernetes_host" {
|
||||
description = "Kubernetes TokenReview API address."
|
||||
type = string
|
||||
default = "https://kubernetes.default.svc.cluster.local:443"
|
||||
}
|
||||
|
||||
variable "kubernetes_role_ttl_seconds" {
|
||||
description = "TTL for workload Kubernetes auth tokens."
|
||||
type = number
|
||||
default = 3600
|
||||
}
|
||||
|
||||
variable "kubernetes_token_audience" {
|
||||
description = "Audience used by projected service account tokens."
|
||||
type = string
|
||||
default = "vault"
|
||||
}
|
||||
|
||||
variable "kv_mount_path" {
|
||||
description = "Workload Vault KV-v2 mount path."
|
||||
type = string
|
||||
default = "kv"
|
||||
}
|
||||
|
||||
variable "operator_role_name" {
|
||||
description = "Workload Vault Kubernetes auth role for human operators."
|
||||
type = string
|
||||
default = "vault-operator-dev"
|
||||
}
|
||||
|
||||
variable "operator_service_account_name" {
|
||||
description = "Service account authorized to open workload Vault operator sessions."
|
||||
type = string
|
||||
default = "vault-operator"
|
||||
}
|
||||
|
||||
variable "operator_service_account_namespace" {
|
||||
description = "Namespace of the workload Vault operator service account."
|
||||
type = string
|
||||
default = "vault"
|
||||
}
|
||||
|
||||
variable "operator_token_ttl_seconds" {
|
||||
description = "TTL for workload Vault operator sessions."
|
||||
type = number
|
||||
default = 1800
|
||||
}
|
||||
|
||||
variable "platform_admin_policy_name" {
|
||||
description = "Policy used only for short-lived break-glass administration."
|
||||
type = string
|
||||
default = "platform-admin-dev"
|
||||
}
|
||||
|
||||
variable "transit_mount_path" {
|
||||
description = "Workload Vault Transit mount path for application cryptography."
|
||||
type = string
|
||||
default = "transit"
|
||||
}
|
||||
|
||||
variable "vault_addr" {
|
||||
description = "Workload Vault API address reachable by the approved runner."
|
||||
type = string
|
||||
default = "http://127.0.0.1:8200"
|
||||
}
|
||||
|
||||
variable "vault_token" {
|
||||
description = "Short-lived token used only for this Terraform run."
|
||||
type = string
|
||||
sensitive = true
|
||||
ephemeral = true
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/vault" {
|
||||
version = "5.7.0"
|
||||
constraints = "~> 5.7.0"
|
||||
hashes = [
|
||||
"h1:Pm0AcUSYmBPZgRahQX/ahiYcjtZODSAEc2rK8r8MQ18=",
|
||||
"zh:1dd9ab6d23f61a5e522efcb462f1fd6f4a210c77b9038c8e12fa5fa663b45d01",
|
||||
"zh:3c98d37ead857c980f7b9285f8c3e1eb7a8fd6d6799275c311c6997973389cc9",
|
||||
"zh:3df895fbaed383e3748ba1b50f5f1046f75503483bc3d783992059f85c85ba31",
|
||||
"zh:3e9faaa0a85c6f03c7fd7f8b7008bb3fbb8777f26c001875947cafa47f91c657",
|
||||
"zh:52a057d0c6cde7cbfd9ceb78a3781dcfc81cf108c533f454530ea6bb87a9bea8",
|
||||
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
|
||||
"zh:8521c3825254a5f7fbff8f42ca57cabf052366f0420f5f239ebebf8292c03d0e",
|
||||
"zh:953563d429e40087eb34faf22f28e781e50eee27cfc9ac1ad04308ba592a647f",
|
||||
"zh:a52dd76bb7f5b86cb8de7380d2e68b47ec4445782c16ee205e6a013be35a57b6",
|
||||
"zh:bdad38c95a14c8cce1eeadcc539cf9bf74902ce7c662b79105ad993bb48ec073",
|
||||
"zh:d3c676d7d12c15b58518fa3ee7fc398a13893b4057fe9bf4bc1fe635f3fb995a",
|
||||
"zh:f8673b6c06da80e912c9e32dd4853f07bfca386968d5b33c9fceb6f68b519959",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
terraform {
|
||||
required_version = ">= 1.11.0"
|
||||
|
||||
required_providers {
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "~> 5.7.0"
|
||||
}
|
||||
}
|
||||
|
||||
backend "s3" {}
|
||||
}
|
||||
|
||||
provider "vault" {
|
||||
address = var.vault_addr
|
||||
skip_child_token = true
|
||||
token = var.vault_token
|
||||
}
|
||||
|
||||
locals {
|
||||
migration_role_name = "auth-db-migration-dev"
|
||||
operator_role_name = "postgres-operator-dev"
|
||||
|
||||
creation_statements = [
|
||||
<<-EOT
|
||||
CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
|
||||
GRANT "${var.auth_db_role}" TO "{{name}}";
|
||||
EOT
|
||||
]
|
||||
|
||||
revocation_statements = [
|
||||
<<-EOT
|
||||
REASSIGN OWNED BY "{{name}}" TO "${var.auth_db_role}";
|
||||
DROP OWNED BY "{{name}}";
|
||||
REVOKE "${var.auth_db_role}" FROM "{{name}}";
|
||||
DROP ROLE IF EXISTS "{{name}}";
|
||||
EOT
|
||||
]
|
||||
}
|
||||
|
||||
resource "vault_database_secret_backend_connection" "platform_postgres" {
|
||||
allowed_roles = [local.migration_role_name, local.operator_role_name]
|
||||
backend = var.database_mount_path
|
||||
name = var.database_config_name
|
||||
plugin_name = "postgresql-database-plugin"
|
||||
verify_connection = true
|
||||
|
||||
postgresql {
|
||||
connection_url = "postgresql://{{username}}:{{password}}@${var.postgres_host}:${var.postgres_port}/${var.postgres_database}?sslmode=${var.postgres_sslmode}"
|
||||
password_authentication = "scram-sha-256"
|
||||
password_wo = var.postgres_admin_password
|
||||
password_wo_version = var.postgres_admin_password_version
|
||||
username = var.postgres_admin_username
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_database_secret_backend_role" "auth_db_migration" {
|
||||
backend = var.database_mount_path
|
||||
creation_statements = local.creation_statements
|
||||
db_name = vault_database_secret_backend_connection.platform_postgres.name
|
||||
default_ttl = var.auth_db_migration_default_ttl_seconds
|
||||
max_ttl = var.auth_db_migration_max_ttl_seconds
|
||||
name = local.migration_role_name
|
||||
revocation_statements = local.revocation_statements
|
||||
}
|
||||
|
||||
resource "vault_database_secret_backend_role" "postgres_operator" {
|
||||
backend = var.database_mount_path
|
||||
creation_statements = local.creation_statements
|
||||
db_name = vault_database_secret_backend_connection.platform_postgres.name
|
||||
default_ttl = var.postgres_operator_default_ttl_seconds
|
||||
max_ttl = var.postgres_operator_max_ttl_seconds
|
||||
name = local.operator_role_name
|
||||
revocation_statements = local.revocation_statements
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
variable "auth_db_migration_default_ttl_seconds" {
|
||||
description = "Default TTL for migration credentials."
|
||||
type = number
|
||||
default = 3600
|
||||
}
|
||||
|
||||
variable "auth_db_migration_max_ttl_seconds" {
|
||||
description = "Maximum TTL for migration credentials."
|
||||
type = number
|
||||
default = 86400
|
||||
}
|
||||
|
||||
variable "auth_db_role" {
|
||||
description = "Stable PostgreSQL owner role used by dynamic users."
|
||||
type = string
|
||||
default = "project_auth"
|
||||
}
|
||||
|
||||
variable "database_config_name" {
|
||||
description = "Vault database connection name."
|
||||
type = string
|
||||
default = "platform-postgres-dev"
|
||||
}
|
||||
|
||||
variable "database_mount_path" {
|
||||
description = "Foundation-owned database secrets mount path."
|
||||
type = string
|
||||
default = "database"
|
||||
}
|
||||
|
||||
variable "postgres_admin_password" {
|
||||
description = "PostgreSQL admin password passed only through a write-only provider field."
|
||||
type = string
|
||||
sensitive = true
|
||||
ephemeral = true
|
||||
}
|
||||
|
||||
variable "postgres_admin_password_version" {
|
||||
description = "Increment whenever postgres_admin_password is rotated."
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "postgres_admin_username" {
|
||||
description = "Dedicated database administration username."
|
||||
type = string
|
||||
default = "postgres"
|
||||
}
|
||||
|
||||
variable "postgres_database" {
|
||||
description = "Database in which dynamic migration objects are owned and revoked."
|
||||
type = string
|
||||
default = "project_auth"
|
||||
}
|
||||
|
||||
variable "postgres_host" {
|
||||
description = "Platform PostgreSQL service DNS name."
|
||||
type = string
|
||||
default = "postgres.platform.svc.cluster.local"
|
||||
}
|
||||
|
||||
variable "postgres_operator_default_ttl_seconds" {
|
||||
description = "Default TTL for operator database credentials."
|
||||
type = number
|
||||
default = 3600
|
||||
}
|
||||
|
||||
variable "postgres_operator_max_ttl_seconds" {
|
||||
description = "Maximum TTL for operator database credentials."
|
||||
type = number
|
||||
default = 28800
|
||||
}
|
||||
|
||||
variable "postgres_port" {
|
||||
description = "Platform PostgreSQL service port."
|
||||
type = number
|
||||
default = 5432
|
||||
}
|
||||
|
||||
variable "postgres_sslmode" {
|
||||
description = "PostgreSQL SSL mode. Dev currently uses disable; production must use verify-full."
|
||||
type = string
|
||||
default = "disable"
|
||||
|
||||
validation {
|
||||
condition = contains(["disable", "require", "verify-ca", "verify-full"], var.postgres_sslmode)
|
||||
error_message = "postgres_sslmode must be disable, require, verify-ca, or verify-full."
|
||||
}
|
||||
}
|
||||
|
||||
variable "vault_addr" {
|
||||
description = "Workload Vault API address."
|
||||
type = string
|
||||
default = "http://127.0.0.1:8200"
|
||||
}
|
||||
|
||||
variable "vault_token" {
|
||||
description = "Short-lived token carrying vault-database-automation-dev."
|
||||
type = string
|
||||
sensitive = true
|
||||
ephemeral = true
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
resource "vault_kubernetes_auth_backend_role" "this" {
|
||||
for_each = var.roles
|
||||
|
||||
audience = one(each.value.audiences)
|
||||
backend = var.backend
|
||||
bound_service_account_names = each.value.service_account_names
|
||||
bound_service_account_namespaces = each.value.service_account_namespaces
|
||||
role_name = each.key
|
||||
token_policies = each.value.token_policies
|
||||
token_ttl = each.value.token_ttl
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
variable "backend" {
|
||||
description = "Kubernetes auth backend path."
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "roles" {
|
||||
description = "Kubernetes auth roles keyed by Vault role name."
|
||||
type = map(object({
|
||||
audiences = set(string)
|
||||
service_account_names = set(string)
|
||||
service_account_namespaces = set(string)
|
||||
token_policies = set(string)
|
||||
token_ttl = number
|
||||
}))
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_version = ">= 1.11.0"
|
||||
|
||||
required_providers {
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "~> 5.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
resource "vault_policy" "this" {
|
||||
for_each = var.policies
|
||||
|
||||
name = each.key
|
||||
policy = each.value
|
||||
}
|
||||
|
||||
output "names" {
|
||||
description = "Policy names keyed by their requested names."
|
||||
value = { for name, policy in vault_policy.this : name => policy.name }
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
variable "policies" {
|
||||
description = "Map of Vault policy names to HCL policy documents."
|
||||
type = map(string)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_version = ">= 1.11.0"
|
||||
|
||||
required_providers {
|
||||
vault = {
|
||||
source = "hashicorp/vault"
|
||||
version = "~> 5.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user