# Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 # This module unseals the replication secondary follower nodes terraform { required_providers { enos = { source = "app.terraform.io/hashicorp-qti/enos" } } } 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 "follower_public_ips" { type = list(string) description = "Vault cluster follower Public IP addresses" } variable "vault_seal_type" { type = string description = "The Vault seal type" } variable "vault_unseal_keys" {} locals { followers = toset([for idx in range(var.vault_instance_count - 1) : tostring(idx)]) vault_bin_path = "${var.vault_install_dir}/vault" } # After replication is enabled the secondary follower nodes are expected to be sealed, # so we wait for the secondary follower nodes to update the seal status resource "enos_remote_exec" "wait_until_sealed" { for_each = { for idx, follower in local.followers : idx => follower } environment = { VAULT_ADDR = "http://127.0.0.1:8200" VAULT_INSTALL_DIR = var.vault_install_dir } scripts = [abspath("${path.module}/scripts/wait-until-sealed.sh")] transport = { ssh = { host = element(var.follower_public_ips, each.key) } } } # The follower nodes on secondary replication cluster incorrectly report # unseal progress 2/3 (Issue: https://hashicorp.atlassian.net/browse/VAULT-12309), # so we restart the followers to clear the status and to autounseal incase of awskms seal type resource "enos_remote_exec" "restart_followers" { depends_on = [enos_remote_exec.wait_until_sealed] for_each = { for idx, follower in local.followers : idx => follower } inline = ["sudo systemctl restart vault"] transport = { ssh = { host = element(var.follower_public_ips, each.key) } } } # We cannot use the vault_unseal resouce due to the known issue # (https://hashicorp.atlassian.net/browse/VAULT-12311). We use a custom # script to allow retry for unsealing the secondary followers resource "enos_remote_exec" "unseal_followers" { depends_on = [enos_remote_exec.restart_followers] # The unseal keys are required only for seal_type shamir for_each = { for idx, follower in local.followers : idx => follower if var.vault_seal_type == "shamir" } environment = { VAULT_ADDR = "http://127.0.0.1:8200" VAULT_INSTALL_DIR = var.vault_install_dir UNSEAL_KEYS = join(",", var.vault_unseal_keys) } scripts = [abspath("${path.module}/scripts/unseal-node.sh")] transport = { ssh = { host = element(var.follower_public_ips, each.key) } } } # This is a second attempt needed to unseal the secondary followers # using a custom script due to get past the known issue # (https://hashicorp.atlassian.net/browse/VAULT-12311) resource "enos_remote_exec" "unseal_followers_again" { depends_on = [enos_remote_exec.unseal_followers] for_each = { for idx, follower in local.followers : idx => follower if var.vault_seal_type == "shamir" } environment = { VAULT_ADDR = "http://127.0.0.1:8200" VAULT_INSTALL_DIR = var.vault_install_dir UNSEAL_KEYS = join(",", var.vault_unseal_keys) } scripts = [abspath("${path.module}/scripts/unseal-node.sh")] transport = { ssh = { host = element(var.follower_public_ips, each.key) } } }