Skip to content

Hashicorp Vault with KMS Auto Unseal, S3 storage, and DynamoDB high availability

License

Notifications You must be signed in to change notification settings

MarletteFunding/terraform-aws-vault

 
 

Repository files navigation

Terraform Module: Hashicorp Vault on AWS

Production-ready Vault in a Terraform module

Goals

This is a Terraform module for creating a production-grade Hashicorp Vault deployment on AWS. Some stated goals:

  • Maximum security
  • Minimal unmanaged dependencies, to reduce operational complexity
  • Ease of deployment, able to be used out of the box

Architecture

Vault Architecture Diagram

Normally, Hashicorp recommends using Consul (another one of their tools) as both the storage and high-availability (HA) backend for Vault. This presents a number of challenges:

  • Generating Consul agent certificates and Gossip token
  • Deploying Consul in an autoscaling group along with IAM resources
  • Bootstrapping Consul's ACL system and backing up the master token
  • Keeping Consul single-tenant (to prevent data loss/corruption in Vault)
  • Monitoring and logging of Consul itself
  • Taking periodic Consul snapshots as backup

In order to reduce operational complexity as much as possible, we instead opt for Amazon S3 for Vault's storage backend and AWS DynamoDB for its HA backend. As these are managed services, we can offload much our SLA onto them and focus on maintaining Vault itself. This also loosens our coupling to Consul and simplifies deployment greatly.

Usage

First, build an AMI using the Packer build definition in this repo. This module searches for the most recent version of this AMI.

module "vault" {
  source = "github.com/pbar1/terraform-aws-vault?ref=v2.0.0"

  environment = "test"
  region      = "us-west-2"
  name        = "vault"

  ssh_key_name = "..."
  vpc_id       = "..."
  subnet_ids   = ["...", "...", "..."]
  zone_id      = "..."

  domain_name                 = "vault.example.com"
  acme_registration_email     = "..."
  acme_route53_hosted_zone_id = "..."

  # these must already exist
  ssm_path_datadog_api_key      = "/..." 
  ssm_path_sumologic_access_id  = "/..."
  ssm_path_sumologic_access_key = "/..."

  # these will be created
  ssm_path_vault_recovery_keys_b64 = "/..."
  ssm_path_vault_root_token        = "/..."
}

Requirements

Name Version
terraform >= 0.13

Providers

Name Version
aws n/a
template n/a

Inputs

Name Description Type Default Required
allowed_security_groups List of security groups allowed to access the Vault API. list [] no
ami_account_ids List of AWS account IDs to use when filtering for the Vault AMI list [] no
certificate_arn ARN of the ACM certificate to be used by the ALB. any n/a yes
dogstatsd_tags List of tags to attach to DogStatsD metrics. Written as a raw HCL string string "[\"vault_cluster:vault\"]\n" no
domain_name Domain name of DNS entry to create any n/a yes
dynamodb_read_capacity Read capacity for Vault's DynamoDB storgage backend number 5 no
dynamodb_read_capacity_max Max read capacity for Vault's DynamoDB storgage backend number 20 no
dynamodb_read_scale_target Percentage of current DynamoDB read capacity at which auto scaling triggers number 50 no
dynamodb_write_capacity Write capacity for Vault's DynamoDB storgage backend number 5 no
dynamodb_write_capacity_max Max write capacity for Vault's DynamoDB storgage backend number 20 no
dynamodb_write_scale_target Percentage of current DynamoDB write capacity at which auto scaling triggers number 50 no
ebs_root_volume_delete_on_termination n/a bool true no
ebs_root_volume_device_name The location in which the root volume is mounted. Defaults to /dev/xvda, which is where Amazon Linux 2 mounts its root volume. string "/dev/xvda" no
ebs_root_volume_encrypted n/a bool true no
ebs_root_volume_size n/a number 30 no
ebs_root_volume_type n/a string "gp2" no
enable_cross_zone_load_balancing Enable cross zone load balancing bool true no
enable_termination_protection Enable EC2 instance termination protection bool true no
environment Environment name - valid values are build, dev, staging, and prod any n/a yes
extra_cidr_blocks List of CIDR blocks allowed to access the Vault API. The VPC in which Vault resides is already covered. list [] no
instance_type EC2 instance type for Vault instances string "r5.large" no
internal_lb Whether to make the Vault load balancer internal bool true no
max_instances Maximum number of Vault instances in the auto scaling group number 3 no
min_instances Minimum number of Vault instances in the auto scaling group number 3 no
name Name of the app, service, etc. For example: vault or terraform. No environment or region information, the module will take care of naming for you. any n/a yes
region AWS region name, in the form of us-west-2 and eu-central-1 any n/a yes
spot n/a bool false no
ssh_key_name Name of the SSH keypair to use for the Vault EC2 instances any n/a yes
ssm_path_datadog_api_key Path to the Datadog API key in SSM Parameter Store (Expected to be of type SecureString, encrypted by the default SSM KMS key) any n/a yes
ssm_path_sumologic_access_id Path to the Sumo Logic Access ID in SSM Parameter Store (Expected to be of type String) any n/a yes
ssm_path_sumologic_access_key Path to the Sumo Logic Access Key in SSM Parameter Store (Expected to be of type SecureString, encrypted by the default SSM KMS key) any n/a yes
ssm_path_vault_recovery_keys_b64 Path to store the Vault recovery keys (in base64) in SSM Parameter Store upon initialization string "" no
ssm_path_vault_root_token Path to store the Vault root token in SSM Parameter Store upon initialization string "" no
subnet_ids List of subnet IDs to launch the Vault auto scaling group in list n/a yes
tags Extra tags to add to all resources created by this module map {} no
vault_version Version of Vault to deploy. Will search for a privately-owned AMI that satisfies the condition. any n/a yes
vpc_id ID of the AWS VPC to create the Vault cluster in any n/a yes
zone_id Route53 hosted zone ID to create the DNS entry in (should probably be private) any n/a yes

Outputs

Name Description
ami_id ID of the AMI used to launch the auto scaling group
ami_name Name of the AMI used to launch the auto scaling group
kms_key_id ID of the KMS key that Vault uses for Auto Unseal
name Name of resources created by this module
role_arn ARN of the AWS IAM role that Vault runs as
role_name Name of the AWS IAM role that Vault runs as
ssm_path_vault_recovery_keys_b64 Path in SSM Parameter Store to Vault recovery keys in base64 format
ssm_path_vault_root_token Path in SSM Parameter Store to Vault root token
tags Tags applied to AWS resources created by this module
url URL to reach the Vault cluster at

About

Hashicorp Vault with KMS Auto Unseal, S3 storage, and DynamoDB high availability

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • HCL 60.7%
  • Shell 32.4%
  • Go 6.9%