Intro
Subnets, public and private subnets, these are all networking issues. Therefore, network basics are required to understand the difference between public and private subnets. Network concepts may seem a little complicated at first. Don’t be afraid! I will explain the necessary ones, starting from general to specific.
What is AWS?
Amazon Web Services (AWS) is the world’s most comprehensive and broadly adopted cloud platform. It offers over 200 fully-featured services from data centers globally. These data centers and the servers are connected over cables, forming a giant physical network. AWS also virtualizes the storage and computing capacities of the physical servers. That makes it possible to serve the enormous power more efficiently. So users can immediately access thousands of high process instances and tens of terabytes of storage.
What is a VPC?
The virtualization creates the need for a virtual network, which connects virtual machines and devices, no matter their location, using softwares. And this brings us to the virtual private cloud. A Virtual Private Cloud (VPC) is a virtual network dedicated to your AWS account. It is a private area logically isolated from other virtual networks in the AWS Cloud. You can launch your AWS resources, such as Amazon EC2 instances, into your VPC.
What does CIDR Block means?
When you create a VPC, you must specify a range of IPv4 addresses for the VPC in the form of a Classless Inter-Domain Routing (CIDR) block; for example, 10.0.0.0/16. This is the primary CIDR block for your VPC. Here, 10.0.0.0/16 defines 65536 IPv4 addresses in your VPC. Using these IPv4 addresses, you can create your resources within the VPC. They can communicate with each other and connect to the internet as needed. However, you are restricted with the addresses in that range.
What is a subnet?
A subnet, or subnetwork, is a network inside a network. In other words, it is a subnet(work) under Virtual Private Cloud (VPC). A subnet means a range of IP addresses in your Amazon VPC. You can launch AWS resources into a specific subnet, such as EC2 instances. When you create a subnet, you specify the IPv4 CIDR block for the subnet, a subset of the VPC CIDR block. If we compare the IPv4 range that we defined for VPC to a cake, the subnet is a slice. It is possible to cut pieces of different sizes, a sub-CIDR block, or a range of IPv4 addresses.
What is a Public subnet?
A public subnet is a subnet that is associated with a route table that has a route to an Internet gateway. This gateway connects the subnet(work) to the Internet and to other AWS services. Thus, the resources in that subnet able to communicate with the Internet.
What is a Private subnet?
A private subnet is a subnet that is associated with a route table that doesn’t have a route to an internet gateway. Resources in a private subnet cannot communicate directly with the Internet, and vice versa.
What is the difference between public and private subnets?
Let’s get to the point: The difference between public and private subnets. The instances in the public subnet can send outbound traffic directly to the Internet with the help of Internet Gateway, whereas the instances in the private subnet can’t because we are not attaching Internet Gateway to the Private Subnets.
Instead, the instances in the private subnet can access the Internet by using a Network Address Translation (NAT) gateway that resides in the public subnet.
Instances or resources living in the Private Subnet will be safer than Public Subnet because any traffic initiated from the internet can not reach directly to the endpoints in Private Subnet, but can reach in Public Subnet. Of course, we have many security measures and tools to prevent unwanted traffic like Security Groups, NACL, AWS WAF on top of existing VPC,Subnets and Routing Table to shape the traffic. But those are other posts topics.
TL;DR or Summary
The private cloud defined in your AWS account is called Virtual Private Cloud (VPC). VPC is a private network where your resources, such as the EC2 instance, are located. These resources need IPv4 addresses to communicate with each other and the Internet. You define a specific range of IPv4 when creating your VPC at the very beginning. It is also possible to create subnet(work) by dividing these addresses into narrower ranges, called a subnet. A subnet connected to the Internet is called a public subnet, and a non-connected subnet is called a private subnet. Simply put, how they can access to the Internet is the difference between public and private subnets.
Please feel free to ask if you get confused!
VPC Module.
Giờ chúng ta sẽ install vpc có public subnet và private subnet bằng VPC module.
Đầu tiên là file: c1-versions.tf
# Terraform Settings Block terraform { required_version = ">= 1.0.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 3.63" } } backend "s3" { bucket = "private-windows-nimtechnology-eks-tf-lock" key = "network.tfstate" region = "us-east-1" dynamodb_table = "private-windows-nimtechnology-eks-tf-lock" } } # Terraform Provider Block provider "aws" { region = var.aws_region }
Tiếp đến common variables: c2-01-generic-variables.tf
# Input Variables # AWS Region variable "aws_region" { description = "Region in which AWS Resources to be created" type = string default = "us-east-1" } # Environment Variable variable "environment" { description = "Environment Variable used as a prefix" type = string default = "dev" } # Business Division variable "business_divsion" { description = "Business Division in the large organization this Infrastructure belongs" type = string default = "nimtechnology" } # Business Division variable "owners" { description = "Business Division in the large organization this Infrastructure belongs" type = string default = "devops" }
Tạo 1 biến local thường được sử dụng để đặt tên. c2-02-local-values.tf
# Define Local Values in Terraform locals { owners = var.owners environment = var.environment common_tags = { owners = local.owners environment = local.environment } cluster_name = "${local.environment}-${local.owners}-${var.business_divsion}" }
Tiếp đến là các variables dành riêng cho VPC: c3-01-vpc-variables.tf
# VPC Input Variables # VPC CIDR Block variable "vpc_cidr_block" { description = "VPC CIDR Block" type = string default = "10.194.0.0/21" } # VPC Availability Zones /* variable "vpc_availability_zones" { description = "VPC Availability Zones" type = list(string) default = ["us-west-2a", "us-west-2b"] } */ # VPC Public Subnets variable "vpc_public_subnets" { description = "VPC Public Subnets" type = list(string) default = ["10.194.3.0/24"] } # VPC Private Subnets variable "vpc_private_subnets" { description = "VPC Private Subnets" type = list(string) default = ["10.194.0.0/24", "10.194.1.0/24", "10.194.2.0/24"] } # VPC Database Subnets # variable "vpc_database_subnets" { # description = "VPC Database Subnets" # type = list(string) # default = ["10.0.151.0/24", "10.0.152.0/24"] # } # VPC Create Database Subnet Group (True / False) variable "vpc_create_database_subnet_group" { description = "VPC Create Database Subnet Group" type = bool default = true } # VPC Create Database Subnet Route Table (True or False) variable "vpc_create_database_subnet_route_table" { description = "VPC Create Database Subnet Route Table" type = bool default = true } # VPC Enable NAT Gateway (True or False) variable "vpc_enable_nat_gateway" { description = "Enable NAT Gateways for Private Subnets Outbound Communication" type = bool default = true } # VPC Single NAT Gateway (True or False) variable "vpc_single_nat_gateway" { description = "Enable only single NAT Gateway in one Availability Zone to save costs during our demos" type = bool default = true }
Tiếp đến khai báo vpc terraform module: c3-02-vpc-module.tf
# AWS Availability Zones Datasource data "aws_availability_zones" "available" { } # Create VPC Terraform Module module "vpc" { source = "terraform-aws-modules/vpc/aws" # version = "3.11.0" version = "~> 3.16.1" # VPC Basic Details name = local.cluster_name cidr = var.vpc_cidr_block azs = data.aws_availability_zones.available.names public_subnets = var.vpc_public_subnets private_subnets = var.vpc_private_subnets # NAT Gateways - Outbound Communication enable_nat_gateway = var.vpc_enable_nat_gateway single_nat_gateway = var.vpc_single_nat_gateway # VPC DNS Parameters enable_dns_hostnames = true enable_dns_support = true tags = local.common_tags vpc_tags = local.common_tags # Additional Tags to Subnets public_subnet_tags = { Type = "Public Subnets" "kubernetes.io/role/elb" = 1 "kubernetes.io/cluster/${local.cluster_name}" = "shared" } private_subnet_tags = { Type = "private-subnets" "kubernetes.io/role/internal-elb" = 1 "kubernetes.io/cluster/${local.cluster_name}" = "shared" } # database_subnet_tags = { # Type = "database-subnets" # } }
Bạn có thể để ý tag chỗ này khác quan trọng. Ví VPC sẽ chưa EKS(k8s)
public_subnet_tags
andprivate_subnet_tags
: These are setting AWS tags on the public and private subnets respectively.public_subnet_tags
includes tags specific to Kubernetes to indicate that the public subnet should be used for an external load balancer (kubernetes.io/role/elb
) and it’s a part of the specific Kubernetes cluster (kubernetes.io/cluster/${local.cluster_name}
).private_subnet_tags
includes tags specific to Kubernetes to indicate that the private subnet should be used for an internal load balancer (kubernetes.io/role/internal-elb
) and it’s also a part of the specific Kubernetes cluster (kubernetes.io/cluster/${local.cluster_name}
).
Tiếp đến là output để bạn reuse thông tin của VPC bằng The terraform_remote_state Data Source
c3-03-vpc-output.tf
# VPC Output Values # VPC ID output "vpc_id" { description = "The ID of the VPC" value = module.vpc.vpc_id } # VPC CIDR blocks output "vpc_cidr_block" { description = "The CIDR block of the VPC" value = module.vpc.vpc_cidr_block } # VPC Private Subnets output "private_subnets" { description = "List of IDs of private subnets" value = module.vpc.private_subnets } # VPC Public Subnets output "public_subnets" { description = "List of IDs of public subnets" value = module.vpc.public_subnets } # VPC NAT gateway Public IP output "nat_public_ips" { description = "List of public Elastic IPs created for AWS NAT Gateway" value = module.vpc.nat_public_ips } # VPC AZs output "azs" { description = "A list of availability zones spefified as argument to this module" value = module.vpc.azs }