Skip to content

Commit

Permalink
OPS-6392 Replace ELB with ALB (#34)
Browse files Browse the repository at this point in the history
* OPS-6392 Replace ELB with ALB

* OPS-6392 Add private records for ALB

* OPS-6392 Fix examples outputs
  • Loading branch information
snovikov authored Dec 12, 2024
1 parent d74d8a3 commit dd18b10
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 65 deletions.
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ Type: `string`

Default: `""`

### <a name="input_vault_route53_private_dns_name"></a> [vault\_route53\_private\_dns\_name](#input\_vault\_route53\_private\_dns\_name)

Description: The Route53 private DNS name for the vault ELB. If not set, no Route53 record will be created.

Type: `string`

Default: `""`

### <a name="input_ssh_user"></a> [ssh\_user](#input\_ssh\_user)

Description: User name used for SSH-connections.
Expand Down Expand Up @@ -186,19 +194,13 @@ Type: `number`

Default: `3`

### <a name="input_vault_ingress_cidr_https"></a> [vault\_ingress\_cidr\_https](#input\_vault\_ingress\_cidr\_https)

Description: List of CIDR's from which you are allowed to https access the vault cluster.
### <a name="input_vault_ingress_cidr"></a> [vault\_ingress\_cidr](#input\_vault\_ingress\_cidr)

Type: `list(string)`
Description: CIDR's from which you are allowed to https access the vault cluster.

Default:
Type: `string`

```json
[
"0.0.0.0/0"
]
```
Default: `"0.0.0.0/0"`

### <a name="input_security_group_names"></a> [security\_group\_names](#input\_security\_group\_names)

Expand Down Expand Up @@ -255,11 +257,11 @@ Default: `null`

| Name | Description |
|------|-------------|
| <a name="output_alb_fqdn_vault"></a> [alb\_fqdn\_vault](#output\_alb\_fqdn\_vault) | The AWS provided CNAME of the Vault ALB. |
| <a name="output_alb_route53_public_dns_name_vault"></a> [alb\_route53\_public\_dns\_name\_vault](#output\_alb\_route53\_public\_dns\_name\_vault) | The Route53 name attached to the Vault ALB, if specified in variables. |
| <a name="output_asg_name_consul_cluster"></a> [asg\_name\_consul\_cluster](#output\_asg\_name\_consul\_cluster) | Autoscaling group name of the Consul cluster. |
| <a name="output_asg_name_vault_cluster"></a> [asg\_name\_vault\_cluster](#output\_asg\_name\_vault\_cluster) | Autoscaling group name of the Vault cluster. |
| <a name="output_aws_region"></a> [aws\_region](#output\_aws\_region) | Used AWS region. |
| <a name="output_elb_fqdn_vault"></a> [elb\_fqdn\_vault](#output\_elb\_fqdn\_vault) | The AWS provided CNAME of the Vault ELB. |
| <a name="output_elb_route53_public_dns_name_vault"></a> [elb\_route53\_public\_dns\_name\_vault](#output\_elb\_route53\_public\_dns\_name\_vault) | The Route53 name attached to the Vault ELB, if spcified in variables. |
| <a name="output_iam_role_arn_consul_cluster"></a> [iam\_role\_arn\_consul\_cluster](#output\_iam\_role\_arn\_consul\_cluster) | IAM role ARN attached to the Consul cluster. |
| <a name="output_iam_role_arn_vault_cluster"></a> [iam\_role\_arn\_vault\_cluster](#output\_iam\_role\_arn\_vault\_cluster) | IAM role ARN attached to the Vault cluster. |
| <a name="output_iam_role_id_consul_cluster"></a> [iam\_role\_id\_consul\_cluster](#output\_iam\_role\_id\_consul\_cluster) | IAM role ID attached to the Consul cluster. |
Expand Down
29 changes: 29 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
data "aws_region" "current" {}

data "aws_route53_zone" "public" {
count = var.vault_route53_public_dns_name != "" ? 1 : 0

private_zone = false

# Removes the first sub-domain part from the FQDN to use as hosted zone.
name = "${replace(var.vault_route53_public_dns_name, "/^.+?\\./", "")}."
}

data "aws_route53_zone" "private" {
count = var.vault_route53_private_dns_name != "" ? 1 : 0

private_zone = true

# Removes the first sub-domain part from the FQDN to use as hosted zone.
name = "${replace(var.vault_route53_private_dns_name, "/^.+?\\./", "")}."
}

data "aws_security_groups" "alb" {
filter {
name = "group-name"
values = var.security_group_names
}
filter {
name = "vpc-id"
values = [var.vpc_id]
}
}
4 changes: 2 additions & 2 deletions examples/custom-vpc-with-vault/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ No resources.
| Name | Description |
|------|-------------|
| <a name="output_elb_fqdn_bastion"></a> [elb\_fqdn\_bastion](#output\_elb\_fqdn\_bastion) | AWS generated CNAME for the bastion host ELB |
| <a name="output_elb_fqdn_vault"></a> [elb\_fqdn\_vault](#output\_elb\_fqdn\_vault) | AWS generated CNAME for the vault ELB |
| <a name="output_elb_route53_public_dns_name_bastion"></a> [elb\_route53\_public\_dns\_name\_bastion](#output\_elb\_route53\_public\_dns\_name\_bastion) | Route53 public DNS name for the bastion host ELB |
| <a name="output_elb_route53_public_dns_name_vault"></a> [elb\_route53\_public\_dns\_name\_vault](#output\_elb\_route53\_public\_dns\_name\_vault) | Route53 public DNS name for the vault ELB |
| <a name="output_alb_fqdn_vault"></a> [alb\_fqdn\_vault](#output\_alb\_fqdn\_vault) | AWS generated CNAME for the vault ALB |
| <a name="output_alb_route53_public_dns_name_vault"></a> [alb\_route53\_public\_dns\_name\_vault](#output\_alb\_route53\_public\_dns\_name\_vault) | Route53 public DNS name for the vault ALB |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
6 changes: 3 additions & 3 deletions examples/custom-vpc-with-vault/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ module "aws_vault" {
vault_cluster_name = "vault-example-vault"

# Security
ssh_keys = ["ssh-ed25519 AAAAC3Nznte5aaCdi1a1Lzaai/tX6Mc2E+S6g3lrClL09iBZ5cW2OZdSIqomcMko 2 mysshkey"]
ssh_security_group_id = module.aws_vpc.bastion_security_group_id
vault_ingress_cidr_https = ["0.0.0.0/0"]
ssh_keys = ["ssh-ed25519 AAAAC3Nznte5aaCdi1a1Lzaai/tX6Mc2E+S6g3lrClL09iBZ5cW2OZdSIqomcMko 2 mysshkey"]
ssh_security_group_id = module.aws_vpc.bastion_security_group_id
vault_ingress_cidr = "0.0.0.0/0"

ssl_certificate_id = "arn:aws:acm:eu-central-1:123456789012:certificate/xxxxx-xxxx-xxxx-xxxx-xxxxx"
}
16 changes: 8 additions & 8 deletions examples/custom-vpc-with-vault/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ output "elb_fqdn_bastion" {
description = "AWS generated CNAME for the bastion host ELB"
}

output "elb_fqdn_vault" {
value = module.aws_vault.elb_fqdn_vault
description = "AWS generated CNAME for the vault ELB"
}

output "elb_route53_public_dns_name_bastion" {
value = module.aws_vpc.bastion_route53_public_dns_name
description = "Route53 public DNS name for the bastion host ELB"
}

output "elb_route53_public_dns_name_vault" {
value = module.aws_vault.elb_route53_public_dns_name_vault
description = "Route53 public DNS name for the vault ELB"
output "alb_fqdn_vault" {
value = module.aws_vault.alb_fqdn_vault
description = "AWS generated CNAME for the vault ALB"
}

output "alb_route53_public_dns_name_vault" {
value = module.aws_vault.alb_route53_public_dns_name_vault
description = "Route53 public DNS name for the vault ALB"
}
124 changes: 97 additions & 27 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ module "vault_cluster" {

health_check_type = "EC2"

elb_security_group_id = module.vault_elb.security_group_ids[0]
alb_security_group_id = module.vault_alb.security_group_id
consul_security_group_id = module.consul_cluster.security_group_id
ssh_security_group_id = var.ssh_security_group_id

Expand All @@ -40,38 +40,108 @@ module "consul_iam_policies_servers" {
iam_role_id = module.vault_cluster.iam_role_id
}

module "vault_elb" {
source = "github.com/Flaconi/terraform-aws-elb?ref=v2.0.0"

name = var.vault_cluster_name
vpc_id = var.vpc_id
subnet_ids = var.public_subnet_ids

lb_port = 443
lb_protocol = "HTTPS"
instance_port = 8200
instance_protocol = "HTTPS"
ssl_certificate_id = var.ssl_certificate_id

target = "HTTPS:8200/v1/sys/health?standbyok=true"
timeout = 5
interval = 15
healthy_threshold = 2
unhealthy_threshold = 2

inbound_cidr_blocks = var.vault_ingress_cidr_https
security_group_names = var.security_group_names

route53_public_dns_name = var.vault_route53_public_dns_name

public_dns_evaluate_target_health = false
module "vault_alb" {
source = "github.com/terraform-aws-modules/terraform-aws-alb?ref=v9.12.0"

name = var.vault_cluster_name
vpc_id = var.vpc_id
subnets = var.public_subnet_ids

security_group_name = "${var.name}-alb"
security_group_description = "ALB security group for external connection"
security_group_ingress_rules = {
all_http = {
from_port = 80
to_port = 80
ip_protocol = "tcp"
cidr_ipv4 = var.vault_ingress_cidr
description = "HTTP web traffic"
}
all_https = {
from_port = 443
to_port = 443
ip_protocol = "tcp"
cidr_ipv4 = var.vault_ingress_cidr
description = "HTTPS web traffic"
}
}
security_group_egress_rules = {
all = {
ip_protocol = "-1"
cidr_ipv4 = "0.0.0.0/0"
description = "AWS default egress rule"
}
}
security_groups = data.aws_security_groups.alb.ids

# new
listeners = {
http-https-redirect = {
port = 80
protocol = "HTTP"
redirect = {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
https = {
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-3-2021-06"
certificate_arn = var.ssl_certificate_id

forward = {
target_group_key = "vault"
}
}
}

target_groups = {
vault = {
name_prefix = "vault"
protocol = "HTTPS"
port = 8200

create_attachment = false

health_check = {
enable = true
path = "/v1/sys/health?standbyok=true"
port = "traffic-port"
protocol = "HTTPS"
timeout = 5
interval = 15
healthy_threshold = 2
unhealthy_threshold = 2
}
}
}

# Route53 Record(s)
route53_records = merge(
var.vault_route53_public_dns_name != "" ? {
public = {
name = var.vault_route53_public_dns_name
type = "A"
zone_id = data.aws_route53_zone.public[0].id
}
} : {},
var.vault_route53_private_dns_name != "" ? {
private = {
name = var.vault_route53_private_dns_name
type = "A"
zone_id = data.aws_route53_zone.private[0].id
}
} : {}
)

tags = var.tags
}

resource "aws_autoscaling_attachment" "vault" {
autoscaling_group_name = module.vault_cluster.asg_name
elb = module.vault_elb.id
lb_target_group_arn = module.vault_alb.target_groups["vault"].arn
}

module "consul_cluster" {
Expand Down
2 changes: 1 addition & 1 deletion modules/vault-cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ machines.
| <a name="input_wait_for_capacity_timeout"></a> [wait\_for\_capacity\_timeout](#input\_wait\_for\_capacity\_timeout) | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. Setting this to '0' causes Terraform to skip all Capacity Waiting behavior. | `string` | `"10m"` | no |
| <a name="input_health_check_type"></a> [health\_check\_type](#input\_health\_check\_type) | Controls how health checking is done. Must be one of EC2 or ELB. | `string` | `"EC2"` | no |
| <a name="input_health_check_grace_period"></a> [health\_check\_grace\_period](#input\_health\_check\_grace\_period) | Time, in seconds, after instance comes into service before checking health. | `number` | `60` | no |
| <a name="input_elb_security_group_id"></a> [elb\_security\_group\_id](#input\_elb\_security\_group\_id) | ID of the security group of a public ELB from which you can API access the Vault instances. | `string` | n/a | yes |
| <a name="input_alb_security_group_id"></a> [alb\_security\_group\_id](#input\_alb\_security\_group\_id) | ID of the security group of a public ELB from which you can API access the Vault instances. | `string` | n/a | yes |
| <a name="input_ssh_security_group_id"></a> [ssh\_security\_group\_id](#input\_ssh\_security\_group\_id) | ID of the security group of a bastion ssh instance from where you can ssh into the Vault instances. | `string` | n/a | yes |
| <a name="input_consul_security_group_id"></a> [consul\_security\_group\_id](#input\_consul\_security\_group\_id) | ID of the security group of the Consul instances to allow traffic from Consul into Vault. | `string` | n/a | yes |
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | The name of the Vault cluster (e.g. vault-stage). This variable is used to namespace all resources created by this module. | `string` | n/a | yes |
Expand Down
2 changes: 1 addition & 1 deletion modules/vault-cluster/security-groups.tf
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ module "lc_security_group" {
from_port = "8200"
to_port = "8200"
protocol = "tcp"
source_security_group_id = var.elb_security_group_id
source_security_group_id = var.alb_security_group_id
description = "External API. Allow API access to Vault instances from this security group (from ELB or instances)."
},
]
Expand Down
2 changes: 1 addition & 1 deletion modules/vault-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ variable "health_check_grace_period" {
type = number
}

variable "elb_security_group_id" {
variable "alb_security_group_id" {
description = "ID of the security group of a public ELB from which you can API access the Vault instances."
type = string
}
Expand Down
12 changes: 6 additions & 6 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
output "elb_fqdn_vault" {
value = module.vault_elb.fqdn
description = "The AWS provided CNAME of the Vault ELB."
output "alb_fqdn_vault" {
value = module.vault_alb.dns_name
description = "The AWS provided CNAME of the Vault ALB."
}

output "elb_route53_public_dns_name_vault" {
value = module.vault_elb.route53_public_dns_name
description = "The Route53 name attached to the Vault ELB, if spcified in variables."
output "alb_route53_public_dns_name_vault" {
value = var.vault_route53_public_dns_name
description = "The Route53 name attached to the Vault ALB, if specified in variables."
}

output "asg_name_consul_cluster" {
Expand Down
14 changes: 10 additions & 4 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ variable "vault_route53_public_dns_name" {
type = string
}

variable "vault_route53_private_dns_name" {
description = "The Route53 private DNS name for the vault ELB. If not set, no Route53 record will be created."
default = ""
type = string
}

variable "ssh_user" {
description = "User name used for SSH-connections."
type = string
Expand Down Expand Up @@ -84,10 +90,10 @@ variable "ssh_security_group_id" {
type = string
}

variable "vault_ingress_cidr_https" {
description = "List of CIDR's from which you are allowed to https access the vault cluster."
type = list(string)
default = ["0.0.0.0/0"]
variable "vault_ingress_cidr" {
description = "CIDR's from which you are allowed to https access the vault cluster."
type = string
default = "0.0.0.0/0"
}

variable "security_group_names" {
Expand Down

0 comments on commit dd18b10

Please sign in to comment.