feat(multi-env): Phase D3 — erp iac creates erp-sandbox Vault auth + creds + KV #12
58
iac/main.tf
58
iac/main.tf
@@ -1,32 +1,66 @@
|
|||||||
locals {
|
locals {
|
||||||
app = {
|
app = {
|
||||||
name = "erp"
|
name = "erp"
|
||||||
product_name = "dolibarr" # unused
|
product_name = "dolibarr" # unused
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Environments this app is deployed to. By the elision rule (factory runbook
|
||||||
|
# conventions.md / ADR-0002) env=prod renders identical to the single-env
|
||||||
|
# baseline; non-prod envs get a "<name>-<env>" instance id from the module.
|
||||||
|
envs = toset(["prod", "sandbox"])
|
||||||
}
|
}
|
||||||
|
|
||||||
module "app_roles" {
|
module "app_roles" {
|
||||||
source = "git::ssh://git@192.168.1.202:2222/arcodange-org/tools.git//hashicorp-vault/iac/modules/app_roles?depth=1&ref=main"
|
source = "git::ssh://git@192.168.1.202:2222/arcodange-org/tools.git//hashicorp-vault/iac/modules/app_roles?depth=1&ref=main"
|
||||||
name = local.app.name
|
for_each = local.envs
|
||||||
|
name = local.app.name
|
||||||
|
env = each.key
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "random_password" "admin_initial_password" {
|
resource "random_password" "admin_initial_password" {
|
||||||
length = 32
|
for_each = local.envs
|
||||||
|
length = 32
|
||||||
}
|
}
|
||||||
resource "random_uuid" "dolibarr_id" { # used for encryption as well as when buying modules
|
resource "random_uuid" "dolibarr_id" { # used for encryption as well as when buying modules
|
||||||
|
for_each = local.envs
|
||||||
lifecycle {
|
lifecycle {
|
||||||
prevent_destroy = true
|
prevent_destroy = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "vault_kv_secret_v2" "dolibarr_admin_setup" {
|
resource "vault_kv_secret_v2" "dolibarr_admin_setup" {
|
||||||
mount = module.app_roles.mount_paths.kvv2
|
for_each = local.envs
|
||||||
name = format("%sconfig", module.app_roles.kvv2_path_prefix)
|
mount = module.app_roles[each.key].mount_paths.kvv2
|
||||||
data_json = jsonencode(
|
name = format("%sconfig", module.app_roles[each.key].kvv2_path_prefix)
|
||||||
{
|
data_json = jsonencode(
|
||||||
DOLI_ADMIN_LOGIN = "admin",
|
{
|
||||||
DOLI_ADMIN_PASSWORD = random_password.admin_initial_password.result
|
DOLI_ADMIN_LOGIN = "admin",
|
||||||
DOLI_INSTANCE_UNIQUE_ID = random_uuid.dolibarr_id.result
|
DOLI_ADMIN_PASSWORD = random_password.admin_initial_password[each.key].result
|
||||||
}
|
DOLI_INSTANCE_UNIQUE_ID = random_uuid.dolibarr_id[each.key].result
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# State migration (ADR-0002 Phase D): re-key the pre-existing single-env resources
|
||||||
|
# into the for_each map under the "prod" key so that introducing for_each does NOT
|
||||||
|
# plan a destroy+create. This is critical for random_uuid.dolibarr_id — it carries
|
||||||
|
# prevent_destroy = true (it is the prod Dolibarr encryption id + paid-module
|
||||||
|
# binding), so a missing moved block would HARD-FAIL the apply rather than silently
|
||||||
|
# losing it. The module's own internal moved (role -> role[0]) chains with the
|
||||||
|
# module re-key here.
|
||||||
|
moved {
|
||||||
|
from = module.app_roles
|
||||||
|
to = module.app_roles["prod"]
|
||||||
|
}
|
||||||
|
moved {
|
||||||
|
from = random_password.admin_initial_password
|
||||||
|
to = random_password.admin_initial_password["prod"]
|
||||||
|
}
|
||||||
|
moved {
|
||||||
|
from = random_uuid.dolibarr_id
|
||||||
|
to = random_uuid.dolibarr_id["prod"]
|
||||||
|
}
|
||||||
|
moved {
|
||||||
|
from = vault_kv_secret_v2.dolibarr_admin_setup
|
||||||
|
to = vault_kv_secret_v2.dolibarr_admin_setup["prod"]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user