Compare commits

..

No commits in common. "multidevice" and "master" have entirely different histories.

55 changed files with 19 additions and 2354 deletions

22
.gitignore vendored
View File

@ -6,9 +6,6 @@
*.tfstate *.tfstate
*.tfstate.* *.tfstate.*
# Backend config public ignore
backend.hcl
# Crash log files # Crash log files
crash.log crash.log
crash.*.log crash.*.log
@ -36,3 +33,22 @@ override.tf.json
# Ignore CLI configuration files # Ignore CLI configuration files
.terraformrc .terraformrc
terraform.rc terraform.rc
# ---> Ansible
*.retry
# ---> Linux
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*

View File

@ -1,45 +0,0 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/aws" {
version = "5.39.0"
constraints = ">= 3.0.0, >= 3.15.0, >= 4.0.0"
hashes = [
"h1:isoOv/JipnnPD3j8Df6XwGU1i4egjlygrgBv0RfsZ7g=",
"zh:01e405306470ed784bc9d38dbaeff394bd2c0f7d58e5592c5d0165c87d84e4b0",
"zh:0328fbd42a91e50601318d2c364a80ebd3b4e5755c85df6fafd2fed80bc54598",
"zh:042420e08d1ef1e2ed51c394539a6db27e031bedb9eaa19db9ccaf9fa93b9b36",
"zh:47dee460b2c06676e16f5070fff71e5e9eb24b74bcd7b4f7b53eea8ebd3c972f",
"zh:49c34f21a05bf5150e3a0a87c997fcd831ae81e3f2df86191e2fdd231525b585",
"zh:4d5a98726216e260296bdc13e562179a743ef4738b65154da697c2d9e9eb5c9b",
"zh:7fb08af13c868d8d20519b373eeb6707a0cea078495123e28e71727993474f53",
"zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
"zh:a57e7e44f79991e55be02f2b147a433b5a2690188be0510409b79e9b00e37009",
"zh:aeeb120cd6245f67ae3e52e13005c2dc1f091787564dd6b39ee6c05b2c239c53",
"zh:b5d39c6e55d0355f9fd93a802355166bd27edaf9acb753b190562474447674b2",
"zh:cfcc1922b380db5f90fd5ffc1e49fb9f316e6c41de4603f65b05d20ace72e15e",
"zh:d221d8cea09229743d2647944c0420a8e9e5d7e3ff088b30cbce85a8b051dcab",
"zh:dccca0239df6d39686b0f0947040b3c0e1270a4bab268c402b742cf5a7759296",
"zh:ef0564fb70e8210db9bf472f662e093a1a1f204a1c1cb46467231be1a78882f3",
]
}
provider "registry.terraform.io/hashicorp/tls" {
version = "4.0.5"
constraints = ">= 3.0.0"
hashes = [
"h1:gthwVUwv0WLGMwx7GR/N6XyIONzrSJJaXD6dDJB4FlY=",
"zh:01cfb11cb74654c003f6d4e32bbef8f5969ee2856394a96d127da4949c65153e",
"zh:0472ea1574026aa1e8ca82bb6df2c40cd0478e9336b7a8a64e652119a2fa4f32",
"zh:1a8ddba2b1550c5d02003ea5d6cdda2eef6870ece86c5619f33edd699c9dc14b",
"zh:1e3bb505c000adb12cdf60af5b08f0ed68bc3955b0d4d4a126db5ca4d429eb4a",
"zh:6636401b2463c25e03e68a6b786acf91a311c78444b1dc4f97c539f9f78de22a",
"zh:76858f9d8b460e7b2a338c477671d07286b0d287fd2d2e3214030ae8f61dd56e",
"zh:a13b69fb43cb8746793b3069c4d897bb18f454290b496f19d03c3387d1c9a2dc",
"zh:a90ca81bb9bb509063b736842250ecff0f886a91baae8de65c8430168001dad9",
"zh:c4de401395936e41234f1956ebadbd2ed9f414e6908f27d578614aaa529870d4",
"zh:c657e121af8fde19964482997f0de2d5173217274f6997e16389e7707ed8ece8",
"zh:d68b07a67fbd604c38ec9733069fbf23441436fecf554de6c75c032f82e1ef19",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
]
}

35
main.tf
View File

@ -1,35 +0,0 @@
module "networking" {
source = "./modules/networking"
azs = var.azs
shared_san = var.shared_san
resource_name_prefix = var.resource_name_prefix
}
module "vault-starter" {
source = "./modules/matts-vault-starter"
vault_version = var.vault_version
node_count = var.node_count
instance_type = var.instance_type
# user_supplied_iam_role_name = var.user_supplied_iam_role_name
user_supplied_ami_id = var.user_supplied_ami_id
# user_supplied_kms_key_arn = var.user_supplied_kms_key_arn
# user_supplied_userdata_path = var.user_supplied_userdata_path
lb_type = var.lb_type
lb_health_check_path = var.lb_health_check_path
allowed_inbound_cidrs_lb = var.allowed_inbound_cidrs_lb
allowed_inbound_cidrs_ssh = var.allowed_inbound_cidrs_ssh
kms_key_deletion_window = var.kms_key_deletion_window
ssl_policy = var.ssl_policy
# === Supplied by ./modules/networking ===
depends_on = [module.networking]
private_subnet_ids = module.networking.private_subnet_ids
secrets_manager_arn = module.networking.secrets_manager_arn
vpc_id = module.networking.vpc_id
lb_certificate_arn = module.networking.lb_certificate_arn
leader_tls_servername = module.networking.leader_tls_servername
}

View File

@ -1,89 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
data "aws_region" "current" {}
module "iam" {
source = "./modules/iam"
aws_region = data.aws_region.current.name
kms_key_arn = module.kms.kms_key_arn
permissions_boundary = var.permissions_boundary
resource_name_prefix = var.resource_name_prefix
secrets_manager_arn = var.secrets_manager_arn
user_supplied_iam_role_name = var.user_supplied_iam_role_name
}
module "kms" {
source = "./modules/kms"
common_tags = var.common_tags
kms_key_deletion_window = var.kms_key_deletion_window
resource_name_prefix = var.resource_name_prefix
user_supplied_kms_key_arn = var.user_supplied_kms_key_arn
}
module "loadbalancer" {
source = "./modules/load_balancer"
allowed_inbound_cidrs = var.allowed_inbound_cidrs_lb
common_tags = var.common_tags
lb_certificate_arn = var.lb_certificate_arn
lb_deregistration_delay = var.lb_deregistration_delay
lb_health_check_path = var.lb_health_check_path
lb_subnets = var.private_subnet_ids
lb_type = var.lb_type
resource_name_prefix = var.resource_name_prefix
ssl_policy = var.ssl_policy
vault_sg_id = module.vm.vault_sg_id
vpc_id = module.networking.vpc_id
}
module "networking" {
source = "./modules/networking"
vpc_id = var.vpc_id
}
module "user_data" {
source = "./modules/user_data"
aws_region = data.aws_region.current.name
kms_key_arn = module.kms.kms_key_arn
leader_tls_servername = var.leader_tls_servername
resource_name_prefix = var.resource_name_prefix
secrets_manager_arn = var.secrets_manager_arn
user_supplied_userdata_path = var.user_supplied_userdata_path
vault_version = var.vault_version
}
locals {
vault_target_group_arns = concat(
[module.loadbalancer.vault_target_group_arn],
var.additional_lb_target_groups,
)
}
module "vm" {
source = "./modules/vm"
allowed_inbound_cidrs = var.allowed_inbound_cidrs_lb
allowed_inbound_cidrs_ssh = var.allowed_inbound_cidrs_ssh
aws_iam_instance_profile = module.iam.aws_iam_instance_profile
common_tags = var.common_tags
instance_type = var.instance_type
key_name = var.key_name
lb_type = var.lb_type
node_count = var.node_count
resource_name_prefix = var.resource_name_prefix
userdata_script = module.user_data.vault_userdata_base64_encoded
user_supplied_ami_id = var.user_supplied_ami_id
vault_lb_sg_id = module.loadbalancer.vault_lb_sg_id
vault_subnets = var.private_subnet_ids
vault_target_group_arns = local.vault_target_group_arns
vpc_id = module.networking.vpc_id
}

View File

@ -1,21 +0,0 @@
# AWS IAM Module
## Required variables
* `aws_region` - Specific AWS region being used
* `kms_key_arn` - KMS Key ARN used for Vault auto-unseal permissions
* `resource_name_prefix` - Resource name prefix used for tagging and naming AWS resources
* `secrets_manager_arn` - Secrets manager ARN where TLS cert info is stored
## Example usage
```hcl
module "iam" {
source = "./modules/iam"
aws_region = data.aws_region.current.name
kms_key_arn = var.kms_key_arn
resource_name_prefix = var.resource_name_prefix
secrets_manager_arn = var.secrets_manager_arn
}
```

View File

@ -1,120 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
resource "aws_iam_instance_profile" "vault" {
name_prefix = "${var.resource_name_prefix}-vault"
role = var.user_supplied_iam_role_name != null ? var.user_supplied_iam_role_name : aws_iam_role.instance_role[0].name
}
resource "aws_iam_role" "instance_role" {
count = var.user_supplied_iam_role_name != null ? 0 : 1
name_prefix = "${var.resource_name_prefix}-vault"
permissions_boundary = var.permissions_boundary
assume_role_policy = data.aws_iam_policy_document.instance_role.json
}
data "aws_iam_policy_document" "instance_role" {
statement {
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy" "cloud_auto_join" {
count = var.user_supplied_iam_role_name != null ? 0 : 1
name = "${var.resource_name_prefix}-vault-auto-join"
role = aws_iam_role.instance_role[0].id
policy = data.aws_iam_policy_document.cloud_auto_join.json
}
data "aws_iam_policy_document" "cloud_auto_join" {
statement {
effect = "Allow"
actions = [
"ec2:DescribeInstances",
]
resources = ["*"]
}
}
resource "aws_iam_role_policy" "auto_unseal" {
count = var.user_supplied_iam_role_name != null ? 0 : 1
name = "${var.resource_name_prefix}-vault-auto-unseal"
role = aws_iam_role.instance_role[0].id
policy = data.aws_iam_policy_document.auto_unseal.json
}
data "aws_iam_policy_document" "auto_unseal" {
statement {
effect = "Allow"
actions = [
"kms:DescribeKey",
"kms:Encrypt",
"kms:Decrypt",
]
resources = [
var.kms_key_arn,
]
}
}
resource "aws_iam_role_policy" "session_manager" {
count = var.user_supplied_iam_role_name != null ? 0 : 1
name = "${var.resource_name_prefix}-vault-ssm"
role = aws_iam_role.instance_role[0].id
policy = data.aws_iam_policy_document.session_manager.json
}
data "aws_iam_policy_document" "session_manager" {
statement {
effect = "Allow"
actions = [
"ssm:UpdateInstanceInformation",
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
]
resources = [
"*",
]
}
}
resource "aws_iam_role_policy" "secrets_manager" {
count = var.user_supplied_iam_role_name != null ? 0 : 1
name = "${var.resource_name_prefix}-vault-secrets-manager"
role = aws_iam_role.instance_role[0].id
policy = data.aws_iam_policy_document.secrets_manager.json
}
data "aws_iam_policy_document" "secrets_manager" {
statement {
effect = "Allow"
actions = [
"secretsmanager:GetSecretValue",
]
resources = [
var.secrets_manager_arn,
]
}
}

View File

@ -1,10 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "aws_iam_instance_profile" {
value = aws_iam_instance_profile.vault.name
}

View File

@ -1,38 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "aws_region" {
type = string
description = "Specific AWS region being used"
}
variable "kms_key_arn" {
type = string
description = "KMS Key ARN used for Vault auto-unseal permissions"
}
variable "permissions_boundary" {
description = "(Optional) IAM Managed Policy to serve as permissions boundary for IAM Role"
type = string
default = null
}
variable "resource_name_prefix" {
type = string
description = "Resource name prefix used for tagging and naming AWS resources"
}
variable "secrets_manager_arn" {
type = string
description = "Secrets manager ARN where TLS cert info is stored"
}
variable "user_supplied_iam_role_name" {
type = string
description = "(OPTIONAL) User-provided IAM role name. This will be used for the instance profile provided to the AWS launch configuration. The minimum permissions must match the defaults generated by the IAM submodule for cloud auto-join and auto-unseal."
default = null
}

View File

@ -1,17 +0,0 @@
# AWS KMS Module
## Required variables
* `kms_key_deletion_window` - Duration in days after which the key is deleted after destruction of the resource (must be between 7 and 30 days)
* `resource_name_prefix` - Resource name prefix used for tagging and naming AWS resources
## Example usage
```hcl
module "kms" {
source = "./modules/kms"
kms_key_deletion_window = var.kms_key_deletion_window
resource_name_prefix = var.resource_name_prefix
}
```

View File

@ -1,20 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
resource "aws_kms_key" "vault" {
count = var.user_supplied_kms_key_arn != null ? 0 : 1
deletion_window_in_days = var.kms_key_deletion_window
description = "AWS KMS Customer-managed key used for Vault auto-unseal and encryption"
enable_key_rotation = false
is_enabled = true
key_usage = "ENCRYPT_DECRYPT"
tags = merge(
{ Name = "${var.resource_name_prefix}-vault-key" },
var.common_tags,
)
}

View File

@ -1,10 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "kms_key_arn" {
value = var.user_supplied_kms_key_arn != null ? var.user_supplied_kms_key_arn : aws_kms_key.vault[0].arn
}

View File

@ -1,28 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "common_tags" {
type = map(string)
description = "(Optional) Map of common tags for all taggable AWS resources."
default = {}
}
variable "kms_key_deletion_window" {
type = number
description = "Duration in days after which the key is deleted after destruction of the resource (must be between 7 and 30 days)."
}
variable "resource_name_prefix" {
type = string
description = "Resource name prefix used for tagging and naming AWS resources"
}
variable "user_supplied_kms_key_arn" {
type = string
description = "(OPTIONAL) User-provided KMS key ARN. Providing this will disable the KMS submodule from generating a KMS key used for Vault auto-unseal"
default = null
}

View File

@ -1,29 +0,0 @@
# AWS Load Balancer Module
## Required variables
* `lb_certificate_arn` - ARN of TLS certificate imported into ACM for use with LB listener
* `lb_health_check_path` - The endpoint to check for Vault's health status
* `lb_subnets` - Subnets where load balancer will be deployed
* `lb_type` - The type of load balancer to provision: network or application
* `resource_name_prefix` - Resource name prefix used for tagging and naming AWS resources
* `ssl_policy` - SSL policy to use on LB listener
* `vault_sg_id` - Security group ID of Vault cluster
* `vpc_id` - VPC ID where Vault will be deployed
## Example usage
```hcl
module "loadbalancer" {
source = "./modules/load_balancer"
lb_certificate_arn = var.lb_certificate_arn
lb_health_check_path = var.lb_health_check_path
lb_subnets = var.vault_subnet_ids
lb_type = var.lb_type
resource_name_prefix = var.resource_name_prefix
ssl_policy = var.ssl_policy
vault_sg_id = var.vault_sg_id
vpc_id = var.vpc_id
}
```

View File

@ -1,95 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
resource "aws_security_group" "vault_lb" {
count = var.lb_type == "application" ? 1 : 0
description = "Security group for the application load balancer"
name = "${var.resource_name_prefix}-vault-lb-sg"
vpc_id = var.vpc_id
tags = merge(
{ Name = "${var.resource_name_prefix}-vault-lb-sg" },
var.common_tags,
)
}
resource "aws_security_group_rule" "vault_lb_inbound" {
count = var.lb_type == "application" && var.allowed_inbound_cidrs != null ? 1 : 0
description = "Allow specified CIDRs access to load balancer on port 8200"
security_group_id = aws_security_group.vault_lb[0].id
type = "ingress"
from_port = 8200
to_port = 8200
protocol = "tcp"
cidr_blocks = var.allowed_inbound_cidrs
}
resource "aws_security_group_rule" "vault_lb_outbound" {
count = var.lb_type == "application" ? 1 : 0
description = "Allow outbound traffic from load balancer to Vault nodes on port 8200"
security_group_id = aws_security_group.vault_lb[0].id
type = "egress"
from_port = 8200
to_port = 8200
protocol = "tcp"
source_security_group_id = var.vault_sg_id
}
locals {
lb_security_groups = var.lb_type == "network" ? null : [aws_security_group.vault_lb[0].id]
lb_protocol = var.lb_type == "network" ? "TCP" : "HTTPS"
}
resource "aws_lb" "vault_lb" {
name = "${var.resource_name_prefix}-vault-lb"
internal = true
load_balancer_type = var.lb_type
subnets = var.lb_subnets
security_groups = local.lb_security_groups
drop_invalid_header_fields = var.lb_type == "application" ? true : null
tags = merge(
{ Name = "${var.resource_name_prefix}-vault-lb" },
var.common_tags,
)
}
resource "aws_lb_target_group" "vault" {
name = "${var.resource_name_prefix}-vault-tg"
deregistration_delay = var.lb_deregistration_delay
target_type = "instance"
port = 8200
protocol = local.lb_protocol
vpc_id = var.vpc_id
health_check {
healthy_threshold = 2
unhealthy_threshold = 2
protocol = "HTTPS"
port = "traffic-port"
path = var.lb_health_check_path
interval = 30
}
tags = merge(
{ Name = "${var.resource_name_prefix}-vault-tg" },
var.common_tags,
)
}
resource "aws_lb_listener" "vault" {
load_balancer_arn = aws_lb.vault_lb.id
port = 8200
protocol = local.lb_protocol
ssl_policy = local.lb_protocol == "HTTPS" ? var.ssl_policy : null
certificate_arn = local.lb_protocol == "HTTPS" ? var.lb_certificate_arn : null
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.vault.arn
}
}

View File

@ -1,31 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "vault_lb_arn" {
description = "ARN of Vault load balancer"
value = aws_lb.vault_lb.arn
}
output "vault_lb_dns_name" {
description = "DNS name of Vault load balancer"
value = aws_lb.vault_lb.dns_name
}
output "vault_lb_sg_id" {
description = "Security group ID of Vault load balancer"
value = var.lb_type == "application" ? aws_security_group.vault_lb[0].id : null
}
output "vault_lb_zone_id" {
description = "Zone ID of Vault load balancer"
value = aws_lb.vault_lb.zone_id
}
output "vault_target_group_arn" {
description = "Target group ARN to register Vault nodes with"
value = aws_lb_target_group.vault.arn
}

View File

@ -1,64 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "allowed_inbound_cidrs" {
type = list(string)
description = "List of CIDR blocks to permit inbound traffic from to load balancer"
default = null
}
variable "common_tags" {
type = map(string)
description = "(Optional) Map of common tags for all taggable AWS resources."
default = {}
}
variable "lb_certificate_arn" {
type = string
description = "ARN of TLS certificate imported into ACM for use with LB listener"
}
variable "lb_deregistration_delay" {
type = string
description = "Amount time, in seconds, for Vault LB target group to wait before changing the state of a deregistering target from draining to unused."
default = 300
}
variable "lb_health_check_path" {
type = string
description = "The endpoint to check for Vault's health status."
}
variable "lb_subnets" {
type = list(string)
description = "Subnets where load balancer will be deployed"
}
variable "lb_type" {
description = "The type of load balancer to provison: network or application."
type = string
}
variable "resource_name_prefix" {
type = string
description = "Resource name prefix used for tagging and naming AWS resources"
}
variable "ssl_policy" {
type = string
description = "SSL policy to use on LB listener"
}
variable "vault_sg_id" {
type = string
description = "Security group ID of Vault cluster"
}
variable "vpc_id" {
type = string
description = "VPC ID where Vault will be deployed"
}

View File

@ -1,15 +0,0 @@
# AWS Networking Module
## Required variables
* `vpc_id` - VPC ID where Vault will be deployed
## Example usage
```hcl
module "networking" {
source = "./modules/networking"
vpc_id = var.vpc_id
}
```

View File

@ -1,10 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
data "aws_vpc" "selected" {
id = var.vpc_id
}

View File

@ -1,10 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "vpc_id" {
value = data.aws_vpc.selected.id
}

View File

@ -1,11 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "vpc_id" {
type = string
description = "VPC ID where Vault will be deployed"
}

View File

@ -1,25 +0,0 @@
# AWS User Data Module
## Required variables
* `aws_region` - AWS region where Vault is being deployed
* `kms_key_arn` - KMS Key ARN used for Vault auto-unseal
* `leader_tls_servername` - One of the shared DNS SAN used to create the certs use for mTLS
* `resource_name_prefix` - Resource name prefix used for tagging and naming AWS resources
* `secrets_manager_arn` - Secrets manager ARN where TLS cert info is stored
* `vault_version` - Vault version
## Example usage
```hcl
module "user_data" {
source = "./modules/user_data"
aws_region = data.aws_region.current.name
kms_key_arn = var.kms_key_arn
leader_tls_servername = var.leader_tls_servername
resource_name_prefix = var.resource_name_prefix
secrets_manager_arn = var.secrets_manager_arn
vault_version = var.vault_version
}
```

View File

@ -1,22 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
locals {
vault_user_data = base64encode(
templatefile(
"${path.module}/templates/install_vault.sh.tpl",
{
region = var.aws_region
name = var.resource_name_prefix
vault_version = var.vault_version
kms_key_arn = var.kms_key_arn
secrets_manager_arn = var.secrets_manager_arn
leader_tls_servername = var.leader_tls_servername
}
)
)
}

View File

@ -1,10 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "vault_userdata_base64_encoded" {
value = base64encode(local.vault_user_data)
}

View File

@ -1,83 +0,0 @@
#!/usr/bin/env bash
imds_token=$( curl -Ss -H "X-aws-ec2-metadata-token-ttl-seconds: 30" -XPUT 169.254.169.254/latest/api/token )
instance_id=$( curl -Ss -H "X-aws-ec2-metadata-token: $imds_token" 169.254.169.254/latest/meta-data/instance-id )
local_ipv4=$( curl -Ss -H "X-aws-ec2-metadata-token: $imds_token" 169.254.169.254/latest/meta-data/local-ipv4 )
# install package
curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add -
apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
apt-get update
apt-get install -y vault=${vault_version}-* awscli jq
echo "Configuring system time"
timedatectl set-timezone UTC
# removing any default installation files from /opt/vault/tls/
rm -rf /opt/vault/tls/*
# /opt/vault/tls should be readable by all users of the system
chmod 0755 /opt/vault/tls
# vault-key.pem should be readable by the vault group only
touch /opt/vault/tls/vault-key.pem
chown root:vault /opt/vault/tls/vault-key.pem
chmod 0640 /opt/vault/tls/vault-key.pem
secret_result=$(aws secretsmanager get-secret-value --secret-id ${secrets_manager_arn} --region ${region} --output text --query SecretString)
jq -r .vault_cert <<< "$secret_result" | base64 -d > /opt/vault/tls/vault-cert.pem
jq -r .vault_ca <<< "$secret_result" | base64 -d > /opt/vault/tls/vault-ca.pem
jq -r .vault_pk <<< "$secret_result" | base64 -d > /opt/vault/tls/vault-key.pem
cat << EOF > /etc/vault.d/vault.hcl
ui = true
disable_mlock = true
storage "raft" {
path = "/opt/vault/data"
node_id = "$instance_id"
retry_join {
auto_join = "provider=aws region=${region} tag_key=${name}-vault tag_value=server"
auto_join_scheme = "https"
leader_tls_servername = "${leader_tls_servername}"
leader_ca_cert_file = "/opt/vault/tls/vault-ca.pem"
leader_client_cert_file = "/opt/vault/tls/vault-cert.pem"
leader_client_key_file = "/opt/vault/tls/vault-key.pem"
}
}
cluster_addr = "https://$local_ipv4:8201"
api_addr = "https://$local_ipv4:8200"
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = false
tls_cert_file = "/opt/vault/tls/vault-cert.pem"
tls_key_file = "/opt/vault/tls/vault-key.pem"
tls_client_ca_file = "/opt/vault/tls/vault-ca.pem"
}
seal "awskms" {
region = "${region}"
kms_key_id = "${kms_key_arn}"
}
EOF
# vault.hcl should be readable by the vault group only
chown root:root /etc/vault.d
chown root:vault /etc/vault.d/vault.hcl
chmod 640 /etc/vault.d/vault.hcl
systemctl enable vault
systemctl start vault
echo "Setup Vault profile"
cat <<PROFILE | sudo tee /etc/profile.d/vault.sh
export VAULT_ADDR="https://127.0.0.1:8200"
export VAULT_CACERT="/opt/vault/tls/vault-ca.pem"
PROFILE

View File

@ -1,43 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "aws_region" {
type = string
description = "AWS region where Vault is being deployed"
}
variable "kms_key_arn" {
type = string
description = "KMS Key ARN used for Vault auto-unseal"
}
variable "leader_tls_servername" {
type = string
description = "One of the shared DNS SAN used to create the certs use for mTLS"
default = "vault.great-hyperlobic-omnicognate-neutron-wrangler.space"
}
variable "resource_name_prefix" {
type = string
description = "Resource name prefix used for tagging and naming AWS resources"
}
variable "secrets_manager_arn" {
type = string
description = "Secrets manager ARN where TLS cert info is stored"
}
variable "user_supplied_userdata_path" {
type = string
description = "File path to custom userdata script being supplied by the user"
default = null
}
variable "vault_version" {
type = string
description = "Vault version"
}

View File

@ -1,30 +0,0 @@
# AWS VM Module
## Required variables
* `aws_iam_instance_profile` - IAM instance profile name to use for Vault instances
* `lb_type` - The type of load balancer being used to front Vault instances
* `resource_name_prefix` - Resource name prefix used for tagging and naming AWS resources
* `userdata_script` - Userdata script for EC2 instance. Must be base64-encoded.
* `vault_lb_sg_id` - Security group ID of Vault load balancer (will not be read if you are using a network load balancer)
* `vault_subnets` - Private subnets where Vault will be deployed
* `vault_target_group_arn` - Target group ARN to register Vault nodes with
* `vpc_id` - VPC ID where Vault will be deployed
## Example usage
```hcl
module "vm" {
source = "./modules/vm"
aws_iam_instance_profile = var.aws_iam_instance_profile
instance_type = var.instance_type
lb_type = var.lb_type
resource_name_prefix = var.resource_name_prefix
userdata_script = var.userdata_script
vault_lb_sg_id = var.vault_lb_sg_id
vault_subnets = var.vault_subnet_ids
vault_target_group_arn = var.vault_target_group_arn
vpc_id = var.vpc_id
}
```

View File

@ -1,3 +0,0 @@
data "aws_ssm_parameter" "latest_ami" {
name = "/aws/service/debian/release/12/latest/amd64"
}

View File

@ -1,205 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
data "aws_ami" "ubuntu" {
count = var.user_supplied_ami_id != null ? 0 : 1
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_security_group" "vault" {
name = "${var.resource_name_prefix}-vault"
vpc_id = var.vpc_id
tags = merge(
{ Name = "${var.resource_name_prefix}-vault-sg" },
var.common_tags,
)
}
resource "aws_security_group_rule" "vault_internal_api" {
description = "Allow Vault nodes to reach other on port 8200 for API"
security_group_id = aws_security_group.vault.id
type = "ingress"
from_port = 8200
to_port = 8200
protocol = "tcp"
self = true
}
resource "aws_security_group_rule" "vault_internal_raft" {
description = "Allow Vault nodes to communicate on port 8201 for replication traffic, request forwarding, and Raft gossip"
security_group_id = aws_security_group.vault.id
type = "ingress"
from_port = 8201
to_port = 8201
protocol = "tcp"
self = true
}
# The following data source gets used if the user has
# specified a network load balancer.
# This will lock down the EC2 instance security group to
# just the subnets that the load balancer spans
# (which are the private subnets the Vault instances use)
data "aws_subnet" "subnet" {
count = length(var.vault_subnets)
id = var.vault_subnets[count.index]
}
locals {
subnet_cidr_blocks = [for s in data.aws_subnet.subnet : s.cidr_block]
}
resource "aws_security_group_rule" "vault_network_lb_inbound" {
count = var.lb_type == "network" ? 1 : 0
description = "Allow load balancer to reach Vault nodes on port 8200"
security_group_id = aws_security_group.vault.id
type = "ingress"
from_port = 8200
to_port = 8200
protocol = "tcp"
cidr_blocks = local.subnet_cidr_blocks
}
resource "aws_security_group_rule" "vault_application_lb_inbound" {
count = var.lb_type == "application" ? 1 : 0
description = "Allow load balancer to reach Vault nodes on port 8200"
security_group_id = aws_security_group.vault.id
type = "ingress"
from_port = 8200
to_port = 8200
protocol = "tcp"
source_security_group_id = var.vault_lb_sg_id
}
resource "aws_security_group_rule" "vault_network_lb_ingress" {
count = var.lb_type == "network" && var.allowed_inbound_cidrs != null ? 1 : 0
description = "Allow specified CIDRs access to load balancer and nodes on port 8200"
security_group_id = aws_security_group.vault.id
type = "ingress"
from_port = 8200
to_port = 8200
protocol = "tcp"
cidr_blocks = var.allowed_inbound_cidrs
}
resource "aws_security_group_rule" "vault_ssh_inbound" {
count = var.allowed_inbound_cidrs_ssh != null ? 1 : 0
description = "Allow specified CIDRs SSH access to Vault nodes"
security_group_id = aws_security_group.vault.id
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = var.allowed_inbound_cidrs_ssh
}
resource "aws_security_group_rule" "vault_outbound" {
description = "Allow Vault nodes to send outbound traffic"
security_group_id = aws_security_group.vault.id
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_launch_template" "vault" {
name = "${var.resource_name_prefix}-vault"
image_id = var.user_supplied_ami_id != null ? var.user_supplied_ami_id : data.aws_ssm_parameter.latest_ami.value
instance_type = var.instance_type
key_name = var.key_name != null ? var.key_name : null
user_data = var.userdata_script
vpc_security_group_ids = [
aws_security_group.vault.id,
]
block_device_mappings {
device_name = "/dev/sda1"
ebs {
volume_type = "gp3"
volume_size = 100
throughput = 150
iops = 3000
delete_on_termination = true
}
}
iam_instance_profile {
name = var.aws_iam_instance_profile
}
metadata_options {
http_endpoint = "enabled"
http_tokens = "required"
}
}
resource "aws_autoscaling_group" "vault" {
name = "${var.resource_name_prefix}-vault"
min_size = var.node_count
max_size = var.node_count + 2
desired_capacity = var.node_count
vpc_zone_identifier = var.vault_subnets
target_group_arns = var.vault_target_group_arns
launch_template {
id = aws_launch_template.vault.id
version = "$Latest"
}
enabled_metrics = [
"GroupDesiredCapacity",
"GroupInServiceCapacity",
"GroupPendingCapacity",
"GroupMinSize",
"GroupMaxSize",
"GroupInServiceInstances",
"GroupPendingInstances",
"GroupStandbyInstances",
"GroupStandbyCapacity",
"GroupTerminatingCapacity",
"GroupTerminatingInstances",
"GroupTotalCapacity",
"GroupTotalInstances"
]
tag {
key = "Name"
value = "${var.resource_name_prefix}-vault-server"
propagate_at_launch = true
}
dynamic "tag" {
for_each = var.common_tags
content {
key = tag.key
value = tag.value
propagate_at_launch = true
}
}
tag {
key = "${var.resource_name_prefix}-vault"
value = "server"
propagate_at_launch = true
}
}

View File

@ -1,21 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "asg_name" {
description = "Name of autoscaling group"
value = aws_autoscaling_group.vault.name
}
output "launch_template_id" {
description = "ID of launch template for Vault autoscaling group"
value = aws_launch_template.vault.id
}
output "vault_sg_id" {
description = "Security group ID of Vault cluster"
value = aws_security_group.vault.id
}

View File

@ -1,86 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "allowed_inbound_cidrs" {
type = list(string)
description = "List of CIDR blocks to permit inbound traffic from to load balancer"
default = null
}
variable "allowed_inbound_cidrs_ssh" {
type = list(string)
description = "List of CIDR blocks to give SSH access to Vault nodes"
default = null
}
variable "aws_iam_instance_profile" {
type = string
description = "IAM instance profile name to use for Vault instances"
}
variable "common_tags" {
type = map(string)
description = "(Optional) Map of common tags for all taggable AWS resources."
default = {}
}
variable "instance_type" {
type = string
description = "EC2 instance type"
}
variable "key_name" {
type = string
description = "key pair to use for SSH access to instance"
}
variable "lb_type" {
description = "The type of load balancer to provision: network or application."
type = string
}
variable "node_count" {
type = number
description = "Number of Vault nodes to deploy in ASG"
default = 2
}
variable "resource_name_prefix" {
type = string
description = "Resource name prefix used for tagging and naming AWS resources"
}
variable "userdata_script" {
type = string
description = "Userdata script for EC2 instance"
}
variable "user_supplied_ami_id" {
type = string
description = "AMI ID to use with Vault instances"
default = null
}
variable "vault_lb_sg_id" {
type = string
description = "Security group ID of Vault load balancer"
}
variable "vault_subnets" {
type = list(string)
description = "Private subnets where Vault will be deployed"
}
variable "vault_target_group_arns" {
type = list(string)
description = "Target group ARN(s) to register Vault nodes with"
}
variable "vpc_id" {
type = string
description = "VPC ID where Vault will be deployed"
}

View File

@ -1,71 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "asg_name" {
value = module.vm.asg_name
}
output "kms_key_arn" {
value = module.kms.kms_key_arn
}
output "launch_template_id" {
value = module.vm.launch_template_id
}
output "vault_lb_dns_name" {
description = "DNS name of Vault load balancer"
value = module.loadbalancer.vault_lb_dns_name
}
output "vault_lb_zone_id" {
description = "Zone ID of Vault load balancer"
value = module.loadbalancer.vault_lb_zone_id
}
output "vault_lb_arn" {
description = "ARN of Vault load balancer"
value = module.loadbalancer.vault_lb_arn
}
output "vault_target_group_arn" {
description = "Target group ARN to register Vault nodes with"
value = module.loadbalancer.vault_target_group_arn
}
output "vault_sg_id" {
description = "Security group ID of Vault cluster"
value = module.vm.vault_sg_id
}
# supplied by ./modules/vps-secrets
# output "lb_certificate_arn" {
# description = "ARN of ACM cert to use with Vault LB listener"
# value = module.secrets.lb_certificate_arn
# }
# output "leader_tls_servername" {
# description = "Shared SAN that will be given to the Vault nodes configuration for use as leader_tls_servername"
# value = module.secrets.leader_tls_servername
# }
# output "private_subnet_ids" {
# description = "Private subnet IDs"
# value = module.vpc.private_subnet_ids
# }
# output "secrets_manager_arn" {
# description = "ARN of secrets_manager secret"
# value = module.secrets.secrets_manager_arn
# }
# output "vpc_id" {
# description = "The ID of the VPC"
# value = module.vpc.vpc_id
# }

View File

@ -1,194 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "resource_name_prefix" {
type = string
description = "Prefix for resource names in VPC infrastructure"
default = "vault"
}
variable "key_name" {
type = string
default = null
description = "(Optional) key pair to use for SSH access to instance"
}
variable "lb_deregistration_delay" {
type = string
description = "Amount time, in seconds, for Vault LB target group to wait before changing the state of a deregistering target from draining to unused."
default = 300
}
variable "permissions_boundary" {
description = "(Optional) IAM Managed Policy to serve as permissions boundary for created IAM Roles"
type = string
default = null
}
variable "vault_version" {
type = string
default = "1.15.5"
description = "Vault version"
}
variable "vpc_id" {
type = string
description = "VPC ID where Vault will be deployed"
}
variable "aws_region" {
description = "AWS region to deploy resources into"
type = string
default = "us-east-1"
}
# === General ===
variable "common_tags" {
type = map(string)
description = "(Optional) Map of common tags for all taggable AWS resources."
default = {
"project" = "vault"
}
}
variable "tags" {
type = map(string)
description = "Tags for VPC resources"
default = {
"Terraform" = "true"
"Environment" = "dev"
"Project" = "vault"
}
}
# === config ===
variable "instance_type" {
type = string
description = "The instance type to use for Vault nodes"
default = "t3.micro"
}
variable "additional_lb_target_groups" {
type = list(string)
description = "(Optional) List of load balancer target groups to associate with the Vault cluster. These target groups are _in addition_ to the LB target group this module provisions by default."
default = []
}
variable "lb_type" {
description = "The type of load balancer to provision; network or application."
type = string
default = "application"
validation {
condition = contains(["application", "network"], var.lb_type)
error_message = "The variable lb_type must be one of: application, network."
}
}
variable "node_count" {
type = number
description = "**Required** Number of Vault nodes to deploy in ASG"
default = 2
}
# === user supplied variables ===
variable "user_supplied_ami_id" {
type = string
description = "**Required** User-provided AMI ID to use with Vault instances. If you provide this value, please ensure it will work with the default userdata script (assumes latest version of Ubuntu LTS). Otherwise, please provide your own userdata script using the user_supplied_userdata_path variable."
default = null
}
variable "user_supplied_iam_role_name" {
type = string
description = "**Required** User-provided IAM role name. This will be used for the instance profile provided to the AWS launch configuration. The minimum permissions must match the defaults generated by the IAM submodule for cloud auto-join and auto-unseal."
default = null
}
variable "user_supplied_kms_key_arn" {
type = string
description = "**Required** User-provided KMS key ARN. Providing this will disable the KMS submodule from generating a KMS key used for Vault auto-unseal"
default = null
}
variable "user_supplied_userdata_path" {
type = string
description = "**Required** File path to custom userdata script being supplied by the user"
default = null
}
# === VPC ===
variable "azs" {
description = "availability zones to use in AWS region"
type = list(string)
default = [
"eu-north-1a",
"eu-north-1b",
]
}
variable "allowed_inbound_cidrs_lb" {
type = list(string)
description = "**Required** CIDR blocks to allow inbound traffic to the load balancer"
default = ["0.0.0.0/0"]
}
variable "allowed_inbound_cidrs_ssh" {
type = list(string)
description = "**Required** CIDR blocks to allow inbound SSH traffic to the Vault instances"
default = ["0.0.0.0/0"]
}
# === Certs ===
variable "ssl_policy" {
type = string
description = "**Required** The SSL policy to use for the load balancer"
default = "ELBSecurityPolicy-TLS-1-2-2017-01"
}
variable "lb_health_check_path" {
type = string
description = "The endpoint to check for Vault's health status."
default = "/v1/sys/health?activecode=200&standbycode=200&sealedcode=200&uninitcode=200"
}
variable "kms_key_deletion_window" {
type = number
default = 7
description = "**Required**Duration in days after which the key is deleted after destruction of the resource (must be between 7 and 30 days)."
}
# === Supplied by ./modules/vpc-secrets ===
variable "secrets_manager_arn" {
type = string
description = "**Supplied by module/vpc-secrets** **Required** Secrets manager ARN where TLS cert info is stored"
}
variable "leader_tls_servername" {
type = string
description = "**Supplied by module/vpc-secrets** **Required** One of the shared DNS SAN used to create the certs use for mTLS"
default = "vault.great-hyperlobic-omnicognate-neutron-wrangler.space"
}
variable "lb_certificate_arn" {
type = string
description = "**Supplied by module/vpc-secrets** **Required** ARN of TLS certificate imported into ACM for use with LB listener"
}
# variable "vpc_id" {
# type = string
# description = "**Supplied by module/vpc-secrets** **Required** VPC ID where Vault will be deployed"
# }
variable "private_subnet_ids" {
type = list(string)
description = "**Supplied by module/vpc-secrets** **Required** Subnet IDs to deploy Vault into"
}

View File

@ -1,14 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
terraform {
required_version = ">= 1.7.0"
required_providers {
aws = ">= 4.0.0"
}
}

View File

@ -1,33 +0,0 @@
# EXAMPLE: Prerequisite Configuration (VPC and Secrets)
## About This Example
In order to deploy the Vault module, you must have an AWS VPC that
meets the requirements [listed in the main
README](../../README.md#how-to-use-this-module) along with TLS certs that can be
used with the Vault nodes and load balancer. If you do not already have these
resources, you can use the code provided in this directory to provision them.
## How to Use This Module
1. Ensure your AWS credentials are [configured
correctly](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)
2. Configure required (and optional if desired) variables
3. Run `terraform init` and `terraform apply`
## Required variables
* `resource_name_prefix` - string value to use as base for resource names
## Note
- The default AWS region is `us-east-1` (as specified by the `aws_region`
variable). You may change this if wish to deploy Vault elsewhere, but please
be sure to change the value for the `azs` variable as well and specify the
appropriate availability zones for your new region.
### Security Note:
- The [Terraform State](https://www.terraform.io/docs/language/state/index.html)
produced by this code has sensitive data (cert private keys) stored in it.
Please secure your Terraform state using the [recommendations listed
here](https://www.terraform.io/docs/language/state/sensitive-data.html#recommendations).

View File

@ -1,3 +0,0 @@
data "aws_ssm_parameter" "latest_ami" {
name = "/aws/service/debian/release/12/latest/amd64"
}

View File

@ -1,51 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
provider "aws" {
region = var.aws_region
}
module "vpc" {
source = "./modules/aws-vpc/"
azs = var.azs
common_tags = var.tags
resource_name_prefix = var.resource_name_prefix
}
module "secrets" {
source = "./modules/vpc-secrets/"
shared_san = var.shared_san
resource_name_prefix = var.resource_name_prefix
}
module "bastion" {
source = "Guimove/bastion/aws"
bastion_ami = var.use_latest_ami ? data.aws_ssm_parameter.latest_ami.value : var.user_supplied_ami_id
bucket_name = var.bastion_bucket_name
region = var.aws_region
vpc_id = module.vpc.vpc_id
is_lb_private = "false"
bastion_host_key_pair = "Vault"
create_dns_record = "true"
hosted_zone_id = var.hosted_zone_id
bastion_record_name = var.bastion_record_name
bastion_iam_policy_name = "VaultBastionHostPolicy"
elb_subnets = [
"subnet-id1a",
"subnet-id1b"
]
auto_scaling_group_subnets = [
"subnet-id1a",
"subnet-id1b"
]
tags = merge(
{ "Name" = "${var.resource_name_prefix}-bastion"},
var.common_tags
)
}

View File

@ -1,21 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~>5.5.0"
name = "${var.resource_name_prefix}-vault"
cidr = var.vpc_cidr
azs = var.azs
enable_nat_gateway = true
one_nat_gateway_per_az = true
private_subnets = var.private_subnet_cidrs
public_subnets = var.public_subnet_cidrs
tags = var.common_tags
}

View File

@ -1,17 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "private_subnet_ids" {
description = "Private subnet IDs"
value = module.vpc.private_subnets
}
output "vpc_id" {
description = "The ID of the VPC"
value = module.vpc.vpc_id
}

View File

@ -1,49 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "azs" {
description = "availability zones to use in AWS region"
type = list(string)
default = ["eu-north-1a", "eu-north-1b"]
}
variable "common_tags" {
type = map(string)
description = "Tags for VPC resources"
}
variable "resource_name_prefix" {
description = "Prefix for resource names (e.g. \"prod\")"
type = string
}
variable "private_subnet_cidrs" {
description = "CIDR blocks for private subnets"
type = list(string)
default = [
"10.0.0.0/19",
"10.0.32.0/19",
# "10.0.64.0/19",
]
}
variable "public_subnet_cidrs" {
description = "CIDR blocks for public subnets"
type = list(string)
default = [
"10.0.128.0/20",
"10.0.144.0/20",
# "10.0.160.0/20",
]
}
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
default = "10.0.0.0/16"
}

View File

@ -1,9 +0,0 @@
locals {
name_prefix = var.bastion_launch_template_name
security_group = join("", flatten([aws_security_group.bastion_host_security_group[*].id, var.bastion_security_group_id]))
// the compact() function checks for null values and gets rid of them
// the length is a check to ensure we dont have an empty array, as an empty array would throw an error for the cidr_block argument
ipv4_cidr_block = length(compact(data.aws_subnet.subnets[*].cidr_block)) == 0 ? null : concat(data.aws_subnet.subnets[*].cidr_block, var.cidrs)
ipv6_cidr_block = length(compact(data.aws_subnet.subnets[*].ipv6_cidr_block)) == 0 ? null : concat(data.aws_subnet.subnets[*].ipv6_cidr_block, var.ipv6_cidrs)
}

View File

@ -1,89 +0,0 @@
# Load Balancer
#
# HTTPS is terminated at the load balancer. The load balancer will then communicate
# with the targets over HTTP. The Targets (vault instances) are in a private
# subnet, cut off from any external access. This means that they're still perfectly
# secure AND we don't incur the overhead of extra TLS handshakes and encryption.
## Application Load Balancer
resource "aws_lb" "alb" {
// Can't give it a full name_prefix due to 32 character limit on LBs
// and the fact that Terraform adds a 26 character random bit to the end.
// https://github.com/terraform-providers/terraform-provider-aws/issues/1666
name_prefix = "vault-"
internal = var.private_mode
load_balancer_type = "application"
security_groups = [aws_security_group.load_balancer.id]
subnets = aws_subnet.public.*.id
idle_timeout = 60
ip_address_type = var.private_mode ? "ipv4" : "dualstack"
tags = merge(
{ "Name" = "${var.main_project_tag}-alb"},
{ "Project" = var.main_project_tag }
)
}
## Target Group
resource "aws_lb_target_group" "alb_targets" {
name_prefix = "vault-"
port = 8200
protocol = "HTTPS"
vpc_id = aws_vpc.vault.id
deregistration_delay = 30
target_type = "instance"
health_check {
enabled = true
interval = 10
path = "/v1/sys/health" // the Vault API health port
protocol = "HTTPS"
timeout = 5
healthy_threshold = 3
unhealthy_threshold = 3
matcher = "200"
}
tags = merge(
{ "Name" = "${var.main_project_tag}-tg"},
{ "Project" = var.main_project_tag }
)
}
## Load Balancer Listeners
### Redirect to HTTPS
resource "aws_lb_listener" "alb_http_redirect" {
load_balancer_arn = aws_lb.alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
// For information on the below reserved keywords
// https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#rule-action-types
redirect {
host = "#{host}"
path = "/#{path}"
port = 443
protocol = "HTTPS"
query = "#{query}"
status_code = "HTTP_301"
}
}
}
### HTTPS
resource "aws_lb_listener" "alb_https" {
load_balancer_arn = aws_lb.alb.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-FS-2018-06" // Enable Forward Secrecy
certificate_arn = data.aws_acm_certificate.vault_alb_cert.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.alb_targets.arn
}
}

View File

@ -1,23 +0,0 @@
# === General ===
variable "resource_name_prefix" {
type = string
description = "Resource name prefix used for tagging and naming AWS resources"
default = "prod-vault"
}
variable "common_tags" {
type = map(string)
description = "(Optional) Map of common tags for all taggable AWS resources."
default = {
"project" = "vault"
}
}
# === Config ===
variable "key_name" {
description = "(Optional) key pair to use for SSH access to instance"
type = string
default = "Vault"
}

View File

@ -1,12 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
resource "aws_acm_certificate" "vault" {
private_key = tls_private_key.server.private_key_pem
certificate_body = tls_locally_signed_cert.server.cert_pem
certificate_chain = tls_self_signed_cert.ca.cert_pem
}

View File

@ -1,20 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
resource "aws_secretsmanager_secret" "tls" {
name = "${var.resource_name_prefix}-tls-secret"
description = "contains TLS certs and private keys"
kms_key_id = var.kms_key_id
recovery_window_in_days = var.recovery_window
tags = var.tags
}
resource "aws_secretsmanager_secret_version" "tls" {
secret_id = aws_secretsmanager_secret.tls.id
secret_string = local.secret
}

View File

@ -1,21 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "lb_certificate_arn" {
description = "ARN of ACM cert to use with Vault LB listener"
value = aws_acm_certificate.vault.arn
}
output "leader_tls_servername" {
description = "Shared SAN that will be given to the Vault nodes configuration for use as leader_tls_servername"
value = var.shared_san
}
output "secrets_manager_arn" {
description = "ARN of secrets_manager secret"
value = aws_secretsmanager_secret.tls.arn
}

View File

@ -1,95 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
# Generate a private key so you can create a CA cert with it.
resource "tls_private_key" "ca" {
algorithm = "RSA"
rsa_bits = 2048
}
# Create a CA cert with the private key you just generated.
resource "tls_self_signed_cert" "ca" {
private_key_pem = tls_private_key.ca.private_key_pem
subject {
common_name = "ca.vault.server.com"
}
validity_period_hours = 720 # 30 days
allowed_uses = [
"cert_signing",
"crl_signing",
]
is_ca_certificate = true
# provisioner "local-exec" {
# command = "echo '${tls_self_signed_cert.ca.cert_pem}' > ./vault-ca.pem"
# }
}
# Generate another private key. This one will be used
# To create the certs on your Vault nodes
resource "tls_private_key" "server" {
algorithm = "RSA"
rsa_bits = 2048
# provisioner "local-exec" {
# command = "echo '${tls_private_key.server.private_key_pem}' > ./vault-key.pem"
# }
}
resource "tls_cert_request" "server" {
private_key_pem = tls_private_key.server.private_key_pem
subject {
common_name = var.shared_san
}
dns_names = [
var.shared_san,
"localhost",
]
ip_addresses = [
"127.0.0.1",
]
}
resource "tls_locally_signed_cert" "server" {
cert_request_pem = tls_cert_request.server.cert_request_pem
ca_private_key_pem = tls_private_key.ca.private_key_pem
ca_cert_pem = tls_self_signed_cert.ca.cert_pem
validity_period_hours = 720 # 30 days
allowed_uses = [
"client_auth",
"digital_signature",
"key_agreement",
"key_encipherment",
"server_auth",
]
provisioner "local-exec" {
command = "echo '${tls_locally_signed_cert.server.cert_pem}' > ./vault-crt.pem"
}
}
locals {
tls_data = {
vault_ca = base64encode(tls_self_signed_cert.ca.cert_pem)
vault_cert = base64encode(tls_locally_signed_cert.server.cert_pem)
vault_pk = base64encode(tls_private_key.server.private_key_pem)
}
}
locals {
secret = jsonencode(local.tls_data)
}

View File

@ -1,38 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "kms_key_id" {
type = string
description = "Specifies the ARN or ID of the AWS KMS customer master key (CMK) to be used to encrypt the secret values in the versions stored in this secret. If you don't specify this value, then Secrets Manager defaults to using the AWS account's default CMK (the one named aws/secretsmanager"
default = null
}
variable "recovery_window" {
type = number
description = "Specifies the number of days that AWS Secrets Manager waits before it can delete the secret"
default = 0
}
variable "resource_name_prefix" {
type = string
description = "Prefix for resource names (e.g. \"prod\")"
}
# variable related to TLS cert generation
variable "shared_san" {
type = string
description = "This is a shared server name that the certs for all Vault nodes contain. This is the same value you will supply as input to the Vault installation module for the leader_tls_servername variable."
}
variable "tags" {
type = map(string)
description = "Tags for secrets manager secret"
default = {
Vault = "tls-data"
}
}

View File

@ -1,33 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
output "lb_certificate_arn" {
description = "ARN of ACM cert to use with Vault LB listener"
value = module.secrets.lb_certificate_arn
}
output "leader_tls_servername" {
description = "Shared SAN that will be given to the Vault nodes configuration for use as leader_tls_servername"
value = module.secrets.leader_tls_servername
}
output "private_subnet_ids" {
description = "Private subnet IDs"
value = module.vpc.private_subnet_ids
}
output "secrets_manager_arn" {
description = "ARN of secrets_manager secret"
value = module.secrets.secrets_manager_arn
}
output "vpc_id" {
description = "The ID of the VPC"
value = module.vpc.vpc_id
}

View File

@ -1,96 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
variable "aws_region" {
description = "AWS region to deploy resources into"
type = string
default = "eu-north-1"
}
variable "azs" {
description = "availability zones to use in AWS region"
type = list(string)
}
variable "shared_san" {
description = "This is a shared server name that the certs for all Vault nodes contain. This is the same value you will supply as input to the Vault installation module for the leader_tls_servername variable."
type = string
default = "vault.great-hyperlobic-omnicognate-neutron-wrangler.space"
}
variable "tags" {
description = "Tags for VPC resources"
type = map(string)
default = {}
}
variable "resource_name_prefix" {
description = "Resource name prefix used for tagging and naming AWS resources"
type = string
default = "prod"
}
# === Bastion ===
variable "bastion_bucket_name" {
description = "Bucket name where the bastion will store the logs"
type = string
default = "omnicognate-vault-bastion-access-logs"
}
variable "create_dns_record" {
description = "True or false?"
type = bool
default = true
}
variable "hosted_zone_id" {
description = "Name of the hosted zone where we'll register the bastion DNS name"
type = string
default = "vault.great-hyperlobic-omnicognate-neutron-wrangler.space"
}
variable "bastion_record_name" {
description = ""
type = string
default = "vault.vault.great-hyperlobic-omnicognate-neutron-wrangler.space"
}
variable "common_tags" {
type = map(string)
description = "(Optional) Map of common tags for all taggable AWS resources."
default = {
"project" = "vault"
}
}
variable "use_latest_ami" {
description = "Use the latest AMI for bastion?"
type = bool
default = true
}
variable "user_supplied_ami_id" {
description = "User-provided AMI ID to use with bastion."
type = string
default = "ami-0506d6d51f1916a96"
}
variable "bastion_instance_type" {
description = "The instance type to use for the bastion"
type = string
default = "t3.micro"
}
variable "key_name" {
description = "(Optional) key pair to use for SSH access to instance"
type = string
default = "Vault"
}

View File

@ -1,15 +0,0 @@
/**
* Copyright © 2014-2022 HashiCorp, Inc.
*
* This Source Code is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
terraform {
required_version = ">= 1.2.1"
required_providers {
aws = ">= 3.0.0"
tls = ">= 3.0.0"
}
}

View File

@ -1,35 +0,0 @@
# output "lb_certificate_arn" {
# description = "ARN of ACM cert to use with Vault LB listener"
# value = module.networking.lb_certificate_arn
# }
# output "leader_tls_servername" {
# description = "Shared SAN that will be given to the Vault nodes configuration for use as leader_tls_servername"
# value = module.networking.leader_tls_servername
# }
# output "private_subnet_ids" {
# description = "Private subnet IDs"
# value = module.networking.private_subnet_ids
# }
# output "secrets_manager_arn" {
# description = "ARN of secrets_manager secret"
# value = module.networking.secrets_manager_arn
# }
# output "vpc_id" {
# description = "The ID of the VPC"
# value = module.networking.vpc_id
# }
output "role_arn" {
description = "The ARN of the role"
value = var.role_arn
}
output "key_name" {
description = "The name of the key"
value = var.key_name
}

View File

@ -1,22 +0,0 @@
terraform {
backend "s3" {
# PROVIDE THIS KEY ... FILE ISOLATION
key = "vault-prod/terraform.tfstate"
# PROVIDE THIS KEY ... FILE ISOLATION
}
required_version = ">= 1.7.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0.0"
}
}
}
provider "aws" {
region = var.aws_region
# using aws-vault to assume a role
assume_role {
duration = "1h"
role_arn = var.role_arn
}
}

View File

@ -1,164 +0,0 @@
# === General ===
variable "resource_name_prefix" {
type = string
description = "Resource name prefix used for tagging and naming AWS resources"
default = "prod"
}
variable "vault_version" {
type = string
description = "Vault version"
default = "1.15.5"
}
variable "aws_region" {
type = string
description = "AWS region where Vault will be deployed"
default = "eu-north-1"
}
variable "role_arn" {
type = string
description = "The assumed role to use for this project."
}
variable "key_name" {
description = "(Optional) key pair to use for SSH access to instance"
type = string
default = "Vault"
}
variable "common_tags" {
type = map(string)
description = "(Optional) Map of common tags for all taggable AWS resources."
default = {
"project" = "vault"
}
}
# === config ===
variable "instance_type" {
type = string
description = "The instance type to use for Vault nodes"
default = "t3.micro"
}
variable "shared_san" {
type = string
description = "This is a shared server name that the certs for all Vault nodes contain. This is the same value you will supply as input to the Vault installation module for the leader_tls_servername variable."
}
variable "lb_type" {
description = "The type of load balancer to provision; network or application."
type = string
default = "application"
validation {
condition = contains(["application", "network"], var.lb_type)
error_message = "The variable lb_type must be one of: application, network."
}
}
variable "node_count" {
type = number
description = "**Required** Number of Vault nodes to deploy in ASG"
default = 2
}
# === user supplied variables ===
variable "user_supplied_ami_id" {
type = string
description = "**Optional** User-provided AMI ID to use with Vault instances. If you provide this value, please ensure it will work with the default userdata script (assumes latest version of Ubuntu LTS). Otherwise, please provide your own userdata script using the user_supplied_userdata_path variable."
default = "ami-0506d6d51f1916a96"
}
# variable "user_supplied_iam_role_name" {
# type = string
# description = "**Optional** User-provided IAM role name. This will be used for the instance profile provided to the AWS launch configuration. The minimum permissions must match the defaults generated by the IAM submodule for cloud auto-join and auto-unseal."
# default = null
# }
variable "user_supplied_kms_key_arn" {
type = string
description = "**Optional** User-provided KMS key ARN. Providing this will disable the KMS submodule from generating a KMS key used for Vault auto-unseal"
default = null
}
# variable "user_supplied_userdata_path" {
# type = string
# description = "**Optional** File path to custom userdata script being supplied by the user"
# default = null
# }
# === VPC ===
variable "azs" {
description = "availability zones to use in AWS region"
type = list(string)
default = [
"eu-north-1a",
"eu-north-1b",
]
}
variable "allowed_inbound_cidrs_lb" {
type = list(string)
description = "**Required** CIDR blocks to allow inbound traffic to the load balancer"
default = ["0.0.0.0/0"]
}
variable "allowed_inbound_cidrs_ssh" {
type = list(string)
description = "**Required** CIDR blocks to allow inbound SSH traffic to the Vault instances"
default = ["0.0.0.0/0"]
}
# === Certs ===
variable "ssl_policy" {
type = string
description = "**Required** The SSL policy to use for the load balancer"
default = "ELBSecurityPolicy-TLS-1-2-2017-01"
}
variable "lb_health_check_path" {
type = string
description = "The endpoint to check for Vault's health status."
default = "/v1/sys/health?activecode=200&standbycode=200&sealedcode=200&uninitcode=200"
}
variable "kms_key_deletion_window" {
type = number
default = 7
description = "**Required**Duration in days after which the key is deleted after destruction of the resource (must be between 7 and 30 days)."
}
# === Supplied by ./modules/networking ===
# variable "secrets_manager_arn" {
# type = string
# description = "**Supplied by module/networking** **Required** Secrets manager ARN where TLS cert info is stored"
# }
variable "leader_tls_servername" {
type = string
description = "**Supplied by module/networking** **Required** One of the shared DNS SAN used to create the certs use for mTLS"
}
# variable "lb_certificate_arn" {
# type = string
# description = "**Supplied by module/networking** **Required** ARN of TLS certificate imported into ACM for use with LB listener"
# }
# variable "vpc_id" {
# type = string
# description = "**Supplied by module/networking** **Required** VPC ID where Vault will be deployed"
# }
# variable "private_subnet_ids" {
# type = list(string)
# description = "**Supplied by module/networking** **Required** Subnet IDs to deploy Vault into"
# }

Binary file not shown.