Skip to content

Commit

Permalink
Merge pull request #1 from TechHoldingLLC/vpc
Browse files Browse the repository at this point in the history
Terraform module for VPC
  • Loading branch information
kaustubhposhiya authored Nov 28, 2023
2 parents b4942ed + 904c97f commit b40fc61
Show file tree
Hide file tree
Showing 10 changed files with 603 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
terraform.tfstate*
.terraform*
tfplan
85 changes: 85 additions & 0 deletions EXAMPLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# VPC
Below is an examples of calling this module.

## Create a Basic VPC with only Public Subnets
```
module "vpc" {
source = "./vpc"
name = "test-vpc"
create_private_subnets = false
cidr_block = "10.0.0.0/16" # update the value according to the needs
providers = {
aws = aws
}
}
```

## Create a VPC with Private Subnet and NAT Instance
```
module "vpc" {
source = "./vpc"
name = "test-vpc"
cidr_block = "10.0.0.0/16"
number_of_aws_az_use = 2
create_private_subnets = true
nat_type = "instance"
nat_instance_key_name = "test-vpc-nat-instance"
nat_instance_sg_ingress = [
{
protocol = -1
from_port = 0
to_port = 0
cidr_blocks = ["10.0.0.0/16"]
}
]
nat_instance_sg_egress = [
{
protocol = -1
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
]
providers = {
aws = aws
}
}
```


## Create a VPC with Private Subnet and NAT Gateway
```
module "vpc" {
source = "./vpc"
name = "test-vpc"
cidr_block = "10.0.0.0/16"
create_private_subnets = true
nat_type = "gateway"
providers = {
aws = aws
}
}
```

## Create a VPC with Flow logs
```
module "vpc" {
source = "./vpc"
name = "test-vpc"
cidr_block = "10.0.0.0/16"
create_private_subnets = true
nat_type = "gateway"
enable_flow_log = true
providers = {
aws = aws
}
}
```

88 changes: 86 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,86 @@
# terraform-aws-vpc
Terraform module for VPC
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.5 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.5 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_ec2_nat_instance"></a> [ec2\_nat\_instance](#module\_ec2\_nat\_instance) | git::https://github.com/TechHoldingLLC/terraform-aws-ec2.git | v1.0.0 |
| <a name="module_nat_instance_sg"></a> [nat\_instance\_sg](#module\_nat\_instance\_sg) | git::https://github.com/TechHoldingLLC/terraform-aws-security-group.git | v0.0.1 |

## Resources

| Name | Type |
|------|------|
| [aws_cloudwatch_log_group.vpc_flow_log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource |
| [aws_eip.ngw_eip](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
| [aws_flow_log.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/flow_log) | resource |
| [aws_iam_role.vpc_flow_log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy.vpc_flow_log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
| [aws_internet_gateway.igw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource |
| [aws_nat_gateway.ngw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway) | resource |
| [aws_route.igw_route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route.ngw_route](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route) | resource |
| [aws_route_table.private_route_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
| [aws_route_table.public_route_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table) | resource |
| [aws_route_table_association.private_route_table_assoc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_route_table_association.public_route_table_assoc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association) | resource |
| [aws_subnet.private_subnet](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_subnet.public_subnet](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet) | resource |
| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) | resource |
| [aws_ami.amazon_linux_nat_instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source |
| [aws_iam_policy_document.vpc_flow_log](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.vpc_flow_log_trust_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_cidr_block"></a> [cidr\_block](#input\_cidr\_block) | The CIDR block defining the private IP address space used | `string` | n/a | yes |
| <a name="input_create_private_subnets"></a> [create\_private\_subnets](#input\_create\_private\_subnets) | Create private subnets flag | `bool` | `false` | no |
| <a name="input_enable_flow_log"></a> [enable\_flow\_log](#input\_enable\_flow\_log) | Flag to enable/disable vpc flow log | `bool` | `false` | no |
| <a name="input_flow_log_retention_in_days"></a> [flow\_log\_retention\_in\_days](#input\_flow\_log\_retention\_in\_days) | Flow logs retention in days | `number` | `0` | no |
| <a name="input_name"></a> [name](#input\_name) | VPC name | `string` | n/a | yes |
| <a name="input_nat_instance_ami_id"></a> [nat\_instance\_ami\_id](#input\_nat\_instance\_ami\_id) | NAT instance AMI id | `string` | `""` | no |
| <a name="input_nat_instance_key_name"></a> [nat\_instance\_key\_name](#input\_nat\_instance\_key\_name) | NAT instance key pair name | `string` | `""` | no |
| <a name="input_nat_instance_sg_egress"></a> [nat\_instance\_sg\_egress](#input\_nat\_instance\_sg\_egress) | Egress for Nat instance Security Group | `list(any)` | `[]` | no |
| <a name="input_nat_instance_sg_ingress"></a> [nat\_instance\_sg\_ingress](#input\_nat\_instance\_sg\_ingress) | Ingress for Nat instance Security Group | `list(any)` | `[]` | no |
| <a name="input_nat_instance_type"></a> [nat\_instance\_type](#input\_nat\_instance\_type) | NAT instance type | `string` | `"t3.nano"` | no |
| <a name="input_nat_type"></a> [nat\_type](#input\_nat\_type) | NAT type i.e `instance` or `gateway` | `string` | `""` | no |
| <a name="input_number_of_aws_az_use"></a> [number\_of\_aws\_az\_use](#input\_number\_of\_aws\_az\_use) | How many aws avaibility zones use for deployment | `number` | `2` | no |
| <a name="input_number_of_nat_gw"></a> [number\_of\_nat\_gw](#input\_number\_of\_nat\_gw) | Number of nat gateway for private subnets | `number` | `1` | no |
| <a name="input_subnet_mask_bits"></a> [subnet\_mask\_bits](#input\_subnet\_mask\_bits) | Number of bits to use in CIDR subnet mask | `number` | `8` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_availability_zones"></a> [availability\_zones](#output\_availability\_zones) | n/a |
| <a name="output_cidr_block"></a> [cidr\_block](#output\_cidr\_block) | n/a |
| <a name="output_id"></a> [id](#output\_id) | n/a |
| <a name="output_name"></a> [name](#output\_name) | n/a |
| <a name="output_nat_gateway_id"></a> [nat\_gateway\_id](#output\_nat\_gateway\_id) | n/a |
| <a name="output_nat_instance_ip"></a> [nat\_instance\_ip](#output\_nat\_instance\_ip) | n/a |
| <a name="output_nat_instance_security_group_ids"></a> [nat\_instance\_security\_group\_ids](#output\_nat\_instance\_security\_group\_ids) | n/a |
| <a name="output_private_route_table_ids"></a> [private\_route\_table\_ids](#output\_private\_route\_table\_ids) | n/a |
| <a name="output_private_subnet_ids"></a> [private\_subnet\_ids](#output\_private\_subnet\_ids) | n/a |
| <a name="output_private_subnets_availability_zone"></a> [private\_subnets\_availability\_zone](#output\_private\_subnets\_availability\_zone) | n/a |
| <a name="output_private_subnets_cidr"></a> [private\_subnets\_cidr](#output\_private\_subnets\_cidr) | n/a |
| <a name="output_public_route_table_ids"></a> [public\_route\_table\_ids](#output\_public\_route\_table\_ids) | n/a |
| <a name="output_public_subnet_availability_zones"></a> [public\_subnet\_availability\_zones](#output\_public\_subnet\_availability\_zones) | n/a |
| <a name="output_public_subnet_cidrs"></a> [public\_subnet\_cidrs](#output\_public\_subnet\_cidrs) | n/a |
| <a name="output_public_subnet_ids"></a> [public\_subnet\_ids](#output\_public\_subnet\_ids) | n/a |

## License

Apache 2 Licensed. See [LICENSE](https://github.com/TechHoldingLLC/terraform-aws-vpc/blob/main/LICENSE) for full details.
7 changes: 7 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#################
# vpc/data.tf #
#################

data "aws_availability_zones" "available" {
state = "available"
}
61 changes: 61 additions & 0 deletions flow-logs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
######################
# vpc/flow-logs.tf #
######################

resource "aws_cloudwatch_log_group" "vpc_flow_log" {
count = var.enable_flow_log ? 1 : 0
name = "/vpc/${aws_vpc.vpc.tags.Name}/flow_log"
retention_in_days = var.flow_log_retention_in_days
}

resource "aws_flow_log" "vpc" {
count = var.enable_flow_log ? 1 : 0
iam_role_arn = aws_iam_role.vpc_flow_log.0.arn
log_destination = aws_cloudwatch_log_group.vpc_flow_log.0.arn
traffic_type = "ALL"
vpc_id = aws_vpc.vpc.id
}

resource "aws_iam_role" "vpc_flow_log" {
count = var.enable_flow_log ? 1 : 0
name = "${aws_vpc.vpc.tags.Name}-vpc-flow-log"
assume_role_policy = data.aws_iam_policy_document.vpc_flow_log_trust_policy.json
}

data "aws_iam_policy_document" "vpc_flow_log_trust_policy" {
statement {

effect = "Allow"

principals {
type = "Service"
identifiers = ["vpc-flow-logs.amazonaws.com"]
}

actions = ["sts:AssumeRole"]
}
}

resource "aws_iam_role_policy" "vpc_flow_log" {
count = var.enable_flow_log ? 1 : 0
name = aws_iam_role.vpc_flow_log.0.name
role = aws_iam_role.vpc_flow_log.0.name
policy = data.aws_iam_policy_document.vpc_flow_log.json
}

data "aws_iam_policy_document" "vpc_flow_log" {
statement {

effect = "Allow"

actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
]

resources = ["*"]
}
}
77 changes: 77 additions & 0 deletions nat-instance.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#########################
# vpc/nat-instance.tf #
#########################


data "aws_ami" "amazon_linux_nat_instance" {
most_recent = true

filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-ebs"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

owners = ["amazon"] # Canonical
}

module "ec2_nat_instance" {
count = var.nat_type == "instance" ? 1 : 0
source = "git::https://github.com/TechHoldingLLC/terraform-aws-ec2.git?ref=v1.0.0"
name = "${var.name}-nat-instance"
ami_id = var.nat_instance_ami_id == "" ? data.aws_ami.amazon_linux_nat_instance.id : var.nat_instance_ami_id
instance_type = var.nat_instance_type
subnet = element(aws_subnet.public_subnet.*.id, 1)
vpc_id = aws_vpc.vpc.id
eip = true
source_dest_check = false
key_name = var.nat_instance_key_name
disable_api_termination = false

user_data = <<END
#!/bin/bash
sudo echo "net.ipv4.ip_forward=1" > /etc/sysctl.conf
sudo sysctl -p
sudo /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo yum install -y iptables-services
sudo service iptables save
sudo chkconfig iptables on
sudo service iptables start
END

security_group_ids = [module.nat_instance_sg.0.id]

providers = {
aws = aws
}
}

module "nat_instance_sg" {
count = var.nat_type == "instance" ? 1 : 0
source = "git::https://github.com/TechHoldingLLC/terraform-aws-security-group.git?ref=v0.0.1"
name = "${var.name}-nat-instance"
vpc_id = aws_vpc.vpc.id
egress = length(var.nat_instance_sg_egress) > 0 ? var.nat_instance_sg_egress : [
{
protocol = -1
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
]
ingress = length(var.nat_instance_sg_ingress) > 0 ? var.nat_instance_sg_ingress : [
{
protocol = -1
from_port = 0
to_port = 0
cidr_blocks = [aws_vpc.vpc.cidr_block]
}
]
providers = {
aws = aws
}
}
63 changes: 63 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
####################
# vpc/outputs.tf #
####################

output "availability_zones" {
value = slice(data.aws_availability_zones.available.names, 0, var.number_of_aws_az_use)
}

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

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

output "name" {
value = aws_vpc.vpc.tags.Name
}

output "nat_instance_security_group_ids" {
value = var.nat_type == "instance" ? module.nat_instance_sg.0.id : null
}

output "nat_instance_ip" {
value = var.nat_type == "instance" ? module.ec2_nat_instance.0.public_ip : null
}

output "nat_gateway_id" {
value = var.nat_type == "gateway" ? aws_nat_gateway.ngw.*.id : null
}

output "public_route_table_ids" {
value = aws_route_table.public_route_table.*.id
}

output "public_subnet_ids" {
value = aws_subnet.public_subnet.*.id
}

output "public_subnet_availability_zones" {
value = aws_subnet.public_subnet.*.availability_zone
}

output "public_subnet_cidrs" {
value = aws_subnet.public_subnet.*.cidr_block
}

output "private_subnet_ids" {
value = var.create_private_subnets ? aws_subnet.private_subnet.*.id : null
}

output "private_route_table_ids" {
value = aws_route_table.private_route_table.*.id
}

output "private_subnets_availability_zone" {
value = var.create_private_subnets ? aws_subnet.private_subnet.*.availability_zone : null
}

output "private_subnets_cidr" {
value = var.create_private_subnets ? aws_subnet.private_subnet.*.cidr_block : null
}
Loading

0 comments on commit b40fc61

Please sign in to comment.