-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 |
+| [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 |
+
+### Outputs
+
+| Name | Description |
+|------|-------------|
+| [approle_mount](#output_approle_mount) | The approle mount for the tenant |
+| [extra_role_policies](#output_extra_role_policies) | The tenant extra role policy names |
+| [extra_roles](#output_extra_roles) | The tenant extra approle roles |
+| [root_policy](#output_root_policy) | The tenant root policy name |
+| [root_role](#output_root_role) | The tenant root approle role |
+
diff --git a/auth.tf b/auth.tf
new file mode 100644
index 0000000..f554194
--- /dev/null
+++ b/auth.tf
@@ -0,0 +1,17 @@
+resource "vault_auth_backend" "approle" {
+ type = "approle"
+ path = "${var.prefix}/approle"
+ tune {
+ default_lease_ttl = "3600s"
+ max_lease_ttl = "14400s"
+ }
+}
+
+resource "vault_identity_group" "this" {
+ name = var.name
+ type = "internal"
+ metadata = {
+ tenant = var.name
+ prefix = var.prefix
+ }
+}
diff --git a/examples/.gitkeep b/examples/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/extra_policies.tf b/extra_policies.tf
new file mode 100644
index 0000000..4d9535c
--- /dev/null
+++ b/extra_policies.tf
@@ -0,0 +1,38 @@
+resource "vault_approle_auth_backend_role" "extra" {
+ for_each = var.additional_roles
+
+ backend = vault_auth_backend.approle.path
+ role_name = each.key
+ token_policies = ["default", "${vault_policy.extra[each.key].name}"]
+}
+
+resource "random_uuid" "extra_secret_id" { for_each = var.additional_roles }
+
+resource "vault_approle_auth_backend_role_secret_id" "extra" {
+ for_each = var.additional_roles
+
+ backend = vault_auth_backend.approle.path
+ role_name = vault_approle_auth_backend_role.extra[each.key].role_name
+ secret_id = random_uuid.extra_secret_id[each.key].result
+}
+
+resource "vault_policy" "extra" {
+ for_each = var.additional_roles
+
+ name = "${var.prefix}-${each.key}"
+ policy = file(each.value.policy_file)
+}
+
+resource "vault_identity_entity" "extra" {
+ for_each = var.additional_roles
+
+ name = "${var.prefix}-${each.key}"
+}
+
+resource "vault_identity_entity_alias" "extra" {
+ for_each = var.additional_roles
+
+ name = vault_approle_auth_backend_role.extra[each.key].role_id
+ mount_accessor = vault_auth_backend.approle.accessor
+ canonical_id = vault_identity_entity.extra[each.key].id
+}
diff --git a/main.tf b/main.tf
new file mode 100644
index 0000000..cfa3b67
--- /dev/null
+++ b/main.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_version = ">= 1.0.0"
+ required_providers {
+ vault = {
+ source = "hashicorp/vault"
+ version = "~> 4.2.0"
+ }
+ random = {
+ source = "hashicorp/random"
+ version = "~> 3.6.2"
+ }
+ }
+}
diff --git a/modules/.gitkeep b/modules/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/outputs.tf b/outputs.tf
new file mode 100644
index 0000000..7d2c537
--- /dev/null
+++ b/outputs.tf
@@ -0,0 +1,52 @@
+output "approle_mount" {
+ value = vault_auth_backend.approle
+ sensitive = true
+ description = "The approle mount for the tenant"
+}
+
+
+output "root_role" {
+ value = {
+ role_id = vault_approle_auth_backend_role.root.role_name
+ secret_id = vault_approle_auth_backend_role_secret_id.root.secret_id
+ }
+ sensitive = true
+ description = "The tenant root approle role"
+ depends_on = [
+ vault_approle_auth_backend_role.root,
+ vault_approle_auth_backend_role_secret_id.root
+ ]
+}
+
+output "root_policy" {
+ value = vault_policy.root.name
+ sensitive = false
+ description = "The tenant root policy name"
+ depends_on = [vault_policy.root]
+}
+
+output "extra_roles" {
+ value = {
+ for key, role in vault_approle_auth_backend_role.extra :
+ key => {
+ role_id = role.role_name
+ secret_id = vault_approle_auth_backend_role_secret_id.extra[key].secret_id
+ }
+ }
+ sensitive = true
+ description = "The tenant extra approle roles"
+ depends_on = [
+ vault_approle_auth_backend_role.extra,
+ vault_approle_auth_backend_role_secret_id.extra
+ ]
+}
+
+output "extra_role_policies" {
+ value = {
+ for key, policy in vault_policy.extra :
+ key => policy.name
+ }
+ sensitive = false
+ description = "The tenant extra role policy names"
+ depends_on = [vault_policy.extra]
+}
diff --git a/policies/root.policy.hcl b/policies/root.policy.hcl
new file mode 100644
index 0000000..9aeeaa9
--- /dev/null
+++ b/policies/root.policy.hcl
@@ -0,0 +1,19 @@
+path "${tenant_prefix}/*" {
+ capabilities = ["create", "update", "read", "delete", "list"]
+}
+
+path "sys/mounts/${tenant_prefix}/*" {
+ capabilities = ["create", "update", "read", "delete", "list"]
+}
+
+path "sys/remount" {
+ capabilities = ["update", "sudo"]
+ allowed_parameters = {
+ "from" = ["${tenant_prefix}/*"]
+ "to" = ["${tenant_prefix}/*"]
+ }
+}
+
+path "sys/remount/status/*" {
+ capabilities = ["read"]
+}
diff --git a/root.tf b/root.tf
new file mode 100644
index 0000000..6a756cb
--- /dev/null
+++ b/root.tf
@@ -0,0 +1,28 @@
+resource "vault_approle_auth_backend_role" "root" {
+ backend = vault_auth_backend.approle.path
+ role_name = "${var.name}-root"
+ token_policies = ["default", vault_policy.root.name]
+}
+
+resource "random_uuid" "root_secret_id" {}
+
+resource "vault_approle_auth_backend_role_secret_id" "root" {
+ backend = vault_auth_backend.approle.path
+ role_name = vault_approle_auth_backend_role.root.role_name
+ 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"
+}
+
+resource "vault_identity_entity_alias" "root" {
+ name = vault_approle_auth_backend_role.root.role_id
+ mount_accessor = vault_auth_backend.approle.accessor
+ canonical_id = vault_identity_entity.root.id
+}
diff --git a/variables.tf b/variables.tf
new file mode 100644
index 0000000..89cc6a1
--- /dev/null
+++ b/variables.tf
@@ -0,0 +1,37 @@
+variable "name" {
+ type = string
+ description = "The name of the tenant you want to create"
+ validation {
+ condition = can(regex("^[-a-zA-Z0-9_]*$", var.name))
+ error_message = "The tenant name must only contain alphanumeric characters, dashes, and underscores."
+ }
+}
+
+variable "prefix" {
+ type = string
+ 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
+ }))
+ 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 = {...}
+ }
+ EOT
+}