Saturday 7 July 2018

Create AWS Infrastructure With Terraform | VPC | Public/Private Subnets | Internet-gateway | Security-groups | EC2-Instances

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:

Terraform is Write, Plan and Create Infrastructure As a Code. We have already covered the basics of Terraform in our previous tutorial (Blog & Video Tutorial). We recommend you to go through it once before continuing this tutorial.

# 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.

4 comments:

 

Copyright @ 2013 Appychip.

Designed by Appychip & YouTube Channel