enos(artifactory): unify dev and test scenario artifactory metadata into new module (#29891)

* enos(artifactory): unify dev and test scenario artifactory metadata into new module

There was previously a lot of shared logic between
`build_artifactory_artifact` and `build_artifactory_package` as it
regards to building an artifact name. When it comes down to it, both
modules are very similar and their only major difference is searching
for any artifact (released or not) by either a combination of
`revision`, `edition`, `version`, and `type` vs. searching for a
released artifact with a combination of `version`, `edition`, and
`type`.

Rather than bolt on new `s390x` and `fips1403` artifact metadata to
both, I factored their metadata for package names and such into a
unified and shared `artifact/metadata` module that is now called by
both.

This was tricky as dev and test scenarios currently differ in what
we pass in as the `vault_version`, but we hope to remove that
difference soon. We also add metadata support for the forthcoming
FIPS 140-3.

This commit was tested extensively, along with other test scenarios
in support for `s390x but will be useful immediately for FIPS 140-3
so I've extracted it out.

Signed-off-by: Ryan Cragun <me@ryan.ec>

* Fix artifactory metadata before merge

The initial pass of the artifactory metadata was largely untested and
extracted from a different branch. After testing, this commit fixes a
few issues with the metadata module.

In order to test this I also had to fix an issue where AWS secrets
engine testing became a requirement but is impossible unless you exectue
against a blessed AWS account that has required roles. Instead, we now
make those verification opt-in via a new variable.

We also make some improvements to the pki-verify-certificates script so
that it works reliably against all our supported distros.

We also update our dynamic configuration to use the updated versions in
samples.

Signed-off-by: Ryan Cragun <me@ryan.ec>
This commit is contained in:
Ryan Cragun 2025-04-25 14:55:26 -06:00 committed by GitHub
parent ee50909f5b
commit f61bd3230c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 641 additions and 354 deletions

View File

@ -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

View File

@ -39,7 +39,12 @@ scenario "dev_pr_replication" {
exclude {
artifact = ["deb"]
distro = ["rhel"]
distro = ["rhel", "amzn"]
}
exclude {
artifact = ["deb", "rpm"]
distro = ["sles", "leap"]
}
exclude {

View File

@ -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]
}
}

View File

@ -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"]
}
}

View File

@ -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

View File

@ -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" {

View File

@ -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

View File

@ -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_<arch>.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
}

View File

@ -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_<arch>.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}"
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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 }

View File

@ -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
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -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" {

View File

@ -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}"

View File

@ -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"},
}