Skip to content
This repository has been archived by the owner on Jan 25, 2023. It is now read-only.

Commit

Permalink
Merge pull request #122 from hashicorp/fix/run-vault
Browse files Browse the repository at this point in the history
Fix/run vault
  • Loading branch information
Etiene authored Dec 18, 2018
2 parents 15adcd4 + 0cfebdb commit 3ff5d57
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 88 deletions.
2 changes: 1 addition & 1 deletion examples/vault-consul-ami/vault-consul.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"min_packer_version": "0.12.0",
"variables": {
"aws_region": "us-east-1",
"vault_version": "0.11.5",
"vault_version": "1.0.0",
"consul_module_version": "v0.4.2",
"consul_version": "1.3.1",
"consul_download_url": "{{env `CONSUL_DOWNLOAD_URL`}}",
Expand Down
8 changes: 7 additions & 1 deletion modules/run-vault/run-vault
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,17 @@ function generate_vault_config {

local auto_unseal_config=""
if [[ "$enable_auto_unseal" == "true" ]]; then

local endpoint=""
if [[ -n "$auto_unseal_endpoint" ]]; then
endpoint="endpoint = '$auto_unseal_endpoint'"
fi

auto_unseal_config=$(cat <<EOF
seal "awskms" {
kms_key_id = "$auto_unseal_kms_key_id"
region = "$auto_unseal_kms_key_region"
endpoint = "$auto_unseal_endpoint"
$endpoint
}\n
EOF
)
Expand Down
99 changes: 99 additions & 0 deletions test/vault_cluster_autounseal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package test

import (
"fmt"
"testing"
"time"

"github.com/gruntwork-io/terratest/modules/aws"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/retry"
"github.com/gruntwork-io/terratest/modules/ssh"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
)

// This is the alias of a KMS key we have previously created that lives in the
// AWS account where our CI tests run. We have one with the same alias in
// every region. This key is necessary for the test of an Enterprise Vault feature
// called auto unseal. If you wish to run test this locally, replace this with
// the alias of an KMS key you already have on the AWS account you use for running
// your tests or create a new one. Beware that creating an AWS KMS key costs money.
const AUTO_UNSEAL_KMS_KEY_ALIAS = "dedicated-test-key"

const VAULT_AUTO_UNSEAL_AUTH_PATH = "examples/vault-auto-unseal"
const VAR_VAULT_AUTO_UNSEAL_KMS_KEY_ALIAS = "auto_unseal_kms_key_alias"

// Test the Vault auto unseal example by:
//
// 1. Copying the code in this repo to a temp folder so tests on the Terraform code can run in parallel without the
// state files overwriting each other.
// 2. Building the AMI in the vault-consul-ami example with the given build name
// 3. Deploying a cluster of 1 vault server using the example Terraform code
// 4. Sshing into vault node to initialize the server and check that it booted unsealed
// 5. Increasing the the cluster size to 3 and check that new nodes are unsealed when they boot and join the cluster
func runVaultAutoUnsealTest(t *testing.T, amiId string, awsRegion string, sshUserName string) {
examplesDir := test_structure.CopyTerraformFolderToTemp(t, REPO_ROOT, VAULT_AUTO_UNSEAL_AUTH_PATH)

defer test_structure.RunTestStage(t, "teardown", func() {
teardownResources(t, examplesDir)
})

defer test_structure.RunTestStage(t, "log", func() {
terraformOptions := test_structure.LoadTerraformOptions(t, examplesDir)
keyPair := test_structure.LoadEc2KeyPair(t, examplesDir)

getVaultLogs(t, "vaultAutoUnseal", terraformOptions, amiId, awsRegion, sshUserName, keyPair)
})

test_structure.RunTestStage(t, "deploy", func() {
uniqueId := random.UniqueId()
terraformVars := map[string]interface{}{
VAR_VAULT_AUTO_UNSEAL_KMS_KEY_ALIAS: AUTO_UNSEAL_KMS_KEY_ALIAS,
VAR_VAULT_CLUSTER_SIZE: 1,
}
deployCluster(t, amiId, awsRegion, examplesDir, uniqueId, terraformVars)
})

test_structure.RunTestStage(t, "validate", func() {
terraformOptions := test_structure.LoadTerraformOptions(t, examplesDir)
keyPair := test_structure.LoadEc2KeyPair(t, examplesDir)

testAutoUnseal(t, OUTPUT_VAULT_CLUSTER_ASG_NAME, sshUserName, terraformOptions, awsRegion, keyPair)
})
}

func testAutoUnseal(t *testing.T, asgNameOutputVar string, sshUserName string, terraformOptions *terraform.Options, awsRegion string, keyPair *aws.Ec2Keypair) {
asgName := terraform.OutputRequired(t, terraformOptions, asgNameOutputVar)
nodeIpAddresses := getIpAddressesOfAsgInstances(t, asgName, awsRegion)
logger.Logf(t, fmt.Sprintf("IP ADDRESS OF INSTANCE %s", nodeIpAddresses[0]))
initialCluster := VaultCluster{
Leader: ssh.Host{
Hostname: nodeIpAddresses[0],
SshUserName: sshUserName,
SshKeyPair: keyPair.KeyPair,
},
}

establishConnectionToCluster(t, initialCluster)
waitForVaultToBoot(t, initialCluster)

retry.DoWithRetry(t, "Initializing the cluster", 10, 10*time.Second, func() (string, error) {
return ssh.CheckSshCommandE(t, initialCluster.Leader, "vault operator init")
})
assertStatus(t, initialCluster.Leader, Leader)

logger.Logf(t, "Increasing the cluster size and running 'terraform apply' again")
terraformOptions.Vars[VAR_VAULT_CLUSTER_SIZE] = 3
terraform.Apply(t, terraformOptions)

logger.Logf(t, "The cluster now should be bigger and the new nodes should boot unsealed (on standby mode already)")
newCluster := findVaultClusterNodes(t, asgNameOutputVar, sshUserName, terraformOptions, awsRegion, keyPair)
establishConnectionToCluster(t, newCluster)
for _, node := range newCluster.Nodes() {
if node.Hostname != initialCluster.Leader.Hostname {
assertStatus(t, node, Standby)
}
}
}
85 changes: 0 additions & 85 deletions test/vault_cluster_enterprise_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,13 @@ import (
"time"

"github.com/gruntwork-io/terratest/modules/aws"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/retry"
"github.com/gruntwork-io/terratest/modules/ssh"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/gruntwork-io/terratest/modules/test-structure"
)

// This is the alias of a KMS key we have previously created that lives in the
// AWS account where our CI tests run. We have one with the same alias in
// every region. This key is necessary for the test of an Enterprise Vault feature
// called auto unseal. If you wish to run test this locally, replace this with
// the alias of an KMS key you already have on the AWS account you use for running
// your tests or create a new one. Beware that creating an AWS KMS key costs money.
const AUTO_UNSEAL_KMS_KEY_ALIAS = "dedicated-test-key"

const VAULT_AUTO_UNSEAL_AUTH_PATH = "examples/vault-auto-unseal"
const VAR_VAULT_AUTO_UNSEAL_KMS_KEY_ALIAS = "auto_unseal_kms_key_alias"

// To test this on circle ci you need a url set as an environment variable, VAULT_AMI_TEMPLATE_VAR_DOWNLOAD_URL
// which you would also have to set locally if you want to run this test locally.
// The reason is to prevent the actual url from being visible on code and logs
Expand All @@ -38,45 +26,6 @@ func getUrlFromEnv(t *testing.T) string {
return url
}

// Test the Vault auto unseal example by:
//
// 1. Copying the code in this repo to a temp folder so tests on the Terraform code can run in parallel without the
// state files overwriting each other.
// 2. Building the AMI in the vault-consul-ami example with the given build name
// 3. Deploying a cluster of 1 vault server using the example Terraform code
// 4. Sshing into vault node to initialize the server and check that it booted unsealed
// 5. Increasing the the cluster size to 3 and check that new nodes are unsealed when they boot and join the cluster
func runVaultAutoUnsealTest(t *testing.T, amiId string, awsRegion string, sshUserName string) {
examplesDir := test_structure.CopyTerraformFolderToTemp(t, REPO_ROOT, VAULT_AUTO_UNSEAL_AUTH_PATH)

defer test_structure.RunTestStage(t, "teardown", func() {
teardownResources(t, examplesDir)
})

defer test_structure.RunTestStage(t, "log", func() {
terraformOptions := test_structure.LoadTerraformOptions(t, examplesDir)
keyPair := test_structure.LoadEc2KeyPair(t, examplesDir)

getVaultLogs(t, "vaultAutoUnseal", terraformOptions, amiId, awsRegion, sshUserName, keyPair)
})

test_structure.RunTestStage(t, "deploy", func() {
uniqueId := random.UniqueId()
terraformVars := map[string]interface{}{
VAR_VAULT_AUTO_UNSEAL_KMS_KEY_ALIAS: AUTO_UNSEAL_KMS_KEY_ALIAS,
VAR_VAULT_CLUSTER_SIZE: 1,
}
deployCluster(t, amiId, awsRegion, examplesDir, uniqueId, terraformVars)
})

test_structure.RunTestStage(t, "validate", func() {
terraformOptions := test_structure.LoadTerraformOptions(t, examplesDir)
keyPair := test_structure.LoadEc2KeyPair(t, examplesDir)

testAutoUnseal(t, OUTPUT_VAULT_CLUSTER_ASG_NAME, sshUserName, terraformOptions, awsRegion, keyPair)
})
}

// Test the Vault enterprise cluster example by:
//
// 1. Copy the code in this repo to a temp folder so tests on the Terraform code can run in parallel without the
Expand Down Expand Up @@ -115,40 +64,6 @@ func runVaultEnterpriseClusterTest(t *testing.T, amiId string, awsRegion string,
})
}

func testAutoUnseal(t *testing.T, asgNameOutputVar string, sshUserName string, terraformOptions *terraform.Options, awsRegion string, keyPair *aws.Ec2Keypair) {
asgName := terraform.OutputRequired(t, terraformOptions, asgNameOutputVar)
nodeIpAddresses := getIpAddressesOfAsgInstances(t, asgName, awsRegion)
logger.Logf(t, fmt.Sprintf("IP ADDRESS OF INSTANCE %s", nodeIpAddresses[0]))
initialCluster := VaultCluster{
Leader: ssh.Host{
Hostname: nodeIpAddresses[0],
SshUserName: sshUserName,
SshKeyPair: keyPair.KeyPair,
},
}

establishConnectionToCluster(t, initialCluster)
waitForVaultToBoot(t, initialCluster)

retry.DoWithRetry(t, "Initializing the cluster", 10, 10*time.Second, func() (string, error) {
return ssh.CheckSshCommandE(t, initialCluster.Leader, "vault operator init")
})
assertStatus(t, initialCluster.Leader, Leader)

logger.Logf(t, "Increasing the cluster size and running 'terraform apply' again")
terraformOptions.Vars[VAR_VAULT_CLUSTER_SIZE] = 3
terraform.Apply(t, terraformOptions)

logger.Logf(t, "The cluster now should be bigger and the new nodes should boot unsealed (on standby mode already)")
newCluster := findVaultClusterNodes(t, asgNameOutputVar, sshUserName, terraformOptions, awsRegion, keyPair)
establishConnectionToCluster(t, newCluster)
for _, node := range newCluster.Nodes() {
if node.Hostname != initialCluster.Leader.Hostname {
assertStatus(t, node, Standby)
}
}
}

// Check if the enterprise version of consul and vault is installed
func checkEnterpriseInstall(t *testing.T, asgNameOutputVar string, sshUserName string, terratestOptions *terraform.Options, awsRegion string, keyPair *aws.Ec2Keypair) {
asgName := terraform.OutputRequired(t, terratestOptions, asgNameOutputVar)
Expand Down
2 changes: 1 addition & 1 deletion test/vault_main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var testCases = []testCase{
{
"TestVaultAutoUnseal",
runVaultAutoUnsealTest,
true,
false,
},
{
"TestEnterpriseInstallation",
Expand Down

0 comments on commit 3ff5d57

Please sign in to comment.