Giter Site home page Giter Site logo

lyrise / terraform-aws-nat-instance Goto Github PK

View Code? Open in Web Editor NEW

This project forked from benwiggins/terraform-aws-nat-instance

0.0 0.0 0.0 84 KB

Terraform module to provision a NAT Instance using an Auto Scaling Group and Spot Instance from $1/month

Home Page: https://registry.terraform.io/modules/int128/nat-instance/aws/

License: Apache License 2.0

Shell 16.11% Makefile 1.45% HCL 82.44%

terraform-aws-nat-instance's Introduction

terraform-aws-nat-instance CircleCI

This is a Terraform module which provisions a NAT instance.

Features:

  • Providing NAT for private subnet(s)
  • Auto healing using an auto scaling group
  • Saving cost using a spot instance (from $1/month)
  • Fixed source IP address by reattaching ENI
  • Supporting Systems Manager Session Manager
  • Compatible with workspaces

Terraform 0.12 or later is required.

Warning: Generally you should use a NAT gateway. This module provides a very low cost solution for testing purpose.

Getting Started

You can use this module with terraform-aws-modules/vpc/aws module as follows:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"

  name                 = "main"
  cidr                 = "172.18.0.0/16"
  azs                  = ["us-west-2a", "us-west-2b", "us-west-2c"]
  private_subnets      = ["172.18.64.0/20", "172.18.80.0/20", "172.18.96.0/20"]
  public_subnets       = ["172.18.128.0/20", "172.18.144.0/20", "172.18.160.0/20"]
  enable_dns_hostnames = true
}

module "nat" {
  source = "int128/nat-instance/aws"

  name                        = "main"
  vpc_id                      = module.vpc.vpc_id
  public_subnet               = module.vpc.public_subnets[0]
  private_subnets_cidr_blocks = module.vpc.private_subnets_cidr_blocks
  private_route_table_ids     = module.vpc.private_route_table_ids
}

resource "aws_eip" "nat" {
  network_interface = module.nat.eni_id
  tags = {
    "Name" = "nat-instance-main"
  }
}

Now create an EC2 instance in the private subnet to verify the NAT configuration. Open the AWS Systems Manager Session Manager, log in to the instance and make sure you have external access from the instance.

See also the example.

How it works

This module provisions the following resources:

  • Auto Scaling Group with mixed instances policy
  • Launch Template
  • Elastic Network Interface
  • Security Group
  • IAM Role for SSM and ENI attachment
  • VPC Route (optional)

You need to attach your elastic IP to the ENI.

Take a look at the diagram:

diagram

By default the latest Amazon Linux 2 image is used. You can set image_id for a custom image.

The instance will execute runonce.sh and snat.sh to enable NAT as follows:

  1. Attach the ENI to eth1.
  2. Set the kernel parameters for IP forwarding and masquerade.
  3. Switch the default route to eth1.

Configuration

User data

You can set additional write_files and runcmd section. For example,

module "nat" {
  user_data_write_files = [
    {
      path : "/opt/nat/run.sh",
      content : file("./run.sh"),
      permissions : "0755",
    },
  ]
  user_data_runcmd = [
    ["/opt/nat/run.sh"],
  ]
}

See also cloud-init modules and the example for more.

SSH access

You can enable SSH access by setting key_name option and opening the security group. For example,

module "nat" {
  key_name = "YOUR_KEY_PAIR"
}

resource "aws_security_group_rule" "nat_ssh" {
  security_group_id = module.nat.sg_id
  type              = "ingress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
}

Migration guide

Upgrade to v2 from v1

This module no longer creates an EIP since v2.

To keep your EIP when you migrate to module v2, rename the EIP in the state as follows:

% terraform state mv -dry-run module.nat.aws_eip.this aws_eip.nat
Would move "module.nat.aws_eip.this" to "aws_eip.nat"

% terraform state mv module.nat.aws_eip.this aws_eip.nat
Move "module.nat.aws_eip.this" to "aws_eip.nat"
Successfully moved 1 object(s).

Contributions

This is an open source software. Feel free to open issues and pull requests.

Requirements

Name Version
terraform >= 0.12.0

Providers

Name Version
aws n/a

Modules

No modules.

Resources

Name Type
aws_autoscaling_group.this resource
aws_iam_instance_profile.this resource
aws_iam_role.this resource
aws_iam_role_policy.eni resource
aws_iam_role_policy_attachment.ssm resource
aws_launch_template.this resource
aws_network_interface.this resource
aws_route.this resource
aws_security_group.this resource
aws_security_group_rule.egress resource
aws_security_group_rule.ingress_any resource
aws_ami.this data source

Inputs

Name Description Type Default Required
enabled Enable or not costly resources bool true no
image_id AMI of the NAT instance. Default to the latest Amazon Linux 2 string "" no
instance_types Candidates of spot instance type for the NAT instance. This is used in the mixed instances policy list(string)
[
"t3.nano",
"t3a.nano"
]
no
key_name Name of the key pair for the NAT instance. You can set this to assign the key pair to the NAT instance string "" no
name Name for all the resources as identifier string n/a yes
private_route_table_ids List of ID of the route tables for the private subnets. You can set this to assign the each default route to the NAT instance list(string) [] no
private_subnets_cidr_blocks List of CIDR blocks of the private subnets. The NAT instance accepts connections from this subnets list(string) n/a yes
public_subnet ID of the public subnet to place the NAT instance string n/a yes
ssm_policy_arn SSM Policy to be attached to instance profile string "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" no
tags Tags applied to resources created with this module map(string) {} no
use_spot_instance Whether to use spot or on-demand EC2 instance bool true no
user_data_runcmd Additional runcmd section of cloud-init list(list(string)) [] no
user_data_write_files Additional write_files section of cloud-init list(any) [] no
vpc_id ID of the VPC string n/a yes

Outputs

Name Description
eni_id ID of the ENI for the NAT instance
eni_private_ip Private IP of the ENI for the NAT instance
iam_role_name Name of the IAM role for the NAT instance
sg_id ID of the security group of the NAT instance

terraform-aws-nat-instance's People

Contributors

int128 avatar renovate[bot] avatar benwiggins avatar lethgir avatar github-actions[bot] avatar dreamrace avatar gleidsoncampos avatar nelg avatar pietzschke avatar mackenzie-oa avatar thongdong7 avatar yutachaos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.