# Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: BUSL-1.1 terraform { required_providers { aws = { source = "hashicorp/aws" } enos = { source = "app.terraform.io/hashicorp-qti/enos" } } } variable "vault_api_addr" { type = string description = "The API address of the Vault cluster" } variable "vault_install_dir" { type = string description = "The directory where the Vault binary will be installed" } variable "vault_instance_count" { type = number description = "How many vault instances are in the cluster" } variable "vault_instances" { type = map(object({ private_ip = string public_ip = string })) description = "The vault cluster instances that were created" } variable "vault_local_artifact_path" { type = string description = "The path to a locally built vault artifact to install" default = null } variable "vault_artifactory_release" { type = object({ username = string token = string url = string sha256 = string }) description = "Vault release version and edition to install from artifactory.hashicorp.engineering" default = null } variable "vault_seal_type" { type = string description = "The Vault seal type" } variable "vault_unseal_keys" { type = list(string) description = "The keys to use to unseal Vault when not using auto-unseal" default = null } locals { instances = { for idx in range(var.vault_instance_count) : idx => { public_ip = values(var.vault_instances)[idx].public_ip private_ip = values(var.vault_instances)[idx].private_ip } } followers = toset([for idx in range(var.vault_instance_count - 1) : tostring(idx)]) follower_ips = compact(split(" ", enos_remote_exec.get_follower_public_ips.stdout)) vault_bin_path = "${var.vault_install_dir}/vault" } resource "enos_bundle_install" "upgrade_vault_binary" { for_each = local.instances destination = var.vault_install_dir artifactory = var.vault_artifactory_release path = var.vault_local_artifact_path transport = { ssh = { host = each.value.public_ip } } } resource "enos_remote_exec" "get_leader_public_ip" { depends_on = [enos_bundle_install.upgrade_vault_binary] scripts = [abspath("${path.module}/scripts/get-leader-public-ip.sh")] environment = { VAULT_INSTALL_DIR = var.vault_install_dir, VAULT_INSTANCES = jsonencode(local.instances) } transport = { ssh = { host = local.instances[0].public_ip } } } resource "enos_remote_exec" "get_follower_public_ips" { depends_on = [enos_bundle_install.upgrade_vault_binary] environment = { VAULT_INSTALL_DIR = var.vault_install_dir, VAULT_INSTANCES = jsonencode(local.instances) } scripts = [abspath("${path.module}/scripts/get-follower-public-ips.sh")] transport = { ssh = { host = local.instances[0].public_ip } } } resource "enos_remote_exec" "restart_followers" { for_each = local.followers depends_on = [enos_remote_exec.get_follower_public_ips] scripts = [abspath("${path.module}/scripts/restart-vault.sh")] transport = { ssh = { host = trimspace(local.follower_ips[tonumber(each.key)]) } } } resource "enos_vault_unseal" "followers" { depends_on = [enos_remote_exec.restart_followers] for_each = { for idx, follower in local.followers : idx => follower if var.vault_seal_type == "shamir" } bin_path = local.vault_bin_path vault_addr = var.vault_api_addr seal_type = var.vault_seal_type unseal_keys = var.vault_unseal_keys transport = { ssh = { host = trimspace(local.follower_ips[each.key]) } } } resource "enos_remote_exec" "restart_leader" { depends_on = [enos_vault_unseal.followers] scripts = [abspath("${path.module}/scripts/restart-vault.sh")] transport = { ssh = { host = trimspace(enos_remote_exec.get_leader_public_ip.stdout) } } } resource "enos_vault_unseal" "leader" { count = var.vault_seal_type == "shamir" ? 1 : 0 depends_on = [enos_remote_exec.restart_leader] bin_path = local.vault_bin_path vault_addr = var.vault_api_addr seal_type = var.vault_seal_type unseal_keys = var.vault_unseal_keys transport = { ssh = { host = trimspace(enos_remote_exec.get_leader_public_ip.stdout) } } }