Skip to content

Commit

Permalink
Updates repo structure to conform to the Terraform Registry requireme…
Browse files Browse the repository at this point in the history
…nts (#98)

* Updates repo structure to conform to the Terraform Registry requirements

* fix path

* update readme

* Test public ip

* Instance state must be running 🤦‍♂️

* Explain name collisions
  • Loading branch information
bwhaley authored May 13, 2024
1 parent b86e5f9 commit d240843
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 19 deletions.
File renamed without changes.
12 changes: 4 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ The two main elements of the NAT instance solution are:
1. The NAT instance Auto Scaling Groups, one per zone, with a corresponding standby NAT Gateway
1. The replace-route Lambda function

Both are deployed by the Terraform module located in [`modules/terraform-aws-alternat`](modules/terraform-aws-alternat).
Both are deployed by the Terraform module.

### NAT Instance Auto Scaling Group and Standby NAT Gateway

The solution deploys an Auto Scaling Group (ASG) for each provided public subnet. Each ASG contains a single instance. When the instance boots, the [user data](modules/terraform-aws-alternat/alternat.sh.tftpl) initializes the instance to do the NAT stuff.
The solution deploys an Auto Scaling Group (ASG) for each provided public subnet. Each ASG contains a single instance. When the instance boots, the [user data](alternat.sh.tftpl) initializes the instance to do the NAT stuff.

By default, the ASGs are configured with a [maximum instance lifetime](https://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-max-instance-lifetime.html). This is to facilitate periodic replacement of the instance to automate patching. When the maximum instance lifetime is reached (14 days by default), the following occurs:

Expand Down Expand Up @@ -123,7 +123,7 @@ docker push <your_registry_url>/<your_repo:<release tag or short git commit sha>

### Use the Terraform Module

Start by reviewing the available [input variables](modules/terraform-aws-alternat/variables.tf). Example usage:
Start by reviewing the available [input variables](variables.tf). Example usage:

```hcl
locals {
Expand All @@ -144,7 +144,7 @@ data "aws_subnet" "subnet" {
}
module "alternat_instances" {
source = "git::https://github.com/chime/terraform-aws-alternat.git//modules/terraform-aws-alternat?ref=v0.3.3"
source = "chime/alternat/aws?ref=v0.3.3"
alternat_image_uri = "0123456789012.dkr.ecr.us-east-1.amazonaws.com/alternat-functions-lambda"
alternat_image_tag = "v0.3.3"
Expand Down Expand Up @@ -204,10 +204,6 @@ If you are using the open source terraform-aws-vpc module, you can set `nat_gate

AlterNATively, you can remove the NAT Gateways and their EIPs from your existing configuration and then `terraform import` them to allow alterNAT to manage them.

#### Why isn't this module published on the Terraform registry?

While we'd like for this to be available on the Terraform Registry, it requires a specific repo naming convention and folder structure that we do not want to adopt.

### Other Considerations

- Read [the Amazon EC2 instance network bandwidth page](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-network-bandwidth.html) carefully. In particular:
Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion examples/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ locals {
}

module "alternat" {
source = "../modules/terraform-aws-alternat"
# To use Alternat from the Terraform Registry:
# source = "chime/alternat/aws"
source = "./.."

create_nat_gateways = var.create_nat_gateways
ingress_security_group_cidr_blocks = var.private_subnets
Expand Down
2 changes: 1 addition & 1 deletion modules/terraform-aws-alternat/lambda.tf → lambda.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ locals {
data "archive_file" "lambda" {
count = var.lambda_package_type == "Zip" ? 1 : 0
type = "zip"
source_dir = "${path.module}/../../functions/replace-route"
source_dir = "${path.module}/functions/replace-route"
excludes = ["__pycache__"]
output_path = var.lambda_zip_path
}
Expand Down
2 changes: 1 addition & 1 deletion modules/terraform-aws-alternat/main.tf → main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ data "cloudinit_config" "config" {

part {
content_type = "text/x-shellscript"
content = file("${path.module}/../../scripts/alternat.sh")
content = file("${path.module}/scripts/alternat.sh")
}

dynamic "part" {
Expand Down
File renamed without changes.
20 changes: 16 additions & 4 deletions test/alternat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"

terraws "github.com/gruntwork-io/terratest/modules/aws"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/retry"
"github.com/gruntwork-io/terratest/modules/ssh"
Expand All @@ -25,6 +26,11 @@ import (
"github.com/stretchr/testify/require"
)

// Maintainer's note: This test will currently cause name collisions if multiple tests run in parallel
// in the same account. This is because the test uses a fixed name prefix for resources. This could be fixed
// by using GetRandomStableRegion and updating some resources (such as IAM role and CloudWatch event name)
// to use a random suffix.

func TestAlternat(t *testing.T) {
// Uncomment any of the following lines to skip that part of the test.
// This is useful for iterating during test development.
Expand Down Expand Up @@ -169,7 +175,7 @@ net.ipv4.ip_local_port_range = 1024 65535
// Validate that private route tables have routes to the Internet via NAT Gateway
maxRetries := 12
waitTime := 10 * time.Second
retry.DoWithRetry(t, "Validating route through NAT Gateway", maxRetries, waitTime, func() (string, error) {
output := retry.DoWithRetry(t, "Validating route through NAT Gateway", maxRetries, waitTime, func() (string, error) {
routeTables, err := getRouteTables(t, ec2Client, vpcID)
require.NoError(t, err)
for _, rt := range routeTables {
Expand All @@ -181,6 +187,8 @@ net.ipv4.ip_local_port_range = 1024 65535
}
return "All private route tables route through NAT Gateway", nil
})
logger := logger.Logger{}
logger.Logf(t, output)
updateEgress(t, ec2Client, sgId, false)
})
}
Expand Down Expand Up @@ -250,6 +258,10 @@ func getNatInstancePublicIp(t *testing.T, ec2Client *ec2.Client) (string, error)
Name: aws.String("tag:Name"),
Values: []string{namePrefix + "*"},
},
{
Name: aws.String("instance-state-name"),
Values: []string{"running"},
},
},
}
maxRetries := 6
Expand All @@ -260,11 +272,11 @@ func getNatInstancePublicIp(t *testing.T, ec2Client *ec2.Client) (string, error)
return "", err
}

ip := aws.ToString(result.Reservations[0].Instances[0].PublicIpAddress)
if ip == "" {
publicIp := aws.ToString(result.Reservations[0].Instances[0].PublicIpAddress)
if publicIp == "" {
return "", fmt.Errorf("Public IP not found")
}
return ip, nil
return publicIp, nil
})

return ip, nil
Expand Down
8 changes: 4 additions & 4 deletions modules/terraform-aws-alternat/variables.tf → variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
variable "additional_instance_policies" {
description = "Additional policies for the HA NAT instance IAM role."
description = "Additional policies for the Alternat instance IAM role."
type = list(object({
policy_name = string
policy_json = string
Expand All @@ -8,13 +8,13 @@ variable "additional_instance_policies" {
}

variable "alternat_image_tag" {
description = "The tag of the container image for the HA NAT Lambda functions."
description = "The tag of the container image for the Alternat Lambda functions."
type = string
default = "latest"
}

variable "alternat_image_uri" {
description = "The URI of the container image for the HA NAT Lambda functions."
description = "The URI of the container image for the Alternat Lambda functions."
type = string
default = ""
}
Expand Down Expand Up @@ -68,7 +68,7 @@ variable "enable_lambda_endpoint" {
}

variable "enable_ssm" {
description = "Whether to enable SSM on the HA NAT instances."
description = "Whether to enable SSM on the Alternat instances."
type = bool
default = true
}
Expand Down
File renamed without changes.

0 comments on commit d240843

Please sign in to comment.