Getting started with Terraform and AWS
Terraform is an open-source tool that enables you to define and manage your AWS infrastructure as code. It provides a simple, declarative language for defining resources, making it easy to automate the provisioning and management of complex infrastructure.
In this post, we’ll provide a step-by-step guide for using Terraform and AWS to manage your infrastructure. Specifically, we’ll show you how to:
- Set up your AWS credentials and choose a region.
- Create a Virtual Private Cloud (VPC) with public and private subnets.
- Launch an EC2 instance in one of the private subnets.
- Create a private S3 bucket.
By the end of this tutorial, you’ll have a secure, scalable infrastructure that is easy to manage and maintain using Terraform.
Step 1: Set up your AWS credentials and choose a region
Before you can start using Terraform and AWS, you’ll need to set up your AWS credentials and choose a region. To do this, follow these steps:
- Go to the AWS Management Console and sign in with your AWS account.
- Click on your username in the top right corner of the console, and then click on “My Security Credentials” from the dropdown menu.
- Scroll down to the “Access keys” section and click on “Create New Access Key”.
- Click on the “Show Access Key” button to view your access key and secret key.
- Make a note of these values, as you’ll need them later when configuring Terraform.
- Scroll down to the “Regions” section and choose the region where you want to create your resources. Make a note of this region, as you’ll need it later when configuring Terraform.

Step 2: Create a VPC with public and private subnets
Now that you have your AWS credentials and region set up, you can start creating your infrastructure with Terraform. The first thing you’ll need to do is create a VPC with public and private subnets. To do this, add the following code to a file named main.tf
:
# Configure the AWS provider
provider "aws" {
access_key = "ACCESS_KEY"
secret_key = "SECRET_KEY"
region = "REGION"
}
# Create a VPC
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/8"
}
# Create private subnets
resource "aws_subnet" "private" {
count = 3
vpc_id = aws_vpc.example.id
cidr_block = "10.0.$(count.index+1).0/24"
availability_zone = "REGION$(count.index+1)"
private_ip_address_count = "5"
map_public_ip_on_launch = false
}
# Create public subnets
resource "aws_subnet" "public" {
count = 3
vpc_id = aws_vpc.example.id
cidr_block = "10.1.$(count.index).0/24"
availability_zone = "REGION$(count.index+1)"
private_ip_address_count = "5"
map_public_ip_on_launch = true
}
# Create an EC2 instance
resource "aws_instance" "example" {
ami = "AMI_ID"
instance_type = "t2.micro"
subnet_id = aws_subnet.private[0].id
}
# Create a private S3 bucket
resource "aws_s3_bucket" "private" {
bucket = "private-bucket"
acl = "private"
}
Before applying any changes to your infrastructure with Terraform, it is a good practice to run the terraform plan
command. This command generates an execution plan that shows you the actions that Terraform will take when you apply the changes.
There are several benefits to running terraform plan
before terraform apply
:
- It allows you to preview the changes that will be made to your infrastructure before they are actually applied. This can help you avoid making unintended changes or causing disruptions to your infrastructure.
- It helps you catch any syntax errors or other issues in your Terraform code before the changes are applied. This can save you time and frustration by allowing you to fix any issues before they cause problems.
- It provides a chance to review the changes with your team or stakeholders before they are applied. This can help ensure that everyone is aware of the changes that are being made and that they are in line with your organization’s goals and policies.
Overall, running terraform plan
before terraform apply
is a best practice that can help you manage your infrastructure more effectively and with greater confidence.
Once you have confirmed the plan to be correct, proceed with applying the changes:
terraform apply
The output will look like this:
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_s3_bucket.private will be created
+ resource "aws_s3_bucket" "private" {
+ acceleration_status = (known after apply)
+ acl = "private"
+ arn = (known after apply)
+ bucket = "private-bucket"
+ bucket_domain_name = (known after apply)
+ bucket_regional_domain_name = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ policy = (known after apply)
+ region = (known after apply)
+ request_payer = (known after apply)
+ tags = (known after apply)
+ versioning = (known after apply)
+ website_domain = (known after apply)
+ website_endpoint = (known after apply)
}
# aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "AMI_ID"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ network_interface_id = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tenancy = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ ebs_block_device {
+ delete_on_termination = (known after apply)
+ device_name = (known after apply)
+ encrypted = (known after apply)
+ iops = (known after apply)
+ kms_key_id = (known after apply)
+ snapshot_id = (known after apply)
+ volume_id = (known after apply)
+ volume_size = (known after apply)
+ volume_type = (known after apply)
}
}
Plan: 3 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
aws_s3_bucket.private: Creating...
aws_instance.example: Creating...
aws_s3_bucket.private: Creation complete after 5s [id=private-bucket]
aws_instance.example: Creation complete after 1m [id=i-01234567890abcdef]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
In this example, Terraform and AWS has successfully created the S3 bucket and EC2 instance, and has output the ID of each resource. You can now use these resources in your infrastructure or view their properties in the AWS Management Console.
Looking for more like this? Check out our DevOps and SRE section.
Leave a Reply
You must be logged in to post a comment.