diff --git a/.github/workflows/test-run-enos-scenario-matrix.yml b/.github/workflows/test-run-enos-scenario-matrix.yml index ac88e5cc0d..359e9dfd6a 100644 --- a/.github/workflows/test-run-enos-scenario-matrix.yml +++ b/.github/workflows/test-run-enos-scenario-matrix.yml @@ -202,6 +202,7 @@ jobs: echo "ENOS_VAR_vault_radar_license_path=./support/vault-radar.hclic" echo "ENOS_VAR_vault_revision=${{ inputs.vault-revision }}" echo "ENOS_VAR_vault_upgrade_initial_version=${{ matrix.attributes.upgrade_initial_version }}" + echo "ENOS_VAR_verify_aws_secrets_engine=true" echo "ENOS_VAR_verify_log_secrets=true" } | tee -a "$GITHUB_ENV" - uses: hashicorp/setup-terraform@v3 diff --git a/enos/enos-dev-scenario-pr-replication.hcl b/enos/enos-dev-scenario-pr-replication.hcl index 70699bef2c..77fbd59fac 100644 --- a/enos/enos-dev-scenario-pr-replication.hcl +++ b/enos/enos-dev-scenario-pr-replication.hcl @@ -39,7 +39,12 @@ scenario "dev_pr_replication" { exclude { artifact = ["deb"] - distro = ["rhel"] + distro = ["rhel", "amzn"] + } + + exclude { + artifact = ["deb", "rpm"] + distro = ["sles", "leap"] } exclude { diff --git a/enos/enos-dev-scenario-single-cluster.hcl b/enos/enos-dev-scenario-single-cluster.hcl index f0eddab6ea..40cec5a5c4 100644 --- a/enos/enos-dev-scenario-single-cluster.hcl +++ b/enos/enos-dev-scenario-single-cluster.hcl @@ -36,7 +36,12 @@ scenario "dev_single_cluster" { exclude { artifact = ["deb"] - distro = ["rhel"] + distro = ["rhel", "amzn"] + } + + exclude { + artifact = ["deb", "rpm"] + distro = ["sles", "leap"] } exclude { @@ -143,6 +148,7 @@ scenario "dev_single_cluster" { artifactory_username = local.use_artifactory ? var.artifactory_username : null artifactory_token = local.use_artifactory ? var.artifactory_token : null distro = matrix.distro + distro_version = global.distro_version[matrix.distro] } } diff --git a/enos/enos-dynamic-config.hcl b/enos/enos-dynamic-config.hcl index 4aceebe7ca..15f7de6dc4 100644 --- a/enos/enos-dynamic-config.hcl +++ b/enos/enos-dynamic-config.hcl @@ -12,9 +12,9 @@ globals { aws_region = ["us-east-1", "us-west-2"] distro_version_amzn = ["2023"] distro_version_leap = ["15.6"] - distro_version_rhel = ["8.10", "9.4"] + distro_version_rhel = ["8.10", "9.5"] distro_version_sles = ["15.6"] distro_version_ubuntu = ["20.04", "24.04"] - upgrade_initial_version = ["1.16.1", "1.16.2", "1.16.3", "1.17.0-rc1", "1.17.0", "1.17.1", "1.17.2", "1.17.3", "1.17.4", "1.17.5", "1.17.6", "1.18.0-rc1", "1.18.0"] + upgrade_initial_version = ["1.17.0", "1.17.1", "1.17.2", "1.17.3", "1.17.4", "1.17.5", "1.17.6", "1.18.0-rc1", "1.18.0", "1.18.1", "1.18.2", "1.18.3", "1.18.4", "1.18.5", "1.19.0-rc1", "1.19.0", "1.19.1", "1.19.2"] } } diff --git a/enos/enos-globals.hcl b/enos/enos-globals.hcl index 8bf937c4a7..8f5e2149b5 100644 --- a/enos/enos-globals.hcl +++ b/enos/enos-globals.hcl @@ -30,7 +30,7 @@ globals { } rhel = { "8.10" = ["nc"] - "9.4" = ["nc"] + "9.5" = ["nc"] } sles = { // When installing Vault RPM packages on a SLES AMI, the openssl package provided diff --git a/enos/enos-modules.hcl b/enos/enos-modules.hcl index 0181231648..ebe2c60495 100644 --- a/enos/enos-modules.hcl +++ b/enos/enos-modules.hcl @@ -310,13 +310,15 @@ module "vault_verify_removed_node_shim" { module "vault_verify_secrets_engines_create" { source = "./modules/verify_secrets_engines/modules/create" - vault_install_dir = var.vault_install_dir + create_aws_secrets_engine = var.verify_aws_secrets_engine + vault_install_dir = var.vault_install_dir } module "vault_verify_secrets_engines_read" { source = "./modules/verify_secrets_engines/modules/read" - vault_install_dir = var.vault_install_dir + verify_aws_secrets_engine = var.verify_aws_secrets_engine + vault_install_dir = var.vault_install_dir } module "vault_verify_default_lcq" { diff --git a/enos/enos-variables.hcl b/enos/enos-variables.hcl index 91402071a9..169e9f1d01 100644 --- a/enos/enos-variables.hcl +++ b/enos/enos-variables.hcl @@ -90,7 +90,7 @@ variable "distro_version_leap" { variable "distro_version_rhel" { description = "The version of RHEL to use" type = string - default = "9.4" // or "8.10" + default = "9.5" // or "8.10" } variable "distro_version_sles" { @@ -206,6 +206,12 @@ variable "vault_upgrade_initial_version" { default = "1.13.13" } +variable "verify_aws_secrets_engine" { + description = "If true we'll verify AWS secrets engines behavior. Because of user creation restrictions in Doormat AWS accounts, only turn this on for CI, as it depends on resources that exist only in those accounts" + type = bool + default = false +} + variable "verify_log_secrets" { description = "If true and var.vault_enable_audit_devices is true we'll verify that the audit log does not contain unencrypted secrets. Requires var.vault_radar_license_path to be set to a valid license file." type = bool diff --git a/enos/modules/artifact/metadata/main.tf b/enos/modules/artifact/metadata/main.tf new file mode 100644 index 0000000000..111ed3a614 --- /dev/null +++ b/enos/modules/artifact/metadata/main.tf @@ -0,0 +1,229 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +// Given the architecture, distro, version, edition, and desired package type, +// return the metadata for an artifact. + +variable "arch" { + description = "The artifact platform architecture" + type = string + + validation { + condition = contains(["amd64", "arm64", "s390x"], var.arch) + error_message = <<-EOF + distro must be one of "amd64", "arm64", "s390x" + EOF + } +} + +variable "distro" { + description = "The target operating system distro" + type = string + + validation { + condition = contains(["amzn", "leap", "rhel", "sles", "ubuntu"], var.distro) + error_message = <<-EOF + distro must be one of "amzn", "leap", "rhel", "sles", "ubuntu" + EOF + } +} + +variable "edition" { + description = "The Vault edition. E.g. ent or ent.hsm.fips1403" + type = string + + validation { + condition = contains(["oss", "ce", "ent", "ent.fips1402", "ent.fips1403", "ent.hsm", "ent.hsm.fips1402", "ent.hsm.fips1403"], var.edition) + error_message = <<-EOF + edition must be one of "oss", "ce", "ent", "ent.fips1402", "ent.fips1403", "ent.hsm", "ent.hsm.fips1402", "ent.hsm.fips1403" + EOF + } +} + +variable "package_type" { + description = "The artifact packaging type" + type = string + + validation { + condition = contains(["package", "rpm", "deb", "zip", "bundle"], var.package_type) + error_message = <<-EOF + package_type must be one of "package", "rpm", "deb", "zip", "bundle" + EOF + } +} + +variable "vault_version" { + description = "The version of Vault or Vault Enterprise. E.g 1.18.2, 1.19.0-rc1, 1.18.5+ent.hsm" + type = string +} + +locals { + package_extension_amd64_deb = "-1_amd64.deb" + package_extension_amd64_rpm = "-1.x86_64.rpm" + package_extension_arm64_deb = "-1_arm64.deb" + package_extension_arm64_rpm = "-1.aarch64.rpm" + package_extension_s390x_deb = "-1_s390x.deb" + package_extension_s390x_rpm = "-1.s390x.rpm" + + // file name extensions for the install packages of vault for the various architectures, distributions and editions + package_extensions = { + amd64 = { + amzn = local.package_extension_amd64_rpm + leap = local.package_extension_amd64_rpm + rhel = local.package_extension_amd64_rpm + sles = local.package_extension_amd64_rpm + ubuntu = local.package_extension_amd64_deb + } + arm64 = { + amzn = local.package_extension_arm64_rpm + leap = local.package_extension_arm64_rpm + rhel = local.package_extension_arm64_rpm + sles = local.package_extension_arm64_rpm + ubuntu = local.package_extension_arm64_deb + } + s390x = { + amzn = null + leap = local.package_extension_s390x_rpm + rhel = local.package_extension_s390x_rpm + sles = local.package_extension_s390x_rpm + ubuntu = local.package_extension_s390x_deb + } + } + + package_prefixes_rpm = { + "ce" = "vault-" + "ent" = "vault-enterprise-", + "ent.fips1402" = "vault-enterprise-fips1402-", + "ent.fips1403" = "vault-enterprise-fips1403-", + "ent.hsm" = "vault-enterprise-hsm-", + "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402-", + "ent.hsm.fips1403" = "vault-enterprise-hsm-fips1403-", + "oss" = "vault-" + } + + package_prefixes_deb = { + "ce" = "vault_" + "ent" = "vault-enterprise_", + "ent.fips1402" = "vault-enterprise-fips1402_", + "ent.fips1403" = "vault-enterprise-fips1403_", + "ent.hsm" = "vault-enterprise-hsm_", + "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402_", + "ent.hsm.fips1403" = "vault-enterprise-hsm-fips1403_", + "oss" = "vault_" + } + + // file name prefixes for the install packages of vault for the various distributions and artifact types (package or bundle) + package_prefixes = { + amzn = local.package_prefixes_rpm, + leap = local.package_prefixes_rpm, + rhel = local.package_prefixes_rpm, + sles = local.package_prefixes_rpm, + ubuntu = local.package_prefixes_deb, + } + + // Stable release Artifactory repos for packages + release_repo_rpm = "hashicorp-rpm-release-local*" + release_repo_apt = "hashicorp-apt-release-local*" + release_repos = { + amzn = local.release_repo_rpm + leap = local.release_repo_rpm + rhel = local.release_repo_rpm + sles = local.release_repo_rpm + ubuntu = local.release_repo_apt + } + release_repo = local.release_repos[var.distro] + + // Stable release Artifactory paths for packages + release_package_rpm_arch = { + "amd64" = "x86_64", + "arm64" = "aarch64", + "s390x" = "s390x", + } + release_path_deb = "pool/${var.arch}/main" + release_sub_path_rpm = "${local.release_package_rpm_arch[var.arch]}/stable" + release_path_distro = { + amzn = { + "2" = "AmazonLinux/2/${local.release_sub_path_rpm}" + "2023" = "AmazonLinux/latest/${local.release_sub_path_rpm}" + "latest" = "AmazonLinux/latest/${local.release_sub_path_rpm}" + } + leap = { + "15.6" = "RHEL/9/${local.release_sub_path_rpm}" + } + rhel = { + "8.10" = "RHEL/8/${local.release_sub_path_rpm}" + "9.5" = "RHEL/9/${local.release_sub_path_rpm}" + } + sles = { + "15.6" = "RHEL/9/${local.release_sub_path_rpm}" + } + ubuntu = { + "20.04" = local.release_path_deb, + "22.04" = local.release_path_deb, + "24.04" = local.release_path_deb, + } + } + release_paths = local.release_path_distro[var.distro] + + // Reduce our supported inputs into two classes: system packages or a binary bundled into a zip archive. + package_type = contains(["package", "deb", "rpm"], var.package_type) ? "package" : "bundle" + + // Get the base version. This might still include pre-release metadata + // E.g. 1.18.2 => 1.18.2, 1.18.0-rc1 => 1.18.0-rc1, 1.18.0+ent.hsm => 1.18.0 + semverish_version = try(split("+", var.vault_version)[0], var.vault_version) + + // Determine the "product name". This corresponds properties on the artifactory artifact. + product_name = strcontains(var.edition, "ent") ? "vault-enterprise" : "vault" + + // Create the "product version", which is corresponds to properties on the artifactory artifact. + // It's the version along with edition metadata. We normalize all enterprise editions to .ent. + // E.g. 1.16.0-beta1+ent.hsm.fips1403 -> 1.16.0-beta+ent + product_version = strcontains(var.edition, "ent") ? "${local.semverish_version}+ent" : local.semverish_version + + // Convert product version strings to a syntax that matches deb and rpm packaging. + // E.g. 1.16.0-beta+ent -> 1.16.0~beta+ent + package_version = replace(local.product_version, "-", "~") + + // Get the bundle version. If the vault_version includes metadata, use it. Otherwise add the edition to it. + bundle_version = strcontains(var.vault_version, "+") ? var.vault_version : strcontains(var.edition, "ent") ? "${var.vault_version}+${var.edition}" : var.vault_version + + // Prefix for the artifact name. E.g.: vault_, vault-, vault-enterprise_, vault-enterprise-hsm-fips1402-, etc + artifact_name_prefix = local.package_type == "package" ? local.package_prefixes[var.distro][var.edition] : "vault_" + + // The version for the artifact name. + artifact_version = local.package_type == "package" ? local.package_version : local.bundle_version + + // Suffix and extension for the artifact name. E.g.: _linux_.zip, + artifact_name_extension = local.package_type == "package" ? local.package_extensions[var.arch][var.distro] : "_linux_${var.arch}.zip" + + // Combine prefix/suffix/extension together to form the artifact name + artifact_name = "${local.artifact_name_prefix}${local.artifact_version}${local.artifact_name_extension}" + +} +output "artifact_name" { + value = local.artifact_name +} + +output "package_type" { + value = local.package_type +} + +output "package_version" { + value = local.package_version +} + +output "product_name" { + value = local.product_name +} + +output "product_version" { + value = local.product_version +} + +output "release_repo" { + value = local.release_repo +} + +output "release_paths" { + value = local.release_paths +} diff --git a/enos/modules/build_artifactory_artifact/locals.tf b/enos/modules/build_artifactory_artifact/locals.tf deleted file mode 100644 index 97a3ab689c..0000000000 --- a/enos/modules/build_artifactory_artifact/locals.tf +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - -locals { - - // file name extensions for the install packages of vault for the various architectures, distributions and editions - package_extensions = { - amd64 = { - amzn = "-1.x86_64.rpm" - leap = "-1.x86_64.rpm" - rhel = "-1.x86_64.rpm" - sles = "-1.x86_64.rpm" - ubuntu = "-1_amd64.deb" - } - arm64 = { - amzn = "-1.aarch64.rpm" - leap = "-1.aarch64.rpm" - rhel = "-1.aarch64.rpm" - sles = "-1.aarch64.rpm" - ubuntu = "-1_arm64.deb" - } - } - - // product_version --> artifact_version - artifact_version = replace(var.product_version, var.edition, "ent") - - // file name prefixes for the install packages of vault for the various distributions and artifact types (package or bundle) - artifact_package_release_names = { - amzn = { - "ce" = "vault-" - "ent" = "vault-enterprise-", - "ent.fips1402" = "vault-enterprise-fips1402-", - "ent.hsm" = "vault-enterprise-hsm-", - "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402-", - }, - leap = { - "ce" = "vault-" - "ent" = "vault-enterprise-", - "ent.fips1402" = "vault-enterprise-fips1402-", - "ent.hsm" = "vault-enterprise-hsm-", - "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402-", - }, - rhel = { - "ce" = "vault-" - "ent" = "vault-enterprise-", - "ent.fips1402" = "vault-enterprise-fips1402-", - "ent.hsm" = "vault-enterprise-hsm-", - "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402-", - }, - sles = { - "ce" = "vault-" - "ent" = "vault-enterprise-", - "ent.fips1402" = "vault-enterprise-fips1402-", - "ent.hsm" = "vault-enterprise-hsm-", - "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402-", - } - ubuntu = { - "ce" = "vault_" - "ent" = "vault-enterprise_", - "ent.fips1402" = "vault-enterprise-fips1402_", - "ent.hsm" = "vault-enterprise-hsm_", - "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402_", - } - } - - # Prefix for the artifact name. Ex: vault_, vault-, vault-enterprise_, vault-enterprise-hsm-fips1402-, etc - artifact_name_prefix = var.artifact_type == "package" ? local.artifact_package_release_names[var.distro][var.edition] : "vault_" - # Suffix and extension for the artifact name. Ex: _linux_.zip, - artifact_name_extension = var.artifact_type == "package" ? local.package_extensions[var.arch][var.distro] : "_linux_${var.arch}.zip" - # Combine prefix/suffix/extension together to form the artifact name - artifact_name = var.artifact_type == "package" ? "${local.artifact_name_prefix}${replace(local.artifact_version, "-", "~")}${local.artifact_name_extension}" : "${local.artifact_name_prefix}${var.product_version}${local.artifact_name_extension}" -} diff --git a/enos/modules/build_artifactory_artifact/main.tf b/enos/modules/build_artifactory_artifact/main.tf index fb8e4c0e1d..97d4e04d45 100644 --- a/enos/modules/build_artifactory_artifact/main.tf +++ b/enos/modules/build_artifactory_artifact/main.tf @@ -10,16 +10,92 @@ terraform { } } +variable "artifactory_username" { + type = string + description = "The username to use when connecting to artifactory" + default = null +} + +variable "artifactory_token" { + type = string + description = "The token to use when connecting to artifactory" + default = null + sensitive = true +} + +variable "artifactory_host" { + type = string + description = "The artifactory host to search for vault artifacts" + default = "https://artifactory.hashicorp.engineering/artifactory" +} + +variable "artifactory_repo" { + type = string + description = "The artifactory repo to search for vault artifacts" + default = "hashicorp-crt-stable-local*" +} + +variable "arch" {} +variable "artifact_type" {} +variable "artifact_path" {} +variable "distro" {} +variable "edition" {} +variable "revision" {} +variable "product_version" {} +variable "build_tags" { default = null } +variable "bundle_path" { default = null } +variable "goarch" { default = null } +variable "goos" { default = null } + +module "artifact_metadata" { + source = "../artifact/metadata" + + arch = var.arch + distro = var.distro + edition = var.edition + package_type = var.artifact_type + vault_version = var.product_version +} + data "enos_artifactory_item" "vault" { username = var.artifactory_username token = var.artifactory_token - name = local.artifact_name + name = module.artifact_metadata.artifact_name host = var.artifactory_host repo = var.artifactory_repo - path = var.edition == "ce" ? "vault/*" : "vault-enterprise/*" + path = "${module.artifact_metadata.product_name}/*" properties = tomap({ - "commit" = var.revision - "product-name" = var.edition == "ce" ? "vault" : "vault-enterprise" - "product-version" = local.artifact_version + "commit" = var.revision, + "product-name" = module.artifact_metadata.product_name, + "product-version" = module.artifact_metadata.product_version, }) } + +output "url" { + value = data.enos_artifactory_item.vault.results[0].url + description = "The artifactory download url for the artifact" +} + +output "sha256" { + value = data.enos_artifactory_item.vault.results[0].sha256 + description = "The sha256 checksum for the artifact" +} + +output "size" { + value = data.enos_artifactory_item.vault.results[0].size + description = "The size in bytes of the artifact" +} + +output "name" { + value = data.enos_artifactory_item.vault.results[0].name + description = "The name of the artifact" +} + +output "vault_artifactory_release" { + value = { + url = data.enos_artifactory_item.vault.results[0].url + sha256 = data.enos_artifactory_item.vault.results[0].sha256 + username = var.artifactory_username + token = var.artifactory_token + } +} diff --git a/enos/modules/build_artifactory_artifact/outputs.tf b/enos/modules/build_artifactory_artifact/outputs.tf deleted file mode 100644 index d05b5bf795..0000000000 --- a/enos/modules/build_artifactory_artifact/outputs.tf +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -output "url" { - value = data.enos_artifactory_item.vault.results[0].url - description = "The artifactory download url for the artifact" -} - -output "sha256" { - value = data.enos_artifactory_item.vault.results[0].sha256 - description = "The sha256 checksum for the artifact" -} - -output "size" { - value = data.enos_artifactory_item.vault.results[0].size - description = "The size in bytes of the artifact" -} - -output "name" { - value = data.enos_artifactory_item.vault.results[0].name - description = "The name of the artifact" -} - -output "vault_artifactory_release" { - value = { - url = data.enos_artifactory_item.vault.results[0].url - sha256 = data.enos_artifactory_item.vault.results[0].sha256 - username = var.artifactory_username - token = var.artifactory_token - } -} diff --git a/enos/modules/build_artifactory_artifact/variables.tf b/enos/modules/build_artifactory_artifact/variables.tf deleted file mode 100644 index a2d9042af5..0000000000 --- a/enos/modules/build_artifactory_artifact/variables.tf +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 -variable "artifactory_username" { - type = string - description = "The username to use when connecting to artifactory" - default = null -} - -variable "artifactory_token" { - type = string - description = "The token to use when connecting to artifactory" - default = null - sensitive = true -} - -variable "artifactory_host" { - type = string - description = "The artifactory host to search for vault artifacts" - default = "https://artifactory.hashicorp.engineering/artifactory" -} - -variable "artifactory_repo" { - type = string - description = "The artifactory repo to search for vault artifacts" - default = "hashicorp-crt-stable-local*" -} -variable "arch" {} -variable "artifact_type" {} -variable "artifact_path" {} -variable "distro" {} -variable "edition" {} -variable "revision" {} -variable "product_version" {} -variable "build_tags" { default = null } -variable "bundle_path" { default = null } -variable "goarch" { default = null } -variable "goos" { default = null } diff --git a/enos/modules/build_artifactory_package/main.tf b/enos/modules/build_artifactory_package/main.tf index 1e7d0826d2..2444b1eeb6 100644 --- a/enos/modules/build_artifactory_package/main.tf +++ b/enos/modules/build_artifactory_package/main.tf @@ -39,7 +39,6 @@ variable "distro" { variable "distro_version" { type = string description = "The RHEL version for .rpm packages" - default = "9" } variable "edition" { @@ -63,97 +62,53 @@ variable "goarch" { default = null } variable "goos" { default = null } variable "revision" { default = null } -locals { - // File name prefixes for the various distributions and editions - artifact_prefix = { - ubuntu = { - "ce" = "vault_" - "ent" = "vault-enterprise_", - "ent.hsm" = "vault-enterprise-hsm_", - "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402_", - "oss" = "vault_" - }, - rhel = { - "ce" = "vault-" - "ent" = "vault-enterprise-", - "ent.hsm" = "vault-enterprise-hsm-", - "ent.hsm.fips1402" = "vault-enterprise-hsm-fips1402-", - "oss" = "vault-" - } - } +module "artifact_metadata" { + source = "../artifact/metadata" - // Format the version and edition to use in the artifact name - artifact_version = { - "ce" = "${var.product_version}" - "ent" = "${var.product_version}+ent" - "ent.hsm" = "${var.product_version}+ent" - "ent.hsm.fips1402" = "${var.product_version}+ent" - "oss" = "${var.product_version}" - } - - // File name extensions for the various architectures and distributions - artifact_extension = { - amd64 = { - ubuntu = "-1_amd64.deb" - rhel = "-1.x86_64.rpm" - } - arm64 = { - ubuntu = "-1_arm64.deb" - rhel = "-1.aarch64.rpm" - } - } - - // Use the above variables to construct the artifact name to look up in Artifactory. - // Will look something like: - // vault_1.12.2-1_arm64.deb - // vault-enterprise_1.12.2+ent-1_amd64.deb - // vault-enterprise-hsm-1.12.2+ent-1.x86_64.rpm - artifact_name = "${local.artifact_prefix[var.distro][var.edition]}${local.artifact_version[var.edition]}${local.artifact_extension[var.arch][var.distro]}" - - // The path within the Artifactory repo that corresponds to the appropriate architecture - artifactory_repo_path_dir = { - "amd64" = "x86_64" - "arm64" = "aarch64" - } + arch = var.arch + distro = var.distro + edition = var.edition + package_type = var.artifact_type != null ? var.artifact_type : "package" + vault_version = var.product_version } -data "enos_artifactory_item" "vault_package" { +data "enos_artifactory_item" "vault" { username = var.artifactory_username token = var.artifactory_token - name = local.artifact_name + name = module.artifact_metadata.artifact_name host = var.artifactory_host - repo = var.distro == "rhel" ? "hashicorp-rpm-release-local*" : "hashicorp-apt-release-local*" - path = var.distro == "rhel" ? "RHEL/${var.distro_version}/${local.artifactory_repo_path_dir[var.arch]}/stable" : "pool/${var.arch}/main" + repo = module.artifact_metadata.release_repo + path = module.artifact_metadata.release_paths[var.distro_version] } output "results" { - value = data.enos_artifactory_item.vault_package.results + value = data.enos_artifactory_item.vault.results } output "url" { - value = data.enos_artifactory_item.vault_package.results[0].url + value = data.enos_artifactory_item.vault.results[0].url description = "The artifactory download url for the artifact" } output "sha256" { - value = data.enos_artifactory_item.vault_package.results[0].sha256 + value = data.enos_artifactory_item.vault.results[0].sha256 description = "The sha256 checksum for the artifact" } output "size" { - value = data.enos_artifactory_item.vault_package.results[0].size + value = data.enos_artifactory_item.vault.results[0].size description = "The size in bytes of the artifact" } output "name" { - value = data.enos_artifactory_item.vault_package.results[0].name + value = data.enos_artifactory_item.vault.results[0].name description = "The name of the artifact" } output "release" { value = { - url = data.enos_artifactory_item.vault_package.results[0].url - sha256 = data.enos_artifactory_item.vault_package.results[0].sha256 + url = data.enos_artifactory_item.vault.results[0].url + sha256 = data.enos_artifactory_item.vault.results[0].sha256 username = var.artifactory_username token = var.artifactory_token } diff --git a/enos/modules/ec2_info/main.tf b/enos/modules/ec2_info/main.tf index 1ca8d575f6..12fecf0fce 100644 --- a/enos/modules/ec2_info/main.tf +++ b/enos/modules/ec2_info/main.tf @@ -27,7 +27,7 @@ locals { } "rhel" = { "8.10" = data.aws_ami.rhel_8["arm64"].id - "9.4" = data.aws_ami.rhel_9["arm64"].id + "9.5" = data.aws_ami.rhel_9["arm64"].id } "sles" = { "15.6" = data.aws_ami.sles_15["arm64"].id @@ -48,7 +48,7 @@ locals { } "rhel" = { "8.10" = data.aws_ami.rhel_8["x86_64"].id - "9.4" = data.aws_ami.rhel_9["x86_64"].id + "9.5" = data.aws_ami.rhel_9["x86_64"].id } "sles" = { "15.6" = data.aws_ami.sles_15["x86_64"].id @@ -117,7 +117,6 @@ data "aws_ami" "rhel_8" { most_recent = true for_each = local.architectures - # Currently latest latest point release-1 filter { name = "name" values = ["RHEL-8.10*HVM-20*"] @@ -140,10 +139,9 @@ data "aws_ami" "rhel_9" { most_recent = true for_each = local.architectures - # Currently latest latest point release-1 filter { name = "name" - values = ["RHEL-9.4*HVM-20*"] + values = ["RHEL-9.5*HVM-20*"] } filter { diff --git a/enos/modules/verify_secrets_engines/modules/create/aws.tf b/enos/modules/verify_secrets_engines/modules/create/aws.tf index 4bc58eae7b..a96902ed4a 100644 --- a/enos/modules/verify_secrets_engines/modules/create/aws.tf +++ b/enos/modules/verify_secrets_engines/modules/create/aws.tf @@ -1,106 +1,21 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: BUSL-1.1 +module "create_aws_secrets_engine" { + count = var.create_aws_secrets_engine ? 1 : 0 + source = "./aws" + + hosts = var.hosts + leader_host = var.leader_host + vault_addr = var.vault_addr + vault_root_token = var.vault_root_token + vault_install_dir = var.vault_install_dir +} + locals { - // Variables - aws_mount = "aws" - vault_aws_role = "enos_test_role" - my_email = split("/", data.aws_caller_identity.current.arn)[2] - - // Output - aws_output = { - aws_role = data.aws_iam_role.premade_demo_assumed_role.name - aws_role_arn = data.aws_iam_role.premade_demo_assumed_role.arn - aws_policy_arn = data.aws_iam_policy.premade_demo_user_policy.arn - aws_user_name = aws_iam_user.aws_enos_test_user.name - aws_access_key = aws_iam_access_key.aws_enos_test_user.id - aws_secret_key = aws_iam_access_key.aws_enos_test_user.secret - mount = local.aws_mount - region = data.aws_region.current.name - vault_aws_role = local.vault_aws_role - } + aws_state = var.create_aws_secrets_engine ? module.create_aws_secrets_engine[0].state : null } -resource "random_id" "unique_suffix" { - byte_length = 4 -} - -data "aws_caller_identity" "current" {} - -data "aws_region" "current" {} - -# Using Pre-made policy and role -data "aws_iam_policy" "premade_demo_user_policy" { - name = "DemoUser" -} - -data "aws_iam_role" "premade_demo_assumed_role" { - name = "vault-assumed-role-credentials-demo" -} - -# Creating new test user -resource "aws_iam_user" "aws_enos_test_user" { - name = "demo-${local.my_email}-${random_id.unique_suffix.hex}" - permissions_boundary = data.aws_iam_policy.premade_demo_user_policy.arn - force_destroy = true -} - -resource "aws_iam_user_policy_attachment" "aws_enos_test_user" { - user = aws_iam_user.aws_enos_test_user.name - policy_arn = data.aws_iam_policy.premade_demo_user_policy.arn -} - -resource "aws_iam_access_key" "aws_enos_test_user" { - user = aws_iam_user.aws_enos_test_user.name - lifecycle { - prevent_destroy = false - } -} - -# Enable AWS secrets engine -resource "enos_remote_exec" "secrets_enable_aws_secret" { - environment = { - ENGINE = local.aws_mount - MOUNT = local.aws_mount - VAULT_ADDR = var.vault_addr - VAULT_TOKEN = var.vault_root_token - VAULT_INSTALL_DIR = var.vault_install_dir - } - - scripts = [abspath("${path.module}/../../scripts/secrets-enable.sh")] - - transport = { - ssh = { - host = var.leader_host.public_ip - } - } -} - -# Generate AWS Credentials -resource "enos_remote_exec" "aws_generate_roles" { - depends_on = [enos_remote_exec.secrets_enable_aws_secret] - for_each = var.hosts - - environment = { - AWS_REGION = local.aws_output.region - ENGINE = local.aws_mount - MOUNT = local.aws_mount - AWS_USER_NAME = local.aws_output.aws_user_name - AWS_POLICY_ARN = local.aws_output.aws_policy_arn - AWS_ROLE_ARN = local.aws_output.aws_role_arn - AWS_ACCESS_KEY_ID = local.aws_output.aws_access_key - AWS_SECRET_ACCESS_KEY = local.aws_output.aws_secret_key - VAULT_AWS_ROLE = local.vault_aws_role - VAULT_ADDR = var.vault_addr - VAULT_TOKEN = var.vault_root_token - VAULT_INSTALL_DIR = var.vault_install_dir - } - - scripts = [abspath("${path.module}/../../scripts/aws-generate-roles.sh")] - - transport = { - ssh = { - host = each.value.public_ip - } - } +output "aws" { + value = local.aws_state } diff --git a/enos/modules/verify_secrets_engines/modules/create/aws/aws.tf b/enos/modules/verify_secrets_engines/modules/create/aws/aws.tf new file mode 100644 index 0000000000..3fc5a79e73 --- /dev/null +++ b/enos/modules/verify_secrets_engines/modules/create/aws/aws.tf @@ -0,0 +1,153 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +terraform { + required_providers { + enos = { + source = "registry.terraform.io/hashicorp-forge/enos" + } + } +} + +variable "hosts" { + type = map(object({ + ipv6 = string + private_ip = string + public_ip = string + })) + description = "The Vault cluster instances that were created" +} + +variable "leader_host" { + type = object({ + ipv6 = string + private_ip = string + public_ip = string + }) + + description = "Vault cluster leader host" +} + +variable "vault_addr" { + type = string + description = "The local vault API listen address" +} + +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" + default = null +} + +locals { + // Variables + aws_mount = "aws" + vault_aws_role = "enos_test_role" + my_email = split("/", data.aws_caller_identity.current.arn)[2] + + // State output + state = { + aws_role = data.aws_iam_role.premade_demo_assumed_role.name + aws_role_arn = data.aws_iam_role.premade_demo_assumed_role.arn + aws_policy_arn = data.aws_iam_policy.premade_demo_user_policy.arn + aws_user_name = aws_iam_user.aws_enos_test_user.name + aws_access_key = aws_iam_access_key.aws_enos_test_user.id + aws_secret_key = aws_iam_access_key.aws_enos_test_user.secret + mount = local.aws_mount + region = data.aws_region.current.name + vault_aws_role = local.vault_aws_role + } +} + +output "state" { + value = local.state +} + +resource "random_id" "unique_suffix" { + byte_length = 4 +} + +data "aws_caller_identity" "current" {} + +data "aws_region" "current" {} + +# Using Pre-made policy and role +data "aws_iam_policy" "premade_demo_user_policy" { + name = "DemoUser" +} + +data "aws_iam_role" "premade_demo_assumed_role" { + name = "vault-assumed-role-credentials-demo" +} + +# Creating new test user +resource "aws_iam_user" "aws_enos_test_user" { + name = "demo-${local.my_email}-${random_id.unique_suffix.hex}" + permissions_boundary = data.aws_iam_policy.premade_demo_user_policy.arn + force_destroy = true +} + +resource "aws_iam_user_policy_attachment" "aws_enos_test_user" { + user = aws_iam_user.aws_enos_test_user.name + policy_arn = data.aws_iam_policy.premade_demo_user_policy.arn +} + +resource "aws_iam_access_key" "aws_enos_test_user" { + user = aws_iam_user.aws_enos_test_user.name + lifecycle { + prevent_destroy = false + } +} + +# Enable AWS secrets engine +resource "enos_remote_exec" "secrets_enable_aws_secret" { + environment = { + ENGINE = local.aws_mount + MOUNT = local.aws_mount + VAULT_ADDR = var.vault_addr + VAULT_TOKEN = var.vault_root_token + VAULT_INSTALL_DIR = var.vault_install_dir + } + + scripts = [abspath("${path.module}/../../../scripts/secrets-enable.sh")] + + transport = { + ssh = { + host = var.leader_host.public_ip + } + } +} + +# Generate AWS Credentials +resource "enos_remote_exec" "aws_generate_roles" { + depends_on = [enos_remote_exec.secrets_enable_aws_secret] + for_each = var.hosts + + environment = { + AWS_REGION = local.state.region + ENGINE = local.aws_mount + MOUNT = local.aws_mount + AWS_USER_NAME = local.state.aws_user_name + AWS_POLICY_ARN = local.state.aws_policy_arn + AWS_ROLE_ARN = local.state.aws_role_arn + AWS_ACCESS_KEY_ID = local.state.aws_access_key + AWS_SECRET_ACCESS_KEY = local.state.aws_secret_key + VAULT_AWS_ROLE = local.vault_aws_role + VAULT_ADDR = var.vault_addr + VAULT_TOKEN = var.vault_root_token + VAULT_INSTALL_DIR = var.vault_install_dir + } + + scripts = [abspath("${path.module}/../../../scripts/aws-generate-roles.sh")] + + transport = { + ssh = { + host = each.value.public_ip + } + } +} diff --git a/enos/modules/verify_secrets_engines/modules/create/main.tf b/enos/modules/verify_secrets_engines/modules/create/main.tf index 1357c002e3..265d738b85 100644 --- a/enos/modules/verify_secrets_engines/modules/create/main.tf +++ b/enos/modules/verify_secrets_engines/modules/create/main.tf @@ -9,6 +9,19 @@ terraform { } } +variable "create_aws_secrets_engine" { + type = bool + description = <<-EOF + Whether or not we'll verify the AWS secrets engine. Due to the various security requirements in + Doormat managed AWS accounts, our implementation of the verification requires us to use a + an external 'DemoUser' role and associated policy in order to create additional users. This is + configured in vault_ci and vault_enterprise_ci but does not exist in all AWS accounts. As such, + it's disabled by default. + See: https://github.com/hashicorp/honeybee-templates/blob/main/templates/iam_policy/DemoUser.yaml + EOF + default = false +} + variable "hosts" { type = map(object({ ipv6 = string @@ -50,6 +63,6 @@ output "state" { identity = local.identity_output kv = local.kv_output pki = local.pki_output - aws = local.aws_output + aws = local.aws_state } } diff --git a/enos/modules/verify_secrets_engines/modules/read/aws.tf b/enos/modules/verify_secrets_engines/modules/read/aws.tf index b491164e58..e2e9a8a22f 100644 --- a/enos/modules/verify_secrets_engines/modules/read/aws.tf +++ b/enos/modules/verify_secrets_engines/modules/read/aws.tf @@ -1,29 +1,15 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: BUSL-1.1 -# Verify PKI Certificate -resource "enos_remote_exec" "aws_verify_new_creds" { - for_each = var.hosts +module "verify_aws_secrets_engine" { + count = var.verify_aws_secrets_engine ? 1 : 0 + source = "./aws" - environment = { - AWS_REGION = "${var.create_state.aws.region}" - MOUNT = "${var.create_state.aws.mount}" - AWS_USER_NAME = "${var.create_state.aws.aws_user_name}" - AWS_ACCESS_KEY_ID = "${var.create_state.aws.aws_access_key}" - AWS_SECRET_ACCESS_KEY = "${var.create_state.aws.aws_secret_key}" - VAULT_AWS_ROLE = "${var.create_state.aws.vault_aws_role}" - VAULT_ADDR = var.vault_addr - VAULT_TOKEN = var.vault_root_token - VAULT_INSTALL_DIR = var.vault_install_dir - VERIFY_AWS_ENGINE_CERTS = var.verify_aws_engine_creds - } + create_state = var.create_state + vault_addr = var.vault_addr + vault_root_token = var.vault_root_token + vault_install_dir = var.vault_install_dir + verify_aws_engine_creds = var.verify_aws_engine_creds - scripts = [abspath("${path.module}/../../scripts/aws-verify-new-creds.sh")] - - transport = { - ssh = { - host = each.value.public_ip - } - } + hosts = var.hosts } - diff --git a/enos/modules/verify_secrets_engines/modules/read/aws/aws.tf b/enos/modules/verify_secrets_engines/modules/read/aws/aws.tf new file mode 100644 index 0000000000..6be2491996 --- /dev/null +++ b/enos/modules/verify_secrets_engines/modules/read/aws/aws.tf @@ -0,0 +1,69 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: BUSL-1.1 + +terraform { + required_providers { + enos = { + source = "registry.terraform.io/hashicorp-forge/enos" + } + } +} + +variable "hosts" { + type = map(object({ + ipv6 = string + private_ip = string + public_ip = string + })) + description = "The Vault cluster instances that were created" +} + +variable "create_state" { + description = "The state of the secrets engines from the 'create' module" +} + +variable "vault_addr" { + type = string + description = "The local vault API listen address" +} + +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" + default = null +} + +variable "verify_aws_engine_creds" { + type = bool +} + +# Verify PKI Certificate +resource "enos_remote_exec" "aws_verify_new_creds" { + for_each = var.hosts + + environment = { + AWS_REGION = "${var.create_state.aws.region}" + MOUNT = "${var.create_state.aws.mount}" + AWS_USER_NAME = "${var.create_state.aws.aws_user_name}" + AWS_ACCESS_KEY_ID = "${var.create_state.aws.aws_access_key}" + AWS_SECRET_ACCESS_KEY = "${var.create_state.aws.aws_secret_key}" + VAULT_AWS_ROLE = "${var.create_state.aws.vault_aws_role}" + VAULT_ADDR = var.vault_addr + VAULT_TOKEN = var.vault_root_token + VAULT_INSTALL_DIR = var.vault_install_dir + VERIFY_AWS_ENGINE_CERTS = var.verify_aws_engine_creds + } + + scripts = [abspath("${path.module}/../../../scripts/aws-verify-new-creds.sh")] + + transport = { + ssh = { + host = each.value.public_ip + } + } +} diff --git a/enos/modules/verify_secrets_engines/modules/read/main.tf b/enos/modules/verify_secrets_engines/modules/read/main.tf index 269146b3f4..66a3c29aea 100644 --- a/enos/modules/verify_secrets_engines/modules/read/main.tf +++ b/enos/modules/verify_secrets_engines/modules/read/main.tf @@ -38,10 +38,22 @@ variable "vault_root_token" { default = null } -variable "verify_aws_engine_creds" { +variable "verify_aws_secrets_engine" { type = bool - description = "Flag to verify AWS Engine creds" - default = true + description = <<-EOF + Whether or not we'll verify the AWS secrets engine. Due to the various security requirements in + Doormat managed AWS accounts, our implementation of the verification requires us to use a + an external 'DemoUser' role and associated policy in order to create additional users. This is + configured in vault_ci and vault_enterprise_ci but does not exist in all AWS accounts. As such, + it's disabled by default. + See: https://github.com/hashicorp/honeybee-templates/blob/main/templates/iam_policy/DemoUser.yaml + EOF + default = false +} + +variable "verify_aws_engine_creds" { + type = bool + default = true } variable "verify_pki_certs" { diff --git a/enos/modules/verify_secrets_engines/scripts/pki-verify-certificates.sh b/enos/modules/verify_secrets_engines/scripts/pki-verify-certificates.sh index cadd81d5c0..e738bd7c41 100755 --- a/enos/modules/verify_secrets_engines/scripts/pki-verify-certificates.sh +++ b/enos/modules/verify_secrets_engines/scripts/pki-verify-certificates.sh @@ -47,8 +47,8 @@ ROOT_CA_CERT=$("$binpath" read pki/cert/ca | jq -r '.data.certificate') # Verifying Certificates if [ "${VERIFY_PKI_CERTS}" = true ]; then if [ ! -d "${TEST_DIR}" ]; then - echo "Directory does not exist. Creating it now." - mkdir -p "${TEST_DIR}" # Need to create this directory for Enterprise test + echo "Directory does not exist. Creating it now." + mkdir -p "${TEST_DIR}" # Need to create this directory for Enterprise test fi TMP_FILE="tmp-vault-cert.pem" @@ -61,9 +61,11 @@ if [ "${VERIFY_PKI_CERTS}" = true ]; then echo "Verifying certificate contents..." openssl x509 -in "${TEST_DIR}/${TMP_FILE}" -text -noout || fail "The certificate appears to be improperly configured or contains errors" CURR_CERT_SERIAL=$(echo "${CERT}" | tr -d ':' | tr '[:lower:]' '[:upper:]') - TMP_CERT_SUBJECT=$(openssl x509 -in "${TEST_DIR}/${TMP_FILE}" -noout -subject | awk -F'CN[ ]*=[ ]*' '{print "CN=" $2}') - TMP_CERT_ISSUER=$(openssl x509 -in "${TEST_DIR}/${TMP_FILE}" -noout -issuer | awk -F'CN[ ]*=[ ]*' '{print "CN=" $2}') - TMP_CERT_SERIAL=$(openssl x509 -in "${TEST_DIR}/${TMP_FILE}" -noout -serial | awk -F'=' '{print $2}') + if ! TMP_CERT_SUBJECT=$(openssl x509 -in "${TEST_DIR}/${TMP_FILE}" -noout -subject | cut -d '=' -f2-); then + fail "failed to read certificate subject: $TMP_CERT_SUBJECT" + fi + TMP_CERT_ISSUER=$(openssl x509 -in "${TEST_DIR}/${TMP_FILE}" -noout -issuer | cut -d '=' -f2-) + TMP_CERT_SERIAL=$(openssl x509 -in "${TEST_DIR}/${TMP_FILE}" -noout -serial | cut -d '=' -f2-) [[ "${TMP_CERT_SUBJECT}" == *"${COMMON_NAME}.com"* ]] || fail "Subject is incorrect. Actual Subject: ${TMP_CERT_SUBJECT}" [[ "${TMP_CERT_ISSUER}" == *"${COMMON_NAME}.com"* ]] || fail "Issuer is incorrect. Actual Issuer: ${TMP_CERT_ISSUER}" [[ "${TMP_CERT_SERIAL}" == *"${CURR_CERT_SERIAL}"* ]] || fail "Certificate Serial is incorrect. Actual certificate Serial: ${CURR_CERT_SERIAL},${TMP_CERT_SERIAL}" diff --git a/tools/pipeline/internal/pkg/generate/enos_dynamic_config.go b/tools/pipeline/internal/pkg/generate/enos_dynamic_config.go index ccbc1b02c1..678e98161f 100644 --- a/tools/pipeline/internal/pkg/generate/enos_dynamic_config.go +++ b/tools/pipeline/internal/pkg/generate/enos_dynamic_config.go @@ -135,7 +135,7 @@ func (e *EnosDynamicConfigReq) getSampleAttrs(ctx context.Context) (*SampleAttrs // Current distro defaults DistroVersionAmzn: []string{"2023"}, DistroVersionLeap: []string{"15.6"}, - DistroVersionRhel: []string{"8.10", "9.4"}, + DistroVersionRhel: []string{"8.10", "9.5"}, DistroVersionSles: []string{"15.6"}, DistroVersionUbuntu: []string{"20.04", "24.04"}, }