feat: major restructuring in migration to terragrunt
- migrate from individual terraform files to config-driven terragrunt module structure - add vault_cluster module with config discovery system - replace individual .tf files with centralized config.hcl - restructure auth and secret backends as configurable modules - move auth roles and secret backends to yaml-based configuration - convert policies from .hcl to .yaml format, add rules/auth definition - add pre-commit hooks for yaml formatting and file cleanup - add terragrunt cache to gitignore - update makefile with terragrunt commands and format target
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
|
||||
resource "vault_auth_backend" "approle" {
|
||||
type = "approle"
|
||||
path = var.path
|
||||
|
||||
tune {
|
||||
default_lease_ttl = var.default_lease_ttl
|
||||
max_lease_ttl = var.max_lease_ttl
|
||||
listing_visibility = var.listing_visibility
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
output "backend" {
|
||||
description = "The created auth backend"
|
||||
value = vault_auth_backend.approle
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "path" {
|
||||
description = "Mount path of the AppRole auth backend"
|
||||
type = string
|
||||
default = "approle"
|
||||
}
|
||||
|
||||
variable "listing_visibility" {
|
||||
description = "Specifies whether to show this mount in the UI-specific listing endpoint. Valid values are 'unauth' or 'hidden'"
|
||||
type = string
|
||||
default = null
|
||||
validation {
|
||||
condition = var.listing_visibility == null || contains(["unauth", "hidden"], var.listing_visibility)
|
||||
error_message = "listing_visibility must be either 'unauth' or 'hidden'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "default_lease_ttl" {
|
||||
description = "Specifies the default time-to-live. If set, this overrides the global default. Must be a valid duration string"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "max_lease_ttl" {
|
||||
description = "Specifies the maximum time-to-live. If set, this overrides the global default. Must be a valid duration string"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
# Expected keys in KV secret for salt: salt
|
||||
data "vault_kv_secret_v2" "salt_config" {
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/auth_backend/${var.mount_path}"
|
||||
}
|
||||
|
||||
# Expected keys in KV secret for role_id: role_id (when use_deterministic_role_id = false)
|
||||
data "vault_kv_secret_v2" "role_config" {
|
||||
count = var.use_deterministic_role_id ? 0 : 1
|
||||
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/auth_approle_role/${var.mount_path}/${var.approle_name}"
|
||||
}
|
||||
|
||||
locals {
|
||||
salt = data.vault_kv_secret_v2.salt_config.data["salt"]
|
||||
role_id_input = "${local.salt}-${var.approle_name}-${var.mount_path}"
|
||||
deterministic_role_id = uuidv5("dns", "${local.role_id_input}")
|
||||
|
||||
# Use deterministic role-id by default, or read from KV if specified
|
||||
role_id = var.use_deterministic_role_id ? local.deterministic_role_id : data.vault_kv_secret_v2.role_config[0].data["role_id"]
|
||||
}
|
||||
|
||||
resource "vault_approle_auth_backend_role" "role" {
|
||||
backend = var.mount_path
|
||||
role_name = var.approle_name
|
||||
role_id = local.role_id
|
||||
token_policies = var.token_policies
|
||||
token_ttl = var.token_ttl
|
||||
token_max_ttl = var.token_max_ttl
|
||||
bind_secret_id = var.bind_secret_id
|
||||
secret_id_ttl = var.secret_id_ttl
|
||||
token_bound_cidrs = var.token_bound_cidrs
|
||||
alias_metadata = var.alias_metadata
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
|
||||
variable "approle_name" {
|
||||
description = "Name of the AppRole role"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "mount_path" {
|
||||
description = "Mount path of the AppRole auth backend"
|
||||
type = string
|
||||
default = "approle"
|
||||
}
|
||||
|
||||
variable "token_policies" {
|
||||
description = "List of policies to assign to the role (passed from policy_auth_map)"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "token_ttl" {
|
||||
description = "The TTL period of tokens issued using this role"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "token_max_ttl" {
|
||||
description = "The maximum TTL period of tokens issued using this role"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "bind_secret_id" {
|
||||
description = "Whether or not to require secret_id to be presented when logging in using this AppRole"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "secret_id_ttl" {
|
||||
description = "The TTL period of SecretIDs generated against this AppRole"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "token_bound_cidrs" {
|
||||
description = "List of CIDR blocks that can authenticate using this role"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "alias_metadata" {
|
||||
description = "The metadata to be tied to generated entity alias. This should be a list or map containing the metadata in key value pairs"
|
||||
type = map(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "use_deterministic_role_id" {
|
||||
description = "Whether to use deterministic role-id generation (true) or read pre-generated role-id from KV (false)"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
# Expected keys in KV secret: kubernetes_ca_cert, token_reviewer_jwt
|
||||
data "vault_kv_secret_v2" "auth_backend_config" {
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/auth_backend/${var.path}"
|
||||
}
|
||||
|
||||
resource "vault_auth_backend" "kubernetes" {
|
||||
type = "kubernetes"
|
||||
path = var.path
|
||||
|
||||
tune {
|
||||
default_lease_ttl = var.default_lease_ttl
|
||||
max_lease_ttl = var.max_lease_ttl
|
||||
listing_visibility = var.listing_visibility
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_kubernetes_auth_backend_config" "config" {
|
||||
backend = vault_auth_backend.kubernetes.path
|
||||
kubernetes_host = var.kubernetes_host
|
||||
kubernetes_ca_cert = data.vault_kv_secret_v2.auth_backend_config.data["kubernetes_ca_cert"]
|
||||
token_reviewer_jwt = data.vault_kv_secret_v2.auth_backend_config.data["token_reviewer_jwt"]
|
||||
disable_iss_validation = var.disable_iss_validation
|
||||
use_annotations_as_alias_metadata = var.use_annotations_as_alias_metadata
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "path" {
|
||||
description = "Mount path of the Kubernetes auth backend"
|
||||
type = string
|
||||
default = "kubernetes"
|
||||
}
|
||||
|
||||
variable "disable_iss_validation" {
|
||||
description = "Disable JWT issuer validation"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "use_annotations_as_alias_metadata" {
|
||||
description = "Use annotations as alias metadata"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "listing_visibility" {
|
||||
description = "Specifies whether to show this mount in the UI-specific listing endpoint. Valid values are 'unauth' or 'hidden'"
|
||||
type = string
|
||||
default = null
|
||||
validation {
|
||||
condition = var.listing_visibility == null || contains(["unauth", "hidden"], var.listing_visibility)
|
||||
error_message = "listing_visibility must be either 'unauth' or 'hidden'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "default_lease_ttl" {
|
||||
description = "Specifies the default time-to-live. If set, this overrides the global default. Must be a valid duration string"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "max_lease_ttl" {
|
||||
description = "Specifies the maximum time-to-live. If set, this overrides the global default. Must be a valid duration string"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "kubernetes_host" {
|
||||
description = "Host must be a host string, a host:port pair, or a URL to the base of the Kubernetes API server"
|
||||
type = string
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
resource "vault_kubernetes_auth_backend_role" "role" {
|
||||
backend = var.backend
|
||||
role_name = var.role_name
|
||||
bound_service_account_names = var.bound_service_account_names
|
||||
bound_service_account_namespaces = var.bound_service_account_namespaces
|
||||
token_ttl = var.token_ttl
|
||||
token_policies = var.token_policies
|
||||
audience = var.audience
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
variable "backend" {
|
||||
description = "The unique path of the Kubernetes auth backend to configure"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "role_name" {
|
||||
description = "The name of the role"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "bound_service_account_names" {
|
||||
description = "List of service account names able to access this role"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "bound_service_account_namespaces" {
|
||||
description = "List of namespaces allowed to access this role"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "token_ttl" {
|
||||
description = "The TTL period of tokens issued using this role, in seconds"
|
||||
type = number
|
||||
default = 3600
|
||||
}
|
||||
|
||||
variable "token_policies" {
|
||||
description = "List of policies to assign to the role (passed from policy_auth_map)"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "audience" {
|
||||
description = "Audience claim to verify in the JWT"
|
||||
type = string
|
||||
default = "vault"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
# Expected keys in KV secret: url, binddn, bindpass
|
||||
data "vault_kv_secret_v2" "auth_backend_config" {
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/auth_backend/${var.path}"
|
||||
}
|
||||
|
||||
resource "vault_ldap_auth_backend" "ldap" {
|
||||
path = var.path
|
||||
url = data.vault_kv_secret_v2.auth_backend_config.data["url"]
|
||||
userdn = var.userdn
|
||||
userattr = var.userattr
|
||||
upndomain = var.upndomain
|
||||
discoverdn = var.discoverdn
|
||||
groupdn = var.groupdn
|
||||
groupfilter = var.groupfilter
|
||||
groupattr = var.groupattr
|
||||
binddn = data.vault_kv_secret_v2.auth_backend_config.data["binddn"]
|
||||
bindpass = data.vault_kv_secret_v2.auth_backend_config.data["bindpass"]
|
||||
alias_metadata = var.alias_metadata
|
||||
username_as_alias = var.username_as_alias
|
||||
|
||||
tune {
|
||||
default_lease_ttl = var.default_lease_ttl
|
||||
max_lease_ttl = var.max_lease_ttl
|
||||
listing_visibility = var.listing_visibility
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "path" {
|
||||
description = "Mount path of the LDAP auth backend"
|
||||
type = string
|
||||
default = "ldap"
|
||||
}
|
||||
|
||||
variable "userdn" {
|
||||
description = "Base DN under which to perform user search"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "userattr" {
|
||||
description = "Attribute on user objects matching the username"
|
||||
type = string
|
||||
default = "uid"
|
||||
}
|
||||
|
||||
variable "upndomain" {
|
||||
description = "UPN domain for users"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "discoverdn" {
|
||||
description = "Use anonymous bind to discover the bind DN of a user"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "groupdn" {
|
||||
description = "Base DN under which to perform group search"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "groupfilter" {
|
||||
description = "Go template for querying group membership"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "groupattr" {
|
||||
description = "LDAP attribute to follow on objects returned by groupfilter"
|
||||
type = string
|
||||
default = "cn"
|
||||
}
|
||||
|
||||
|
||||
variable "listing_visibility" {
|
||||
description = "Specifies whether to show this mount in the UI-specific listing endpoint. Valid values are 'unauth' or 'hidden'"
|
||||
type = string
|
||||
default = null
|
||||
validation {
|
||||
condition = var.listing_visibility == null || contains(["unauth", "hidden"], var.listing_visibility)
|
||||
error_message = "listing_visibility must be either 'unauth' or 'hidden'."
|
||||
}
|
||||
}
|
||||
|
||||
variable "default_lease_ttl" {
|
||||
description = "Specifies the default time-to-live. If set, this overrides the global default. Must be a valid duration string"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "max_lease_ttl" {
|
||||
description = "Specifies the maximum time-to-live. If set, this overrides the global default. Must be a valid duration string"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "alias_metadata" {
|
||||
description = "The metadata to be tied to generated entity alias. This should be a list or map containing the metadata in key value pairs"
|
||||
type = map(string)
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "username_as_alias" {
|
||||
description = "Force the auth method to use the username passed by the user as the alias name"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
resource "vault_ldap_auth_backend_group" "group" {
|
||||
groupname = var.groupname
|
||||
policies = var.policies
|
||||
backend = var.backend
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
variable "groupname" {
|
||||
description = "Name of the LDAP group"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "policies" {
|
||||
description = "List of policies to assign to the LDAP group"
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "backend" {
|
||||
description = "Path of the LDAP auth backend"
|
||||
type = string
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Expected keys in KV secret: token (if not bootstrapping)
|
||||
data "vault_kv_secret_v2" "secret_backend_config" {
|
||||
count = var.bootstrap ? 0 : 1
|
||||
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/secret_backend/${var.path}"
|
||||
}
|
||||
|
||||
resource "vault_consul_secret_backend" "consul" {
|
||||
path = var.path
|
||||
description = var.description
|
||||
address = var.address
|
||||
token = var.bootstrap ? null : data.vault_kv_secret_v2.secret_backend_config[0].data["token"]
|
||||
bootstrap = var.bootstrap
|
||||
scheme = var.scheme
|
||||
ca_cert = var.ca_cert
|
||||
client_cert = var.client_cert
|
||||
client_key = var.client_key
|
||||
default_lease_ttl_seconds = var.default_lease_ttl_seconds
|
||||
max_lease_ttl_seconds = var.max_lease_ttl_seconds
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "path" {
|
||||
description = "Mount path of the Consul secrets engine"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Human-friendly description of the mount"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "address" {
|
||||
description = "The address of the Consul instance"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "bootstrap" {
|
||||
description = "Whether to bootstrap the Consul backend"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "scheme" {
|
||||
description = "The scheme to use when connecting to Consul"
|
||||
type = string
|
||||
default = "https"
|
||||
}
|
||||
|
||||
variable "ca_cert" {
|
||||
description = "CA certificate for TLS verification"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "client_cert" {
|
||||
description = "Client certificate for TLS authentication"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "client_key" {
|
||||
description = "Client key for TLS authentication"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "default_lease_ttl_seconds" {
|
||||
description = "Default lease TTL in seconds"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "max_lease_ttl_seconds" {
|
||||
description = "Maximum lease TTL in seconds"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
resource "vault_consul_secret_backend_role" "role" {
|
||||
backend = var.backend
|
||||
name = var.name
|
||||
consul_roles = var.consul_roles
|
||||
ttl = var.ttl
|
||||
max_ttl = var.max_ttl
|
||||
local = var.local
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
variable "backend" {
|
||||
description = "The unique path where the Consul backend is mounted"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "The name of the role"
|
||||
type = string
|
||||
}
|
||||
|
||||
|
||||
variable "consul_roles" {
|
||||
description = "List of Consul roles to attach to tokens"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
|
||||
variable "ttl" {
|
||||
description = "TTL for generated tokens"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "max_ttl" {
|
||||
description = "Maximum TTL for generated tokens"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "local" {
|
||||
description = "Whether tokens should be local to the datacenter"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
# Expected keys in KV secret: service_account_jwt, kubernetes_ca_cert
|
||||
data "vault_kv_secret_v2" "secret_backend_config" {
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/secret_backend/${var.path}"
|
||||
}
|
||||
|
||||
resource "vault_kubernetes_secret_backend" "kubernetes" {
|
||||
path = var.path
|
||||
description = var.description
|
||||
default_lease_ttl_seconds = var.default_lease_ttl_seconds
|
||||
max_lease_ttl_seconds = var.max_lease_ttl_seconds
|
||||
kubernetes_host = var.kubernetes_host
|
||||
kubernetes_ca_cert = data.vault_kv_secret_v2.secret_backend_config.data["kubernetes_ca_cert"]
|
||||
service_account_jwt = data.vault_kv_secret_v2.secret_backend_config.data["service_account_jwt"]
|
||||
disable_local_ca_jwt = var.disable_local_ca_jwt
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "path" {
|
||||
description = "Mount path of the Kubernetes secrets engine"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Human-friendly description of the mount"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "default_lease_ttl_seconds" {
|
||||
description = "Default lease TTL in seconds"
|
||||
type = number
|
||||
default = 600
|
||||
}
|
||||
|
||||
variable "max_lease_ttl_seconds" {
|
||||
description = "Maximum lease TTL in seconds"
|
||||
type = number
|
||||
default = 86400
|
||||
}
|
||||
|
||||
variable "kubernetes_host" {
|
||||
description = "The Kubernetes API server URL"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "disable_local_ca_jwt" {
|
||||
description = "Whether to disable local CA JWT validation"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
locals {
|
||||
# Auto-generate role rules path: resources/secret_backend/{backend_path}/roles/{role_name}.yaml
|
||||
role_rules_file = "resources/secret_backend/${var.backend}/roles/${var.name}.yaml"
|
||||
|
||||
# Auto-generate extra labels based on country/region and role name
|
||||
auto_labels = merge(var.extra_labels, {
|
||||
vault-region = "${var.country}-${var.region}"
|
||||
vault-role = var.name
|
||||
})
|
||||
}
|
||||
|
||||
resource "vault_kubernetes_secret_backend_role" "role" {
|
||||
backend = var.backend
|
||||
name = var.name
|
||||
allowed_kubernetes_namespaces = var.allowed_kubernetes_namespaces
|
||||
kubernetes_role_type = var.kubernetes_role_type
|
||||
generated_role_rules = file("${path.module}/../../../../../../../../${local.role_rules_file}")
|
||||
extra_labels = local.auto_labels
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "backend" {
|
||||
description = "The unique path where the Kubernetes backend is mounted"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "The name of the role"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "allowed_kubernetes_namespaces" {
|
||||
description = "List of allowed Kubernetes namespaces"
|
||||
type = list(string)
|
||||
default = ["*"]
|
||||
}
|
||||
|
||||
variable "kubernetes_role_type" {
|
||||
description = "Type of Kubernetes role (Role or ClusterRole)"
|
||||
type = string
|
||||
default = "Role"
|
||||
}
|
||||
|
||||
variable "extra_labels" {
|
||||
description = "Additional labels to apply to generated Kubernetes objects"
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
resource "vault_mount" "kv" {
|
||||
path = var.path
|
||||
type = "kv"
|
||||
description = var.description
|
||||
|
||||
options = {
|
||||
version = var.kv_version
|
||||
type = var.type
|
||||
}
|
||||
}
|
||||
|
||||
resource "vault_kv_secret_backend_v2" "config" {
|
||||
count = var.type == "kv-v2" && var.max_versions != null ? 1 : 0
|
||||
|
||||
mount = vault_mount.kv.path
|
||||
max_versions = var.max_versions
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
variable "path" {
|
||||
description = "Mount path of the KV secrets engine"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "type" {
|
||||
description = "Type of the secrets engine"
|
||||
type = string
|
||||
default = "kv-v2"
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Human-friendly description of the mount"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "kv_version" {
|
||||
description = "KV secrets engine version"
|
||||
type = string
|
||||
default = "2"
|
||||
}
|
||||
|
||||
variable "max_versions" {
|
||||
description = "Maximum number of versions to keep per key"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
resource "vault_mount" "pki" {
|
||||
path = var.path
|
||||
type = "pki"
|
||||
description = var.description
|
||||
max_lease_ttl_seconds = var.max_lease_ttl_seconds
|
||||
}
|
||||
|
||||
data "vault_pki_secret_backend_issuer" "issuer" {
|
||||
backend = vault_mount.pki.path
|
||||
issuer_ref = var.issuer_ref
|
||||
}
|
||||
|
||||
resource "vault_pki_secret_backend_config_urls" "config_urls" {
|
||||
backend = vault_mount.pki.path
|
||||
|
||||
issuing_certificates = var.issuing_certificates
|
||||
crl_distribution_points = var.crl_distribution_points
|
||||
ocsp_servers = var.ocsp_servers
|
||||
enable_templating = var.enable_templating
|
||||
}
|
||||
|
||||
resource "vault_pki_secret_backend_config_issuers" "issuers" {
|
||||
count = var.default_issuer_ref != null ? 1 : 0
|
||||
|
||||
backend = vault_mount.pki.path
|
||||
default = var.default_issuer_ref
|
||||
default_follows_latest_issuer = var.default_follows_latest_issuer
|
||||
}
|
||||
|
||||
resource "vault_pki_secret_backend_crl_config" "crl" {
|
||||
backend = vault_mount.pki.path
|
||||
expiry = var.crl_expiry
|
||||
disable = var.crl_disable
|
||||
ocsp_disable = var.ocsp_disable
|
||||
auto_rebuild = var.auto_rebuild
|
||||
enable_delta = var.enable_delta
|
||||
delta_rebuild_interval = var.delta_rebuild_interval
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
variable "path" {
|
||||
description = "Path where the PKI backend will be mounted"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Description of the PKI mount"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "max_lease_ttl_seconds" {
|
||||
description = "Maximum possible lease duration for tokens and secrets in seconds"
|
||||
type = number
|
||||
}
|
||||
|
||||
variable "issuer_ref" {
|
||||
description = "Reference to the PKI issuer (default, or issuer ID/name)"
|
||||
type = string
|
||||
default = "default"
|
||||
}
|
||||
|
||||
variable "issuing_certificates" {
|
||||
description = "List of URLs for issuing certificates"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "crl_distribution_points" {
|
||||
description = "List of URLs for CRL distribution points"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "ocsp_servers" {
|
||||
description = "List of OCSP server URLs"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "enable_templating" {
|
||||
description = "Whether to enable URL templating"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "default_issuer_ref" {
|
||||
description = "Default issuer reference"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "default_follows_latest_issuer" {
|
||||
description = "Whether the default issuer follows the latest issuer"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "crl_expiry" {
|
||||
description = "CRL expiry time"
|
||||
type = string
|
||||
default = "72h"
|
||||
}
|
||||
|
||||
variable "crl_disable" {
|
||||
description = "Whether to disable CRL"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "ocsp_disable" {
|
||||
description = "Whether to disable OCSP"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "auto_rebuild" {
|
||||
description = "Whether to enable auto rebuild of CRL"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "enable_delta" {
|
||||
description = "Whether to enable delta CRL"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "delta_rebuild_interval" {
|
||||
description = "Delta CRL rebuild interval"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
resource "vault_mount" "pki" {
|
||||
path = var.path
|
||||
type = "pki"
|
||||
description = var.description
|
||||
max_lease_ttl_seconds = var.max_lease_ttl_seconds
|
||||
}
|
||||
|
||||
resource "vault_pki_secret_backend_root_cert" "root_cert" {
|
||||
backend = vault_mount.pki.path
|
||||
common_name = var.common_name
|
||||
issuer_name = var.issuer_name
|
||||
ttl = var.ttl
|
||||
format = var.format
|
||||
type = "internal"
|
||||
}
|
||||
|
||||
data "vault_pki_secret_backend_issuer" "issuer" {
|
||||
backend = vault_mount.pki.path
|
||||
issuer_ref = vault_pki_secret_backend_root_cert.root_cert.issuer_id
|
||||
|
||||
depends_on = [vault_pki_secret_backend_root_cert.root_cert]
|
||||
}
|
||||
|
||||
resource "vault_pki_secret_backend_config_urls" "urls" {
|
||||
backend = vault_mount.pki.path
|
||||
|
||||
issuing_certificates = var.issuing_certificates
|
||||
crl_distribution_points = var.crl_distribution_points
|
||||
ocsp_servers = var.ocsp_servers
|
||||
enable_templating = var.enable_templating
|
||||
}
|
||||
|
||||
resource "vault_pki_secret_backend_config_issuers" "issuers" {
|
||||
backend = vault_mount.pki.path
|
||||
default = data.vault_pki_secret_backend_issuer.issuer.issuer_id
|
||||
default_follows_latest_issuer = var.default_follows_latest_issuer
|
||||
|
||||
depends_on = [
|
||||
vault_pki_secret_backend_root_cert.root_cert,
|
||||
data.vault_pki_secret_backend_issuer.issuer
|
||||
]
|
||||
}
|
||||
|
||||
resource "vault_pki_secret_backend_crl_config" "crl" {
|
||||
backend = vault_mount.pki.path
|
||||
expiry = var.crl_expiry
|
||||
disable = var.crl_disable
|
||||
ocsp_disable = var.ocsp_disable
|
||||
auto_rebuild = var.auto_rebuild
|
||||
enable_delta = var.enable_delta
|
||||
delta_rebuild_interval = var.delta_rebuild_interval
|
||||
|
||||
depends_on = [vault_pki_secret_backend_root_cert.root_cert]
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
variable "path" {
|
||||
description = "Mount path of the PKI secrets engine"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Human-friendly description of the mount"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "max_lease_ttl_seconds" {
|
||||
description = "Maximum lease TTL in seconds"
|
||||
type = number
|
||||
default = 315360000 # 87600 * 3600
|
||||
}
|
||||
|
||||
variable "common_name" {
|
||||
description = "Common name for the root certificate"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "issuer_name" {
|
||||
description = "Name for the root CA issuer"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "ttl" {
|
||||
description = "TTL for the root certificate in seconds"
|
||||
type = number
|
||||
default = 315360000 # 87600 * 3600
|
||||
}
|
||||
|
||||
variable "format" {
|
||||
description = "Format for the certificate"
|
||||
type = string
|
||||
default = "pem"
|
||||
}
|
||||
|
||||
variable "issuing_certificates" {
|
||||
description = "List of issuing certificate URLs"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "crl_distribution_points" {
|
||||
description = "List of CRL distribution point URLs"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "ocsp_servers" {
|
||||
description = "List of OCSP server URLs"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "enable_templating" {
|
||||
description = "Whether to enable templating for URL configuration"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "default_issuer_ref" {
|
||||
description = "Reference to the default issuer"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "default_follows_latest_issuer" {
|
||||
description = "Whether the default issuer should follow the latest issuer"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "crl_expiry" {
|
||||
description = "CRL expiration time"
|
||||
type = string
|
||||
default = "72h"
|
||||
}
|
||||
|
||||
variable "crl_disable" {
|
||||
description = "Whether to disable CRL"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "ocsp_disable" {
|
||||
description = "Whether to disable OCSP"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "auto_rebuild" {
|
||||
description = "Whether to auto-rebuild CRL"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "enable_delta" {
|
||||
description = "Whether to enable delta CRL"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "delta_rebuild_interval" {
|
||||
description = "Delta CRL rebuild interval"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
resource "vault_pki_secret_backend_role" "role" {
|
||||
backend = var.backend
|
||||
name = var.name
|
||||
allow_ip_sans = var.allow_ip_sans
|
||||
allowed_domains = var.allowed_domains
|
||||
allow_subdomains = var.allow_subdomains
|
||||
allow_glob_domains = var.allow_glob_domains
|
||||
allow_bare_domains = var.allow_bare_domains
|
||||
enforce_hostnames = var.enforce_hostnames
|
||||
allow_any_name = var.allow_any_name
|
||||
max_ttl = var.max_ttl
|
||||
key_bits = var.key_bits
|
||||
country = var.country
|
||||
use_csr_common_name = var.use_csr_common_name
|
||||
use_csr_sans = var.use_csr_sans
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
variable "backend" {
|
||||
description = "The unique path where the PKI backend is mounted"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "The name of the role"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "allow_ip_sans" {
|
||||
description = "Whether IP Subject Alternative Names are allowed"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allowed_domains" {
|
||||
description = "List of allowed domains for certificates"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "allow_subdomains" {
|
||||
description = "Whether subdomains are allowed"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allow_glob_domains" {
|
||||
description = "Whether glob domains are allowed"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allow_bare_domains" {
|
||||
description = "Whether bare domains are allowed"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "enforce_hostnames" {
|
||||
description = "Whether to enforce hostnames"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allow_any_name" {
|
||||
description = "Whether any name is allowed"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "max_ttl" {
|
||||
description = "Maximum TTL for certificates in seconds"
|
||||
type = number
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "key_bits" {
|
||||
description = "Number of bits for the key"
|
||||
type = number
|
||||
default = 4096
|
||||
}
|
||||
|
||||
variable "country" {
|
||||
description = "List of countries for certificate subject"
|
||||
type = list(string)
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "use_csr_common_name" {
|
||||
description = "Whether to use CSR common name"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "use_csr_sans" {
|
||||
description = "Whether to use CSR Subject Alternative Names"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
resource "vault_mount" "ssh" {
|
||||
path = var.path
|
||||
type = "ssh"
|
||||
description = var.description
|
||||
max_lease_ttl_seconds = var.max_lease_ttl_seconds
|
||||
}
|
||||
|
||||
resource "vault_ssh_secret_backend_ca" "ssh_ca" {
|
||||
count = var.generate_signing_key != null ? 1 : 0
|
||||
|
||||
backend = vault_mount.ssh.path
|
||||
generate_signing_key = var.generate_signing_key
|
||||
key_type = var.key_type
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
variable "path" {
|
||||
description = "Mount path of the SSH secrets engine"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Human-friendly description of the mount"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "max_lease_ttl_seconds" {
|
||||
description = "Maximum lease TTL in seconds"
|
||||
type = number
|
||||
default = 315360000 # 87600 * 3600
|
||||
}
|
||||
|
||||
variable "generate_signing_key" {
|
||||
description = "Whether to generate a signing key for the CA"
|
||||
type = bool
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "key_type" {
|
||||
description = "Type of key to generate for the CA"
|
||||
type = string
|
||||
default = "ssh-rsa"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
resource "vault_ssh_secret_backend_role" "role" {
|
||||
backend = var.backend
|
||||
name = var.name
|
||||
key_type = var.key_type
|
||||
algorithm_signer = var.algorithm_signer
|
||||
ttl = var.ttl
|
||||
allow_host_certificates = var.allow_host_certificates
|
||||
allow_user_certificates = var.allow_user_certificates
|
||||
allowed_domains = var.allowed_domains
|
||||
allow_subdomains = var.allow_subdomains
|
||||
allow_bare_domains = var.allow_bare_domains
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
variable "backend" {
|
||||
description = "The unique path where the SSH backend is mounted"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "The name of the role"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "key_type" {
|
||||
description = "The type of key used by this role"
|
||||
type = string
|
||||
default = "ca"
|
||||
}
|
||||
|
||||
variable "algorithm_signer" {
|
||||
description = "Algorithm used to sign certificates"
|
||||
type = string
|
||||
default = "rsa-sha2-256"
|
||||
}
|
||||
|
||||
variable "ttl" {
|
||||
description = "TTL for certificates issued by this role"
|
||||
type = number
|
||||
default = 315360000 # 87600 * 3600
|
||||
}
|
||||
|
||||
variable "allow_host_certificates" {
|
||||
description = "Whether this role can issue host certificates"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allow_user_certificates" {
|
||||
description = "Whether this role can issue user certificates"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allowed_domains" {
|
||||
description = "List of allowed domains for certificates"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "allow_subdomains" {
|
||||
description = "Whether subdomains are allowed"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allow_bare_domains" {
|
||||
description = "Whether bare domains are allowed"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
resource "vault_mount" "transit" {
|
||||
path = var.path
|
||||
type = "transit"
|
||||
description = var.description
|
||||
default_lease_ttl_seconds = var.default_lease_ttl_seconds
|
||||
max_lease_ttl_seconds = var.max_lease_ttl_seconds
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
variable "path" {
|
||||
description = "Mount path of the transit secrets engine"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "description" {
|
||||
description = "Human-friendly description of the mount"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "default_lease_ttl_seconds" {
|
||||
description = "Default lease TTL in seconds"
|
||||
type = number
|
||||
default = 3600
|
||||
}
|
||||
|
||||
variable "max_lease_ttl_seconds" {
|
||||
description = "Maximum lease TTL in seconds"
|
||||
type = number
|
||||
default = 86400
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
resource "vault_transit_secret_backend_key" "key" {
|
||||
backend = var.backend
|
||||
name = var.name
|
||||
type = var.type
|
||||
deletion_allowed = var.deletion_allowed
|
||||
derived = var.derived
|
||||
exportable = var.exportable
|
||||
allow_plaintext_backup = var.allow_plaintext_backup
|
||||
auto_rotate_period = var.auto_rotate_period
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
variable "backend" {
|
||||
description = "The unique path where the transit backend is mounted"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "name" {
|
||||
description = "The name of the encryption key"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "type" {
|
||||
description = "The type of key to create"
|
||||
type = string
|
||||
default = "aes256-gcm96"
|
||||
}
|
||||
|
||||
variable "deletion_allowed" {
|
||||
description = "Whether the key is allowed to be deleted"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "derived" {
|
||||
description = "Whether the key supports key derivation"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "exportable" {
|
||||
description = "Whether the key is exportable"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "allow_plaintext_backup" {
|
||||
description = "Whether the key supports plaintext backup"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "auto_rotate_period" {
|
||||
description = "Period for automatic key rotation"
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
locals {
|
||||
policy_hcl = join("\n", [
|
||||
for rule in var.policy_rules :
|
||||
"path \"${rule.path}\" {\n capabilities = ${jsonencode(rule.capabilities)}\n}"
|
||||
])
|
||||
}
|
||||
|
||||
resource "vault_policy" "this" {
|
||||
name = var.policy_name
|
||||
policy = local.policy_hcl
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
variable "policy_name" {
|
||||
description = "Name of the Vault policy"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "policy_rules" {
|
||||
description = "List of policy rules for this policy"
|
||||
type = list(object({
|
||||
path = string
|
||||
capabilities = list(string)
|
||||
}))
|
||||
}
|
||||
Reference in New Issue
Block a user