Posted: Saturday, February 4, 2023

Word Count: 1037

Reading Time: 5 minutes


Summary

The following Azure vWAN deployment includes the following:

  • 1 x VPC with 2 x subnets; 1 x private and 1 x public
  • 2 x windows EC2 instances deployed to each subnet
  • Security Group and Route Table configurations
  • RDP into the Jump the jumpbox

Tools

AWS NAT Gateway – Terraform: Click Here
Visual Studio Code: Click Here
AWS S3 cli: Click Here
Terraform Download Click Here

Price Estimate Table

ResourceCost per hour
T2.medium or t3a.medium instance x 2$0.12
VPC with NAT Gateway$0.06
Monthly Estimate$132.00

Architectural Diagram

Execution

Standard Terraform commands can be used to deploy the lab.

Deployment
terraform init
terraform plan -out=awsnat
terraform apply "awsnat"

When the deployment has been completed, the output will provide the external IP address of the jumpbox.

Terraform AWS NAT Gateway

Additionally, the private key would have been copied to the local directory.

Terraform AWS NAT Gateway Private Key
Removal
terraform apply -destroy
Connecting to Jumpbox

From the AWS console, select the jumpbox instance, which would be the instance assigned a public ip address and select connect.

At the top of the window, select RDP client. Ensure that the “Connect using RDP client” radio button is select and click “Get Password“.

Toward the bottom of the window either, upload the private key or paste its content in the window below. Click Decrypt Password.

Use the decrypted password to RDP into the jumpbox.

Modules

There are 14 modules leveraged in this terraform deployment:

Most variables are set in the variables.tf file in the primary folder.

Compute

This module can be used to provision AWS EC2 Instances.

resource "aws_instance" "aws_instance" {
  ami                    = var.ami
  instance_type          = var.instance_type
  subnet_id              = var.subnet_id
  vpc_security_group_ids = [var.vpc_security_group_ids]

  associate_public_ip_address = var.associate_public_ip_address
  key_name                    = var.key_name

}


output "extip" {
  value = aws_instance.aws_instance.public_ip

}
ElasticIp

An elastic IP is provisioned to the NAT Gateway. This module creates an elastic IP to be leveraged by the NAT gateway module.

resource "aws_eip" "eip" {
network_interface = var.network_interface
tags = var.tags

}

output "EipPublicIP" {
value = aws_eip.eip.public_ip

}

output "EipID" {
value = aws_eip.eip.id
}
InternetGateway

The internet gateway enables internet communications to the assigned VPC.

resource "aws_internet_gateway" "inetgw" {
vpc_id = var.vpc_id
tags = var.tags
}

output "id" {
value = aws_internet_gateway.inetgw.id
}

output "arn" {
value = aws_internet_gateway.inetgw.arn
}
MyCurrentInfo

I created this module to create information that I can leverage in other modules. In this lab, I only needed to create a variable with my external IP Address.

data "http" "ip" {
  url = "http://ipv4.icanhazip.com"
}

output "MyextIP" {
  value = chomp(data.http.ip.response_body)
}

output "myextIPCIDR" {
  value = "${chomp(data.http.ip.response_body)}/32"
}
PublicNAT

The publicNAT module provisions the NAT gateway into the designated subnet. The NAT gateway should be provisioned into the DMZ or Public Subnet.

resource "aws_nat_gateway" "nat" {
  allocation_id = var.EIPId
  subnet_id     = var.subnet_id

  tags = var.tags


}

output "id" {
  value = aws_nat_gateway.nat.id
}
routeAssociation

This module associates a routetable to specific subnet. In this instance, the route table associated with the NAT gateway is associated to the private subnet.

resource "aws_route_table_association" "routeTableAssociation" {
  subnet_id      = var.subnet_id
  gateway_id     = var.gateway_id
  route_table_id = var.route_table_id
}

output "id" {
  value = aws_route_table_association.routeTableAssociation.id
}
VPC

This lab leverages a single VPC with multiple subnets. This module provisions the VPC. The instance_tenancy argument is defaulted to default in the variables.tf.

resource "aws_vpc" "vpc" {
cidr_block = var.cidr_block
instance_tenancy = var.instance_tenancy
tags = var.tags
}

output "vpcID" {
value = aws_vpc.vpc.id

}

output "vpcCIDR" {
value = aws_vpc.vpc.cidr_block
}
mainRouteTableAssociation

The main route assigns a default route table to the VPC.

resource "aws_main_route_table_association" "mainAssociation" {
  vpc_id         = var.vpc_id
  route_table_id = var.route_table_id
}

output "id" {
  value = aws_main_route_table_association.mainAssociation.id
}
networkInterface

Network interfaces are provisioned to the two EC2 Instances that are deployed.

resource "aws_network_interface" "NIC" {
  subnet_id = var.subnet_id
}

output "arn" {
  value = aws_network_interface.NIC.arn
}

output "id" {
  value = aws_network_interface.NIC.id
}

output "prefixes" {
  value = aws_network_interface.NIC.ipv4_prefixes
}
pemkey

This module exports the pemkey that is created and places it into the command line current directory.

resource "tls_private_key" "privkey" {
  algorithm = var.algorithm
  rsa_bits  = var.rsa_bits
}

resource "aws_key_pair" "kp" {
  key_name   = var.key_name
  public_key = tls_private_key.privkey.public_key_openssh

  provisioner "local-exec" {
    command = "echo '${tls_private_key.privkey.private_key_pem}' > ./${var.key_name}.pem"
  }
}

resource "local_file" "ssh_key" {
  filename = "${var.key_name}.pem"
  content  = tls_private_key.privkey.private_key_pem
}

output "id" {
  value = aws_key_pair.kp.id
}

output "key_name" {
  value = aws_key_pair.kp.key_name
}

routeTable

Several Route Associations are created in this lab. One for the public subnet that creates a default route to the internet gateway, and another that creates a default route to the NAT gateway. The Nat Gateway route association table is assigned to the private subnet.

resource "aws_route_table" "routeble" {
  vpc_id = var.vpc_id
  route  = var.route



  tags = var.tags

}

output "id" {
  value = aws_route_table.routeble.id
}
securityGroup

A security group is created to allow communication between the subnets as well as RDP access into the EC2 instance provisioned in the public subnet.

resource "aws_security_group" "security_group" {
  name        = var.name
  description = var.description
  vpc_id      = var.vpc_id
}

output "id" {
  value = aws_security_group.security_group.id
}

output "arn" {
  value = aws_security_group.security_group.arn
}

securityGroupRule

This module is used to add the rules to the security group that was created from the module above.

resource "aws_security_group_rule" "security_group_rule" {
  type              = var.type
  from_port         = var.from_port
  to_port           = var.to_port
  protocol          = var.protocol
  cidr_blocks       = var.CIDRBlock
  security_group_id = var.security_group_id
}
subnet

This module provisions the subnets in the VPC.

resource "aws_subnet" "subnet" {
  vpc_id     = var.vpc_id
  cidr_block = var.cidr_block

  tags = var.tags
}

output "subnet_id" {
  value = aws_subnet.subnet.id
}