AndrewGuenther / fck-nat

Feasible cost konfigurable NAT: An AWS NAT Instance AMI
https://fck-nat.dev
MIT License
1.32k stars 54 forks source link

Create a fck-nat Terraform module #4

Closed AndrewGuenther closed 10 months ago

nitrocode commented 2 years ago

Instead of creating a new module, it would probably be better to reuse an existing one that supports overriding the ami.

See https://github.com/cloudposse/terraform-aws-dynamic-subnets#input_nat_instance_ami_id

And a complete example

https://github.com/cloudposse/terraform-aws-dynamic-subnets/blob/master/examples/complete/main.tf

AndrewGuenther commented 2 years ago

The intent is that the fck-nat AMI will be compatible with any other NAT instance provider, but certain features like high-availability mode require configuration that many modules don't provide. For example, https://github.com/cloudposse/terraform-aws-dynamic-subnets#input_nat_instance_ami_id only runs a single instance rather than an autoscaling group. A fck-nat Terraform module would be a bit more tailor-made to support features like high-availability mode and other features I have in mind for later on, but the AMI should always be compatible out of the box with modules like the one you linked.

JulianCBC commented 2 years ago

@AndrewGuenther I've been trying to find a solution for NAT on a VPC that's implementable using Terraform and I found this module: https://github.com/int128/terraform-aws-nat-instance which is essentially fck-nat without the AMI or RPMs. (The scripting is spookily similar.)

I'm hacking together some changes to their scripting to resolve a couple of issues I've found in my particular environment that would apply to the HA use-case for fck-nat:

Would you like me to port them over to fck-nat?

Following on from that, would you mind if I propose a patch to that module to make it use fck-nat's scripting? The rough plan would be to either use the fck-nat AMI or to submodule fck-nat into that repository so it can use fck-nat's scripts. This could then make that module the "official" Terraform module for fck-nat.

AndrewGuenther commented 2 years ago

I'm always happy to accept improvements. And you're welcome to contribute anything from fck-nat back over to terraform-aws-nat-instance. That said, I don't know if long-term terraform-aws-nat-instance will be a good fit as an "official" module for fck-nat, but I can definitely direct people there for now. The main reason being that I'm hoping to add additional configuration options in the future and make additional improvements which may extend to infrastructure. However, the fck-nat AMI should always be able to run in a mode which can support setups like terraform-aws-nat-instance has (patching rules being a good example). I think it would definitely simplify that package if it just referred to the fck-nat AMI directly, considering from what I can tell it effectively builds a similar host using user data scripts.

JulianCBC commented 2 years ago

Yeah, fck-nat and terraform-aws-nat-instance are functionally identical, the only real differences being:

IMHO both solutions have their places, your all-in-one, deploy-and-go solution is a great way to get started if you're not using Terraform, whereas the Terraform module uses the latest AMI so it'll get updates faster, which could cause breakage if things change too fast.

Anyway, the first round of fixes have been ported over:

Both are untested in fck-nat, so please review carefully, but functionally identical changes to the module work for me in my environment.

souravjamwal77 commented 1 year ago

+1

ahodges22 commented 1 year ago

I've thrown together a quick Terraform module to spin up a fck-nat instance.

https://registry.terraform.io/modules/ahodges22/fck-nat

souravjamwal77 commented 1 year ago

As per @ahodges22, his TF module should not be used in production. So, does this apply to fck-nat also?

AndrewGuenther commented 1 year ago

Whether you feel fck-nat is viable for your production use is up to you. Fck-nat offers a high availability mode which minimizes downtime in the event of issues which may or may not be acceptable for your use case. Give the docs a read and make the decision that is the best for you.

ssadler commented 1 year ago

This was super easy in the end, in my case at least:

resource "aws_network_interface" "fck-nat-if" {                                       
  subnet_id       = aws_subnet.subnet_public.id                                       
  security_groups = [aws_default_security_group.default_security_group.id]            

  source_dest_check = false                                                           
}                                                                                     

resource "aws_instance" "fck-nat" {                                                   
  ami           = "ami-0d65d4e8bca87cd3f" # Might want to check this...
  instance_type = "t4g.nano"                                                          
  key_name      = "YOUR_KEY_HERE"                                                   

  network_interface {                                                                 
    network_interface_id = aws_network_interface.fck-nat-if.id                        
    device_index         = 0                                                          
  }                                                                                   

  tags = {                                                                            
    Name = "${var.project}-${var.env}-fck-nat"                                        
  }                                                                                   
}                                                                                     

Then all I had to do was add this into the private routing table: network_interface_id = aws_network_interface.fck-nat-if.id

Et voila, you can delete the nat!

jirkavrba commented 1 year ago

I found that you can use data.aws_ami for convenience to get the latest version of fck-nat AMI

data "aws_ami" "fck_nat" {
  filter {
    name   = "name"
    values = ["fck-nat-amzn2-*"]
  }

  owners      = ["568608671756"]
  most_recent = true
}

You can later reference it like this:

resource "aws_instance" "nat" {
  // ...
  image_id = data.aws_ami.fck_nat.image_id
  // ...
}
thecasual commented 1 year ago

+1

sjlu commented 1 year ago

I found that you can use data.aws_ami for convenience to get the latest version of fck-nat AMI

data "aws_ami" "fck_nat" {
  filter {
    name   = "name"
    values = ["fck-nat-amzn2-*"]
  }

  owners      = ["568608671756"]
  most_recent = true
}

You can later reference it like this:

resource "aws_instance" "nat" {
  // ...
  image_id = data.aws_ami.fck_nat.image_id
  // ...
}
  filter {
    name   = "architecture"
    values = ["arm64"]
  }

To get arm64!

ahmgithubahm commented 1 year ago

+1 from me

Devesh-N commented 1 year ago

+1 for me too

alexandruvesa commented 1 year ago

I found that you can use data.aws_ami for convenience to get the latest version of fck-nat AMI

data "aws_ami" "fck_nat" {
  filter {
    name   = "name"
    values = ["fck-nat-amzn2-*"]
  }

  owners      = ["568608671756"]
  most_recent = true
}

You can later reference it like this:

resource "aws_instance" "nat" {
  // ...
  image_id = data.aws_ami.fck_nat.image_id
  // ...
}
  filter {
    name   = "architecture"
    values = ["arm64"]
  }

To get arm64!

Hello ! I tried this approach but I don't find any amis in any region.

`data "aws_ami" "fck_nat" { filter { name = "name" values = ["fck-nat-amzn2-*"] }

owners = ["525479351334"] most_recent = true }

resource "aws_network_interface" "fck-nat-if" { subnet_id = aws_subnet.public-subnet-1.id security_groups = [aws_security_group.load-balancer.id]

source_dest_check = false }

resource "aws_instance" "fck-nat" { ami = data.aws_ami.fck_nat.image_id # Might want to check this... instance_type = "t4g.nano"

network_interface { network_interface_id = aws_network_interface.fck-nat-if.id device_index = 0 } }`

RaJiska commented 11 months ago

Been working on a Terraform module project which implements all the base features as well as the newly merged:

Still have some additional changes that I'd like to add, such as firewall delegation to iptables instead of firegroups (https://github.com/AndrewGuenther/fck-nat/issues/39), or kernel fine-tuning in the hope to have the NAT instance support more load (https://github.com/AndrewGuenther/fck-nat/issues/40).

The project is available on Github https://github.com/RaJiska/terraform-aws-fck-nat, and on Terraform Registry.

AndrewGuenther commented 10 months ago

@RaJiska's module is the blessed/official Terraform module now and I just merged #55 to point to it from the docs. With that, I am going to call this complete! Appreciate all your work @RaJiska!

Docs available in the develop release here: https://fck-nat.dev/develop/deploying/#terraform

Even though the docs are in develop you should be able to use terraform-aws-fck-nat right now ahead of the 1.3 release.