FEATURES OPEN SOURCE ABOUT DOCS LOGIN REGISTER

AWS non-default VPC

Introduction

In this guide we will learn more about creating a custom AWS network for our VMs. The main objective of this guide is to show how you can customize your stack template further to define your own network structure and add instances to your network. We will create a high availability service by creating a two tier structure having a single web server and two database instances. Each server will be in different physical location.

two-tier-vpc.png Table of contents

Before we start..

It is a good idea to familiarize yourself with AWS VPC (Virtual Private Cloud) if you are not familiar with it already, please spend sometime to understand its concepts. This will help you greatly to go through this guide of how we create our stack template for our AWS non-default VPC.

We will create a VPC (Virtual Private Cloud) with subnets created in different availability zones (different physical locations) to ensure higher availability. Learn more about AWS availability zones

In this guide we will learn how to create:

  1. AWS VPC (Virtual Private Cloud)
  2. Subnets
  3. Internet Gateway
  4. Routing Tables
  5. Security Groups
  6. Attach Elastic IPs to our VMs
  7. Create a VM within a subnet

Our intended structure is to have an AWS non-default VPC (Virtual Private Cloud) with three subnets and three VMs with access to internet:

VPC network

Full Stack

This is the full listing of our stack template. Continue reading below to go through the explanation of each section.

# This stack will create a two-tier VPC with Elastic IP

provider:
  aws:
    access_key: '${var.aws_access_key}'
    secret_key: '${var.aws_secret_key}'
resource:
  aws_vpc:
    main:
      cidr_block: 10.0.0.0/16
      instance_tenancy: "default"
      tags:
        Name: 'Koding-VPC'

  aws_subnet:
    subnet1:
      vpc_id: '${aws_vpc.main.id}'
      availability_zone: 'eu-west-1a'
      cidr_block: 10.0.10.0/24
      tags:
        Name: 'Koding-VPC-10.0.10.0'
    subnet2:
      vpc_id: '${aws_vpc.main.id}'
      availability_zone: 'eu-west-1b'
      cidr_block: 10.0.20.0/24
      tags:
        Name: 'Koding-VPC-10.0.20.0'
    subnet3:
      vpc_id: '${aws_vpc.main.id}'
      availability_zone: 'eu-west-1c'
      cidr_block: 10.0.30.0/24
      tags:
        Name: 'Koding-VPC-10.0.30.0'

  aws_internet_gateway:
    internet_gw:
      vpc_id: '${aws_vpc.main.id}'
      tags:
        Name: 'Koding-VPC-internet-gateway'

  aws_route_table:
    internet_rtable:
      vpc_id: '${aws_vpc.main.id}'
      route:
        cidr_block: 0.0.0.0/0
        gateway_id: '${aws_internet_gateway.internet_gw.id}'
      tags:
        Name: 'Koding-VPC-route-table'

  aws_route_table_association:
    subnet1_associate:
      subnet_id: '${aws_subnet.subnet1.id}'
      route_table_id: '${aws_route_table.internet_rtable.id}'
    subnet2_associate:
      subnet_id: '${aws_subnet.subnet2.id}'
      route_table_id: '${aws_route_table.internet_rtable.id}'
    subnet3_associate:
      subnet_id: '${aws_subnet.subnet3.id}'
      route_table_id: '${aws_route_table.internet_rtable.id}'

  aws_security_group:
    security_group:
      name: 'Koding-VPC-sg'
      description: 'Koding VPC allowed traffic'
      vpc_id: '${aws_vpc.main.id}'
      tags:
        Name: 'Koding-allowed-traffic'
      ingress:
        - from_port: 22
          to_port: 22
          protocol: tcp
          cidr_blocks:
            - 0.0.0.0/0
        - from_port: 80
          to_port: 80
          protocol: tcp
          cidr_blocks:
            - 0.0.0.0/0
        - from_port: 56789
          to_port: 56789
          protocol: tcp
          cidr_blocks:
            - 0.0.0.0/0
      egress:
        - from_port: 0
          to_port: 65535
          protocol: tcp
          cidr_blocks:
            - 0.0.0.0/0
  aws_eip:
    team-web-server_eip:
      instance: '${aws_instance.team-web-server.id}'
      vpc: true
    db_master_eip:
      instance: '${aws_instance.db-master.id}'
      vpc: true
    db_slave_eip:
      instance: '${aws_instance.db-slave.id}'
      vpc: true

  aws_instance:
    team-web-server:
      instance_type: t2.micro
      subnet_id: '${aws_subnet.subnet1.id}'
      depends_on: ['aws_internet_gateway.internet_gw']
      vpc_security_group_ids:
        - '${aws_security_group.security_group.id}'
      ami: ''
      tags:
        Name: 'alpha-webserver-${var.koding_user_username}-${var.koding_group_slug}'

    db-master:
      instance_type: t2.micro
      subnet_id: '${aws_subnet.subnet2.id}'
      depends_on: ['aws_internet_gateway.internet_gw']
      vpc_security_group_ids:
        - '${aws_security_group.security_group.id}'
      ami: ''
      tags:
        Name: 'DB-master-${var.koding_user_username}-${var.koding_group_slug}'

    db-slave:
      instance_type: t2.micro
      subnet_id: '${aws_subnet.subnet3.id}'
      depends_on: ['aws_internet_gateway.internet_gw']
      vpc_security_group_ids:
        - '${aws_security_group.security_group.id}'
      ami: ''
      tags:
        Name: 'DB-slave-${var.koding_user_username}-${var.koding_group_slug}'

Steps

Along the next sections, we will write our stack template section by section showing what each section accomplishes in our network

Creating a stack

  1. Click Stacks
  2. Click New Stack
  3. Choose Amazon -> Click Next
  4. Set your AWS credentials in the Credentials tab

For detailed steps on how to create an AWS stack you can refer to Create AWS Stack guide

We created our AWS keys in region EU Ireland (eu-west-1), which means our Availability Zones will be relevant to this region. Learn more about AWS availability zones

regions_01-1.jpg


Edit your stack name

A stack name is auto generated when you create a new stack, however if you plan on having multiple stacks, it is a good practice to name your Stack to something you can remember in a glance.

the-stack-name.png


Provider

The first section defines the service provider, usually you wouldn’t need to change this part

# This stack will create a two-tier VPC with Elastic IP

provider:
  aws:
    access_key: '${var.aws_access_key}'
    secret_key: '${var.aws_secret_key}'

Create a VPC

Create the VPC network that will contain all our VMs

resource:
  aws_vpc:
    main:
      cidr_block: 10.0.0.0/16
      instance_tenancy: "default"
      tags:
        Name: 'Koding-VPC'

Explanation:

Network status:

network-vpc-begin.png


Create subnets

aws_subnet:
    subnet1:
      vpc_id: '${aws_vpc.main.id}'
      availability_zone: 'eu-west-1a'
      cidr_block: 10.0.10.0/24
      tags:
        Name: 'Koding-VPC-10.0.10.0'
    subnet2:
      vpc_id: '${aws_vpc.main.id}'
      availability_zone: 'eu-west-1b'
      cidr_block: 10.0.20.0/24
      tags:
        Name: 'Koding-VPC-10.0.20.0'
    subnet3:
      vpc_id: '${aws_vpc.main.id}'
      availability_zone: 'eu-west-1c'
      cidr_block: 10.0.30.0/24
      tags:
        Name: 'Koding-VPC-10.0.30.0'

Explanation:

Subnet IP name tag Availability Zone
subnet1 10.0.10.0 Koding-VPC-10.0.10.0 eu-west-1a
subnet2 10.0.20.0 Koding-VPC-10.0.20.0 eu-west-1b
subnet3 10.0.30.0 Koding-VPC-10.0.30.0 eu-west-1c

Learn more about AWS availability zones

Network status:

Subnets


Create Internet Gateway

aws_internet_gateway:
  internet_gw:
    vpc_id: '${aws_vpc.main.id}'
    tags:
      Name: 'Koding-VPC-internet-gateway'

Explanation:

Network status:

Internet Gateway


Create Route Table

aws_route_table:
  internet_rtable:
    vpc_id: '${aws_vpc.main.id}'
    route:
      cidr_block: 0.0.0.0/0
      gateway_id: '${aws_internet_gateway.internet_gw.id}'
    tags:
      Name: 'Koding-VPC-route-table'

Explanation:

Network status:

Route Table


Associate route table with our subnets

aws_route_table_association:
  subnet1_associate:
    subnet_id: '${aws_subnet.subnet1.id}'
    route_table_id: '${aws_route_table.internet_rtable.id}'
  subnet2_associate:
    subnet_id: '${aws_subnet.subnet2.id}'
    route_table_id: '${aws_route_table.internet_rtable.id}'
  subnet3_associate:
    subnet_id: '${aws_subnet.subnet3.id}'
      route_table_id: '${aws_route_table.internet_rtable.id}'

Explanation:

aws_route_table_association: we create our route table Associations below_ “aws_route_table_association” header

Network status:

Associate route table


Create Security Group

We will create a single security group to define our allowed IP & ports ranges for our VMs

aws_security_group:
  security_group:
    name: 'Koding-VPC-sg'
    description: 'Koding VPC allowed traffic'
    vpc_id: '${aws_vpc.main.id}'
    tags:
      Name: 'Koding-allowed-traffic'
    ingress:
      - from_port: 22
        to_port: 22
        protocol: tcp
        cidr_blocks:
          - 0.0.0.0/0
      - from_port: 80
        to_port: 80
        protocol: tcp
        cidr_blocks:
          - 0.0.0.0/0
      - from_port: 56789
        to_port: 56789
        protocol: tcp
        cidr_blocks:
          - 0.0.0.0/0
    egress:
      - from_port: 0
        to_port: 65535
        protocol: tcp
        cidr_blocks:
          - 0.0.0.0/0

Explanation:


Generate & assign Elastic IPs

Creating a non-default AWS VPC will not assign public IPs to our VMs, only private IPs. We generate Elastic IPs here and connect them with our instances which we will create in the next section of our Stack Template file.

aws_eip:
  team-web-server_eip:
    instance: '${aws_instance.team-web-server.id}'
    vpc: true
  db_master_eip:
    instance: '${aws_instance.db-master.id}'
    vpc: true
  db_slave_eip:
    instance: '${aws_instance.db-slave.id}'
    vpc: true

Explanation:


Create Instances

This is our last section of our VPC Stack template, we now have everything related to the network set and only waiting for our VMs to be created. As mentioned before we will create a single instance in each subnet.


aws_instance:
  team-web-server:
    instance_type: t2.micro
    subnet_id: '${aws_subnet.subnet1.id}'
    depends_on: ['aws_internet_gateway.internet_gw']
    vpc_security_group_ids:
      - '${aws_security_group.security_group.id}'
    ami: ''
    tags:
      Name: 'alpha-webserver-${var.koding_user_username}-${var.koding_group_slug}'

  db-master:
    instance_type: t2.micro
    subnet_id: '${aws_subnet.subnet2.id}'
    depends_on: ['aws_internet_gateway.internet_gw']
    vpc_security_group_ids:
      - '${aws_security_group.security_group.id}'
    ami: ''
    tags:
      Name: 'DB-master-${var.koding_user_username}-${var.koding_group_slug}'

  db-slave:
    instance_type: t2.micro
    subnet_id: '${aws_subnet.subnet3.id}'
    depends_on: ['aws_internet_gateway.internet_gw']
    vpc_security_group_ids:
      - '${aws_security_group.security_group.id}'
    ami: ''
    tags:
      Name: 'DB-slave-${var.koding_user_username}-${var.koding_group_slug}'

Explanation:

Network status:

Instances


Full steps visualized

These are the steps we moved through to create our AWS non-default VPC:

Full steps animation


Build & Test our stack

Let’s now start to build our stack to test our stack template file

Save & test the stack template

Click Save, your stack should build successfully. If there are any errors you will need to attend to them before building your stack.

VPC success2

Build Stack

Click Initialize and close your stack template, follow the step by step modal to build your Stack. 

Stack building

Successful build!

The three VMs are now ready, you and your team can now use your new stack template to build your environments and start Koding!

all-built.png


Further Notes

Congratulations, you have now learned how to build an AWS non-default VPC for your team. You can further experiment and test your stack file. You might want to consider building your VM’s ready with the packages required for Each VM. You can make use of the user_data header. i.e. install Apache on webserver and MySQL or Postgres on your DB instances. You can refer to Modifying user_data section in our “Advanced stack editing” guide.


Troubleshooting