feat: implement consul ACL management with provider aliases
This commit message captures the major architectural change of implementing Consul ACL management with proper provider aliasing, along with the supporting configuration files and policy definitions for various terraform services. - add consul_acl_management module to manage consul acl policies and roles - add consul backend roles and policies for terraform services (incus, k8s, nomad, repoflow, vault) - add consul provider configuration to root.hcl - add policies to generate credentials for each role - simplify consul_secret_backend_role module to reference acl-managed roles - switch to opentofu for provider foreach support - update terragrunt configuration to support consul backend aliases - update pre-commit hooks to use opentofu instead of terraform - configure tflint exceptions for consul acl management module
This commit is contained in:
@@ -237,6 +237,29 @@ module "consul_secret_backend" {
|
||||
max_lease_ttl_seconds = each.value.max_lease_ttl_seconds
|
||||
}
|
||||
|
||||
# Create data sources for consul backend tokens
|
||||
data "vault_kv_secret_v2" "consul_backend_configs" {
|
||||
for_each = {
|
||||
for k, v in var.consul_secret_backend : k => v
|
||||
if !v.bootstrap
|
||||
}
|
||||
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/secret_backend/${each.key}"
|
||||
}
|
||||
|
||||
# Create Consul ACL management module
|
||||
module "consul_acl_management" {
|
||||
source = "./modules/consul_acl_management"
|
||||
|
||||
country = var.country
|
||||
region = var.region
|
||||
consul_backends = var.consul_secret_backend
|
||||
consul_roles = var.consul_secret_backend_role
|
||||
consul_backend_aliases = var.consul_backend_aliases
|
||||
}
|
||||
|
||||
# Create consul secret backend roles (Vault resources only)
|
||||
module "consul_secret_backend_role" {
|
||||
source = "./modules/consul_secret_backend_role"
|
||||
|
||||
@@ -249,7 +272,7 @@ module "consul_secret_backend_role" {
|
||||
max_ttl = each.value.max_ttl
|
||||
local = each.value.local
|
||||
|
||||
depends_on = [module.consul_secret_backend]
|
||||
depends_on = [module.consul_secret_backend, module.consul_acl_management]
|
||||
}
|
||||
|
||||
module "kubernetes_secret_backend" {
|
||||
@@ -314,3 +337,4 @@ module "pki_mount_only" {
|
||||
enable_delta = each.value.enable_delta
|
||||
delta_rebuild_interval = each.value.delta_rebuild_interval
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
rule "terraform_required_providers" {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
rule "terraform_required_version" {
|
||||
enabled = false
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
# Get consul backend tokens from Vault
|
||||
data "vault_kv_secret_v2" "consul_backend_configs" {
|
||||
for_each = var.consul_backends
|
||||
|
||||
mount = "kv"
|
||||
name = "service/vault/${var.country}/${var.region}/secret_backend/${each.key}"
|
||||
}
|
||||
|
||||
# Create consul provider instances for each consul backend
|
||||
provider "consul" {
|
||||
alias = "by_backend"
|
||||
for_each = var.consul_backend_aliases
|
||||
|
||||
address = var.consul_backends[each.key].address
|
||||
scheme = var.consul_backends[each.key].scheme
|
||||
ca_file = "/etc/pki/tls/certs/ca-bundle.crt"
|
||||
token = data.vault_kv_secret_v2.consul_backend_configs[each.key].data["token"]
|
||||
}
|
||||
|
||||
# Create Consul ACL policies
|
||||
resource "consul_acl_policy" "policies" {
|
||||
for_each = var.consul_roles
|
||||
|
||||
provider = consul.by_backend[each.value.backend]
|
||||
|
||||
name = each.value.name
|
||||
description = each.value.description != null ? each.value.description : "Auto-generated policy for Vault role ${each.value.name}"
|
||||
rules = file("${path.module}/../../../../../../../../resources/secret_backend/${each.value.backend}/${each.value.name}.hcl")
|
||||
datacenters = each.value.datacenters
|
||||
}
|
||||
|
||||
# Create Consul ACL roles
|
||||
resource "consul_acl_role" "roles" {
|
||||
for_each = var.consul_roles
|
||||
|
||||
provider = consul.by_backend[each.value.backend]
|
||||
|
||||
name = each.value.name
|
||||
description = each.value.description != null ? each.value.description : "Auto-generated role for Vault role ${each.value.name}"
|
||||
|
||||
policies = [consul_acl_policy.policies[each.key].name]
|
||||
|
||||
dynamic "service_identities" {
|
||||
for_each = each.value.service_identities != null ? each.value.service_identities : []
|
||||
content {
|
||||
service_name = service_identities.value.service_name
|
||||
datacenters = service_identities.value.datacenters
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "node_identities" {
|
||||
for_each = each.value.node_identities != null ? each.value.node_identities : []
|
||||
content {
|
||||
node_name = node_identities.value.node_name
|
||||
datacenter = node_identities.value.datacenter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
output "consul_acl_policies" {
|
||||
description = "Map of created Consul ACL policies"
|
||||
value = consul_acl_policy.policies
|
||||
}
|
||||
|
||||
output "consul_acl_roles" {
|
||||
description = "Map of created Consul ACL roles"
|
||||
value = consul_acl_role.roles
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
variable "consul_backends" {
|
||||
description = "Map of consul secret backends"
|
||||
type = map(object({
|
||||
address = string
|
||||
scheme = string
|
||||
bootstrap = bool
|
||||
bootstrap_token = optional(string)
|
||||
ca_cert = optional(string)
|
||||
client_cert = optional(string)
|
||||
client_key = optional(string)
|
||||
}))
|
||||
}
|
||||
|
||||
variable "consul_roles" {
|
||||
description = "Map of consul secret backend roles"
|
||||
type = map(object({
|
||||
name = string
|
||||
backend = string
|
||||
description = optional(string)
|
||||
datacenters = optional(list(string))
|
||||
service_identities = optional(list(object({
|
||||
service_name = string
|
||||
datacenters = optional(list(string))
|
||||
})))
|
||||
node_identities = optional(list(object({
|
||||
node_name = string
|
||||
datacenter = string
|
||||
})))
|
||||
}))
|
||||
}
|
||||
|
||||
variable "consul_backend_aliases" {
|
||||
description = "Map of consul backend names to sanitized provider aliases"
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "country" {
|
||||
description = "Country identifier"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "Region identifier"
|
||||
type = string
|
||||
}
|
||||
@@ -18,4 +18,4 @@ resource "vault_consul_secret_backend" "consul" {
|
||||
client_key = var.client_key
|
||||
default_lease_ttl_seconds = var.default_lease_ttl_seconds
|
||||
max_lease_ttl_seconds = var.max_lease_ttl_seconds
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Create Vault Consul secret backend role
|
||||
resource "vault_consul_secret_backend_role" "role" {
|
||||
backend = var.backend
|
||||
name = var.name
|
||||
consul_roles = var.consul_roles
|
||||
consul_roles = [var.name] # Use the role name created by consul_acl_management module
|
||||
ttl = var.ttl
|
||||
max_ttl = var.max_ttl
|
||||
local = var.local
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,4 +32,5 @@ variable "local" {
|
||||
description = "Whether tokens should be local to the datacenter"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,6 +226,7 @@ variable "consul_secret_backend" {
|
||||
description = optional(string)
|
||||
address = string
|
||||
bootstrap = optional(bool, false)
|
||||
bootstrap_token = optional(string)
|
||||
scheme = optional(string, "https")
|
||||
ca_cert = optional(string)
|
||||
client_cert = optional(string)
|
||||
@@ -245,10 +246,26 @@ variable "consul_secret_backend_role" {
|
||||
ttl = optional(number)
|
||||
max_ttl = optional(number)
|
||||
local = optional(bool, false)
|
||||
datacenters = optional(list(string))
|
||||
description = optional(string)
|
||||
service_identities = optional(list(object({
|
||||
service_name = string
|
||||
datacenters = optional(list(string))
|
||||
})))
|
||||
node_identities = optional(list(object({
|
||||
node_name = string
|
||||
datacenter = string
|
||||
})))
|
||||
}))
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "consul_backend_aliases" {
|
||||
description = "Map of consul backend names to sanitized provider aliases"
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
||||
|
||||
variable "kubernetes_secret_backend" {
|
||||
description = "Map of Kubernetes secret engines to create"
|
||||
type = map(object({
|
||||
@@ -287,3 +304,4 @@ variable "policy_rules_map" {
|
||||
})))
|
||||
default = {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user