backport of commit a46def288f06cff8176399f239f87a2a49ba5dd9 (#23869)
Co-authored-by: Ryan Cragun <me@ryan.ec>
This commit is contained in:
parent
ccfb338bee
commit
eb1376dc13
|
@ -41,7 +41,6 @@ jobs:
|
||||||
- uses: hashicorp/setup-terraform@v2
|
- uses: hashicorp/setup-terraform@v2
|
||||||
with:
|
with:
|
||||||
terraform_wrapper: false
|
terraform_wrapper: false
|
||||||
terraform_version: 1.5.7 # QT-623: pin to terraform 1.5.x until a tfjson bug is resolved
|
|
||||||
- uses: hashicorp/action-setup-enos@v1
|
- uses: hashicorp/action-setup-enos@v1
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
|
github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
|
||||||
|
|
|
@ -38,7 +38,6 @@ jobs:
|
||||||
# the Terraform wrapper will break Terraform execution in Enos because
|
# the Terraform wrapper will break Terraform execution in Enos because
|
||||||
# it changes the output to text when we expect it to be JSON.
|
# it changes the output to text when we expect it to be JSON.
|
||||||
terraform_wrapper: false
|
terraform_wrapper: false
|
||||||
terraform_version: 1.5.7 # QT-623: pin to terraform 1.5.x until a tfjson bug is resolved
|
|
||||||
- name: Set up Enos
|
- name: Set up Enos
|
||||||
uses: hashicorp/action-setup-enos@v1
|
uses: hashicorp/action-setup-enos@v1
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -85,7 +85,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
|
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
|
||||||
terraform_wrapper: false
|
terraform_wrapper: false
|
||||||
terraform_version: 1.5.7 # QT-623: pin to terraform 1.5.x until a tfjson bug is resolved
|
|
||||||
- name: Prepare scenario dependencies
|
- name: Prepare scenario dependencies
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ./enos/support/terraform-plugin-cache
|
mkdir -p ./enos/support/terraform-plugin-cache
|
||||||
|
|
|
@ -102,7 +102,6 @@ jobs:
|
||||||
# the Terraform wrapper will break Terraform execution in Enos because
|
# the Terraform wrapper will break Terraform execution in Enos because
|
||||||
# it changes the output to text when we expect it to be JSON.
|
# it changes the output to text when we expect it to be JSON.
|
||||||
terraform_wrapper: false
|
terraform_wrapper: false
|
||||||
terraform_version: 1.5.7 # QT-623: pin to terraform 1.5.x until a tfjson bug is resolved
|
|
||||||
- uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
|
- uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0
|
||||||
with:
|
with:
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI }}
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI }}
|
||||||
|
|
|
@ -216,6 +216,7 @@ data "aws_iam_policy_document" "enos_scenario" {
|
||||||
"kms:ListKeys",
|
"kms:ListKeys",
|
||||||
"kms:ListResourceTags",
|
"kms:ListResourceTags",
|
||||||
"kms:ScheduleKeyDeletion",
|
"kms:ScheduleKeyDeletion",
|
||||||
|
"kms:TagResource",
|
||||||
"servicequotas:ListServiceQuotas"
|
"servicequotas:ListServiceQuotas"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,18 @@ module "replication_data" {
|
||||||
source = "./modules/replication_data"
|
source = "./modules/replication_data"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module "seal_key_awskms" {
|
||||||
|
source = "./modules/seal_key_awskms"
|
||||||
|
|
||||||
|
common_tags = var.tags
|
||||||
|
}
|
||||||
|
|
||||||
|
module "seal_key_shamir" {
|
||||||
|
source = "./modules/seal_key_shamir"
|
||||||
|
|
||||||
|
common_tags = var.tags
|
||||||
|
}
|
||||||
|
|
||||||
module "shutdown_node" {
|
module "shutdown_node" {
|
||||||
source = "./modules/shutdown_node"
|
source = "./modules/shutdown_node"
|
||||||
}
|
}
|
||||||
|
@ -65,6 +77,17 @@ module "shutdown_multiple_nodes" {
|
||||||
source = "./modules/shutdown_multiple_nodes"
|
source = "./modules/shutdown_multiple_nodes"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module "start_vault" {
|
||||||
|
source = "./modules/start_vault"
|
||||||
|
|
||||||
|
install_dir = var.vault_install_dir
|
||||||
|
log_level = var.vault_log_level
|
||||||
|
}
|
||||||
|
|
||||||
|
module "stop_vault" {
|
||||||
|
source = "./modules/stop_vault"
|
||||||
|
}
|
||||||
|
|
||||||
# create target instances using ec2:CreateFleet
|
# create target instances using ec2:CreateFleet
|
||||||
module "target_ec2_fleet" {
|
module "target_ec2_fleet" {
|
||||||
source = "./modules/target_ec2_fleet"
|
source = "./modules/target_ec2_fleet"
|
||||||
|
@ -249,3 +272,10 @@ module "vault_wait_for_leader" {
|
||||||
vault_install_dir = var.vault_install_dir
|
vault_install_dir = var.vault_install_dir
|
||||||
vault_instance_count = var.vault_instance_count
|
vault_instance_count = var.vault_instance_count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module "vault_wait_for_seal_rewrap" {
|
||||||
|
source = "./modules/vault_wait_for_seal_rewrap"
|
||||||
|
|
||||||
|
vault_install_dir = var.vault_install_dir
|
||||||
|
vault_instance_count = var.vault_instance_count
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ scenario "agent" {
|
||||||
distro = ["ubuntu", "rhel"]
|
distro = ["ubuntu", "rhel"]
|
||||||
edition = ["ce", "ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
edition = ["ce", "ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
||||||
seal = ["awskms", "shamir"]
|
seal = ["awskms", "shamir"]
|
||||||
|
seal_ha_beta = ["true", "false"]
|
||||||
|
|
||||||
# Our local builder always creates bundles
|
# Our local builder always creates bundles
|
||||||
exclude {
|
exclude {
|
||||||
|
@ -81,6 +82,15 @@ scenario "agent" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step "create_seal_key" {
|
||||||
|
module = "seal_key_${matrix.seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This step reads the contents of the backend license if we're using a Consul backend and
|
// This step reads the contents of the backend license if we're using a Consul backend and
|
||||||
// the edition is "ent".
|
// the edition is "ent".
|
||||||
step "read_backend_license" {
|
step "read_backend_license" {
|
||||||
|
@ -110,11 +120,11 @@ scenario "agent" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +137,11 @@ scenario "agent" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.backend_tag_key
|
||||||
cluster_tag_key = global.backend_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +181,6 @@ scenario "agent" {
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = global.backend_tag_key
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
cluster_name = step.create_vault_cluster_targets.cluster_name
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
|
@ -186,9 +195,11 @@ scenario "agent" {
|
||||||
local_artifact_path = local.artifact_path
|
local_artifact_path = local.artifact_path
|
||||||
manage_service = local.manage_service
|
manage_service = local.manage_service
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_seal_key.resource_name
|
||||||
|
seal_type = matrix.seal
|
||||||
storage_backend = matrix.backend
|
storage_backend = matrix.backend
|
||||||
target_hosts = step.create_vault_cluster_targets.hosts
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
unseal_method = matrix.seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,11 +400,6 @@ scenario "agent" {
|
||||||
value = step.create_vault_cluster.audit_device_file_path
|
value = step.create_vault_cluster.audit_device_file_path
|
||||||
}
|
}
|
||||||
|
|
||||||
output "awskms_unseal_key_arn" {
|
|
||||||
description = "The Vault cluster KMS key arn"
|
|
||||||
value = step.create_vpc.kms_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
output "cluster_name" {
|
output "cluster_name" {
|
||||||
description = "The Vault cluster name"
|
description = "The Vault cluster name"
|
||||||
value = step.create_vault_cluster.cluster_name
|
value = step.create_vault_cluster.cluster_name
|
||||||
|
@ -434,6 +440,11 @@ scenario "agent" {
|
||||||
value = step.create_vault_cluster.recovery_keys_hex
|
value = step.create_vault_cluster.recovery_keys_hex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "seal_key_name" {
|
||||||
|
description = "The name of the cluster seal key"
|
||||||
|
value = step.create_seal_key.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
output "unseal_keys_b64" {
|
output "unseal_keys_b64" {
|
||||||
description = "The Vault cluster unseal keys"
|
description = "The Vault cluster unseal keys"
|
||||||
value = step.create_vault_cluster.unseal_keys_b64
|
value = step.create_vault_cluster.unseal_keys_b64
|
||||||
|
|
|
@ -12,6 +12,7 @@ scenario "autopilot" {
|
||||||
// release branch's version.
|
// release branch's version.
|
||||||
initial_version = ["1.11.12", "1.12.11", "1.13.6", "1.14.2"]
|
initial_version = ["1.11.12", "1.12.11", "1.13.6", "1.14.2"]
|
||||||
seal = ["awskms", "shamir"]
|
seal = ["awskms", "shamir"]
|
||||||
|
seal_ha_beta = ["true", "false"]
|
||||||
|
|
||||||
# Our local builder always creates bundles
|
# Our local builder always creates bundles
|
||||||
exclude {
|
exclude {
|
||||||
|
@ -77,6 +78,15 @@ scenario "autopilot" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step "create_seal_key" {
|
||||||
|
module = "seal_key_${matrix.seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
step "read_license" {
|
step "read_license" {
|
||||||
module = module.read_license
|
module = module.read_license
|
||||||
|
|
||||||
|
@ -94,11 +104,11 @@ scenario "autopilot" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,22 +124,23 @@ scenario "autopilot" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
cluster_name = step.create_vault_cluster_targets.cluster_name
|
enable_audit_devices = var.vault_enable_audit_devices
|
||||||
install_dir = local.vault_install_dir
|
install_dir = local.vault_install_dir
|
||||||
license = matrix.edition != "ce" ? step.read_license.license : null
|
license = matrix.edition != "ce" ? step.read_license.license : null
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
release = {
|
release = {
|
||||||
edition = matrix.edition
|
edition = matrix.edition
|
||||||
version = matrix.initial_version
|
version = matrix.initial_version
|
||||||
}
|
}
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_seal_key.resource_name
|
||||||
|
seal_type = matrix.seal
|
||||||
storage_backend = "raft"
|
storage_backend = "raft"
|
||||||
storage_backend_addl_config = {
|
storage_backend_addl_config = {
|
||||||
autopilot_upgrade_version = matrix.initial_version
|
autopilot_upgrade_version = matrix.initial_version
|
||||||
}
|
}
|
||||||
target_hosts = step.create_vault_cluster_targets.hosts
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
unseal_method = matrix.seal
|
|
||||||
enable_audit_devices = var.vault_enable_audit_devices
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,11 +201,11 @@ scenario "autopilot" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
cluster_name = step.create_vault_cluster_targets.cluster_name
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +224,7 @@ scenario "autopilot" {
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
enable_audit_devices = var.vault_enable_audit_devices
|
||||||
cluster_name = step.create_vault_cluster_targets.cluster_name
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
log_level = var.vault_log_level
|
log_level = var.vault_log_level
|
||||||
force_unseal = matrix.seal == "shamir"
|
force_unseal = matrix.seal == "shamir"
|
||||||
|
@ -224,13 +235,14 @@ scenario "autopilot" {
|
||||||
manage_service = local.manage_service
|
manage_service = local.manage_service
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
root_token = step.create_vault_cluster.root_token
|
root_token = step.create_vault_cluster.root_token
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_seal_key.resource_name
|
||||||
|
seal_type = matrix.seal
|
||||||
shamir_unseal_keys = matrix.seal == "shamir" ? step.create_vault_cluster.unseal_keys_hex : null
|
shamir_unseal_keys = matrix.seal == "shamir" ? step.create_vault_cluster.unseal_keys_hex : null
|
||||||
storage_backend = "raft"
|
storage_backend = "raft"
|
||||||
storage_backend_addl_config = step.create_autopilot_upgrade_storageconfig.storage_addl_config
|
storage_backend_addl_config = step.create_autopilot_upgrade_storageconfig.storage_addl_config
|
||||||
storage_node_prefix = "upgrade_node"
|
storage_node_prefix = "upgrade_node"
|
||||||
target_hosts = step.create_vault_cluster_upgrade_targets.hosts
|
target_hosts = step.create_vault_cluster_upgrade_targets.hosts
|
||||||
unseal_method = matrix.seal
|
|
||||||
enable_audit_devices = var.vault_enable_audit_devices
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,9 +510,9 @@ scenario "autopilot" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output "awskms_unseal_key_arn" {
|
output "audit_device_file_path" {
|
||||||
description = "The Vault cluster KMS key arn"
|
description = "The file path for the file audit device, if enabled"
|
||||||
value = step.create_vpc.kms_key_arn
|
value = step.create_vault_cluster.audit_device_file_path
|
||||||
}
|
}
|
||||||
|
|
||||||
output "cluster_name" {
|
output "cluster_name" {
|
||||||
|
@ -543,6 +555,11 @@ scenario "autopilot" {
|
||||||
value = step.create_vault_cluster.recovery_keys_hex
|
value = step.create_vault_cluster.recovery_keys_hex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "seal_key_name" {
|
||||||
|
description = "The Vault cluster seal key name"
|
||||||
|
value = step.create_seal_key.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
output "unseal_keys_b64" {
|
output "unseal_keys_b64" {
|
||||||
description = "The Vault cluster unseal keys"
|
description = "The Vault cluster unseal keys"
|
||||||
value = step.create_vault_cluster.unseal_keys_b64
|
value = step.create_vault_cluster.unseal_keys_b64
|
||||||
|
@ -567,9 +584,4 @@ scenario "autopilot" {
|
||||||
description = "The Vault cluster public IPs"
|
description = "The Vault cluster public IPs"
|
||||||
value = step.upgrade_vault_cluster_with_autopilot.public_ips
|
value = step.upgrade_vault_cluster_with_autopilot.public_ips
|
||||||
}
|
}
|
||||||
|
|
||||||
output "vault_audit_device_file_path" {
|
|
||||||
description = "The file path for the file audit device, if enabled"
|
|
||||||
value = step.create_vault_cluster.audit_device_file_path
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ scenario "proxy" {
|
||||||
distro = ["ubuntu", "rhel"]
|
distro = ["ubuntu", "rhel"]
|
||||||
edition = ["ce", "ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
edition = ["ce", "ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
||||||
seal = ["awskms", "shamir"]
|
seal = ["awskms", "shamir"]
|
||||||
|
seal_ha_beta = ["true", "false"]
|
||||||
|
|
||||||
# Our local builder always creates bundles
|
# Our local builder always creates bundles
|
||||||
exclude {
|
exclude {
|
||||||
|
@ -81,6 +82,15 @@ scenario "proxy" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step "create_seal_key" {
|
||||||
|
module = "seal_key_${matrix.seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This step reads the contents of the backend license if we're using a Consul backend and
|
// This step reads the contents of the backend license if we're using a Consul backend and
|
||||||
// the edition is "ent".
|
// the edition is "ent".
|
||||||
step "read_backend_license" {
|
step "read_backend_license" {
|
||||||
|
@ -110,11 +120,11 @@ scenario "proxy" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +137,11 @@ scenario "proxy" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.backend_tag_key
|
||||||
cluster_tag_key = global.backend_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +181,6 @@ scenario "proxy" {
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = global.backend_tag_key
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
cluster_name = step.create_vault_cluster_targets.cluster_name
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
|
@ -186,9 +195,11 @@ scenario "proxy" {
|
||||||
local_artifact_path = local.artifact_path
|
local_artifact_path = local.artifact_path
|
||||||
manage_service = local.manage_service
|
manage_service = local.manage_service
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_seal_key.resource_name
|
||||||
|
seal_type = matrix.seal
|
||||||
storage_backend = matrix.backend
|
storage_backend = matrix.backend
|
||||||
target_hosts = step.create_vault_cluster_targets.hosts
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
unseal_method = matrix.seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,11 +372,6 @@ scenario "proxy" {
|
||||||
value = step.create_vault_cluster.audit_device_file_path
|
value = step.create_vault_cluster.audit_device_file_path
|
||||||
}
|
}
|
||||||
|
|
||||||
output "awskms_unseal_key_arn" {
|
|
||||||
description = "The Vault cluster KMS key arn"
|
|
||||||
value = step.create_vpc.kms_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
output "cluster_name" {
|
output "cluster_name" {
|
||||||
description = "The Vault cluster name"
|
description = "The Vault cluster name"
|
||||||
value = step.create_vault_cluster.cluster_name
|
value = step.create_vault_cluster.cluster_name
|
||||||
|
@ -406,6 +412,11 @@ scenario "proxy" {
|
||||||
value = step.create_vault_cluster.recovery_keys_hex
|
value = step.create_vault_cluster.recovery_keys_hex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "seal_key_name" {
|
||||||
|
description = "The Vault cluster seal key name"
|
||||||
|
value = step.create_seal_key.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
output "unseal_keys_b64" {
|
output "unseal_keys_b64" {
|
||||||
description = "The Vault cluster unseal keys"
|
description = "The Vault cluster unseal keys"
|
||||||
value = step.create_vault_cluster.unseal_keys_b64
|
value = step.create_vault_cluster.unseal_keys_b64
|
||||||
|
|
|
@ -14,6 +14,7 @@ scenario "replication" {
|
||||||
edition = ["ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
edition = ["ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
||||||
primary_backend = ["raft", "consul"]
|
primary_backend = ["raft", "consul"]
|
||||||
primary_seal = ["awskms", "shamir"]
|
primary_seal = ["awskms", "shamir"]
|
||||||
|
seal_ha_beta = ["true", "false"]
|
||||||
secondary_backend = ["raft", "consul"]
|
secondary_backend = ["raft", "consul"]
|
||||||
secondary_seal = ["awskms", "shamir"]
|
secondary_seal = ["awskms", "shamir"]
|
||||||
|
|
||||||
|
@ -86,6 +87,26 @@ scenario "replication" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step "create_primary_seal_key" {
|
||||||
|
module = "seal_key_${matrix.primary_seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
cluster_meta = "primary"
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_secondary_seal_key" {
|
||||||
|
module = "seal_key_${matrix.secondary_seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
cluster_meta = "secondary"
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This step reads the contents of the backend license if we're using a Consul backend and
|
// This step reads the contents of the backend license if we're using a Consul backend and
|
||||||
// the edition is "ent".
|
// the edition is "ent".
|
||||||
step "read_backend_license" {
|
step "read_backend_license" {
|
||||||
|
@ -117,11 +138,11 @@ scenario "replication" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_primary_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,11 +157,11 @@ scenario "replication" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.backend_tag_key
|
||||||
cluster_tag_key = global.backend_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_primary_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,12 +177,12 @@ scenario "replication" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_name = step.create_primary_cluster_targets.cluster_name
|
||||||
cluster_name = step.create_primary_cluster_targets.cluster_name
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_primary_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,11 +195,11 @@ scenario "replication" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_secondary_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,11 +212,11 @@ scenario "replication" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.backend_tag_key
|
||||||
cluster_tag_key = global.backend_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_secondary_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +256,6 @@ scenario "replication" {
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_primary_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_primary_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = global.backend_tag_key
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
consul_license = (matrix.primary_backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
consul_license = (matrix.primary_backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
||||||
|
@ -250,9 +270,11 @@ scenario "replication" {
|
||||||
local_artifact_path = local.artifact_path
|
local_artifact_path = local.artifact_path
|
||||||
manage_service = local.manage_service
|
manage_service = local.manage_service
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_primary_seal_key.resource_name
|
||||||
|
seal_type = matrix.primary_seal
|
||||||
storage_backend = matrix.primary_backend
|
storage_backend = matrix.primary_backend
|
||||||
target_hosts = step.create_primary_cluster_targets.hosts
|
target_hosts = step.create_primary_cluster_targets.hosts
|
||||||
unseal_method = matrix.primary_seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +314,6 @@ scenario "replication" {
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_secondary_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_secondary_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = global.backend_tag_key
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
consul_license = (matrix.secondary_backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
consul_license = (matrix.secondary_backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
||||||
|
@ -307,9 +328,11 @@ scenario "replication" {
|
||||||
local_artifact_path = local.artifact_path
|
local_artifact_path = local.artifact_path
|
||||||
manage_service = local.manage_service
|
manage_service = local.manage_service
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_secondary_seal_key.resource_name
|
||||||
|
seal_type = matrix.secondary_seal
|
||||||
storage_backend = matrix.secondary_backend
|
storage_backend = matrix.secondary_backend
|
||||||
target_hosts = step.create_secondary_cluster_targets.hosts
|
target_hosts = step.create_secondary_cluster_targets.hosts
|
||||||
unseal_method = matrix.secondary_seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +607,6 @@ scenario "replication" {
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_primary_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_primary_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = global.backend_tag_key
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
cluster_name = step.create_primary_cluster_targets.cluster_name
|
cluster_name = step.create_primary_cluster_targets.cluster_name
|
||||||
|
@ -602,11 +624,13 @@ scenario "replication" {
|
||||||
manage_service = local.manage_service
|
manage_service = local.manage_service
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
root_token = step.create_primary_cluster.root_token
|
root_token = step.create_primary_cluster.root_token
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_primary_seal_key.resource_name
|
||||||
|
seal_type = matrix.primary_seal
|
||||||
shamir_unseal_keys = matrix.primary_seal == "shamir" ? step.create_primary_cluster.unseal_keys_hex : null
|
shamir_unseal_keys = matrix.primary_seal == "shamir" ? step.create_primary_cluster.unseal_keys_hex : null
|
||||||
storage_backend = matrix.primary_backend
|
storage_backend = matrix.primary_backend
|
||||||
storage_node_prefix = "newprimary_node"
|
storage_node_prefix = "newprimary_node"
|
||||||
target_hosts = step.create_primary_cluster_additional_targets.hosts
|
target_hosts = step.create_primary_cluster_additional_targets.hosts
|
||||||
unseal_method = matrix.primary_seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,551 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
scenario "seal_ha" {
|
||||||
|
matrix {
|
||||||
|
arch = ["amd64", "arm64"]
|
||||||
|
artifact_source = ["local", "crt", "artifactory"]
|
||||||
|
artifact_type = ["bundle", "package"]
|
||||||
|
backend = ["consul", "raft"]
|
||||||
|
consul_version = ["1.12.9", "1.13.9", "1.14.9", "1.15.5", "1.16.1"]
|
||||||
|
distro = ["ubuntu", "rhel"]
|
||||||
|
edition = ["ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
||||||
|
primary_seal = ["awskms"]
|
||||||
|
secondary_seal = ["awskms"]
|
||||||
|
|
||||||
|
# Our local builder always creates bundles
|
||||||
|
exclude {
|
||||||
|
artifact_source = ["local"]
|
||||||
|
artifact_type = ["package"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# HSM and FIPS 140-2 are only supported on amd64
|
||||||
|
exclude {
|
||||||
|
arch = ["arm64"]
|
||||||
|
edition = ["ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
terraform_cli = terraform_cli.default
|
||||||
|
terraform = terraform.default
|
||||||
|
providers = [
|
||||||
|
provider.aws.default,
|
||||||
|
provider.enos.ubuntu,
|
||||||
|
provider.enos.rhel
|
||||||
|
]
|
||||||
|
|
||||||
|
locals {
|
||||||
|
artifact_path = matrix.artifact_source != "artifactory" ? abspath(var.vault_artifact_path) : null
|
||||||
|
enos_provider = {
|
||||||
|
rhel = provider.enos.rhel
|
||||||
|
ubuntu = provider.enos.ubuntu
|
||||||
|
}
|
||||||
|
manage_service = matrix.artifact_type == "bundle"
|
||||||
|
vault_install_dir = matrix.artifact_type == "bundle" ? var.vault_install_dir : global.vault_install_dir_packages[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
step "get_local_metadata" {
|
||||||
|
skip_step = matrix.artifact_source != "local"
|
||||||
|
module = module.get_local_metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
step "build_vault" {
|
||||||
|
module = "build_${matrix.artifact_source}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
build_tags = var.vault_local_build_tags != null ? var.vault_local_build_tags : global.build_tags[matrix.edition]
|
||||||
|
artifact_path = local.artifact_path
|
||||||
|
goarch = matrix.arch
|
||||||
|
goos = "linux"
|
||||||
|
artifactory_host = matrix.artifact_source == "artifactory" ? var.artifactory_host : null
|
||||||
|
artifactory_repo = matrix.artifact_source == "artifactory" ? var.artifactory_repo : null
|
||||||
|
artifactory_username = matrix.artifact_source == "artifactory" ? var.artifactory_username : null
|
||||||
|
artifactory_token = matrix.artifact_source == "artifactory" ? var.artifactory_token : null
|
||||||
|
arch = matrix.artifact_source == "artifactory" ? matrix.arch : null
|
||||||
|
product_version = var.vault_product_version
|
||||||
|
artifact_type = matrix.artifact_type
|
||||||
|
distro = matrix.artifact_source == "artifactory" ? matrix.distro : null
|
||||||
|
edition = matrix.artifact_source == "artifactory" ? matrix.edition : null
|
||||||
|
revision = var.vault_revision
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "ec2_info" {
|
||||||
|
module = module.ec2_info
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_vpc" {
|
||||||
|
module = module.create_vpc
|
||||||
|
|
||||||
|
variables {
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_primary_seal_key" {
|
||||||
|
module = "seal_key_${matrix.primary_seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
cluster_meta = "primary"
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_secondary_seal_key" {
|
||||||
|
module = "seal_key_${matrix.secondary_seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
cluster_meta = "secondary"
|
||||||
|
common_tags = global.tags
|
||||||
|
other_resources = step.create_primary_seal_key.resource_names
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This step reads the contents of the backend license if we're using a Consul backend and
|
||||||
|
// the edition is "ent".
|
||||||
|
step "read_backend_license" {
|
||||||
|
skip_step = matrix.backend == "raft" || var.backend_edition == "ce"
|
||||||
|
module = module.read_license
|
||||||
|
|
||||||
|
variables {
|
||||||
|
file_name = global.backend_license_path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "read_vault_license" {
|
||||||
|
skip_step = matrix.edition == "ce"
|
||||||
|
module = module.read_license
|
||||||
|
|
||||||
|
variables {
|
||||||
|
file_name = global.vault_license_path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_vault_cluster_targets" {
|
||||||
|
module = module.target_ec2_instances
|
||||||
|
depends_on = [step.create_vpc]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
|
cluster_tag_key = global.vault_tag_key
|
||||||
|
common_tags = global.tags
|
||||||
|
seal_key_names = step.create_secondary_seal_key.resource_names
|
||||||
|
vpc_id = step.create_vpc.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_vault_cluster_backend_targets" {
|
||||||
|
module = matrix.backend == "consul" ? module.target_ec2_instances : module.target_ec2_shim
|
||||||
|
depends_on = [step.create_vpc]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = provider.enos.ubuntu
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
|
seal_key_names = step.create_secondary_seal_key.resource_names
|
||||||
|
cluster_tag_key = global.backend_tag_key
|
||||||
|
common_tags = global.tags
|
||||||
|
vpc_id = step.create_vpc.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_backend_cluster" {
|
||||||
|
module = "backend_${matrix.backend}"
|
||||||
|
depends_on = [
|
||||||
|
step.create_vault_cluster_backend_targets
|
||||||
|
]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = provider.enos.ubuntu
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
||||||
|
cluster_tag_key = global.backend_tag_key
|
||||||
|
license = (matrix.backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
||||||
|
release = {
|
||||||
|
edition = var.backend_edition
|
||||||
|
version = matrix.consul_version
|
||||||
|
}
|
||||||
|
target_hosts = step.create_vault_cluster_backend_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "create_vault_cluster" {
|
||||||
|
module = module.vault_cluster
|
||||||
|
depends_on = [
|
||||||
|
step.create_backend_cluster,
|
||||||
|
step.build_vault,
|
||||||
|
step.create_vault_cluster_targets
|
||||||
|
]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
|
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
||||||
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
|
consul_license = (matrix.backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
||||||
|
consul_release = matrix.backend == "consul" ? {
|
||||||
|
edition = var.backend_edition
|
||||||
|
version = matrix.consul_version
|
||||||
|
} : null
|
||||||
|
enable_audit_devices = var.vault_enable_audit_devices
|
||||||
|
install_dir = local.vault_install_dir
|
||||||
|
license = matrix.edition != "ce" ? step.read_vault_license.license : null
|
||||||
|
local_artifact_path = local.artifact_path
|
||||||
|
manage_service = local.manage_service
|
||||||
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
|
// Only configure our primary seal during our initial cluster setup
|
||||||
|
seal_type = matrix.primary_seal
|
||||||
|
seal_key_name = step.create_primary_seal_key.resource_name
|
||||||
|
storage_backend = matrix.backend
|
||||||
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for our cluster to elect a leader
|
||||||
|
step "wait_for_leader" {
|
||||||
|
module = module.vault_wait_for_leader
|
||||||
|
depends_on = [step.create_vault_cluster]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
timeout = 120 # seconds
|
||||||
|
vault_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "get_vault_cluster_ips" {
|
||||||
|
module = module.vault_get_cluster_ips
|
||||||
|
depends_on = [step.wait_for_leader]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "verify_vault_unsealed" {
|
||||||
|
module = module.vault_verify_unsealed
|
||||||
|
depends_on = [step.wait_for_leader]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_instances = step.create_vault_cluster_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write some test data before we create the new seal
|
||||||
|
step "verify_write_test_data" {
|
||||||
|
module = module.vault_verify_write_data
|
||||||
|
depends_on = [
|
||||||
|
step.create_vault_cluster,
|
||||||
|
step.get_vault_cluster_ips,
|
||||||
|
step.verify_vault_unsealed,
|
||||||
|
]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
leader_public_ip = step.get_vault_cluster_ips.leader_public_ip
|
||||||
|
leader_private_ip = step.get_vault_cluster_ips.leader_private_ip
|
||||||
|
vault_instances = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the initial seal rewrap to complete before we add our HA seal.
|
||||||
|
step "wait_for_initial_seal_rewrap" {
|
||||||
|
module = module.vault_wait_for_seal_rewrap
|
||||||
|
depends_on = [
|
||||||
|
step.verify_write_test_data,
|
||||||
|
]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the vault service on all nodes before we restart with new seal config
|
||||||
|
step "stop_vault" {
|
||||||
|
module = module.stop_vault
|
||||||
|
depends_on = [
|
||||||
|
step.create_vault_cluster,
|
||||||
|
step.verify_write_test_data,
|
||||||
|
step.wait_for_initial_seal_rewrap,
|
||||||
|
]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the secondary seal to the cluster
|
||||||
|
step "add_ha_seal_to_cluster" {
|
||||||
|
module = module.start_vault
|
||||||
|
depends_on = [step.stop_vault]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
|
install_dir = local.vault_install_dir
|
||||||
|
license = matrix.edition != "ce" ? step.read_vault_license.license : null
|
||||||
|
manage_service = local.manage_service
|
||||||
|
seal_type = matrix.primary_seal
|
||||||
|
seal_key_name = step.create_primary_seal_key.resource_name
|
||||||
|
seal_type_secondary = matrix.secondary_seal
|
||||||
|
seal_key_name_secondary = step.create_secondary_seal_key.resource_name
|
||||||
|
storage_backend = matrix.backend
|
||||||
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for our cluster to elect a leader
|
||||||
|
step "wait_for_new_leader" {
|
||||||
|
module = module.vault_wait_for_leader
|
||||||
|
depends_on = [step.add_ha_seal_to_cluster]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
timeout = 120 # seconds
|
||||||
|
vault_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "get_updated_cluster_ips" {
|
||||||
|
module = module.vault_get_cluster_ips
|
||||||
|
depends_on = [step.wait_for_new_leader]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "verify_vault_unsealed_with_new_seal" {
|
||||||
|
module = module.vault_verify_unsealed
|
||||||
|
depends_on = [step.wait_for_new_leader]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_instances = step.create_vault_cluster_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the seal rewrap to complete and verify that no entries failed
|
||||||
|
step "wait_for_seal_rewrap" {
|
||||||
|
module = module.vault_wait_for_seal_rewrap
|
||||||
|
depends_on = [
|
||||||
|
step.add_ha_seal_to_cluster,
|
||||||
|
step.verify_vault_unsealed_with_new_seal,
|
||||||
|
]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_hosts = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "verify_vault_version" {
|
||||||
|
module = module.vault_verify_version
|
||||||
|
depends_on = [step.wait_for_seal_rewrap]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_instances = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_edition = matrix.edition
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_product_version = matrix.artifact_source == "local" ? step.get_local_metadata.version : var.vault_product_version
|
||||||
|
vault_revision = matrix.artifact_source == "local" ? step.get_local_metadata.revision : var.vault_revision
|
||||||
|
vault_build_date = matrix.artifact_source == "local" ? step.get_local_metadata.build_date : var.vault_build_date
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "verify_raft_auto_join_voter" {
|
||||||
|
skip_step = matrix.backend != "raft"
|
||||||
|
module = module.vault_verify_raft_auto_join_voter
|
||||||
|
depends_on = [step.wait_for_seal_rewrap]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_instances = step.create_vault_cluster_targets.hosts
|
||||||
|
vault_root_token = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "verify_replication" {
|
||||||
|
module = module.vault_verify_replication
|
||||||
|
depends_on = [step.wait_for_seal_rewrap]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_edition = matrix.edition
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
vault_instances = step.create_vault_cluster_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "verify_read_test_data" {
|
||||||
|
module = module.vault_verify_read_data
|
||||||
|
depends_on = [step.wait_for_seal_rewrap]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
node_public_ips = step.get_updated_cluster_ips.follower_public_ips
|
||||||
|
vault_install_dir = local.vault_install_dir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
step "verify_ui" {
|
||||||
|
module = module.vault_verify_ui
|
||||||
|
depends_on = [step.wait_for_seal_rewrap]
|
||||||
|
|
||||||
|
providers = {
|
||||||
|
enos = local.enos_provider[matrix.distro]
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
vault_instances = step.create_vault_cluster_targets.hosts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "audit_device_file_path" {
|
||||||
|
description = "The file path for the file audit device, if enabled"
|
||||||
|
value = step.create_vault_cluster.audit_device_file_path
|
||||||
|
}
|
||||||
|
|
||||||
|
output "cluster_name" {
|
||||||
|
description = "The Vault cluster name"
|
||||||
|
value = step.create_vault_cluster.cluster_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "hosts" {
|
||||||
|
description = "The Vault cluster target hosts"
|
||||||
|
value = step.create_vault_cluster.target_hosts
|
||||||
|
}
|
||||||
|
|
||||||
|
output "primary_seal_key_name" {
|
||||||
|
description = "The Vault cluster primary seal key name"
|
||||||
|
value = step.create_primary_seal_key.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "private_ips" {
|
||||||
|
description = "The Vault cluster private IPs"
|
||||||
|
value = step.create_vault_cluster.private_ips
|
||||||
|
}
|
||||||
|
|
||||||
|
output "public_ips" {
|
||||||
|
description = "The Vault cluster public IPs"
|
||||||
|
value = step.create_vault_cluster.public_ips
|
||||||
|
}
|
||||||
|
|
||||||
|
output "root_token" {
|
||||||
|
description = "The Vault cluster root token"
|
||||||
|
value = step.create_vault_cluster.root_token
|
||||||
|
}
|
||||||
|
|
||||||
|
output "recovery_key_shares" {
|
||||||
|
description = "The Vault cluster recovery key shares"
|
||||||
|
value = step.create_vault_cluster.recovery_key_shares
|
||||||
|
}
|
||||||
|
|
||||||
|
output "recovery_keys_b64" {
|
||||||
|
description = "The Vault cluster recovery keys b64"
|
||||||
|
value = step.create_vault_cluster.recovery_keys_b64
|
||||||
|
}
|
||||||
|
|
||||||
|
output "recovery_keys_hex" {
|
||||||
|
description = "The Vault cluster recovery keys hex"
|
||||||
|
value = step.create_vault_cluster.recovery_keys_hex
|
||||||
|
}
|
||||||
|
|
||||||
|
output "secondary_seal_key_name" {
|
||||||
|
description = "The Vault cluster secondary seal key name"
|
||||||
|
value = step.create_secondary_seal_key.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "unseal_keys_b64" {
|
||||||
|
description = "The Vault cluster unseal keys"
|
||||||
|
value = step.create_vault_cluster.unseal_keys_b64
|
||||||
|
}
|
||||||
|
|
||||||
|
output "unseal_keys_hex" {
|
||||||
|
description = "The Vault cluster unseal keys hex"
|
||||||
|
value = step.create_vault_cluster.unseal_keys_hex
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ scenario "smoke" {
|
||||||
distro = ["ubuntu", "rhel"]
|
distro = ["ubuntu", "rhel"]
|
||||||
edition = ["ce", "ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
edition = ["ce", "ent", "ent.fips1402", "ent.hsm", "ent.hsm.fips1402"]
|
||||||
seal = ["awskms", "shamir"]
|
seal = ["awskms", "shamir"]
|
||||||
|
seal_ha_beta = ["true", "false"]
|
||||||
|
|
||||||
# Our local builder always creates bundles
|
# Our local builder always creates bundles
|
||||||
exclude {
|
exclude {
|
||||||
|
@ -81,6 +82,15 @@ scenario "smoke" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step "create_seal_key" {
|
||||||
|
module = "seal_key_${matrix.seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This step reads the contents of the backend license if we're using a Consul backend and
|
// This step reads the contents of the backend license if we're using a Consul backend and
|
||||||
// the edition is "ent".
|
// the edition is "ent".
|
||||||
step "read_backend_license" {
|
step "read_backend_license" {
|
||||||
|
@ -110,11 +120,11 @@ scenario "smoke" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +137,11 @@ scenario "smoke" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.backend_tag_key
|
||||||
cluster_tag_key = global.backend_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +181,6 @@ scenario "smoke" {
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
artifactory_release = matrix.artifact_source == "artifactory" ? step.build_vault.vault_artifactory_release : null
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = global.backend_tag_key
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
cluster_name = step.create_vault_cluster_targets.cluster_name
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
|
@ -186,9 +195,11 @@ scenario "smoke" {
|
||||||
local_artifact_path = local.artifact_path
|
local_artifact_path = local.artifact_path
|
||||||
manage_service = local.manage_service
|
manage_service = local.manage_service
|
||||||
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
packages = concat(global.packages, global.distro_packages[matrix.distro])
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_seal_key.resource_name
|
||||||
|
seal_type = matrix.seal
|
||||||
storage_backend = matrix.backend
|
storage_backend = matrix.backend
|
||||||
target_hosts = step.create_vault_cluster_targets.hosts
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
unseal_method = matrix.seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,11 +363,6 @@ scenario "smoke" {
|
||||||
value = step.create_vault_cluster.audit_device_file_path
|
value = step.create_vault_cluster.audit_device_file_path
|
||||||
}
|
}
|
||||||
|
|
||||||
output "awskms_unseal_key_arn" {
|
|
||||||
description = "The Vault cluster KMS key arn"
|
|
||||||
value = step.create_vpc.kms_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
output "cluster_name" {
|
output "cluster_name" {
|
||||||
description = "The Vault cluster name"
|
description = "The Vault cluster name"
|
||||||
value = step.create_vault_cluster.cluster_name
|
value = step.create_vault_cluster.cluster_name
|
||||||
|
@ -397,6 +403,11 @@ scenario "smoke" {
|
||||||
value = step.create_vault_cluster.recovery_keys_hex
|
value = step.create_vault_cluster.recovery_keys_hex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "seal_key_name" {
|
||||||
|
description = "The Vault cluster seal key name"
|
||||||
|
value = step.create_seal_key.name
|
||||||
|
}
|
||||||
|
|
||||||
output "unseal_keys_b64" {
|
output "unseal_keys_b64" {
|
||||||
description = "The Vault cluster unseal keys"
|
description = "The Vault cluster unseal keys"
|
||||||
value = step.create_vault_cluster.unseal_keys_b64
|
value = step.create_vault_cluster.unseal_keys_b64
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
scenario "ui" {
|
scenario "ui" {
|
||||||
matrix {
|
matrix {
|
||||||
edition = ["ce", "ent"]
|
edition = ["ce", "ent"]
|
||||||
backend = ["consul", "raft"]
|
backend = ["consul", "raft"]
|
||||||
|
seal_ha_beta = ["true", "false"]
|
||||||
}
|
}
|
||||||
|
|
||||||
terraform_cli = terraform_cli.default
|
terraform_cli = terraform_cli.default
|
||||||
|
@ -68,6 +69,15 @@ scenario "ui" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step "create_seal_key" {
|
||||||
|
module = "seal_key_${local.seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This step reads the contents of the backend license if we're using a Consul backend and
|
// This step reads the contents of the backend license if we're using a Consul backend and
|
||||||
// the edition is "ent".
|
// the edition is "ent".
|
||||||
step "read_backend_license" {
|
step "read_backend_license" {
|
||||||
|
@ -97,11 +107,11 @@ scenario "ui" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[local.arch][local.distro][var.ubuntu_distro_version]
|
ami_id = step.ec2_info.ami_ids[local.arch][local.distro][var.ubuntu_distro_version]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = local.vault_tag_key
|
||||||
cluster_tag_key = local.vault_tag_key
|
common_tags = local.tags
|
||||||
common_tags = local.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,11 +124,11 @@ scenario "ui" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = local.backend_tag_key
|
||||||
cluster_tag_key = local.backend_tag_key
|
common_tags = local.tags
|
||||||
common_tags = local.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +167,6 @@ scenario "ui" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = local.backend_tag_key
|
backend_cluster_tag_key = local.backend_tag_key
|
||||||
cluster_name = step.create_vault_cluster_targets.cluster_name
|
cluster_name = step.create_vault_cluster_targets.cluster_name
|
||||||
|
@ -171,9 +180,11 @@ scenario "ui" {
|
||||||
license = matrix.edition != "ce" ? step.read_vault_license.license : null
|
license = matrix.edition != "ce" ? step.read_vault_license.license : null
|
||||||
local_artifact_path = local.bundle_path
|
local_artifact_path = local.bundle_path
|
||||||
packages = global.distro_packages["ubuntu"]
|
packages = global.distro_packages["ubuntu"]
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_seal_key.resource_name
|
||||||
|
seal_type = local.seal
|
||||||
storage_backend = matrix.backend
|
storage_backend = matrix.backend
|
||||||
target_hosts = step.create_vault_cluster_targets.hosts
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
unseal_method = local.seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,11 +223,6 @@ scenario "ui" {
|
||||||
value = step.create_vault_cluster.audit_device_file_path
|
value = step.create_vault_cluster.audit_device_file_path
|
||||||
}
|
}
|
||||||
|
|
||||||
output "awskms_unseal_key_arn" {
|
|
||||||
description = "The Vault cluster KMS key arn"
|
|
||||||
value = step.create_vpc.kms_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
output "cluster_name" {
|
output "cluster_name" {
|
||||||
description = "The Vault cluster name"
|
description = "The Vault cluster name"
|
||||||
value = step.create_vault_cluster.cluster_name
|
value = step.create_vault_cluster.cluster_name
|
||||||
|
@ -257,6 +263,11 @@ scenario "ui" {
|
||||||
value = step.create_vault_cluster.root_token
|
value = step.create_vault_cluster.root_token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "seal_key_name" {
|
||||||
|
description = "The Vault cluster seal key name"
|
||||||
|
value = step.create_seal_key.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
output "ui_test_environment" {
|
output "ui_test_environment" {
|
||||||
value = step.test_ui.ui_test_environment
|
value = step.test_ui.ui_test_environment
|
||||||
description = "The environment variables that are required in order to run the test:enos yarn target"
|
description = "The environment variables that are required in order to run the test:enos yarn target"
|
||||||
|
|
|
@ -16,6 +16,7 @@ scenario "upgrade" {
|
||||||
// those earlier versions.
|
// those earlier versions.
|
||||||
initial_version = ["1.11.12", "1.12.11", "1.13.6", "1.14.2"]
|
initial_version = ["1.11.12", "1.12.11", "1.13.6", "1.14.2"]
|
||||||
seal = ["awskms", "shamir"]
|
seal = ["awskms", "shamir"]
|
||||||
|
seal_ha_beta = ["true", "false"]
|
||||||
|
|
||||||
# Our local builder always creates bundles
|
# Our local builder always creates bundles
|
||||||
exclude {
|
exclude {
|
||||||
|
@ -93,6 +94,15 @@ scenario "upgrade" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
step "create_seal_key" {
|
||||||
|
module = "seal_key_${matrix.seal}"
|
||||||
|
|
||||||
|
variables {
|
||||||
|
cluster_id = step.create_vpc.cluster_id
|
||||||
|
common_tags = global.tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This step reads the contents of the backend license if we're using a Consul backend and
|
// This step reads the contents of the backend license if we're using a Consul backend and
|
||||||
// the edition is "ent".
|
// the edition is "ent".
|
||||||
step "read_backend_license" {
|
step "read_backend_license" {
|
||||||
|
@ -122,11 +132,11 @@ scenario "upgrade" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
ami_id = step.ec2_info.ami_ids[matrix.arch][matrix.distro][global.distro_version[matrix.distro]]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.vault_tag_key
|
||||||
cluster_tag_key = global.vault_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,11 +149,11 @@ scenario "upgrade" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
ami_id = step.ec2_info.ami_ids["arm64"]["ubuntu"]["22.04"]
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
cluster_tag_key = global.backend_tag_key
|
||||||
cluster_tag_key = global.backend_tag_key
|
common_tags = global.tags
|
||||||
common_tags = global.tags
|
seal_key_names = step.create_seal_key.resource_names
|
||||||
vpc_id = step.create_vpc.vpc_id
|
vpc_id = step.create_vpc.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +192,6 @@ scenario "upgrade" {
|
||||||
}
|
}
|
||||||
|
|
||||||
variables {
|
variables {
|
||||||
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
|
|
||||||
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
backend_cluster_name = step.create_vault_cluster_backend_targets.cluster_name
|
||||||
backend_cluster_tag_key = global.backend_tag_key
|
backend_cluster_tag_key = global.backend_tag_key
|
||||||
consul_license = (matrix.backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
consul_license = (matrix.backend == "consul" && var.backend_edition == "ent") ? step.read_backend_license.license : null
|
||||||
|
@ -199,9 +208,11 @@ scenario "upgrade" {
|
||||||
edition = matrix.edition
|
edition = matrix.edition
|
||||||
version = matrix.initial_version
|
version = matrix.initial_version
|
||||||
}
|
}
|
||||||
|
seal_ha_beta = matrix.seal_ha_beta
|
||||||
|
seal_key_name = step.create_seal_key.resource_name
|
||||||
|
seal_type = matrix.seal
|
||||||
storage_backend = matrix.backend
|
storage_backend = matrix.backend
|
||||||
target_hosts = step.create_vault_cluster_targets.hosts
|
target_hosts = step.create_vault_cluster_targets.hosts
|
||||||
unseal_method = matrix.seal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,11 +424,6 @@ scenario "upgrade" {
|
||||||
value = step.create_vault_cluster.audit_device_file_path
|
value = step.create_vault_cluster.audit_device_file_path
|
||||||
}
|
}
|
||||||
|
|
||||||
output "awskms_unseal_key_arn" {
|
|
||||||
description = "The Vault cluster KMS key arn"
|
|
||||||
value = step.create_vpc.kms_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
output "cluster_name" {
|
output "cluster_name" {
|
||||||
description = "The Vault cluster name"
|
description = "The Vault cluster name"
|
||||||
value = step.create_vault_cluster.cluster_name
|
value = step.create_vault_cluster.cluster_name
|
||||||
|
@ -458,6 +464,11 @@ scenario "upgrade" {
|
||||||
value = step.create_vault_cluster.recovery_keys_hex
|
value = step.create_vault_cluster.recovery_keys_hex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "seal_key_name" {
|
||||||
|
description = "The Vault cluster seal key name"
|
||||||
|
value = step.create_seal_key.resource_name
|
||||||
|
}
|
||||||
|
|
||||||
output "unseal_keys_b64" {
|
output "unseal_keys_b64" {
|
||||||
description = "The Vault cluster unseal keys"
|
description = "The Vault cluster unseal keys"
|
||||||
value = step.create_vault_cluster.unseal_keys_b64
|
value = step.create_vault_cluster.unseal_keys_b64
|
||||||
|
|
|
@ -18,18 +18,6 @@ resource "random_string" "cluster_id" {
|
||||||
special = false
|
special = false
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_kms_key" "key" {
|
|
||||||
count = var.create_kms_key ? 1 : 0
|
|
||||||
description = "vault-ci-kms-key"
|
|
||||||
deletion_window_in_days = 7 // 7 is the shortest allowed window
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_kms_alias" "alias" {
|
|
||||||
count = var.create_kms_key ? 1 : 0
|
|
||||||
name = "alias/enos_key-${random_string.cluster_id.result}"
|
|
||||||
target_key_id = aws_kms_key.key[0].key_id
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_vpc" "vpc" {
|
resource "aws_vpc" "vpc" {
|
||||||
cidr_block = var.cidr
|
cidr_block = var.cidr
|
||||||
enable_dns_hostnames = true
|
enable_dns_hostnames = true
|
||||||
|
|
|
@ -1,22 +1,17 @@
|
||||||
# Copyright (c) HashiCorp, Inc.
|
# Copyright (c) HashiCorp, Inc.
|
||||||
# SPDX-License-Identifier: BUSL-1.1
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
output "vpc_id" {
|
output "id" {
|
||||||
description = "Created VPC ID"
|
description = "Created VPC ID"
|
||||||
value = aws_vpc.vpc.id
|
value = aws_vpc.vpc.id
|
||||||
}
|
}
|
||||||
|
|
||||||
output "vpc_cidr" {
|
output "cidr" {
|
||||||
description = "CIDR for whole VPC"
|
description = "CIDR for whole VPC"
|
||||||
value = var.cidr
|
value = var.cidr
|
||||||
}
|
}
|
||||||
|
|
||||||
output "kms_key_arn" {
|
output "cluster_id" {
|
||||||
description = "ARN of the generated KMS key"
|
description = "A unique string associated with the VPC"
|
||||||
value = try(aws_kms_key.key[0].arn, null)
|
value = random_string.cluster_id.result
|
||||||
}
|
|
||||||
|
|
||||||
output "kms_key_alias" {
|
|
||||||
description = "Alias of the generated KMS key"
|
|
||||||
value = try(aws_kms_alias.alias[0].name, null)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,3 @@ variable "common_tags" {
|
||||||
type = map(string)
|
type = map(string)
|
||||||
default = { "Project" : "vault-ci" }
|
default = { "Project" : "vault-ci" }
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "create_kms_key" {
|
|
||||||
description = "Whether or not to create an key management service key"
|
|
||||||
type = bool
|
|
||||||
default = true
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
variable "cluster_id" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "cluster_meta" {
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "common_tags" {
|
||||||
|
type = map(string)
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "other_resources" {
|
||||||
|
type = list(string)
|
||||||
|
default = []
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
cluster_name = var.cluster_meta == null ? var.cluster_id : "${var.cluster_id}-${var.cluster_meta}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_kms_key" "key" {
|
||||||
|
description = "auto-unseal-key-${local.cluster_name}"
|
||||||
|
deletion_window_in_days = 7 // 7 is the shortest allowed window
|
||||||
|
tags = var.common_tags
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_kms_alias" "alias" {
|
||||||
|
name = "alias/auto-unseal-key-${local.cluster_name}"
|
||||||
|
target_key_id = aws_kms_key.key.key_id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "alias" {
|
||||||
|
description = "The key alias name"
|
||||||
|
value = aws_kms_alias.alias.name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "id" {
|
||||||
|
description = "The key ID"
|
||||||
|
value = aws_kms_key.key.key_id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "resource_name" {
|
||||||
|
description = "The ARN"
|
||||||
|
value = aws_kms_key.key.arn
|
||||||
|
}
|
||||||
|
|
||||||
|
output "resource_names" {
|
||||||
|
description = "The list of names"
|
||||||
|
value = compact(concat([aws_kms_key.key.arn], var.other_resources))
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
# A shim unseal key module for shamir seal types
|
||||||
|
|
||||||
|
variable "cluster_id" { default = null }
|
||||||
|
variable "cluster_meta" { default = null }
|
||||||
|
variable "common_tags" { default = null }
|
||||||
|
variable "names" {
|
||||||
|
type = list(string)
|
||||||
|
default = []
|
||||||
|
}
|
||||||
|
|
||||||
|
output "alias" { value = null }
|
||||||
|
output "id" { value = null }
|
||||||
|
output "resource_name" { value = null }
|
||||||
|
output "resource_names" { value = var.names }
|
|
@ -0,0 +1,167 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
# We need to specify the provider source in each module until we publish it
|
||||||
|
# to the public registry
|
||||||
|
enos = {
|
||||||
|
source = "app.terraform.io/hashicorp-qti/enos"
|
||||||
|
version = ">= 0.4.7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "enos_environment" "localhost" {}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
bin_path = "${var.install_dir}/vault"
|
||||||
|
environment = local.seal_secondary == null ? var.environment : merge(
|
||||||
|
var.environment,
|
||||||
|
{ VAULT_ENABLE_SEAL_HA_BETA : tobool(var.seal_ha_beta) },
|
||||||
|
)
|
||||||
|
// In order to get Terraform to plan we have to use collections with keys
|
||||||
|
// that are known at plan time. In order for our module to work our var.target_hosts
|
||||||
|
// must be a map with known keys at plan time. Here we're creating locals
|
||||||
|
// that keep track of index values that point to our target hosts.
|
||||||
|
followers = toset(slice(local.instances, 1, length(local.instances)))
|
||||||
|
instances = [for idx in range(length(var.target_hosts)) : tostring(idx)]
|
||||||
|
key_shares = {
|
||||||
|
"awskms" = null
|
||||||
|
"shamir" = 5
|
||||||
|
}
|
||||||
|
key_threshold = {
|
||||||
|
"awskms" = null
|
||||||
|
"shamir" = 3
|
||||||
|
}
|
||||||
|
leader = toset(slice(local.instances, 0, 1))
|
||||||
|
recovery_shares = {
|
||||||
|
"awskms" = 5
|
||||||
|
"shamir" = null
|
||||||
|
}
|
||||||
|
recovery_threshold = {
|
||||||
|
"awskms" = 3
|
||||||
|
"shamir" = null
|
||||||
|
}
|
||||||
|
seals = local.seal_secondary.type == "none" ? { primary = local.seal_primary } : {
|
||||||
|
primary = local.seal_primary
|
||||||
|
secondary = local.seal_secondary
|
||||||
|
}
|
||||||
|
seals_primary = {
|
||||||
|
"awskms" = {
|
||||||
|
type = "awskms"
|
||||||
|
attributes = {
|
||||||
|
name = "primary"
|
||||||
|
kms_key_id = var.seal_key_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"shamir" = {
|
||||||
|
type = "shamir"
|
||||||
|
attributes = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seal_primary = local.seals_primary[var.seal_type]
|
||||||
|
seals_secondary = {
|
||||||
|
"awskms" = {
|
||||||
|
type = "awskms"
|
||||||
|
attributes = {
|
||||||
|
name = "secondary"
|
||||||
|
kms_key_id = var.seal_key_name_secondary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"none" = {
|
||||||
|
type = "none"
|
||||||
|
attributes = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seal_secondary = local.seals_secondary[var.seal_type_secondary]
|
||||||
|
storage_config = [for idx, host in var.target_hosts : (var.storage_backend == "raft" ?
|
||||||
|
merge(
|
||||||
|
{
|
||||||
|
node_id = "${var.storage_node_prefix}_${idx}"
|
||||||
|
},
|
||||||
|
var.storage_backend_attrs
|
||||||
|
) :
|
||||||
|
{
|
||||||
|
address = "127.0.0.1:8500"
|
||||||
|
path = "vault"
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "enos_vault_start" "leader" {
|
||||||
|
for_each = local.leader
|
||||||
|
|
||||||
|
bin_path = local.bin_path
|
||||||
|
config_dir = var.config_dir
|
||||||
|
environment = local.environment
|
||||||
|
config = {
|
||||||
|
api_addr = "http://${var.target_hosts[each.value].private_ip}:8200"
|
||||||
|
cluster_addr = "http://${var.target_hosts[each.value].private_ip}:8201"
|
||||||
|
cluster_name = var.cluster_name
|
||||||
|
listener = {
|
||||||
|
type = "tcp"
|
||||||
|
attributes = {
|
||||||
|
address = "0.0.0.0:8200"
|
||||||
|
tls_disable = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_level = var.log_level
|
||||||
|
storage = {
|
||||||
|
type = var.storage_backend
|
||||||
|
attributes = ({ for key, value in local.storage_config[each.key] : key => value })
|
||||||
|
}
|
||||||
|
seals = local.seals
|
||||||
|
ui = true
|
||||||
|
}
|
||||||
|
license = var.license
|
||||||
|
manage_service = var.manage_service
|
||||||
|
username = var.service_username
|
||||||
|
unit_name = "vault"
|
||||||
|
|
||||||
|
transport = {
|
||||||
|
ssh = {
|
||||||
|
host = var.target_hosts[each.value].public_ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "enos_vault_start" "followers" {
|
||||||
|
depends_on = [
|
||||||
|
enos_vault_start.leader,
|
||||||
|
]
|
||||||
|
for_each = local.followers
|
||||||
|
|
||||||
|
bin_path = local.bin_path
|
||||||
|
config_dir = var.config_dir
|
||||||
|
environment = local.environment
|
||||||
|
config = {
|
||||||
|
api_addr = "http://${var.target_hosts[each.value].private_ip}:8200"
|
||||||
|
cluster_addr = "http://${var.target_hosts[each.value].private_ip}:8201"
|
||||||
|
cluster_name = var.cluster_name
|
||||||
|
listener = {
|
||||||
|
type = "tcp"
|
||||||
|
attributes = {
|
||||||
|
address = "0.0.0.0:8200"
|
||||||
|
tls_disable = "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log_level = var.log_level
|
||||||
|
storage = {
|
||||||
|
type = var.storage_backend
|
||||||
|
attributes = { for key, value in local.storage_config[each.key] : key => value }
|
||||||
|
}
|
||||||
|
seals = local.seals
|
||||||
|
ui = true
|
||||||
|
}
|
||||||
|
license = var.license
|
||||||
|
manage_service = var.manage_service
|
||||||
|
username = var.service_username
|
||||||
|
unit_name = "vault"
|
||||||
|
|
||||||
|
transport = {
|
||||||
|
ssh = {
|
||||||
|
host = var.target_hosts[each.value].public_ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
output "cluster_name" {
|
||||||
|
description = "The Vault cluster name"
|
||||||
|
value = var.cluster_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "followers" {
|
||||||
|
description = "The follower enos_vault_start resources"
|
||||||
|
value = enos_vault_start.followers
|
||||||
|
}
|
||||||
|
|
||||||
|
output "leader" {
|
||||||
|
description = "The leader enos_vault_start resource"
|
||||||
|
value = enos_vault_start.leader
|
||||||
|
}
|
||||||
|
|
||||||
|
output "private_ips" {
|
||||||
|
description = "Vault cluster target host private_ips"
|
||||||
|
value = [for host in var.target_hosts : host.private_ip]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "public_ips" {
|
||||||
|
description = "Vault cluster target host public_ips"
|
||||||
|
value = [for host in var.target_hosts : host.public_ip]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "target_hosts" {
|
||||||
|
description = "The vault cluster instances that were created"
|
||||||
|
|
||||||
|
value = var.target_hosts
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
variable "cluster_name" {
|
||||||
|
type = string
|
||||||
|
description = "The Vault cluster name"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "config_dir" {
|
||||||
|
type = string
|
||||||
|
description = "The directory to use for Vault configuration"
|
||||||
|
default = "/etc/vault.d"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "environment" {
|
||||||
|
description = "Optional Vault configuration environment variables to set starting Vault"
|
||||||
|
type = map(string)
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "install_dir" {
|
||||||
|
type = string
|
||||||
|
description = "The directory where the vault binary will be installed"
|
||||||
|
default = "/opt/vault/bin"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "license" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
description = "The value of the Vault license"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "log_level" {
|
||||||
|
type = string
|
||||||
|
description = "The vault service log level"
|
||||||
|
default = "info"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = contains(["trace", "debug", "info", "warn", "error"], var.log_level)
|
||||||
|
error_message = "The log_level must be one of 'trace', 'debug', 'info', 'warn', or 'error'."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "manage_service" {
|
||||||
|
type = bool
|
||||||
|
description = "Manage the Vault service users and systemd unit. Disable this to use configuration in RPM and Debian packages"
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_ha_beta" {
|
||||||
|
description = "Enable using Seal HA on clusters that meet minimum version requirements and are enterprise editions"
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_key_name" {
|
||||||
|
type = string
|
||||||
|
description = "The auto-unseal key name"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_key_name_secondary" {
|
||||||
|
type = string
|
||||||
|
description = "The secondary auto-unseal key name"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_type" {
|
||||||
|
type = string
|
||||||
|
description = "The method by which to unseal the Vault cluster"
|
||||||
|
default = "awskms"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = contains(["awskms", "shamir"], var.seal_type)
|
||||||
|
error_message = "The seal_type must be either awskms or shamir. No other unseal methods are supported."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_type_secondary" {
|
||||||
|
type = string
|
||||||
|
description = "A secondary HA seal method. Only supported in Vault Enterprise >= 1.15"
|
||||||
|
default = "none"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = contains(["awskms", "none"], var.seal_type_secondary)
|
||||||
|
error_message = "The secondary_seal_type must be 'awskms' or 'none'. No other secondary unseal methods are supported."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "service_username" {
|
||||||
|
type = string
|
||||||
|
description = "The host username to own the vault service"
|
||||||
|
default = "vault"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "storage_backend" {
|
||||||
|
type = string
|
||||||
|
description = "The storage backend to use"
|
||||||
|
default = "raft"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = contains(["raft", "consul"], var.storage_backend)
|
||||||
|
error_message = "The storage_backend must be either raft or consul. No other storage backends are supported."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "storage_backend_attrs" {
|
||||||
|
type = map(any)
|
||||||
|
description = "An optional set of key value pairs to inject into the storage block"
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "storage_node_prefix" {
|
||||||
|
type = string
|
||||||
|
description = "A prefix to use for each node in the Vault storage configuration"
|
||||||
|
default = "node"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "target_hosts" {
|
||||||
|
description = "The target machines host addresses to use for the Vault cluster"
|
||||||
|
type = map(object({
|
||||||
|
private_ip = string
|
||||||
|
public_ip = string
|
||||||
|
}))
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
# We need to specify the provider source in each module until we publish it
|
||||||
|
# to the public registry
|
||||||
|
enos = {
|
||||||
|
source = "app.terraform.io/hashicorp-qti/enos"
|
||||||
|
version = ">= 0.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "service_name" {
|
||||||
|
type = string
|
||||||
|
description = "The Vault systemd service name"
|
||||||
|
default = "vault"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "target_hosts" {
|
||||||
|
description = "The target machines host addresses to use for the Vault cluster"
|
||||||
|
type = map(object({
|
||||||
|
private_ip = string
|
||||||
|
public_ip = string
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "enos_remote_exec" "shutdown_multiple_nodes" {
|
||||||
|
for_each = var.target_hosts
|
||||||
|
inline = ["sudo systemctl stop ${var.service_name}.service; sleep 5"]
|
||||||
|
|
||||||
|
transport = {
|
||||||
|
ssh = {
|
||||||
|
host = each.value.public_ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,10 +23,6 @@ data "aws_subnets" "vpc" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data "aws_kms_key" "kms_key" {
|
|
||||||
key_id = var.awskms_unseal_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
data "aws_iam_policy_document" "target" {
|
data "aws_iam_policy_document" "target" {
|
||||||
statement {
|
statement {
|
||||||
resources = ["*"]
|
resources = ["*"]
|
||||||
|
@ -37,16 +33,20 @@ data "aws_iam_policy_document" "target" {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
statement {
|
dynamic "statement" {
|
||||||
resources = [var.awskms_unseal_key_arn]
|
for_each = var.seal_key_names
|
||||||
|
|
||||||
actions = [
|
content {
|
||||||
"kms:DescribeKey",
|
resources = [statement.value]
|
||||||
"kms:ListKeys",
|
|
||||||
"kms:Encrypt",
|
actions = [
|
||||||
"kms:Decrypt",
|
"kms:DescribeKey",
|
||||||
"kms:GenerateDataKey"
|
"kms:ListKeys",
|
||||||
]
|
"kms:Encrypt",
|
||||||
|
"kms:Decrypt",
|
||||||
|
"kms:GenerateDataKey"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,6 @@ variable "ami_id" {
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "awskms_unseal_key_arn" {
|
|
||||||
type = string
|
|
||||||
description = "The AWSKMS key ARN if using the awskms unseal method. If specified the instances will be granted kms permissions to the key"
|
|
||||||
default = null
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "cluster_name" {
|
variable "cluster_name" {
|
||||||
type = string
|
type = string
|
||||||
description = "A unique cluster identifier"
|
description = "A unique cluster identifier"
|
||||||
|
@ -73,6 +67,12 @@ variable "project_name" {
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "seal_key_names" {
|
||||||
|
type = list(string)
|
||||||
|
description = "The key management seal key names"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
variable "ssh_allow_ips" {
|
variable "ssh_allow_ips" {
|
||||||
description = "Allowlisted IP addresses for SSH access to target nodes. The IP address of the machine running Enos will automatically allowlisted"
|
description = "Allowlisted IP addresses for SSH access to target nodes. The IP address of the machine running Enos will automatically allowlisted"
|
||||||
type = list(string)
|
type = list(string)
|
||||||
|
|
|
@ -53,10 +53,6 @@ data "aws_subnets" "vpc" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data "aws_kms_key" "kms_key" {
|
|
||||||
key_id = var.awskms_unseal_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
data "aws_iam_policy_document" "target" {
|
data "aws_iam_policy_document" "target" {
|
||||||
statement {
|
statement {
|
||||||
resources = ["*"]
|
resources = ["*"]
|
||||||
|
@ -67,16 +63,20 @@ data "aws_iam_policy_document" "target" {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
statement {
|
dynamic "statement" {
|
||||||
resources = [var.awskms_unseal_key_arn]
|
for_each = var.seal_key_names
|
||||||
|
|
||||||
actions = [
|
content {
|
||||||
"kms:DescribeKey",
|
resources = [statement.value]
|
||||||
"kms:ListKeys",
|
|
||||||
"kms:Encrypt",
|
actions = [
|
||||||
"kms:Decrypt",
|
"kms:DescribeKey",
|
||||||
"kms:GenerateDataKey"
|
"kms:ListKeys",
|
||||||
]
|
"kms:Encrypt",
|
||||||
|
"kms:Decrypt",
|
||||||
|
"kms:GenerateDataKey"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,6 @@ variable "ami_id" {
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "awskms_unseal_key_arn" {
|
|
||||||
type = string
|
|
||||||
description = "The AWSKMS key ARN if using the awskms unseal method. If specified the instances will be granted kms permissions to the key"
|
|
||||||
default = null
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "cluster_name" {
|
variable "cluster_name" {
|
||||||
type = string
|
type = string
|
||||||
description = "A unique cluster identifier"
|
description = "A unique cluster identifier"
|
||||||
|
@ -53,6 +47,12 @@ variable "project_name" {
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "seal_key_names" {
|
||||||
|
type = list(string)
|
||||||
|
description = "The key management seal key names"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
variable "ssh_allow_ips" {
|
variable "ssh_allow_ips" {
|
||||||
description = "Allowlisted IP addresses for SSH access to target nodes. The IP address of the machine running Enos will automatically allowlisted"
|
description = "Allowlisted IP addresses for SSH access to target nodes. The IP address of the machine running Enos will automatically allowlisted"
|
||||||
type = list(string)
|
type = list(string)
|
||||||
|
|
|
@ -13,7 +13,6 @@ terraform {
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "ami_id" { default = null }
|
variable "ami_id" { default = null }
|
||||||
variable "awskms_unseal_key_arn" { default = null }
|
|
||||||
variable "cluster_name" { default = null }
|
variable "cluster_name" { default = null }
|
||||||
variable "cluster_tag_key" { default = null }
|
variable "cluster_tag_key" { default = null }
|
||||||
variable "common_tags" { default = null }
|
variable "common_tags" { default = null }
|
||||||
|
@ -25,6 +24,7 @@ variable "instance_mem_min" { default = null }
|
||||||
variable "instance_types" { default = null }
|
variable "instance_types" { default = null }
|
||||||
variable "max_price" { default = null }
|
variable "max_price" { default = null }
|
||||||
variable "project_name" { default = null }
|
variable "project_name" { default = null }
|
||||||
|
variable "seal_key_names" { default = null }
|
||||||
variable "ssh_allow_ips" { default = null }
|
variable "ssh_allow_ips" { default = null }
|
||||||
variable "ssh_keypair" { default = null }
|
variable "ssh_keypair" { default = null }
|
||||||
variable "vpc_id" { default = null }
|
variable "vpc_id" { default = null }
|
||||||
|
|
|
@ -23,10 +23,6 @@ data "aws_subnets" "vpc" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data "aws_kms_key" "kms_key" {
|
|
||||||
key_id = var.awskms_unseal_key_arn
|
|
||||||
}
|
|
||||||
|
|
||||||
data "aws_iam_policy_document" "target" {
|
data "aws_iam_policy_document" "target" {
|
||||||
statement {
|
statement {
|
||||||
resources = ["*"]
|
resources = ["*"]
|
||||||
|
@ -37,16 +33,20 @@ data "aws_iam_policy_document" "target" {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
statement {
|
dynamic "statement" {
|
||||||
resources = [var.awskms_unseal_key_arn]
|
for_each = var.seal_key_names
|
||||||
|
|
||||||
actions = [
|
content {
|
||||||
"kms:DescribeKey",
|
resources = [statement.value]
|
||||||
"kms:ListKeys",
|
|
||||||
"kms:Encrypt",
|
actions = [
|
||||||
"kms:Decrypt",
|
"kms:DescribeKey",
|
||||||
"kms:GenerateDataKey"
|
"kms:ListKeys",
|
||||||
]
|
"kms:Encrypt",
|
||||||
|
"kms:Decrypt",
|
||||||
|
"kms:GenerateDataKey"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,6 @@ variable "ami_id" {
|
||||||
type = string
|
type = string
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "awskms_unseal_key_arn" {
|
|
||||||
type = string
|
|
||||||
description = "The AWSKMS key ARN if using the awskms unseal method. If specified the instances will be granted kms permissions to the key"
|
|
||||||
default = null
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "cluster_name" {
|
variable "cluster_name" {
|
||||||
type = string
|
type = string
|
||||||
description = "A unique cluster identifier"
|
description = "A unique cluster identifier"
|
||||||
|
@ -73,6 +67,12 @@ variable "max_price" {
|
||||||
default = "0.0416"
|
default = "0.0416"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "seal_key_names" {
|
||||||
|
type = list(string)
|
||||||
|
description = "The key management seal key names"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
variable "ssh_allow_ips" {
|
variable "ssh_allow_ips" {
|
||||||
description = "Allowlisted IP addresses for SSH access to target nodes. The IP address of the machine running Enos will automatically allowlisted"
|
description = "Allowlisted IP addresses for SSH access to target nodes. The IP address of the machine running Enos will automatically allowlisted"
|
||||||
type = list(string)
|
type = list(string)
|
||||||
|
|
|
@ -42,30 +42,6 @@ locals {
|
||||||
"awskms" = 3
|
"awskms" = 3
|
||||||
"shamir" = null
|
"shamir" = null
|
||||||
}
|
}
|
||||||
seal = {
|
|
||||||
"awskms" = {
|
|
||||||
type = "awskms"
|
|
||||||
attributes = {
|
|
||||||
kms_key_id = var.awskms_unseal_key_arn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"shamir" = {
|
|
||||||
type = "shamir"
|
|
||||||
attributes = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
storage_config = [for idx, host in var.target_hosts : (var.storage_backend == "raft" ?
|
|
||||||
merge(
|
|
||||||
{
|
|
||||||
node_id = "${var.storage_node_prefix}_${idx}"
|
|
||||||
},
|
|
||||||
var.storage_backend_addl_config
|
|
||||||
) :
|
|
||||||
{
|
|
||||||
address = "127.0.0.1:8500"
|
|
||||||
path = "vault"
|
|
||||||
})
|
|
||||||
]
|
|
||||||
vault_service_user = "vault"
|
vault_service_user = "vault"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,90 +124,35 @@ resource "enos_consul_start" "consul" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "enos_vault_start" "leader" {
|
module "start_vault" {
|
||||||
|
source = "../start_vault"
|
||||||
|
|
||||||
depends_on = [
|
depends_on = [
|
||||||
enos_consul_start.consul,
|
enos_consul_start.consul,
|
||||||
enos_bundle_install.vault,
|
enos_bundle_install.vault,
|
||||||
]
|
]
|
||||||
for_each = local.leader
|
|
||||||
|
|
||||||
bin_path = local.bin_path
|
cluster_name = var.cluster_name
|
||||||
config_dir = var.config_dir
|
config_dir = var.config_dir
|
||||||
environment = var.config_env_vars
|
install_dir = var.install_dir
|
||||||
config = {
|
license = var.license
|
||||||
api_addr = "http://${var.target_hosts[each.value].private_ip}:8200"
|
log_level = var.log_level
|
||||||
cluster_addr = "http://${var.target_hosts[each.value].private_ip}:8201"
|
manage_service = var.manage_service
|
||||||
cluster_name = var.cluster_name
|
seal_ha_beta = var.seal_ha_beta
|
||||||
listener = {
|
seal_key_name = var.seal_key_name
|
||||||
type = "tcp"
|
seal_key_name_secondary = var.seal_key_name_secondary
|
||||||
attributes = {
|
seal_type = var.seal_type
|
||||||
address = "0.0.0.0:8200"
|
seal_type_secondary = var.seal_type_secondary
|
||||||
tls_disable = "true"
|
service_username = local.vault_service_user
|
||||||
}
|
storage_backend = var.storage_backend
|
||||||
}
|
storage_backend_attrs = var.storage_backend_addl_config
|
||||||
log_level = var.log_level
|
storage_node_prefix = var.storage_node_prefix
|
||||||
storage = {
|
target_hosts = var.target_hosts
|
||||||
type = var.storage_backend
|
|
||||||
attributes = ({ for key, value in local.storage_config[each.key] : key => value })
|
|
||||||
}
|
|
||||||
seal = local.seal[var.unseal_method]
|
|
||||||
ui = true
|
|
||||||
}
|
|
||||||
license = var.license
|
|
||||||
manage_service = var.manage_service
|
|
||||||
username = local.vault_service_user
|
|
||||||
unit_name = "vault"
|
|
||||||
|
|
||||||
transport = {
|
|
||||||
ssh = {
|
|
||||||
host = var.target_hosts[each.value].public_ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "enos_vault_start" "followers" {
|
|
||||||
depends_on = [
|
|
||||||
enos_vault_start.leader,
|
|
||||||
]
|
|
||||||
for_each = local.followers
|
|
||||||
|
|
||||||
bin_path = local.bin_path
|
|
||||||
config_dir = var.config_dir
|
|
||||||
environment = var.config_env_vars
|
|
||||||
config = {
|
|
||||||
api_addr = "http://${var.target_hosts[each.value].private_ip}:8200"
|
|
||||||
cluster_addr = "http://${var.target_hosts[each.value].private_ip}:8201"
|
|
||||||
cluster_name = var.cluster_name
|
|
||||||
listener = {
|
|
||||||
type = "tcp"
|
|
||||||
attributes = {
|
|
||||||
address = "0.0.0.0:8200"
|
|
||||||
tls_disable = "true"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log_level = var.log_level
|
|
||||||
storage = {
|
|
||||||
type = var.storage_backend
|
|
||||||
attributes = { for key, value in local.storage_config[each.key] : key => value }
|
|
||||||
}
|
|
||||||
seal = local.seal[var.unseal_method]
|
|
||||||
ui = true
|
|
||||||
}
|
|
||||||
license = var.license
|
|
||||||
manage_service = var.manage_service
|
|
||||||
username = local.vault_service_user
|
|
||||||
unit_name = "vault"
|
|
||||||
|
|
||||||
transport = {
|
|
||||||
ssh = {
|
|
||||||
host = var.target_hosts[each.value].public_ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "enos_vault_init" "leader" {
|
resource "enos_vault_init" "leader" {
|
||||||
depends_on = [
|
depends_on = [
|
||||||
enos_vault_start.followers,
|
module.start_vault,
|
||||||
]
|
]
|
||||||
for_each = toset([
|
for_each = toset([
|
||||||
for idx, leader in local.leader : leader
|
for idx, leader in local.leader : leader
|
||||||
|
@ -239,13 +160,13 @@ resource "enos_vault_init" "leader" {
|
||||||
])
|
])
|
||||||
|
|
||||||
bin_path = local.bin_path
|
bin_path = local.bin_path
|
||||||
vault_addr = enos_vault_start.leader[0].config.api_addr
|
vault_addr = module.start_vault.leader[0].config.api_addr
|
||||||
|
|
||||||
key_shares = local.key_shares[var.unseal_method]
|
key_shares = local.key_shares[var.seal_type]
|
||||||
key_threshold = local.key_threshold[var.unseal_method]
|
key_threshold = local.key_threshold[var.seal_type]
|
||||||
|
|
||||||
recovery_shares = local.recovery_shares[var.unseal_method]
|
recovery_shares = local.recovery_shares[var.seal_type]
|
||||||
recovery_threshold = local.recovery_threshold[var.unseal_method]
|
recovery_threshold = local.recovery_threshold[var.seal_type]
|
||||||
|
|
||||||
transport = {
|
transport = {
|
||||||
ssh = {
|
ssh = {
|
||||||
|
@ -256,15 +177,15 @@ resource "enos_vault_init" "leader" {
|
||||||
|
|
||||||
resource "enos_vault_unseal" "leader" {
|
resource "enos_vault_unseal" "leader" {
|
||||||
depends_on = [
|
depends_on = [
|
||||||
enos_vault_start.followers,
|
module.start_vault,
|
||||||
enos_vault_init.leader,
|
enos_vault_init.leader,
|
||||||
]
|
]
|
||||||
for_each = enos_vault_init.leader // only unseal the leader if we initialized it
|
for_each = enos_vault_init.leader // only unseal the leader if we initialized it
|
||||||
|
|
||||||
bin_path = local.bin_path
|
bin_path = local.bin_path
|
||||||
vault_addr = enos_vault_start.leader[each.key].config.api_addr
|
vault_addr = module.start_vault.leader[each.key].config.api_addr
|
||||||
seal_type = var.unseal_method
|
seal_type = var.seal_type
|
||||||
unseal_keys = var.unseal_method != "shamir" ? null : coalesce(var.shamir_unseal_keys, enos_vault_init.leader[0].unseal_keys_hex)
|
unseal_keys = var.seal_type != "shamir" ? null : coalesce(var.shamir_unseal_keys, enos_vault_init.leader[0].unseal_keys_hex)
|
||||||
|
|
||||||
transport = {
|
transport = {
|
||||||
ssh = {
|
ssh = {
|
||||||
|
@ -282,13 +203,13 @@ resource "enos_vault_unseal" "followers" {
|
||||||
// initialized the cluster
|
// initialized the cluster
|
||||||
for_each = toset([
|
for_each = toset([
|
||||||
for idx, follower in local.followers : follower
|
for idx, follower in local.followers : follower
|
||||||
if var.unseal_method == "shamir" && var.initialize_cluster
|
if var.seal_type == "shamir" && var.initialize_cluster
|
||||||
])
|
])
|
||||||
|
|
||||||
bin_path = local.bin_path
|
bin_path = local.bin_path
|
||||||
vault_addr = enos_vault_start.followers[each.key].config.api_addr
|
vault_addr = module.start_vault.followers[each.key].config.api_addr
|
||||||
seal_type = var.unseal_method
|
seal_type = var.seal_type
|
||||||
unseal_keys = var.unseal_method != "shamir" ? null : coalesce(var.shamir_unseal_keys, enos_vault_init.leader[0].unseal_keys_hex)
|
unseal_keys = var.seal_type != "shamir" ? null : coalesce(var.shamir_unseal_keys, enos_vault_init.leader[0].unseal_keys_hex)
|
||||||
|
|
||||||
transport = {
|
transport = {
|
||||||
ssh = {
|
ssh = {
|
||||||
|
@ -303,7 +224,7 @@ resource "enos_vault_unseal" "followers" {
|
||||||
// force_unseal to true.
|
// force_unseal to true.
|
||||||
resource "enos_vault_unseal" "maybe_force_unseal" {
|
resource "enos_vault_unseal" "maybe_force_unseal" {
|
||||||
depends_on = [
|
depends_on = [
|
||||||
enos_vault_start.followers,
|
module.start_vault.followers,
|
||||||
]
|
]
|
||||||
for_each = {
|
for_each = {
|
||||||
for idx, host in var.target_hosts : idx => host
|
for idx, host in var.target_hosts : idx => host
|
||||||
|
@ -312,7 +233,7 @@ resource "enos_vault_unseal" "maybe_force_unseal" {
|
||||||
|
|
||||||
bin_path = local.bin_path
|
bin_path = local.bin_path
|
||||||
vault_addr = "http://localhost:8200"
|
vault_addr = "http://localhost:8200"
|
||||||
seal_type = var.unseal_method
|
seal_type = var.seal_type
|
||||||
unseal_keys = coalesce(
|
unseal_keys = coalesce(
|
||||||
var.shamir_unseal_keys,
|
var.shamir_unseal_keys,
|
||||||
try(enos_vault_init.leader[0].unseal_keys_hex, null),
|
try(enos_vault_init.leader[0].unseal_keys_hex, null),
|
||||||
|
@ -325,38 +246,11 @@ resource "enos_vault_unseal" "maybe_force_unseal" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "enos_remote_exec" "vault_write_license" {
|
|
||||||
for_each = toset([
|
|
||||||
for idx, leader in local.leader : leader
|
|
||||||
if var.initialize_cluster
|
|
||||||
])
|
|
||||||
|
|
||||||
depends_on = [
|
|
||||||
enos_vault_unseal.leader,
|
|
||||||
enos_vault_unseal.maybe_force_unseal,
|
|
||||||
]
|
|
||||||
|
|
||||||
environment = {
|
|
||||||
BIN_PATH = local.bin_path,
|
|
||||||
LICENSE = coalesce(var.license, "none")
|
|
||||||
VAULT_TOKEN = coalesce(var.root_token, try(enos_vault_init.leader[0].root_token, null), "none")
|
|
||||||
}
|
|
||||||
|
|
||||||
scripts = [abspath("${path.module}/scripts/vault-write-license.sh")]
|
|
||||||
|
|
||||||
transport = {
|
|
||||||
ssh = {
|
|
||||||
host = var.target_hosts[each.value].public_ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# We need to ensure that the directory used for audit logs is present and accessible to the vault
|
# We need to ensure that the directory used for audit logs is present and accessible to the vault
|
||||||
# user on all nodes, since logging will only happen on the leader.
|
# user on all nodes, since logging will only happen on the leader.
|
||||||
resource "enos_remote_exec" "create_audit_log_dir" {
|
resource "enos_remote_exec" "create_audit_log_dir" {
|
||||||
depends_on = [
|
depends_on = [
|
||||||
enos_vault_start.leader,
|
module.start_vault,
|
||||||
enos_vault_start.followers,
|
|
||||||
enos_vault_unseal.leader,
|
enos_vault_unseal.leader,
|
||||||
enos_vault_unseal.followers,
|
enos_vault_unseal.followers,
|
||||||
enos_vault_unseal.maybe_force_unseal,
|
enos_vault_unseal.maybe_force_unseal,
|
||||||
|
|
|
@ -12,12 +12,6 @@ variable "artifactory_release" {
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "awskms_unseal_key_arn" {
|
|
||||||
type = string
|
|
||||||
description = "The AWSKMS key ARN if using the awskms unseal method"
|
|
||||||
default = null
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "backend_cluster_name" {
|
variable "backend_cluster_name" {
|
||||||
type = string
|
type = string
|
||||||
description = "The name of the backend cluster"
|
description = "The name of the backend cluster"
|
||||||
|
@ -171,6 +165,45 @@ variable "root_token" {
|
||||||
default = null
|
default = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "seal_ha_beta" {
|
||||||
|
description = "Enable using Seal HA on clusters that meet minimum version requirements and are enterprise editions"
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_key_name" {
|
||||||
|
type = string
|
||||||
|
description = "The auto-unseal key name"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_key_name_secondary" {
|
||||||
|
type = string
|
||||||
|
description = "The secondary auto-unseal key name"
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_type" {
|
||||||
|
type = string
|
||||||
|
description = "The method by which to unseal the Vault cluster"
|
||||||
|
default = "awskms"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = contains(["awskms", "shamir"], var.seal_type)
|
||||||
|
error_message = "The seal_type must be either awskms or shamir. No other unseal methods are supported."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "seal_type_secondary" {
|
||||||
|
type = string
|
||||||
|
description = "A secondary HA seal method. Only supported in Vault Enterprise >= 1.15"
|
||||||
|
default = "none"
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = contains(["awskms", "none"], var.seal_type_secondary)
|
||||||
|
error_message = "The secondary_seal_type must be 'awskms' or 'none'. No other secondary unseal methods are supported."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
variable "shamir_unseal_keys" {
|
variable "shamir_unseal_keys" {
|
||||||
type = list(string)
|
type = list(string)
|
||||||
description = "Shamir unseal keys. Often only used adding additional nodes to an already initialized cluster."
|
description = "Shamir unseal keys. Often only used adding additional nodes to an already initialized cluster."
|
||||||
|
@ -207,14 +240,3 @@ variable "target_hosts" {
|
||||||
public_ip = string
|
public_ip = string
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "unseal_method" {
|
|
||||||
type = string
|
|
||||||
description = "The method by which to unseal the Vault cluster"
|
|
||||||
default = "awskms"
|
|
||||||
|
|
||||||
validation {
|
|
||||||
condition = contains(["awskms", "shamir"], var.unseal_method)
|
|
||||||
error_message = "The unseal_method must be either awskms or shamir. No other unseal methods are supported."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,14 +23,14 @@ test -x "$binpath" || fail "unable to locate vault binary at $binpath"
|
||||||
findLeaderInPrivateIPs() {
|
findLeaderInPrivateIPs() {
|
||||||
# Find the leader private IP address
|
# Find the leader private IP address
|
||||||
local leader_private_ip
|
local leader_private_ip
|
||||||
if ! leader_private_ip=$($binpath read sys/leader -format=json | jq -r '.data.leader_address | scan("[0-9]+.[0-9]+.[0-9]+.[0-9]+")') ; then
|
if ! leader_private_ip=$($binpath read sys/leader -format=json | jq -er '.data.leader_address | scan("[0-9]+.[0-9]+.[0-9]+.[0-9]+")') ; then
|
||||||
# Some older versions of vault don't support reading sys/leader. Fallback to the cli status.
|
# Some older versions of vault don't support reading sys/leader. Fallback to the cli status.
|
||||||
if leader_private_ip=$($binpath status -format json | jq '.leader_address | scan("[0-9]+.[0-9]+.[0-9]+.[0-9]+")'); then
|
if ! leader_private_ip=$($binpath status -format json | jq -er '.leader_address | scan("[0-9]+.[0-9]+.[0-9]+.[0-9]+")'); then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if isIn=$(jq -r --arg ip "$leader_private_ip" 'map(select(. == $ip)) | length == 1' <<< "$VAULT_INSTANCE_PRIVATE_IPS"); then
|
if isIn=$(jq -er --arg ip "$leader_private_ip" 'map(select(. == $ip)) | length == 1' <<< "$VAULT_INSTANCE_PRIVATE_IPS"); then
|
||||||
if [[ "$isIn" == "true" ]]; then
|
if [[ "$isIn" == "true" ]]; then
|
||||||
echo "$leader_private_ip"
|
echo "$leader_private_ip"
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
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_root_token" {
|
||||||
|
type = string
|
||||||
|
description = "The vault root token"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vault_instance_count" {
|
||||||
|
type = number
|
||||||
|
description = "The number of instances in the vault cluster"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vault_hosts" {
|
||||||
|
type = map(object({
|
||||||
|
private_ip = string
|
||||||
|
public_ip = string
|
||||||
|
}))
|
||||||
|
description = "The vault cluster hosts that can be expected as a leader"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "timeout" {
|
||||||
|
type = number
|
||||||
|
description = "The max number of seconds to wait before timing out"
|
||||||
|
default = 60
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "retry_interval" {
|
||||||
|
type = number
|
||||||
|
description = "How many seconds to wait between each retry"
|
||||||
|
default = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
private_ips = [for k, v in values(tomap(var.vault_hosts)) : tostring(v["private_ip"])]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "enos_remote_exec" "wait_for_seal_rewrap_to_be_completed" {
|
||||||
|
environment = {
|
||||||
|
RETRY_INTERVAL = var.retry_interval
|
||||||
|
TIMEOUT_SECONDS = var.timeout
|
||||||
|
VAULT_ADDR = "http://127.0.0.1:8200"
|
||||||
|
VAULT_TOKEN = var.vault_root_token
|
||||||
|
VAULT_INSTALL_DIR = var.vault_install_dir
|
||||||
|
}
|
||||||
|
|
||||||
|
scripts = [abspath("${path.module}/scripts/wait-for-seal-rewrap.sh")]
|
||||||
|
|
||||||
|
transport = {
|
||||||
|
ssh = {
|
||||||
|
host = var.vault_hosts[0].public_ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright (c) HashiCorp, Inc.
|
||||||
|
# SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "$1" 1>&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ -z "$RETRY_INTERVAL" ]] && fail "RETRY_INTERVAL env variable has not been set"
|
||||||
|
[[ -z "$TIMEOUT_SECONDS" ]] && fail "TIMEOUT_SECONDS env variable has not been set"
|
||||||
|
[[ -z "$VAULT_ADDR" ]] && fail "VAULT_ADDR env variable has not been set"
|
||||||
|
[[ -z "$VAULT_INSTALL_DIR" ]] && fail "VAULT_INSTALL_DIR env variable has not been set"
|
||||||
|
[[ -z "$VAULT_TOKEN" ]] && fail "VAULT_TOKEN env variable has not been set"
|
||||||
|
|
||||||
|
binpath=${VAULT_INSTALL_DIR}/vault
|
||||||
|
test -x "$binpath" || fail "unable to locate vault binary at $binpath"
|
||||||
|
|
||||||
|
getRewrapData() {
|
||||||
|
$binpath read sys/sealwrap/rewrap -format=json | jq -eMc '.data'
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForRewrap() {
|
||||||
|
local data
|
||||||
|
if ! data=$(getRewrapData); then
|
||||||
|
echo "failed getting /v1/sys/sealwrap/rewrap data" 1>&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! jq -e '.is_running == false' <<< "$data" &> /dev/null; then
|
||||||
|
echo "rewrap is running" 1>&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! jq -e '.entries.failed == 0' <<< "$data" &> /dev/null; then
|
||||||
|
local entries
|
||||||
|
entries=$(jq -Mc '.entries.failed' <<< "$data")
|
||||||
|
echo "rewrap has $entries failed entries" 1>&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! jq -e '.entries.processed == .entries.succeeded' <<< "$data" &> /dev/null; then
|
||||||
|
local processed
|
||||||
|
local succeeded
|
||||||
|
processed=$(jq -Mc '.entries.processed' <<< "$data")
|
||||||
|
succeeded=$(jq -Mc '.entries.succeeded' <<< "$data")
|
||||||
|
echo "the number of processed entries ($processed) does not equal then number of succeeded ($succeeded)" 1>&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
begin_time=$(date +%s)
|
||||||
|
end_time=$((begin_time + TIMEOUT_SECONDS))
|
||||||
|
while [ "$(date +%s)" -lt "$end_time" ]; do
|
||||||
|
if waitForRewrap; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep "$RETRY_INTERVAL"
|
||||||
|
done
|
||||||
|
|
||||||
|
fail "Timed out waiting for seal rewrap to be completed. Data:\n\t$(getRewrapData)"
|
Loading…
Reference in New Issue