Posted: Saturday, February 4, 2023
Word Count: 1037
Reading Time: 5 minutes
The following Azure vWAN deployment includes the following:
AWS NAT Gateway – Terraform: | Click Here |
Visual Studio Code: | Click Here |
AWS S3 cli: | Click Here |
Terraform Download | Click Here |
Resource | Cost per hour |
---|---|
T2.medium or t3a.medium instance x 2 | $0.12 |
VPC with NAT Gateway | $0.06 |
Monthly Estimate | $132.00 |
Standard Terraform commands can be used to deploy the lab.
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.
Additionally, the private key would have been copied to the local directory.
terraform apply -destroy
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.
There are 14 modules leveraged in this terraform deployment:
Most variables are set in the variables.tf file in the primary folder.
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
}
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
}
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
}
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"
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}
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
}