Building Infrastructure from Scratch: Creating a VPC with Terraform
Tags: terraform, aws, vpc
Published: 2024-03-13 22:37:15

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eilsbeonusupr8nvudeh.png)

Embarking on a journey to build cloud infrastructure from scratch can be both exciting and daunting. In this series, we focus on leveraging Infrastructure as Code (IaC) tools like Terraform to set up essential components in the cloud. To start, let's set up a Virtual Private Cloud (VPC) in AWS using Terraform.


## Prerequisites 

Before we start, you'll need to have a few tools and access ready:

- The [Terraform CLI (1.2.0+)](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli).
- The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
- AWS account and associated credentials with permissions to create resources.


## Step1: Crafting the `main.tf` File
Our first step is to create a `main.tf` file. This file will serve as the foundation of our Terraform configuration. Here’s a breakdown of each section in the script:


```
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"  // Specifies the provider source, here it's AWS provided by HashiCorp.
      version = "~> 4.16"        
    }
  }

  required_version = ">= 1.2.0"   // Ensures that Terraform version 1.2.0 or higher is used.
}

provider "aws" {
  region  = "us-east-1"            // Sets the AWS region where the resources will be created. This can be changed as needed.
}

variable "environment" {
  description = "The deployment environment (e.g., dev, qa, prod)"
  type        = string             // Defines a string variable for the deployment environment.

  validation {
    condition     = contains(["dev", "qa", "prod"], var.environment)
    error_message = "The environment must be one of: dev, qa, or prod."  // Validates the environment variable value.
  }
}

variable "env_cidr_map" {
  description = "Map of environment names to CIDR block second octet"
  type        = map(string)        // Defines a map variable, mapping environment names to parts of the CIDR block.
  default = {
    "dev"     = "0"
    "qa"      = "10"
    "prod"    = "20"
  }
}

resource "aws_vpc" "main" {
  cidr_block = "10.${lookup(var.env_cidr_map, var.environment, "0")}.0.0/16" // Sets the VPC CIDR block dynamically based on the environment. 
  // check the 'Learn More' section for details.
  assign_generated_ipv6_cidr_block = true  // Enables the assignment of an IPv6 CIDR block to the VPC.
}

```

## Step 2: Deploying AWS VPC
In this section, we'll walk through the steps to deploy your AWS VPC using Terraform.

### Initialise Terraform
```bash
terraform init
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rkwozii0g25hbzy5lgzn.gif)

### Apply the Terraform Configuration
```bash
terraform apply
```
We have set a custom condition for the `environment` variable. If you provide a value that is not specified in the `contains` function, an error message will be triggered.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h25i31ouzqh2hwecj335.gif)

Let's enter `dev`, and then confirm the action by typing `yes`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btel8lntllmckswzt5oh.gif)

### Verify VPC Creation
Once you receive the completion message, refresh the VPC section in the AWS console to check if a new VPC has been created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/850ovg6ej16nzx5o4ywd.gif)

As you can see, the CIDR block for IPv4 is 10.0.0.0/16 which is mapped correctly with the environment value `dev` in the `lookup` function.

### Clean Up Resources
```bash
terraform destroy
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xt7xdyf04ym7n22gbbv3.gif)

## Learn More
For those who prefer hands-on learning, you can fork and explore the source code from this repository: [GitHub](https://github.com/grit-coding/DevToCodeSnippets/tree/main/tech-tutorials/infrastructure/terraform/create-vpc-terraform).

If you found this guide or the repository useful, a star or a reaction would be much appreciated.😄

For further reading on AWS & Terraform documentation, refer to:
- [VPC CIDR Blocks](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-cidr-blocks.html)
- [Terraform Declaring an Input Value](https://developer.hashicorp.com/terraform/language/values/variables)
- [Terraform Lookup Function](https://developer.hashicorp.com/terraform/language/functions/lookup)
- [Terraform Custom Conditions - Input Variable Validation](https://developer.hashicorp.com/terraform/language/expressions/custom-conditions#input-variable-validation)
- [Terraform Contains Function](https://developer.hashicorp.com/terraform/language/functions/contains)