Setup VPC, Public/Private Subnets, Internet Gateway, Route Table, Security Groups, EC2 Instance With Terraform
How To Use Terraform To Create AWS Infrastructure
Terraform Tutorial To Launch VPC Subnets EC2 Instances
# Introduction To Terraform:
# End Goal
We will be creating a complete infrastructure in a minute using Terraform which can run your whole application. Following are the components we will be creating:
- VPC (Virtual Private Cloud)
- Public subnet (for webserver) & Private subnet (for database server)
- Internet Gateway
- Route Table
- Security Groups (for webserver and database server)
- Key Pair
- EC2 Instance (For webserver and database)
# Video Tutorial
# Prerequisites
- AWS Account
- Basic understanding or knowledge of AWS related terminology
- IAM user access key and secret key (IAM user should have permission to create required resources).
# Create public key
- Generate public key from private key
ssh-keygen -y -f ~/.ssh/pemfile/mumbai.pem
# File to store global variables (variables.tf)
variable "aws_region" { description = "Region for the VPC" default = "ap-southeast-1" } variable "vpc_cidr" { description = "CIDR for the VPC" default = "10.0.0.0/16" } variable "public_subnet_cidr" { description = "CIDR for the public subnet" default = "10.0.1.0/24" } variable "private_subnet_cidr" { description = "CIDR for the private subnet" default = "10.0.2.0/24" } variable "ami" { description = "Amazon Linux AMI" default = "ami-14c5486b"
} variable "key_path" { description = "SSH Public Key path" default = "public_key" }
# Set provider to AWS (provider.tf)
# Define AWS as our provider
provider "aws" {
region = "${var.aws_region}"
}
# Creating VPC, Subnets, Internet Gateway, Route Table, Security Groups (vpc.tf)
# Define our VPC
resource "aws_vpc" "default" {
cidr_block = "${var.vpc_cidr}"
enable_dns_hostnames = true
tags {
Name = "test-vpc"
}
}
# Define the public subnet
resource "aws_subnet" "public-subnet" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "${var.public_subnet_cidr}"
availability_zone = "ap-southeast-1"
tags {
Name = "Web Public Subnet"
}
}
# Define the private subnet
resource "aws_subnet" "private-subnet" {
vpc_id = "${aws_vpc.default.id}"
cidr_block = "${var.private_subnet_cidr}"
availability_zone = "us-east-1b"
tags {
Name = "Database Private Subnet"
}
}
# Define the internet gateway
resource "aws_internet_gateway" "gw" {
vpc_id = "${aws_vpc.default.id}"
tags {
Name = "VPC IGW"
}
}
# Define the route table
resource "aws_route_table" "web-public-rt" {
vpc_id = "${aws_vpc.default.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.gw.id}"
}
tags {
Name = "Public Subnet RT"
}
}
# Assign the route table to the public Subnet
resource "aws_route_table_association" "web-public-rt" {
subnet_id = "${aws_subnet.public-subnet.id}"
route_table_id = "${aws_route_table.web-public-rt.id}"
}
# Define the security group for public subnet
resource "aws_security_group" "sgweb" {
name = "vpc_test_web"
description = "Allow incoming HTTP connections & SSH access"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = -1
to_port = -1
protocol = "icmp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } vpc_id="${aws_vpc.default.id}" tags { Name = "Web Server SG" } } # Define the security group for private subnet resource "aws_security_group" "sgdb"{ name = "sg_test_web" description = "Allow traffic from public subnet" ingress { from_port = 3306 to_port = 3306 protocol = "tcp" cidr_blocks = ["${var.public_subnet_cidr}"] } ingress { from_port = -1 to_port = -1 protocol = "icmp" cidr_blocks = ["${var.public_subnet_cidr}"] } ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["${var.public_subnet_cidr}"] } vpc_id = "${aws_vpc.default.id}" tags { Name = "DB SG" } }
# Creating Key-pair, Instances (resources.tf)
# Define SSH key pair for our instances
resource "aws_key_pair" "default" {
key_name = "mumbai"
public_key = "${file("${var.key_path}")}"
}
# Define webserver inside the public subnet
resource "aws_instance" "wb" {
ami = "${var.ami}"
instance_type = "t1.micro"
key_name = "${aws_key_pair.default.id}"
subnet_id = "${aws_subnet.public-subnet.id}"
vpc_security_group_ids = ["${aws_security_group.sgweb.id}"]
associate_public_ip_address = true
source_dest_check = false
user_data = "${file("userdata.sh")}"1
tags {
Name = "webserver"
}
}
# Define database inside the private subnet
resource "aws_instance" "db" {
ami = "${var.ami}"
instance_type = "t1.micro"
key_name = "${aws_key_pair.default.id}"
subnet_id = "${aws_subnet.private-subnet.id}"
vpc_security_group_ids = ["${aws_security_group.sgdb.id}"]
source_dest_check = false
tags {
Name = "database"
}
}
# Userdata for webserver instance (userdata.sh)
#!/bin/sh
set -x # output log of userdata to /var/log/user-data.log exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
yum install -y httpd service httpd start chkonfig httpd on echo "<html><h1>Hello from Appychip</h2></html>" > /var/www/html/index.html
Finally after creating these files in a folder "terraform-example", you can run "terraform plan" inside terraform-example directory to see what all resources will be created. This will simply tell you what all resources would be created instead of actually creating them. Run "terraform apply" to actually create these resources.
thanks, you gave very good information
ReplyDeleteThis comment has been removed by the author.
DeleteThanks !
ReplyDeleteThat was really a great Article.Thanks for sharing information. COntinue doing this.
ReplyDeleteAWS Online Training Hyderabad
AWS Course