Skip to content

particuleio/terraform-aws-vault

Repository files navigation

terraform-aws-vault

This module sets up a Vault cluster that can span 2 AWS regions. It makes use of the following AWS features:

  • AWS DynamodDB global tables
  • AWS SecretManager global replication
  • AWS KMS cross region replicas
  • Cross region VPC peering

By default resources are replicated in another region to act as a DR plan. It is possible to not run Vault instances on the other region but just keep the resources replicated.

Features

Vault Backend

Vault backend use DynamodDB plugins which allow HA for storage and nodes.

TLS end to end

This module generates a pki to enable full end to end encryption into the vault instances. Certificates for vault are generated at startup on the instances and all the cluster internal communication are done with TLS

Network Load Balancer

To allow end to end TLS, network load balancer are used in TCP mode. This module supports 2 NLB per region, 1 internal and 1 external.

Health Checks

Health Check by default are done with TCP check, this allow to use the Vault with TLS Client cert verification enabled. This also improve failover but route randomly the Vault request to any node, which then in turn forwards to the cluster leader. This generate east-west traffic across AZ and VPC Peering.

Health checks can also use HTTPS if vault client cert verification is disabled. 2 modes are availabled via the variable vault_routing_policy :

  • all : HTTPS healthcheck with all node Healthy
  • leader-only : HTTPS healthcehck with only leader Healthy

When vault_tls_require_and_verify_client_cert is set, health checks default to TCP.

Route53

Support for private and public hosted zone for split horizon DNS. Register automatically the NLB as alias and sets up health check for DNS failover in case an AWS region is not available.

VPC

VPC peering between the 2 provided VPC is enabled by default, if VPCs are already peered it can be disable with vpc_peering_enabled=false.

⚠️ there is a dependency issue when creating everything from scratch in the example folder. vpc_peering_enabled should be turn to true only after the VPC have been created, or use the -target feature.

AMI

Pariticule build and maintain AMI on AWS region available by default. Please pen an issue if you need us to support another region.

AWS SSM

Instances have SSM enable by default, no need for SSH keys.

Requirements

Name Version
terraform ~> 1.3
aws >= 5.0

Providers

Name Version
aws >= 5.0
aws.secondary >= 5.0

Modules

Name Source Version
pki particuleio/pki/tls ~> 2.0
primary ./modules/vault-region n/a
secondary ./modules/vault-region n/a
secrets particuleio/secretsmanager/aws >= 1.2

Resources

Name Type
aws_dynamodb_table.dynamodb_table resource
aws_iam_instance_profile.vault resource
aws_iam_policy.vault resource
aws_iam_role.vault resource
aws_iam_role_policy_attachment.ssm resource
aws_iam_role_policy_attachment.vault resource
aws_kms_alias.seal resource
aws_kms_alias.seal_secondary resource
aws_kms_key.seal resource
aws_kms_replica_key.seal resource
aws_route.acceptor resource
aws_route.requestor resource
aws_route53_record.private_a resource
aws_route53_record.private_a_secondary resource
aws_route53_record.private_aaaa resource
aws_route53_record.private_aaaa_secondary resource
aws_route53_record.public_a resource
aws_route53_record.public_a_secondary resource
aws_route53_record.public_aaaa resource
aws_route53_record.public_aaaa_secondary resource
aws_security_group_rule.peering resource
aws_security_group_rule.peering_secondary resource
aws_vpc_peering_connection.vault resource
aws_vpc_peering_connection_accepter.vault_secondary resource
aws_vpc_peering_connection_options.accepter resource
aws_vpc_peering_connection_options.requester resource
aws_caller_identity.current data source
aws_dynamodb_table.existing_dynamodb_table_primary data source
aws_dynamodb_table.existing_dynamodb_table_secondary data source
aws_elb_service_account.elb_sa data source
aws_iam_policy_document.ec2_trust_policy data source
aws_iam_policy_document.vault data source
aws_kms_key.existing_kms_seal_key_id data source
aws_region.current data source
aws_region.secondary data source
aws_route53_zone.private data source
aws_route53_zone.public data source
aws_route_tables.vpc data source
aws_route_tables.vpc_secondary data source
aws_vpc.vpc data source
aws_vpc.vpc_secondary data source

Inputs

Name Description Type Default Required
ami_name_regex n/a string null no
ami_owners n/a list(string)
[
"886701765425"
]
no
asg n/a any n/a yes
asg_defaults n/a any
{
"asg_associate_public_ip_address": false,
"desired_capacity": 3,
"disk_size": 20,
"instance_type": "t3a.micro",
"key_name": null,
"max_size": 3,
"min_size": 0,
"tags": {},
"tags_as_map": {},
"vpc_zone_identifier": []
}
no
asg_secondary n/a any n/a yes
cfssl_version n/a string "1.6.4" no
existing_dynamodb_tables use exising dynamodbs tables (useful for recovery)
object({
primary = optional(object({
name = string
}))
secondary = optional(object({
name = string
}))
})
{} no
existing_kms_seal_key_id use existing kms unseal key (useful for recovery) string "" no
name_prefix A name to prefix every created resource with string n/a yes
nlb_defaults n/a any
{
"internal": false,
"ip_address_type": "dualstack",
"listener_port": 443,
"subnets": []
}
no
nlbs n/a any
{
"external": {},
"internal": {
"internal": true
}
}
no
nlbs_secondary n/a any
{
"external": {},
"internal": {
"internal": true
}
}
no
route53_private_zone_name n/a string "" no
route53_zone_name n/a string "" no
tags A map of tags to apply to all resources map(string) {} no
vault_additional_config Additional content to include in the vault configuration file string "" no
vault_additional_userdata Additional content to include in the cloud-init userdata for the EC2 instances string "" no
vault_api_address The address that vault will be accessible at string n/a yes
vault_cert_dir The directory on the OS to store Vault certificates string "/usr/local/etc/vault/tls" no
vault_config_dir The directory on the OS to store the Vault configuration string "/usr/local/etc/vault" no
vault_default_lease_ttl n/a string "192h" no
vault_dns_domain The DNS address that vault will be accessible at string n/a yes
vault_max_lease_ttl n/a string "192h" no
vault_pki_ca_config n/a any {} no
vault_pki_client_certs n/a any
{
"default": {
"subject": {
"common_name": "default-vault-client"
},
"usages": [
"client_auth",
"key_encipherement",
"digital_signature"
]
}
}
no
vault_prometheus_retention_time n/a string "6h" no
vault_routing_policy n/a string "all" no
vault_tls_min_version n/a string "tls12" no
vault_tls_require_and_verify_client_cert n/a bool false no
vault_version n/a string "1.14.2" no
vpc_id The ID of the VPC to use string n/a yes
vpc_peering_enabled n/a bool true no
vpc_secondary_id The ID of the VPC to use string n/a yes

Outputs

Name Description
dynamodb n/a
primary n/a
secondary n/a
secrets n/a
vault_dns_domain n/a
vault_pki n/a