From 53be0b9df96dc6e3aaf0b84c1d5a63b6e93ea17f Mon Sep 17 00:00:00 2001 From: Nick Petrovic <4001122+nickpetrovic@users.noreply.github.com> Date: Fri, 22 Mar 2024 14:53:33 -0400 Subject: [PATCH] Add pre-install user data (#86) * add pre-install user data * add ipv6 ingress * add ipv4 precedence note to readme --- README.md | 9 ++++++ modules/terraform-aws-alternat/main.tf | 36 +++++++++++++++++---- modules/terraform-aws-alternat/variables.tf | 19 ++++++++--- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index dc9043c..8b6ae69 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,15 @@ While we'd like for this to be available on the Terraform Registry, it requires - There are four Elastic IP addresses for the NAT instances and four for the NAT Gateways. Be sure to add all eight addresses to any external allow lists if necessary. +- If you plan on running this in a dual stack network (IPv4 and IPv6), you may notice that it takes ~10 minutes for an alternat node to start. In that case, you can use the `nat_instance_user_data_pre_install` variable to prefer IPv4 over IPv6 before running any user data. + + ```tf + nat_instance_user_data_pre_install = <<-EOF + # Prefer IPv4 over IPv6 + echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf + EOF + ``` + ## Future work We would like this benefit to benefit as many users as possible. Possible future enhancements include: diff --git a/modules/terraform-aws-alternat/main.tf b/modules/terraform-aws-alternat/main.tf index e363a7c..1a498d7 100644 --- a/modules/terraform-aws-alternat/main.tf +++ b/modules/terraform-aws-alternat/main.tf @@ -173,6 +173,16 @@ data "cloudinit_config" "config" { gzip = true base64_encode = true + + dynamic "part" { + for_each = var.nat_instance_user_data_pre_install != "" ? [1] : [] + + content { + content_type = "text/x-shellscript" + content = var.nat_instance_user_data_pre_install + } + } + part { content_type = "text/x-shellscript" content = templatefile("${path.module}/alternat.conf.tftpl", { @@ -180,6 +190,7 @@ data "cloudinit_config" "config" { route_table_ids_csv = join(",", each.value) }) } + part { content_type = "text/x-shellscript" content = file("${path.module}/../../scripts/alternat.sh") @@ -282,13 +293,24 @@ resource "aws_security_group_rule" "nat_instance_ingress" { resource "aws_security_group_rule" "nat_instance_ip_range_ingress" { count = length(var.ingress_security_group_cidr_blocks) > 0 ? 1 : 0 - - type = "ingress" - protocol = "-1" - from_port = 0 - to_port = 0 - security_group_id = aws_security_group.nat_instance.id - cidr_blocks = var.ingress_security_group_cidr_blocks + + type = "ingress" + protocol = "-1" + from_port = 0 + to_port = 0 + security_group_id = aws_security_group.nat_instance.id + cidr_blocks = var.ingress_security_group_cidr_blocks +} + +resource "aws_security_group_rule" "nat_instance_ipv6_range_ingress" { + count = length(var.ingress_security_group_ipv6_cidr_blocks) > 0 ? 1 : 0 + + type = "ingress" + protocol = "-1" + from_port = 0 + to_port = 0 + security_group_id = aws_security_group.nat_instance.id + ipv6_cidr_blocks = var.ingress_security_group_ipv6_cidr_blocks } ### NAT instance IAM diff --git a/modules/terraform-aws-alternat/variables.tf b/modules/terraform-aws-alternat/variables.tf index 2d90df5..bfc959e 100644 --- a/modules/terraform-aws-alternat/variables.tf +++ b/modules/terraform-aws-alternat/variables.tf @@ -1,6 +1,6 @@ variable "additional_instance_policies" { description = "Additional policies for the HA NAT instance IAM role." - type = list(object({ + type = list(object({ policy_name = string policy_json = string })) @@ -85,6 +85,12 @@ variable "ingress_security_group_cidr_blocks" { default = [] } +variable "ingress_security_group_ipv6_cidr_blocks" { + description = "A list of IPv6 CIDR blocks that are allowed by the NAT instance." + type = list(string) + default = [] +} + variable "lifecycle_heartbeat_timeout" { description = "The length of time, in seconds, that autoscaled NAT instances should wait in the terminate state before being fully terminated." type = number @@ -161,6 +167,12 @@ variable "nat_instance_eip_ids" { default = [] } +variable "nat_instance_user_data_pre_install" { + description = "Pre-install shell script to run at boot before configuring alternat." + type = string + default = "" +} + variable "nat_instance_user_data_post_install" { description = "Post-install shell script to run at boot after configuring alternat." type = string @@ -175,7 +187,7 @@ variable "tags" { variable "vpc_az_maps" { description = "A map of az to private route tables that the NAT instances will manage." - type = list(object({ + type = list(object({ az = string private_subnet_ids = list(string) public_subnet_id = string @@ -214,7 +226,7 @@ variable "lambda_timeout" { variable "lambda_handlers" { description = "Lambda handlers." - type = object({ + type = object({ connectivity_tester = string, alternat_autoscaling_hook = string, }) @@ -247,4 +259,3 @@ variable "lambda_layer_arns" { description = "List of Lambda layers ARN that will be added to functions" default = null } -