No description
  • HCL 69.8%
  • Smarty 30.2%
Find a file
2026-03-30 08:02:30 -04:00
.github rollback change 2026-02-20 09:56:22 +00:00
docs Apply suggestions from code review 2026-02-17 10:41:30 +00:00
examples/default Merge remote-tracking branch 'origin/main' into feat/add-8201-listener 2026-03-12 17:27:17 +00:00
templates Add wildcard to AWS partition in ARN validation 2026-02-16 11:33:13 +00:00
.copywrite.hcl Exclude yaml files from copywrite 2024-11-06 11:07:50 +00:00
.env.local.example chore(template): merge template changes 🆙 2025-11-01 00:31:34 +00:00
.gitignore chore(template): merge template changes 🆙 2025-04-01 00:31:21 +00:00
.terraform-docs.yml chore(template): merge template changes 🆙 2025-04-01 00:31:21 +00:00
CHANGELOG.md releaase 0.3.0 2026-02-20 09:22:17 +00:00
compute.tf Add optional Network Load Balancer listener for Vault cluster on port 8201 2026-02-13 18:00:46 +00:00
data.tf Merge branch 'main' into issuexyz-abc-issues 2026-01-30 07:54:23 +00:00
iam.tf update to enable ssm 2026-01-29 13:25:09 +00:00
lb.tf fix: update health check path for vault cluster listener to include drsecondarycode 2026-02-27 12:50:29 +00:00
LICENSE [COMPLIANCE] Update Copyright and License Headers (Batch 1 of 1) 2025-12-08 11:32:14 +00:00
locals.tf Merge branch 'main' into issuexyz-abc-issues 2025-12-09 11:21:24 +00:00
network-security.tf refactor: remove security group id support for cluster port access 2026-02-23 17:56:36 +00:00
outputs.tf Add optional Network Load Balancer listener for Vault cluster on port 8201 2026-02-13 18:00:46 +00:00
README.md chore: update README 2026-03-12 17:28:07 +00:00
route53.tf Add VPC filter for route 53 zone lookup if it's a private zone (#49) 2026-03-30 08:02:30 -04:00
Taskfile.yml releasenotes generation 2026-02-20 09:38:15 +00:00
terraform.tf revert change to allow for bump to >= 6.0 and those customers comfortable with current deprecation warnings 2026-02-02 10:09:19 +00:00
variables.tf fix: add validation for asg_health_check_type when enabling vault cluster port listener 2026-02-26 21:58:22 +00:00

Vault Enterprise HVD on AWS EC2

Terraform module aligned with HashiCorp Validated Designs (HVD) to deploy Vault Enterprise on Amazon Web Services (AWS) using EC2 instances. This module deploys Vault Enterprise with integrated storage.

HVD Vault Architecture diagram

Prerequisites

This module requires the following to already be in place in AWS:

  • A VPC with the following:
  • A dedicated KMS Key to support auto-unseal
  • TLS certificate with intermediate certs, certificate private key and CA certificate (required for privately signed cert)
  • Access to Secrets Manager for initial secrets such as product license and TLS certificate material
  • (Optional) A Route53 Hosted Zone if using create_route53_vault_dns_record
  • AWS API credentials for Terraform to deploy:
    • AWS Autoscaling Group, Launch Template and Placement Group
    • AWS IAM Roles and Instance Profile
    • AWS Load Balancer, Listener and Target Group
    • AWS Security Group and Security Group Rules

Supported operating systems

This module supports the following Linux distributions via the ec2_os_distro variable:

Distribution Value AMI source
Ubuntu 22.04 LTS ubuntu (default) Canonical
RHEL 9 rhel Red Hat
Amazon Linux 2023 al2023 Amazon
CentOS centos Custom AMI required

Note: For CentOS deployments, you must provide a custom AMI ID via vm_image_id.

Architecture support

This module supports both x86_64 (amd64) and ARM64 (aarch64) instances. The install script automatically detects the system architecture and downloads the appropriate Vault binary.

Deployment

Upon first deployment, Vault servers will auto-join and form a fresh cluster. The cluster will be in an uninitialized, sealed state. An operator must then connect to the cluster to initialize Vault. If auto-unseal is used via AWS KMS, the Vault nodes will automatically unseal upon initialization. If the Shamir seal is used, the operator must manually unseal each node

Next steps

Deployment options

see Deployment customizations

Examples

Example deployment scenarios can be found in the examples directory of this repo. These examples cover multiple capabilities of the module and are meant to serve as a starting point for operators.

Troubleshooting

see Deployment Troubleshooting

Module support

This open source software is maintained by the HashiCorp Technical Field Organization, independently of our enterprise products. While our Support Engineering team provides dedicated support for our enterprise offerings, this open source software is not included.

  • For help using this open source software, please engage your account team.
  • To report bugs/issues with this open source software, please open them directly against this code repository using the GitHub issues feature.

Please note that there is no official Service Level Agreement (SLA) for support of this software as a HashiCorp customer. This software falls under the definition of Community Software/Versions in your Agreement. We appreciate your understanding and collaboration in improving our open source projects.

Requirements

Name Version
aws >= 5.0

Providers

Name Version
aws >= 5.0

Resources

Name Type
aws_autoscaling_group.main resource
aws_iam_instance_profile.vault_iam_instance_profile resource
aws_iam_role.vault_iam_role resource
aws_iam_role_policy.main resource
aws_iam_role_policy_attachment.aws_ssm resource
aws_launch_template.main resource
aws_lb.vault_lb resource
aws_lb_listener.vault_api resource
aws_lb_listener.vault_cluster resource
aws_lb_target_group.vault_api resource
aws_lb_target_group.vault_cluster resource
aws_placement_group.main resource
aws_route53_record.alias_record resource
aws_security_group.lb resource
aws_security_group.main resource
aws_security_group_rule.egress_all resource
aws_security_group_rule.egress_lb resource
aws_security_group_rule.egress_lb_cluster resource
aws_security_group_rule.ingress_ssh_cidr resource
aws_security_group_rule.ingress_ssh_sg_ids resource
aws_security_group_rule.ingress_vault_api resource
aws_security_group_rule.ingress_vault_api_cidr resource
aws_security_group_rule.ingress_vault_api_lb resource
aws_security_group_rule.ingress_vault_api_lb_cidr resource
aws_security_group_rule.ingress_vault_api_lb_sg_ids resource
aws_security_group_rule.ingress_vault_api_sg_ids resource
aws_security_group_rule.ingress_vault_cluster resource
aws_security_group_rule.ingress_vault_cluster_lb resource
aws_security_group_rule.ingress_vault_cluster_lb_cidr resource
aws_ami.al2023 data source
aws_ami.rhel data source
aws_ami.selected data source
aws_ami.ubuntu data source
aws_kms_key.vault_unseal data source
aws_partition.current data source
aws_region.current data source
aws_route53_zone.vault data source
aws_vpc.main data source

Inputs

Name Description Type Default Required
net_lb_subnet_ids The subnet IDs in the VPC to host the load balancer in. list(string) n/a yes
net_vault_subnet_ids (required) The subnet IDs in the VPC to host the Vault servers in list(string) n/a yes
net_vpc_id (required) The VPC ID to host the cluster in string n/a yes
sm_vault_license_arn The ARN of the license secret in AWS Secrets Manager string n/a yes
sm_vault_tls_ca_bundle (required) The ARN of the CA bundle secret in AWS Secrets Manager, Secret should be stored as a base64-encoded string. Secret type should be plaintext. string n/a yes
sm_vault_tls_cert_arn (required) The ARN of the signed TLS certificate secret in AWS Secrets Manager, Secret should be stored as a base64-encoded string. Secret type should be plaintext. string n/a yes
sm_vault_tls_cert_key_arn (required) The ARN of the signed TLS certificate's private key secret in AWS Secrets Manager, Secret should be stored as a base64-encoded string. Secret type should be plaintext. string n/a yes
vault_fqdn Fully qualified domain name to use for joining peer nodes and optionally DNS string n/a yes
vault_seal_awskms_key_arn The KMS key ID to use for Vault auto-unseal string n/a yes
additional_package_names List of additional repository package names to install set(string) [] no
asg_health_check_grace_period The amount of time to expire before the autoscaling group terminates an unhealthy node is terminated string 600 no
asg_health_check_type Defines how autoscaling health checking is done string "EC2" no
asg_node_count The number of nodes to create in the pool. number 6 no
create_route53_vault_dns_record Boolean to create Route53 Alias Record for vault_hostname resolving to Load Balancer DNS name. If true, route53_vault_hosted_zone_name is also required. bool false no
custom_startup_script_template Filename of a custom Vault Install script template to use in place of the built-in user_data script. The file must exist within a directory named './templates' in your current working directory. string null no
ec2_allow_ssm Boolean to attach the AmazonSSMManagedInstanceCore policy to the Vault instance role (aws_iam_role.vault_iam_role), allowing the SSM agent (if present) to function. bool false no
ec2_os_distro Linux OS distribution type for EC2 instance. Choose from al2023, ubuntu, rhel, centos. string "ubuntu" no
enable_cross_zone_load_balancing Enable cross-zone load balancing for the Network Load Balancer. bool false no
enable_vault_cluster_port_listener Enable Network Load Balancer listener on port 8201 (Vault cluster port). When enabled, creates an additional listener and target group for the cluster port. bool false no
friendly_name_prefix Name prefix to use when naming cloud resources string "vault" no
health_check_deregistration_delay Amount time for Elastic Load Balancing to wait before changing the state of a deregistering target from draining to unused. The range is 0-3600 seconds. number 15 no
health_check_interval Approximate amount of time, in seconds, between health checks of an individual target. The range is 5-300. number 5 no
health_check_timeout Amount of time, in seconds, during which no response from a target means a failed health check. The range is 2120 seconds. number 3 no
iam_role_path Path for IAM entities string "/" no
iam_role_permissions_boundary_arn The ARN of the policy that is used to set the permissions boundary for the role string null no
load_balancing_scheme Type of load balancer to use (INTERNAL, EXTERNAL, or NONE) string "INTERNAL" no
net_ingress_lb_cidr_blocks List of CIDR blocks to allow API access to Vault via Load Balancer. list(string) [] no
net_ingress_lb_cluster_cidr_blocks List of CIDR blocks to allow cluster port (8201) access to Vault via Load Balancer. Only used when enable_vault_cluster_port_listener is true. Required when the cluster port listener is enabled. list(string) null no
net_ingress_lb_security_group_ids List of security group IDs to allow API access to Vault via Load Balancer. list(string) [] no
net_ingress_ssh_cidr_blocks List of CIDR blocks to allow SSH access to Vault instances. list(string) [] no
net_ingress_ssh_security_group_ids List of security group IDs to allow SSH access to Vault instances. list(string) [] no
net_ingress_vault_cidr_blocks List of CIDR blocks to allow API access to Vault instances. list(string) [] no
net_ingress_vault_security_group_ids List of security group IDs to allow API access to Vault instances. list(string) [] no
resource_tags A map containing tags to assign to all resources map(string) {} no
route53_vault_hosted_zone_is_private Boolean indicating if route53_vault_hosted_zone_name is a private hosted zone. bool false no
route53_vault_hosted_zone_name Route53 Hosted Zone name to create vault_hostname Alias record in. Required if create_route53_vault_dns_record is true. string null no
stickiness_enabled Enable sticky sessions by client IP address for the load balancer. bool true no
systemd_dir Path to systemd directory for unit files string "/lib/systemd/system" no
vault_default_lease_ttl_duration The default lease TTL expressed as a time duration in hours, minutes and/or seconds (e.g. 4h30m10s) string "1h" no
vault_dir_bin The bin directory for the Vault binary string "/usr/bin" no
vault_dir_config The directory for Vault server configuration file(s) string "/etc/vault.d" no
vault_dir_home The home directory for the Vault system user string "/opt/vault" no
vault_dir_logs Path to hold Vault file audit device logs string "/var/log/vault" no
vault_disable_mlock Disable the server from executing the mlock syscall bool true no
vault_enable_ui Enable the Vault UI bool true no
vault_group_name Name of group to own Vault files and processes string "vault" no
vault_health_endpoints The status codes to return when querying Vault's sys/health endpoint map(string)
{
"activecode": "200",
"drsecondarycode": "472",
"performancestandbycode": "473",
"perfstandbyok": "true",
"sealedcode": "503",
"standbycode": "429",
"standbyok": "true",
"uninitcode": "200"
}
no
vault_max_lease_ttl_duration The max lease TTL expressed as a time duration in hours, minutes and/or seconds (e.g. 4h30m10s) string "768h" no
vault_plugin_urls (optional list) List of Vault plugin fully qualified URLs (example ["https://releases.hashicorp.com/terraform-provider-oraclepaas/1.5.3/terraform-provider-oraclepaas_1.5.3_linux_amd64.zip"] for deployment to Vault plugins directory) list(string) [] no
vault_port_api The port the Vault API will listen on string "8200" no
vault_port_cluster The port the Vault cluster port will listen on string "8201" no
vault_raft_auto_join_tag A map containing a single tag which will be used by Vault to join other nodes to the cluster. If left blank, the module will use the first entry in tags map(string) null no
vault_raft_performance_multiplier Raft performance multiplier value. Defaults to 5, which is the default Vault value. number 5 no
vault_seal_awskms_region The region the KMS is in. Leave null if in the same region as everything else string null no
vault_seal_type The seal type to use for Vault string "awskms" no
vault_snapshots_bucket_arn The ARN of the S3 bucket for auto-snapshots string null no
vault_telemetry_config Enable telemetry for Vault map(string) null no
vault_tls_disable_client_certs Disable client authentication for the Vault listener. Must be enabled when tls auth method is used. bool true no
vault_tls_require_and_verify_client_cert Require a client to present a client certificate that validates against system CAs bool false no
vault_user_name Name of system user to own Vault files and processes string "vault" no
vault_version The version of Vault to use string "1.17.3+ent" no
vm_boot_disk_configuration The disk (EBS) configuration to use for the Vault nodes
object(
{
volume_type = string
volume_size = number
delete_on_termination = bool
encrypted = bool
}
)
{
"delete_on_termination": true,
"encrypted": true,
"volume_size": 30,
"volume_type": "gp3"
}
no
vm_image_id Custom AMI ID for EC2 launch template. If specified, value of ec2_os_distro must coincide with this custom AMI OS distro. string null no
vm_instance_type The machine type to use for the Vault nodes string "m7i.large" no
vm_key_pair_name The machine SSH key pair name to use for the cluster nodes string null no
vm_vault_audit_disk_configuration The disk (EBS) configuration to use for the Vault nodes
object(
{
volume_type = string
volume_size = number
delete_on_termination = bool
encrypted = bool
}
)
{
"delete_on_termination": true,
"encrypted": true,
"volume_size": 50,
"volume_type": "gp3"
}
no
vm_vault_data_disk_configuration The disk (EBS) configuration to use for the Vault nodes
object(
{
volume_type = string
volume_size = number
volume_iops = number
volume_throughput = number
delete_on_termination = bool
encrypted = bool
}
)
{
"delete_on_termination": true,
"encrypted": true,
"volume_iops": 3000,
"volume_size": 100,
"volume_throughput": 125,
"volume_type": "gp3"
}
no

Outputs

Name Description
vault_cli_config Environment variables to configure the Vault CLI
vault_cluster_listener_arn ARN of the Vault cluster port (8201) listener
vault_cluster_target_group_arn ARN of the Vault cluster port (8201) target group
vault_load_balancer_name The DNS name of the load balancer.
vault_load_balancer_security_group_id The ID of the load balancer security group. Allow ingress to this group on 8200 (or specified var.vault_port_api) to access Vault through the LB.