diff --git a/README.md b/README.md index fb6d51c..1b6171b 100644 --- a/README.md +++ b/README.md @@ -44,15 +44,16 @@ No modules. | [vault_identity_group.this](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/resources/identity_group) | resource | | [vault_policy.extra](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/resources/policy) | resource | | [vault_policy.root](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/resources/policy) | resource | +| [vault_policy_document.root](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/policy_document) | data source | ### Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [additional_roles](#input_additional_roles) | A map of additional role names, with the path to the associated policy file to add for this tenant.
A separate approle auth method is created for this tenant (mounted at auth/-approle) including all the roles declared in this variable.
The variable should look like:
additional_roles = {
devs = {
policy_file = "/some/path/to/policy.hcl"
}
admins = {...}
} |
map(object({
policy_file = string
}))
| `{}` | no | +| [additional_roles](#input_additional_roles) | A map of additional role names, with the path to the associated policy file to add for this tenant.
A separate approle auth method is created for this tenant (mounted at auth/-approle) including all the roles declared in this variable.
The variable should look like:
additional_roles = {
devs = file("path/to/policy.hcl")
admins = data.vault_policy_document.admins.hcl
} | `map(string)` | `{}` | no | | [name](#input_name) | The name of the tenant you want to create | `string` | n/a | yes | | [prefix](#input_prefix) | The prefix to use for the tenant in vault (this will prefix mount points, policies, etc..) | `string` | n/a | yes | -| [root_policy_file](#input_root_policy_file) | The path to the admin policy file for this tenant | `string` | `null` | no | +| [root_policy_extra_rules](#input_root_policy_extra_rules) | A map of additional policies to attach to the root policy. These are merged with the default policies for the root role so that you can customize it to your needs |
map(
object({
path = string
capabilities = list(string)
description = optional(string)
required_parameters = optional(list(string))
allowed_parameter = optional(map(list(any)))
denied_parameter = optional(map(list(any)))
min_wrapping_ttl = optional(number)
max_wrapping_ttl = optional(number)
})
)
| `{}` | no | ### Outputs diff --git a/extra_policies.tf b/extra_policies.tf index 4d9535c..d50ddd7 100644 --- a/extra_policies.tf +++ b/extra_policies.tf @@ -20,7 +20,7 @@ resource "vault_policy" "extra" { for_each = var.additional_roles name = "${var.prefix}-${each.key}" - policy = file(each.value.policy_file) + policy = each.value } resource "vault_identity_entity" "extra" { diff --git a/root.tf b/root.tf index 6a756cb..33f4bd2 100644 --- a/root.tf +++ b/root.tf @@ -1,3 +1,64 @@ +locals { + root_policy_default_rules = { + tenant_prefix_rw = { + path = "${var.prefix}/*" + capabilities = ["create", "update", "read", "delete", "list"] + } + tenant_prefix_mount = { + path = "sys/mounts/${var.prefix}/*" + capabilities = ["create", "update", "read", "delete", "list"] + } + tenant_prefix_remount = { + path = "sys/remount" + capabilities = ["update", "sudo"] + allowed_parameter = { + "from" = ["${var.prefix}/*"] + "to" = ["${var.prefix}/*"] + } + } + tenant_prefix_remount_status = { + path = "sys/remount/status/*" + capabilities = ["read"] + } + } + root_policy_rules = merge(local.root_policy_default_rules, var.root_policy_extra_rules) +} + +data "vault_policy_document" "root" { + dynamic "rule" { + for_each = local.root_policy_rules + content { + path = rule.value.path + capabilities = rule.value.capabilities + description = try(rule.value.description, null) + min_wrapping_ttl = try(rule.value.min_wrapping_ttl, null) + max_wrapping_ttl = try(rule.value.max_wrapping_ttl, null) + required_parameters = try(rule.value.required_parameters, []) + + dynamic "allowed_parameter" { + for_each = try(rule.value.allowed_parameter, null) != null ? rule.value.allowed_parameter : {} + content { + key = allowed_parameter.key + value = allowed_parameter.value + } + } + + dynamic "denied_parameter" { + for_each = try(rule.value.denied_parameter, null) != null ? rule.value.denied_parameter : {} + content { + key = denied_parameter.key + value = denied_parameter.value + } + } + } + } +} + +resource "vault_policy" "root" { + name = "${var.name}-root" + policy = data.vault_policy_document.root.hcl +} + resource "vault_approle_auth_backend_role" "root" { backend = vault_auth_backend.approle.path role_name = "${var.name}-root" @@ -12,11 +73,6 @@ resource "vault_approle_auth_backend_role_secret_id" "root" { secret_id = random_uuid.root_secret_id.result } -resource "vault_policy" "root" { - name = "${var.name}-root" - policy = var.root_policy_file == null ? templatefile("${path.module}/policies/root.policy.hcl", { tenant_prefix = var.prefix }) : file(var.root_policy_file) -} - resource "vault_identity_entity" "root" { name = "${var.prefix}-root" } diff --git a/variables.tf b/variables.tf index 89cc6a1..e639487 100644 --- a/variables.tf +++ b/variables.tf @@ -12,26 +12,33 @@ variable "prefix" { description = "The prefix to use for the tenant in vault (this will prefix mount points, policies, etc..)" } -variable "root_policy_file" { - type = string - default = null - description = "The path to the admin policy file for this tenant" -} - variable "additional_roles" { - type = map(object({ - policy_file = string - })) + type = map(string) default = {} description = <-approle) including all the roles declared in this variable. The variable should look like: additional_roles = { - devs = { - policy_file = "/some/path/to/policy.hcl" - } - admins = {...} + devs = file("path/to/policy.hcl") + admins = data.vault_policy_document.admins.hcl } EOT } + +variable "root_policy_extra_rules" { + type = map( + object({ + path = string + capabilities = list(string) + description = optional(string) + required_parameters = optional(list(string)) + allowed_parameter = optional(map(list(any))) + denied_parameter = optional(map(list(any))) + min_wrapping_ttl = optional(number) + max_wrapping_ttl = optional(number) + }) + ) + description = "A map of additional policies to attach to the root policy. These are merged with the default policies for the root role so that you can customize it to your needs" + default = {} +}