Terraform Tutorial – Basics of Terraform on AWS (Part #1)
Gurvinder Singh
AWS Certified Solutions Architect/ Terraform Certified/ Infrastructure Engineer/Team Lead
Overview
In this multipart tutorial series, we will build with a simple AWS network architecture which consists of a single VPC, with subnets across three availability zones. All subnet will be public subnets i.e. compute resources in these subnets will have access to the internet through an internet gateway attached to the VPC. Each subnet will have a single EC2 instance with ssh access configured. We will obviously build all of this using Terraform and along the way learn about Terraform basics.
Prerequisites
Before starting this tutorial, you will need:
What we will accomplish in this tutorial series
Throughout this series of tutorial, we will walk you through the steps to create the following basic AWS architecture using Terraform.
Part # 1
In this part of the tutorial, we will setup our Terraform development environment and build the basic architecture.
So upon completion of the Part #1 tutorial our base architecture will look like below.
Setup Terraform Environment
Note: I would be using macOS for this tutorial, but Terraform works the same on either platform except few setup differences.
Create a folder on your local machine
# create a folder on your local machine
gsk:~$ mkdir tf-aws-basics-part-1
# change to the newly created folder
gsk:~$ cd tf-aws-basics-part-1
# check version of Terraform
gsk:~$ terraform version
# You’d get an output similar to the below:
Terraform v1.5.1
on darwin_amd64
Note: I am using an AWS IAM account with “AdministratorAccess” to authenticate terraform via local system aws cli.
Create VPC
Create our first terraform config file called ‘variables.tf’ under the folder created above.
Note: all Terraform configuration files have '.tf' extension.
# variables.tf
/*
the variable aws_region defines the AWS region
where we will be creating our resorces
e.g vpc, subnets etc.
*/
variable "aws_region" {
type = string
default = "us-east-2"
}
Create our second terraform config file called ‘providers.tf’ under the same folder as the other file.
# providers.tf
/*
the provider defines to be used to create our resources.
note: var.aws_region refers to the variable 'aws_region'
in the variables.tf file
*/
provider "aws" {
profile = "default"
region = var.aws_region
}
The next command that needs to be run is 'terraform init'
Initializing the backend..
Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v5.6.2...
- Installed hashicorp/aws v5.6.2 (signed by HashiCorp)
-- some output ommitted for for brevity reason --
Terraform has been successfully initialized!
This command downloads all the required plug-ins required by our configuration. In our case, it downloads latest version of the 'aws' plug-in.
So far we have prepared our setup and config to build the following:
Now we will will add config to create our VPC.
Create a new file 'main.tf' in the same folder as the other files.
# main.tf
/*
This is the entry file of terraform configuration files.
All of the resources wil be defined in this file.
*/
#
# please note that the created vpc will be referred as
# aws_vpc.tf_aws_basics_vpc with-in teh configuration code
#
resource "aws_vpc" "tf_aws_basics_vpc" {
# IPV4 CIDR block of the VPC
cidr_block = "10.0.0.0/16"
# enable DNS hotname generation support
enable_dns_hostnames = true
tags = {
# This optional tag `Name` will be used for VPC name
Name = "tf_aws_basics_vpc"
}
}
With above file in place, if you run `terraform plan`, terraform would show you a plan of what it is going to create. You'd get an output on the screen like shown below.
?# aws_vpc.tf_aws_basics_vpc will be created
? + resource "aws_vpc" "tf_aws_basics_vpc" {
? ? ? + arn? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + cidr_block ? ? ? ? ? ? ? ? ? ? ? ? ? = "10.0.0.0/16"
? ? ? + default_network_acl_id ? ? ? ? ? ? ? = (known after apply)
? ? ? + default_route_table_id ? ? ? ? ? ? ? = (known after apply)
? ? ? + default_security_group_id? ? ? ? ? ? = (known after apply)
? ? ? + dhcp_options_id? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + enable_dns_hostnames ? ? ? ? ? ? ? ? = true
? ? ? + enable_dns_support ? ? ? ? ? ? ? ? ? = true
? ? ? + enable_network_address_usage_metrics = (known after apply)
? ? ? + id ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + instance_tenancy ? ? ? ? ? ? ? ? ? ? = "default"
? ? ? + ipv6_association_id? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + ipv6_cidr_block? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + ipv6_cidr_block_network_border_group = (known after apply)
? ? ? + main_route_table_id? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + owner_id ? ? ? ? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + tags ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = {
? ? ? ? ? + "Name" = "tf_aws_basics_vpc"
? ? ? ? }
? ? ? + tags_all ? ? ? ? ? ? ? ? ? ? ? ? ? ? = {
? ? ? ? ? + "Name" = "tf_aws_basics_vpc"
? ? ? ? }
? ? }
Plan: 1 to add, 0 to change, 0 to destroy.
Note: The top line states what will be created after this plan is executed.
To execute the above plan, go ahead and run `terraform apply`, terraform plan would be run again and you'd be prompted for an approval before the resources defined in the configuration files is created.
Terraform used the selected providers to generate the following execution plan. Resource
actions are indicated with the following symbols:
? + create
Terraform will perform the following actions:
? # aws_vpc.tf_aws_basics_vpc will be created
? + resource "aws_vpc" "tf_aws_basics_vpc" {
? ? ? + arn? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + cidr_block ? ? ? ? ? ? ? ? ? ? ? ? ? = "10.0.0.0/16"
? ? ? + default_network_acl_id ? ? ? ? ? ? ? = (known after apply)
? ? ? + default_route_table_id ? ? ? ? ? ? ? = (known after apply)
? ? ? + default_security_group_id? ? ? ? ? ? = (known after apply)
? ? ? + dhcp_options_id? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + enable_dns_hostnames ? ? ? ? ? ? ? ? = true
? ? ? + enable_dns_support ? ? ? ? ? ? ? ? ? = true
? ? ? + enable_network_address_usage_metrics = (known after apply)
? ? ? + id ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + instance_tenancy ? ? ? ? ? ? ? ? ? ? = "default"
? ? ? + ipv6_association_id? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + ipv6_cidr_block? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + ipv6_cidr_block_network_border_group = (known after apply)
? ? ? + main_route_table_id? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + owner_id ? ? ? ? ? ? ? ? ? ? ? ? ? ? = (known after apply)
? ? ? + tags ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? = {
? ? ? ? ? + "Name" = "tf_aws_basics_vpc"
? ? ? ? }
? ? ? + tags_all ? ? ? ? ? ? ? ? ? ? ? ? ? ? = {
? ? ? ? ? + "Name" = "tf_aws_basics_vpc"
? ? ? ? }
? ? }
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
? Terraform will perform the actions described above.
? Only 'yes' will be accepted to approve.
? Enter a value: Yes
One approved the `terraform apply` command will result with the following output.
aws_vpc.tf_aws_basics_vpc: Creating...
aws_vpc.tf_aws_basics_vpc: Still creating... [10s elapsed]
aws_vpc.tf_aws_basics_vpc: Creation complete after 15s [id=vpc-05f7fc990a71a9c97]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Note the AWS Region and the id of the vpc `id=vpc-05f7fc990a71a9c97`
Let us confirm the newly created vpc information by cross checking in the `aws console'.
Also note the name of the VPC is derived from the tags applied in the `main.tf` file' under `aws_vpc.tf_aws_basics_vpc' resource.
So that concludes the Part #1 of this series. If you have any questions or comments, please feel free post it in comments section.
Full code for the first section can be cloned from, AWS CodeCommit repository show below.
https://git-codecommit.us-east-2.amazonaws.com/v1/repos/tf-aws-basics-part-1
Enjoy!!