How to configure and use the Terraform aws_vpc
resource block to create and manage AWS VPCs.
Welcome to our tutorial series where we dive into cloud infrastructure deployment using Terraform or OpenTofu on AWS. In this series, the fundamentals are shown, guiding you through the process of minimizing resource usage and simplifying the deployment complexities associated with cloud infrastructure. This tutorial series is a work in progress.
This comprehensive OpenTofu and Terraform tutorial guides you step-by-step through creating infrastructure in AWS using Terraform.
Infrastructure as Code (IaC) helps maintain consistency, enables version control, enhances collaboration among teams, allows for easier replication of environments, streamlines the deployment and management of infrastructure boosting efficiency, and reducing errors in managing complex systems.
How to start building AWS infrastructure with Terraform: AWS VPC
Read previous sections of the tutorial: AWS with Terraform Tutorial
Terraform AWS Configuration Plan Definition
Previous sections of the Tutorial have covered basic information about Terraform, AWS Cloud, and the Terraform AWS Provider. Now it is time to create a Terraform Plan.
How to create AWS VPCs with Terraform
The first element that should be created in an AWS Terraform Plan is the VPC.
Init, plan, and apply the Terraform plan to create a VPC in AWS.
Common Questions About AWS VPC
What IP range should be used for a VPC? How many VPCs do you need?
Other tutorials for creating infrastructure in AWS using Terraform.
Previous sections of this AWS with Terraform guide have covered basic information about Terraform and AWS. Now it is time to create a Terraform Plan.
In an empty directory, create a file named terraform-aws-tutorial.tf
with the following two blocks:
# Copyright (C) 2018 - 2023 IT Wonder Lab (https://www.itwonderlab.com) # # This software may be modified and distributed under the terms # of the MIT license. See the LICENSE file for details. # -------------------------------- WARNING -------------------------------- # IT Wonder Lab's best practices for infrastructure include modularizing # Terraform/OpenTofu configuration. # In this example, we define everything in a single file. # See other tutorials for best practices at itwonderlab.com # -------------------------------- WARNING -------------------------------- #----------------------------------------- # Define Terrraform Providers and Backend #----------------------------------------- terraform { required_version = "> 1.5" required_providers { aws = { source = "aws" version = "~> 5.0" } } } #----------------------------------------- # Provider: AWS #----------------------------------------- provider "aws" { profile = "ditwl_infradmin" default_tags { tags = { environment = "pro" cost_center = "sales-department" } } }
The first block defines the Terraform version and the required AWS Terraform provider, specifying the version and the provider (none, Hashicorp, or OpenTofu).
The second block configures the AWS Terraform provider by specifying "ditwl_infradmin"
as the AWS CLI profile to use for authentication and a list of tags and values that will be added by default to all the resources created with Terraform.
The AWS CLI profile includes the access key, secret access key, account ID, and the AWS region.
The first element that should be created is a VPC.
The VPC is created in the region specified while configuring the AWS Terraform provider (therefore the one defined by the AWS CLI profile "ditwl_infradmin"
). This example uses the region us-east-1
, located in North Virginia, United States.
VPC definition using Terraform, add the following block to the file terraform-aws-tutorial.tf
:
# VPC, CIDR Block: 172.21.0.0/19 resource "aws_vpc" "ditlw-vpc" { cidr_block = "172.21.0.0/19" #172.21.0.0 - 172.21.31.254 tags = { Name = "ditlw-vpc" tool = "Terraform" } }
The Terraform aws_vpc resource block creates a VPC with a network CIDR of 172.21.0.0/19 and the tags Name = "ditlw-vpc"
and tool = "Terraform"
. Additionally the default tags environment = "pro"
and cost_center = "sales-department"
defined at the AWS Provider block will be automatically added by Terraform.
Other configuration options are available but not needed for a basic VPC.
The VPC properties can be referenced in the Terraform plan using the resource type (aws_vpc
), assigned name (ditlw-vpc
), and the exported attribute, for example:
aws_vpc.ditlw-vpc.id
aws_vpc.ditlw-vpc.arn
aws_vpc.ditlw-vpc.default_route_table_id
The Tag Name and the resource name can be different but the best practice is to keep the same name.
The VPC ID will be used in the next sections as a parameter to create the AWS Subnets and the Default Routing Table.
Terraform configuration plans can be applied iteratively as new infrastructure needs to be added, modified, or destroyed.
Decide between using Terraform or OpenTofu and using the same tool during all the tutorial sections. You can switch tools to test Terraform and OpenTofu compatibility. The code is compatible with both tools and during the tutorial, OpenTofu will be used to run all commands.
Open a command line shell at the same location as the terraform-aws-tutorial.tf
the file is located, and run the Terraform or OpenTofu init, plan, and apply commands:
The init command needs to be run once to download and initialize the required providers and lock files.
$ tofu init Initializing the backend... Initializing provider plugins... - Finding hashicorp/aws versions matching "~> 5.0"... - Installing hashicorp/aws v5.32.1... - Installed hashicorp/aws v5.32.1 (signed, key ID 0C0AF313E5FD9F80) Providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://opentofu.org/docs/cli/plugins/signing/ OpenTofu has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that OpenTofu can guarantee to make the same selections by default when you run "tofu init" in the future. OpenTofu has been successfully initialized! You may now begin working with OpenTofu. Try running "tofu plan" to see any changes that are required for your infrastructure. All OpenTofu commands should now work. If you ever set or change modules or backend configuration for OpenTofu, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary
Run tofu plan
to generate and review the execution plan. Check each line and value to make sure that corresponds to the desired change. In this case, a VPC will be created (as shown with the + sign) and only a few of its initial properties have been specified (the cidr_block and the tags), with the rest of the properties using default provider values or be known after creation.
$ tofu plan OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create OpenTofu will perform the following actions: # aws_vpc.ditlw-vpc will be created + resource "aws_vpc" "ditlw-vpc" { + arn = (known after apply) + cidr_block = "172.21.0.0/19" + 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 = (known after apply) + 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" = "ditlw-vpc" + "tool" = "Terraform" } + tags_all = { + "Name" = "ditlw-vpc" + "cost_center" = "sales-department" + "environment" = "pro" + "tool" = "Terraform" } } Plan: 1 to add, 0 to change, 0 to destroy. ───────────────────────────────────────── Note: You didn't use the -out option to save this plan, so OpenTofu can't guarantee to take exactly these actions if you run "tofu apply" now.
Run tofu apply
to generate and apply the execution plan. OpenTofu will generate a new plan and ask for confirmation before applying the changes. Review again the changes and answer yes or no to apply the changes in AWS.
$ tofu apply OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create OpenTofu will perform the following actions: # aws_vpc.ditlw-vpc will be created + resource "aws_vpc" "ditlw-vpc" { + arn = (known after apply) + cidr_block = "172.21.0.0/19" + 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 = (known after apply) + 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" = "ditlw-vpc" + "tool" = "Terraform" } + tags_all = { + "Name" = "ditlw-vpc" + "cost_center" = "sales-department" + "environment" = "pro" + "tool" = "Terraform" } } Plan: 1 to add, 0 to change, 0 to destroy. Do you want to perform these actions? OpenTofu will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_vpc.ditlw-vpc: Creating... aws_vpc.ditlw-vpc: Creation complete after 5s [id=vpc-0bed1f6c715e9a909] Apply complete! Resources: 1 added, 0 changed, 0 destroyed
Review the result, it should be 1 (resource) added, 0 changed, 0 destroyed
.
You can now run tofu plan
or tofu apply
again to check that OpenTofu has not found any new changes to apply.
$ tofu plan aws_vpc.ditlw-vpc: Refreshing state... [id=vpc-0bed1f6c715e9a909] No changes. Your infrastructure matches the configuration. OpenTofu has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
You can modify the cost_center
tag, add a new one (owner = "IT Wonder Lab"
), and then run tofu plan
or tofu apply
again. This way, OpenTofu will adjust the VPC, ensuring that the necessary changes in AWS align with the Terraform code.
This example demonstrates an in-place update, where the infrastructure is modified without the need to destroy and recreate it. Be aware that some changes require infrastructure destruction (destroy and create).
$ tofu apply aws_vpc.ditlw-vpc: Refreshing state... [id=vpc-0bed1f6c715e9a909] OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place OpenTofu will perform the following actions: # aws_vpc.ditlw-vpc will be updated in-place ~ resource "aws_vpc" "ditlw-vpc" { id = "vpc-0bed1f6c715e9a909" ~ tags = { "Name" = "ditlw-vpc" - "cost_center" = "sales-department" -> null "tool" = "Terraform" } ~ tags_all = { ~ "cost_center" = "sales-department" -> "marketing-department" + "owner" = "IT Wonder Lab" # (3 unchanged elements hidden) } # (14 unchanged attributes hidden) } Plan: 0 to add, 1 to change, 0 to destroy. Do you want to perform these actions? OpenTofu will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_vpc.ditlw-vpc: Modifying... [id=vpc-0bed1f6c715e9a909] aws_vpc.ditlw-vpc: Modifications complete after 5s [id=vpc-0bed1f6c715e9a909] Apply complete! Resources: 0 added, 1 changed, 0 destroyed
Terraform shows an in-place update that:
- "cost_center" = "sales-department" -> null
~ "cost_center" = "sales-department" -> "marketing-department"
+ "owner" = "IT Wonder Lab"
When planning your Virtual Private Cloud (VPC) network CIDR (Classless Inter-Domain Routing), consider the following:
Peering or VPNs: If you plan to connect VPCs or use VPNs, ensure that the CIDR blocks don't overlap with other clouds, existing VPCs, on-premises data centers, and LAN networks.
Private IP addresses are free to use but proper planning is required for routing across the organization.
The number of VPCs and most importantly the services that each VPC provides have an impact on the cost of the Cloud.
Data Transfer Costs for Common Architectures :
For small companies consider each VPC as a data center with its own
This tutorial series is a work in progress and will have these sections:
AWS with Terraform: The Essential Guide: Sections
IT Wonder Lab tutorials are based on the diverse experience of Javier Ruiz, who founded and bootstrapped a SaaS company in the energy sector. His company, later acquired by a NASDAQ traded company, managed over €2 billion per year of electricity for prominent energy producers across Europe and America. Javier has over 25 years of experience in building and managing IT companies, developing cloud infrastructure, leading cross-functional teams, and transitioning his own company from on-premises, consulting, and custom software development to a successful SaaS model that scaled globally.
Are you looking for cloud automation best practices tailored to your company?