 In this tutorial, I will show you how to setup a **VPC** as described in the network diagram below in less than **1 min** using **Terraform**:  The **VPC** topology above is the best demonstration of what will be implemented: * The **private subnet** is inaccessible to the internet (both in and out) * The **public subnet** is accessible and all traffic (0.0.0.0/0) is routed directly to the **internet Gateway** Before we dive in, all the code used in this demo is available at my [**Github**](https://github.com/mlabouardy/terraform-aws-labs). Note: I already did a [**tutorial**](http://www.blog.labouardy.com/manage-aws-infrastracture-as-code-with-terraform/) on how to get started with **Terraform** so make sure to read it for more details. **1 — Global variables** This file contains environment specific configuration like region name, CIDR blocks, and AWS credentials … **2 — Configure the AWS provider** **3 — Create a VPC** **4 — Create Subnets** To make the **public subnet** addressable by the **Internet**, we need an **Internet Gateway**: **5 — Internet Gateway** To allow traffics from the **public subnet** to the internet throught the **NAT Gateway**, we need to create a new **Route Table**. **6 — Route Table** Next, we will create a security group for each subnet. **7 — Security Groups** **7 .1 — WebServer SG** This **Security Group** allows **HTTP/HTTPS** and **SSH** connections from **anywhere**. **7.2 — Database SG** This **Security Group** enable **MySQL 3306** port, **ping** and **SSH** only from the **public subnet**. Now we will deploy the **EC2** instances, but before that we need to create a **key pair** in order to connect later to the instances via **SSH**. **8 — Key Pair** **9 — EC2 Instances** **9.1 — WebServer Instance** This instance will play the role of a **webserver.** Therefore, we pass to the instance **userdata** a shell script **install.sh** which contains commands to install an **Apache Server**: **9.2 — Database Instance** Once you’ve defined all the required templates, make sure to set the **AWS** **credentials** variables as an **envrionment variables**: |export AWS\_ACCESS\_KEY\_ID=”YOUR ACCESS KEY ID” |export AWS\_SECRET\_ACCESS\_KEY=”YOUR SECRET ACCESS KEY” Note: You can always use your **root user** which has access permission to everything, but for security perspective, its recommended to use only a limited permissions user account. So create a new one using **AWS IAM**. To see how terraform plans to create the resources type “**terraform plan**“. To create the infrastructure type “**terraform apply**“: [](https://asciinema.org/a/9wqCgDworzVqM4jDSs6cIHCWJ) That will bring up the **VPC**, and all the necessary resources. Now in your [**AWS Management Console**](https://console.aws.amazon.com/) you should see the resources created:  If you click on the “**Subnets**” menu, you should see the **public** & **private subnets**:  The same goes for the **Route Tables**:  And the **Internet Gateway**:  **Security Groups** also:  **WebServer Security group:**  **Database Security Group:**  And finally the **EC2 Instances:**  **WebServer Instance:**  **Database Instance:**  Don’t forget to destroy the resources if they are not needed by typing “**terraform destroy**“: [](https://asciinema.org/a/0VRbQdMmqVa7E6HhLK0bqTrat)