From a3b51350f0a207858b9ccd3b57fe2cc61877a0e1 Mon Sep 17 00:00:00 2001 From: Ben Partridge Date: Mon, 27 Mar 2023 17:08:13 +1100 Subject: [PATCH 1/2] Adds terraform.lock.hcl to gitignore It was not commited, so let's make it easy to keep it that way. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 339023f..8089af4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Module directory .terraform/ +.terraform.lock.hcl # Jetbrains .idea/ From ae8fc745dd9a1cddbf77e67dbdb1c328bcbc58e1 Mon Sep 17 00:00:00 2001 From: Ben Partridge Date: Mon, 27 Mar 2023 17:07:06 +1100 Subject: [PATCH 2/2] Makes ELB optional This is useful if you use Session Manager to connect to your bastion hosts and don't need to load balance across your bastion hosts. --- main.tf | 31 ++++++++++++++++++++++--------- outputs.tf | 6 +++--- variables.tf | 8 ++++++++ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/main.tf b/main.tf index 1915542..92877ca 100644 --- a/main.tf +++ b/main.tf @@ -29,7 +29,7 @@ resource "aws_security_group" "bastion_host_security_group" { } resource "aws_security_group_rule" "ingress_bastion" { - count = var.bastion_security_group_id == "" ? 1 : 0 + count = var.bastion_security_group_id == "" && var.create_elb ? 1 : 0 description = "Incoming traffic to bastion" type = "ingress" from_port = var.public_ssh_port @@ -148,16 +148,18 @@ resource "aws_route53_record" "bastion_record_name" { name = var.bastion_record_name zone_id = var.hosted_zone_id type = "A" - count = var.create_dns_record ? 1 : 0 + count = var.create_dns_record && var.create_elb ? 1 : 0 alias { evaluate_target_health = true - name = aws_lb.bastion_lb.dns_name - zone_id = aws_lb.bastion_lb.zone_id + name = aws_lb.bastion_lb[0].dns_name + zone_id = aws_lb.bastion_lb[0].zone_id } } resource "aws_lb" "bastion_lb" { + count = var.create_elb ? 1 : 0 + internal = var.is_lb_private name = "${local.name_prefix}-lb" @@ -165,9 +167,18 @@ resource "aws_lb" "bastion_lb" { load_balancer_type = "network" tags = merge(var.tags) + + lifecycle { + precondition { + condition = !var.create_elb || (length(var.elb_subnets) > 0 && var.is_lb_private != null) + error_message = "elb_subnets and is_lb_private must be set when creating a load balancer" + } + } } resource "aws_lb_target_group" "bastion_lb_target_group" { + count = var.create_elb ? 1 : 0 + name = "${local.name_prefix}-lb-target" port = var.public_ssh_port protocol = "TCP" @@ -183,12 +194,14 @@ resource "aws_lb_target_group" "bastion_lb_target_group" { } resource "aws_lb_listener" "bastion_lb_listener_22" { + count = var.create_elb ? 1 : 0 + default_action { - target_group_arn = aws_lb_target_group.bastion_lb_target_group.arn + target_group_arn = aws_lb_target_group.bastion_lb_target_group[0].arn type = "forward" } - load_balancer_arn = aws_lb.bastion_lb.arn + load_balancer_arn = aws_lb.bastion_lb[0].arn port = var.public_ssh_port protocol = "TCP" } @@ -267,9 +280,9 @@ resource "aws_autoscaling_group" "bastion_auto_scaling_group" { health_check_grace_period = 180 health_check_type = "EC2" - target_group_arns = [ - aws_lb_target_group.bastion_lb_target_group.arn, - ] + target_group_arns = var.create_elb ? [ + aws_lb_target_group.bastion_lb_target_group[0].arn, + ] : null termination_policies = [ "OldestLaunchConfiguration", diff --git a/outputs.tf b/outputs.tf index e3471cd..5683e4d 100644 --- a/outputs.tf +++ b/outputs.tf @@ -19,15 +19,15 @@ output "bucket_arn" { } output "elb_ip" { - value = aws_lb.bastion_lb.dns_name + value = var.create_elb ? aws_lb.bastion_lb[0].dns_name : null } output "elb_arn" { - value = aws_lb.bastion_lb.arn + value = var.create_elb ? aws_lb.bastion_lb[0].arn : null } output "target_group_arn" { - value = aws_lb_target_group.bastion_lb_target_group.arn + value = var.create_elb ? aws_lb_target_group.bastion_lb_target_group[0].arn : null } output "private_instances_security_group" { diff --git a/variables.tf b/variables.tf index f850ffa..d0103cd 100644 --- a/variables.tf +++ b/variables.tf @@ -32,6 +32,8 @@ variable "cidrs" { variable "is_lb_private" { description = "If TRUE the load balancer scheme will be \"internal\" else \"internet-facing\"" + nullable = true + default = null } variable "vpc_id" { @@ -77,6 +79,7 @@ variable "bastion_ami" { variable "elb_subnets" { type = list(string) description = "List of subnet were the ELB will be deployed" + default = [] } variable "auto_scaling_group_subnets" { @@ -191,3 +194,8 @@ variable "ipv6_cidrs" { "::/0", ] } + +variable "create_elb" { + description = "Choose if you want to deploy an ELB for accessing bastion hosts. If true, you must set elb_subnets and is_lb_private" + default = true +}