Provisioning EC2 Instances
Write Terraform configurations to deploy and manage Amazon EC2 virtual machines, including network and security group settings.
Provisioning EC2 Instances is a free DevOps Bootcamp lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the DevOps Bootcamp learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
EC2 Instances with Terraform
Welcome! In this lesson, you'll learn to provision and manage Amazon EC2 virtual machines using Terraform.
EC2 (Elastic Compute Cloud) provides scalable virtual servers in the cloud. Using Infrastructure as Code (IaC) with Terraform for EC2 means you can define your servers in code, ensuring consistent, repeatable deployments.
Defining an EC2 Instance
The core resource for an EC2 instance in Terraform is aws_instance. You need to specify at least two key arguments:
ami: The Amazon Machine Image (OS, software) to use.instance_type: The hardware configuration (e.g.,t2.microfor free tier eligible instances).
Here's how a basic aws_instance block looks:
resource "aws_instance" "web_server" {
ami = "ami-053b04dcd42d5397e" # Example: Amazon Linux 2 in us-east-1
instance_type = "t2.micro"
tags = {
Name = "MyWebServer"
}
}Launch Your First EC2
Let's put it all together to launch a simple EC2 instance. This configuration defines the AWS provider and the EC2 instance.
To deploy, save this as a .tf file, then run terraform init, terraform plan, and terraform apply in your terminal.
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "web_server" {
ami = "ami-053b04dcd42d5397e" # Amazon Linux 2 AMI for us-east-1
instance_type = "t2.micro"
tags = {
Name = "MyBasicWebServer"
}
}Secure Your EC2: Security Groups
Security Groups act as virtual firewalls for your EC2 instances. They control what inbound (ingress) and outbound (egress) network traffic is allowed to reach or leave your instance.
It's crucial to configure them correctly to protect your servers from unauthorized access while allowing necessary services, like SSH or HTTP.
Creating a Security Group
You define a security group using the aws_security_group resource. We'll add an ingress rule to allow SSH access (port 22) from anywhere (0.0.0.0/0).
You'll need to specify an existing vpc_id for the security group to reside in.
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh_traffic"
description = "Allow SSH inbound traffic"
vpc_id = "vpc-0123456789abcdef0" # IMPORTANT: Replace with YOUR VPC ID!
ingress {
description = "SSH from anywhere"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1" # All protocols
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "allow_ssh_sg"
}
}Attaching Security Group to EC2
Now, let's update our aws_instance to use this new security group. We reference the security group's ID using aws_security_group.allow_ssh.id.
Remember to replace the vpc_id in the security group with an actual VPC ID from your AWS account to make this runnable.
provider "aws" {
region = "us-east-1"
}
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh_traffic_example"
description = "Allow SSH inbound traffic"
vpc_id = "vpc-0123456789abcdef0" # IMPORTANT: Replace with YOUR VPC ID!
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "web_server" {
ami = "ami-053b04dcd42d5397e"
instance_type = "t2.micro"
vpc_security_group_ids = [
aws_security_group.allow_ssh.id
]
tags = {
Name = "WebServerWithSSH"
}
}EC2 Networking: VPCs & Subnets
Every EC2 instance lives within a Virtual Private Cloud (VPC) and a specific subnet within that VPC. A VPC is an isolated virtual network, and subnets are logical divisions of your VPC (e.g., public or private).
By default, EC2 might launch in a default VPC/subnet. For more control and organization, you often specify which subnet your instance should use.
Creating a Basic Network
To fully control our EC2's network, let's define a minimal VPC and a public subnet. This also requires an Internet Gateway for public access and a Route Table to direct traffic.
This complete setup ensures your EC2 can communicate with the internet.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc-lesson"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true # Instances in this subnet get a public IP
tags = {
Name = "public-subnet-lesson"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "main-gw-lesson"
}
}
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0" # Traffic to the internet
gateway_id = aws_internet_gateway.gw.id
}
tags = {
Name = "public-rt-lesson"
}
}
resource "aws_route_table_association" "public_rt_assoc" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public_rt.id
}EC2 in Your Custom Network
Now, we'll combine all the pieces: a custom VPC, subnet, security group, and our EC2 instance. The EC2 will launch in our specific public subnet and automatically get a public IP.
This complete configuration gives you fine-grained control over your EC2 deployment and makes it accessible for SSH.
provider "aws" {
region = "us-east-1"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = { Name = "main-vpc-lesson" }
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = { Name = "public-subnet-lesson" }
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.main.id
tags = { Name = "main-gw-lesson" }
}
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
tags = { Name = "public-rt-lesson" }
}
resource "aws_route_table_association" "public_rt_assoc" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public_rt.id
}
resource "aws_security_group" "allow_ssh" {
name = "allow_ssh_lesson"
description = "Allow SSH inbound traffic"
vpc_id = aws_vpc.main.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "web_server" {
ami = "ami-053b04dcd42d5397e"
instance_type = "t2.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [
aws_security_group.allow_ssh.id
]
associate_public_ip_address = true
tags = {
Name = "FullWebServerLesson"
}
}EC2 Configuration Check
Which of the following arguments are essential for defining a basic aws_instance resource in Terraform?
Recap: EC2 with Terraform
Great job! You've learned how to provision Amazon EC2 instances using Terraform.
- We defined EC2 instances using the
aws_instanceresource. - We secured them with
aws_security_group, controlling network traffic. - We set up a basic custom network (VPC, subnet, internet gateway, route table) to host our EC2.
- You now have the foundation to deploy and manage your virtual servers as code!
Frequently asked questions
Is the “Provisioning EC2 Instances” lesson free?
Yes — the full text of “Provisioning EC2 Instances” is free to read here on the web, and the DevOps Bootcamp course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the DevOps Bootcamp course, upgrade to CoddyKit PRO.
What will I learn in “Provisioning EC2 Instances”?
Write Terraform configurations to deploy and manage Amazon EC2 virtual machines, including network and security group settings. You practise DevOps Bootcamp with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start DevOps Bootcamp?
No prior experience is required. DevOps Bootcamp on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Provisioning EC2 Instances” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this DevOps Bootcamp lesson?
Yes. Every DevOps Bootcamp lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- AWS Provider Configuration
- Provisioning EC2 Instances
- Managing S3 Buckets and IAM
- Configuring VPC and Networking