open-vault/enos/enos-scenario-agent.hcl

248 lines
8.0 KiB
HCL
Raw Normal View History

# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
scenario "agent" {
matrix {
arch = ["amd64", "arm64"]
artifact_source = ["local", "crt", "artifactory"]
distro = ["ubuntu", "rhel"]
[QT-436] Pseudo random artifact test scenarios (#18056) Introducing a new approach to testing Vault artifacts before merge and after merge/notorization/signing. Rather than run a few static scenarios across the artifacts, we now have the ability to run a pseudo random sample of scenarios across many different build artifacts. We've added 20 possible scenarios for the AMD64 and ARM64 binary bundles, which we've broken into five test groups. On any given push to a pull request branch, we will now choose a random test group and execute its corresponding scenarios against the resulting build artifacts. This gives us greater test coverage but lets us split the verification across many different pull requests. The post-merge release testing pipeline behaves in a similar fashion, however, the artifacts that we use for testing have been notarized and signed prior to testing. We've also reduce the number of groups so that we run more scenarios after merge to a release branch. We intend to take what we've learned building this in Github Actions and roll it into an easier to use feature that is native to Enos. Until then, we'll have to manually add scenarios to each matrix file and manually number the test group. It's important to note that Github requires every matrix to include at least one vector, so every artifact that is being tested must include a single scenario in order for all workflows to pass and thus satisfy branch merge requirements. * Add support for different artifact types to enos-run * Add support for different runner type to enos-run * Add arm64 scenarios to build matrix * Expand build matrices to include different variants * Update Consul versions in Enos scenarios and matrices * Refactor enos-run environment * Add minimum version filtering support to enos-run. This allows us to automatically exclude scenarios that require a more recent version of Vault * Add maximum version filtering support to enos-run. This allows us to automatically exclude scenarios that require an older version of Vault * Fix Node 12 deprecation warnings * Rename enos-verify-stable to enos-release-testing-oss * Convert artifactory matrix into enos-release-testing-oss matrices * Add all Vault editions to Enos scenario matrices * Fix verify version with complex Vault edition metadata * Rename the crt-builder to ci-helper * Add more version helpers to ci-helper and Makefile * Update CODEOWNERS for quality team * Add support for filtering matrices by group and version constraints * Add support for pseudo random test scenario execution Signed-off-by: Ryan Cragun <me@ryan.ec>
2022-12-12 20:46:04 +00:00
edition = ["oss", "ent", "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 {
build_tags = {
[QT-436] Pseudo random artifact test scenarios (#18056) Introducing a new approach to testing Vault artifacts before merge and after merge/notorization/signing. Rather than run a few static scenarios across the artifacts, we now have the ability to run a pseudo random sample of scenarios across many different build artifacts. We've added 20 possible scenarios for the AMD64 and ARM64 binary bundles, which we've broken into five test groups. On any given push to a pull request branch, we will now choose a random test group and execute its corresponding scenarios against the resulting build artifacts. This gives us greater test coverage but lets us split the verification across many different pull requests. The post-merge release testing pipeline behaves in a similar fashion, however, the artifacts that we use for testing have been notarized and signed prior to testing. We've also reduce the number of groups so that we run more scenarios after merge to a release branch. We intend to take what we've learned building this in Github Actions and roll it into an easier to use feature that is native to Enos. Until then, we'll have to manually add scenarios to each matrix file and manually number the test group. It's important to note that Github requires every matrix to include at least one vector, so every artifact that is being tested must include a single scenario in order for all workflows to pass and thus satisfy branch merge requirements. * Add support for different artifact types to enos-run * Add support for different runner type to enos-run * Add arm64 scenarios to build matrix * Expand build matrices to include different variants * Update Consul versions in Enos scenarios and matrices * Refactor enos-run environment * Add minimum version filtering support to enos-run. This allows us to automatically exclude scenarios that require a more recent version of Vault * Add maximum version filtering support to enos-run. This allows us to automatically exclude scenarios that require an older version of Vault * Fix Node 12 deprecation warnings * Rename enos-verify-stable to enos-release-testing-oss * Convert artifactory matrix into enos-release-testing-oss matrices * Add all Vault editions to Enos scenario matrices * Fix verify version with complex Vault edition metadata * Rename the crt-builder to ci-helper * Add more version helpers to ci-helper and Makefile * Update CODEOWNERS for quality team * Add support for filtering matrices by group and version constraints * Add support for pseudo random test scenario execution Signed-off-by: Ryan Cragun <me@ryan.ec>
2022-12-12 20:46:04 +00:00
"oss" = ["ui"]
"ent" = ["ui", "enterprise", "ent"]
"ent.fips1402" = ["ui", "enterprise", "cgo", "hsm", "fips", "fips_140_2", "ent.fips1402"]
"ent.hsm" = ["ui", "enterprise", "cgo", "hsm", "venthsm"]
"ent.hsm.fips1402" = ["ui", "enterprise", "cgo", "hsm", "fips", "fips_140_2", "ent.hsm.fips1402"]
}
bundle_path = matrix.artifact_source != "artifactory" ? abspath(var.vault_bundle_path) : null
packages = ["jq"]
enos_provider = {
rhel = provider.enos.rhel
ubuntu = provider.enos.ubuntu
}
install_artifactory_artifact = local.bundle_path == null
spot_price_max = {
// These prices are based on on-demand cost for t3.medium in us-east
"rhel" = "0.1016"
"ubuntu" = "0.0416"
}
tags = merge({
"Project Name" : var.project_name
"Project" : "Enos",
"Environment" : "ci"
}, var.tags)
vault_instance_types = {
amd64 = "t3a.small"
arm64 = "t4g.small"
}
vault_instance_type = coalesce(var.vault_instance_type, local.vault_instance_types[matrix.arch])
[QT-358] Unify CRT and local builder workflows (#17766) Here we make the following major changes: * Centralize CRT builder logic into a script utility so that we can share the logic for building artifacts in CI or locally. * Simplify the build workflow by calling a reusable workflow many times instead of repeating the contents. * Create a workflow that validates whether or not the build workflow and all child workflows have succeeded to allow for merge protection. Motivation * We need branch requirements for the build workflow and all subsequent integration tests (QT-353) * We need to ensure that the Enos local builder works (QT-558) * Debugging build failures can be difficult because one has to hand craft the steps to recreate the build * Merge conflicts between Vault OSS and Vault ENT build workflows are quite painful. As the build workflow must be the same file and name we'll reduce what is contained in each that is unique. Implementations of building will be unique per edition so we don't have to worry about conflict resolution. * Since we're going to be touching the build workflow to do the first two items we might as well try and improve those other issues at the same time to reduce the overhead of backports and conflicts. Considerations * Build logic for Vault OSS and Vault ENT differs * The Enos local builder was duplicating a lot of what we did in the CRT build workflow * Version and other artifact metadata has been an issue before. Debugging it has been tedious and error prone. * The build workflow is full of brittle copy and paste that is hard to understand, especially for all of the release editions in Vault Enterprise * Branch check requirements for workflows are incredibly painful to use for workflows that are dynamic or change often. The required workflows have to be configured in Github settings by administrators. They would also prevent us from having simple docs PRs since required integration workflows always have to run to satisfy branch requirements. * Doormat credentials requirements that are coming will require us to modify which event types trigger workflows. This changes those ahead of time since we're doing so much to build workflow. The only noticeable impact will be that the build workflow no longer runs on pushes to non-main or release branches. In order to test other branches it requires a workflow_dispatch from the Actions tab or a pull request. Solutions * Centralize the logic that determines build metadata and creates releasable Vault artifacts. Instead of cargo-culting logic multiple times in the build workflow and the Enos local modules, we now have a crt-builder script which determines build metadata and also handles building the UI, Vault, and the package bundle. There are make targets for all of the available sub-commands. Now what we use in the pipeline is the same thing as the local builder, and it can be executed locally by developers. The crt-builder script works in OSS and Enterprise so we will never have to deal with them being divergent or with special casing things in the build workflow. * Refactor the bulk of the Vault building into a reusable workflow that we can call multiple times. This allows us to define Vault builds in a much simpler manner and makes resolving merge conflicts much easier. * Rather than trying to maintain a list and manually configure the branch check requirements for build, we'll trigger a single workflow that uses the github event system to determine if the build workflow (all of the sub-workflows included) have passed. We'll then create branch restrictions on that single workflow down the line. Signed-off-by: Ryan Cragun me@ryan.ec
2022-11-11 20:14:43 +00:00
vault_license_path = abspath(var.vault_license_path != null ? var.vault_license_path : joinpath(path.root, "./support/vault.hclic"))
}
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 : local.build_tags[matrix.edition]
bundle_path = local.bundle_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_source == "artifactory" ? var.vault_artifact_type : null
distro = matrix.artifact_source == "artifactory" ? matrix.distro : null
edition = matrix.artifact_source == "artifactory" ? matrix.edition : null
instance_type = matrix.artifact_source == "artifactory" ? local.vault_instance_type : null
revision = var.vault_revision
}
}
step "find_azs" {
module = module.az_finder
variables {
instance_type = [
var.backend_instance_type,
local.vault_instance_type
]
}
}
step "create_vpc" {
module = module.create_vpc
variables {
ami_architectures = distinct([matrix.arch, "amd64"])
availability_zones = step.find_azs.availability_zones
common_tags = local.tags
}
}
step "read_license" {
skip_step = matrix.edition == "oss"
module = module.read_license
variables {
[QT-358] Unify CRT and local builder workflows (#17766) Here we make the following major changes: * Centralize CRT builder logic into a script utility so that we can share the logic for building artifacts in CI or locally. * Simplify the build workflow by calling a reusable workflow many times instead of repeating the contents. * Create a workflow that validates whether or not the build workflow and all child workflows have succeeded to allow for merge protection. Motivation * We need branch requirements for the build workflow and all subsequent integration tests (QT-353) * We need to ensure that the Enos local builder works (QT-558) * Debugging build failures can be difficult because one has to hand craft the steps to recreate the build * Merge conflicts between Vault OSS and Vault ENT build workflows are quite painful. As the build workflow must be the same file and name we'll reduce what is contained in each that is unique. Implementations of building will be unique per edition so we don't have to worry about conflict resolution. * Since we're going to be touching the build workflow to do the first two items we might as well try and improve those other issues at the same time to reduce the overhead of backports and conflicts. Considerations * Build logic for Vault OSS and Vault ENT differs * The Enos local builder was duplicating a lot of what we did in the CRT build workflow * Version and other artifact metadata has been an issue before. Debugging it has been tedious and error prone. * The build workflow is full of brittle copy and paste that is hard to understand, especially for all of the release editions in Vault Enterprise * Branch check requirements for workflows are incredibly painful to use for workflows that are dynamic or change often. The required workflows have to be configured in Github settings by administrators. They would also prevent us from having simple docs PRs since required integration workflows always have to run to satisfy branch requirements. * Doormat credentials requirements that are coming will require us to modify which event types trigger workflows. This changes those ahead of time since we're doing so much to build workflow. The only noticeable impact will be that the build workflow no longer runs on pushes to non-main or release branches. In order to test other branches it requires a workflow_dispatch from the Actions tab or a pull request. Solutions * Centralize the logic that determines build metadata and creates releasable Vault artifacts. Instead of cargo-culting logic multiple times in the build workflow and the Enos local modules, we now have a crt-builder script which determines build metadata and also handles building the UI, Vault, and the package bundle. There are make targets for all of the available sub-commands. Now what we use in the pipeline is the same thing as the local builder, and it can be executed locally by developers. The crt-builder script works in OSS and Enterprise so we will never have to deal with them being divergent or with special casing things in the build workflow. * Refactor the bulk of the Vault building into a reusable workflow that we can call multiple times. This allows us to define Vault builds in a much simpler manner and makes resolving merge conflicts much easier. * Rather than trying to maintain a list and manually configure the branch check requirements for build, we'll trigger a single workflow that uses the github event system to determine if the build workflow (all of the sub-workflows included) have passed. We'll then create branch restrictions on that single workflow down the line. Signed-off-by: Ryan Cragun me@ryan.ec
2022-11-11 20:14:43 +00:00
file_name = local.vault_license_path
}
}
step "create_vault_cluster_targets" {
module = module.target_ec2_spot_fleet // "target_ec2_instances" can be used for on-demand instances
depends_on = [step.create_vpc]
providers = {
enos = local.enos_provider[matrix.distro]
}
variables {
ami_id = step.create_vpc.ami_ids[matrix.distro][matrix.arch]
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
common_tags = local.tags
instance_type = local.vault_instance_type // only used for on-demand instances
spot_price_max = local.spot_price_max[matrix.distro]
vpc_id = step.create_vpc.vpc_id
}
}
step "create_vault_cluster" {
module = module.vault_cluster
depends_on = [
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
awskms_unseal_key_arn = step.create_vpc.kms_key_arn
cluster_name = step.create_vault_cluster_targets.cluster_name
config_env_vars = {
VAULT_LOG_LEVEL = var.vault_log_level
}
install_dir = var.vault_install_dir
license = matrix.edition != "oss" ? step.read_license.license : null
local_artifact_path = local.bundle_path
packages = local.packages
storage_backend = "raft"
target_hosts = step.create_vault_cluster_targets.hosts
unseal_method = "shamir"
}
}
step "start_vault_agent" {
module = "vault_agent"
depends_on = [
step.build_vault,
step.create_vault_cluster,
]
providers = {
enos = local.enos_provider[matrix.distro]
}
variables {
vault_instances = step.create_vault_cluster_targets.hosts
vault_root_token = step.create_vault_cluster.root_token
vault_agent_template_destination = "/tmp/agent_output.txt"
vault_agent_template_contents = "{{ with secret \\\"auth/token/lookup-self\\\" }}orphan={{ .Data.orphan }} display_name={{ .Data.display_name }}{{ end }}"
}
}
step "verify_vault_agent_output" {
module = module.vault_verify_agent_output
depends_on = [
step.create_vault_cluster,
step.start_vault_agent,
]
providers = {
enos = local.enos_provider[matrix.distro]
}
variables {
vault_instances = step.create_vault_cluster_targets.hosts
vault_agent_template_destination = "/tmp/agent_output.txt"
vault_agent_expected_output = "orphan=true display_name=approle"
}
}
output "awkms_unseal_key_arn" {
description = "The Vault cluster KMS key arn"
value = step.create_vpc.kms_key_arn
}
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 "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 "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
}
}