cd ~/environment/terraform/modules/tf-vpc
## Initialize Terraform
terraform init
## Format code, validate syntax & check security issues
terraform fmt
terraform validate
## Terraform "plan" what it is going to do
terraform plan -out tfplan
## Build the VPC
terraform apply tfplan
## Destroy what we have created !!!
# terraform destroy -auto-approve
One final thing to appreciate is that resources have dependancies. This is automatically handled for you by Terraform, but when reading Terraform code it’s important to read things in the right order:
aws.tf
- Specifies how we connect to Terraform , where the credentials are - and optionally where to store the state file (we are using the default - the local directory)variables.tf
» Defines the variables our terraform code will usedata*.tf
» Any existing resources we will usemain.tf
» an object most other things depend on in AWS.subnets.tf
and security groups mysg*.tf
» depends on the vpc and transit gatewaynat_gateway.tf
» depends on subnets and elastic ipinstance.tf
» has the most dependancies and thus is one of the last resources to be created.variable "tf-count" {
default = 1
}
variable "aws_vpc" {
type = list
default = ["tf-vpc","eks-vpc"]
}
variable "aws_cidr" {
default = {
"tf-vpc" = "172.30.0.0/24"
"eks-vpc" = "10.0.0.0/22"
}
}
The count
variable controls how many resources of a given type that reference it are deployed using the special “count” variable (see later).
The variable aws_vpc
is a list of strings that will be used to name your VPC’s.
The variable aws_cidr
is a “mapping” that uses the vpc name as defined in the variable aws_vpc to pick up an associated CIDR range.
resource "aws_vpc" "VPC" {
count = var.tf-count
assign_generated_ipv6_cidr_block = false
cidr_block = lookup(var.aws_cidr, var.aws_vpc[count.index])
enable_dns_hostnames = false
enable_dns_support = true
instance_tenancy = "default"
tags = {
"Name" = var.aws_vpc[count.index]
}
}
count= var.tf-count » this assigns the special variable “count” to our variable “count”. The Terraform variable count is an iterator - it says “create this resource count times”
“Name” = var.aws_vpc[count.index] » This line looks up the Nth value in the aws_vpc list and uses it as the value in the tag’s Key (Name) , Value (aws_vpc[count.index]) pair.
cidr_block = lookup(var.aws_cidr, var.aws_vpc[count.index]) » This is saying look into our map “var.aws_cidr” - use the index value “var.aws_vpc” using the Nth value in the aws_vpc list - where N = the current value of count
Using variables like this enables us to predefine VPC names and CIDR’s in advance. And check them into source control systems (GitHub, GitLab).
resource "aws_subnet" "tf-public-subnet" {
count = var.tf-count
assign_ipv6_address_on_creation = false
availability_zone = "ap-southeast-1a"
cidr_block = format("172.30.0.%s/27", count.index)
map_public_ip_on_launch = false
tags = {
"Name" = format("Public-Subnet 172.30.0.%s/27", count.index)
}
vpc_id = aws_vpc.VPC[count.index].id
timeouts {}
}
resource "aws_subnet" "tf-private-subnet" {
count = var.tf-count
assign_ipv6_address_on_creation = false
availability_zone = "ap-southeast-1a"
cidr_block = "172.30.0.128/27"
map_public_ip_on_launch = false
tags = {
"Name" = "Private-Subnet 172.30.0.128/27"
}
vpc_id = aws_vpc.VPC[count.index].id
timeouts {}
}
Also notice in this file how the VPC we just created with the vpc.tf file is referenced:
Go to the AWS console as before and find: