Student: Mykola Stepanov
Topic: Infrastructure as Code with Terraform
Cloud Provider: Amazon Web Services (AWS)
Region used: eu-central-1 / Europe (Frankfurt)
This repository contains a Terraform practical task where I created basic AWS infrastructure using Infrastructure as Code.
The task required creating:
- A Terraform project with AWS provider configuration.
- A VPC using a module from the Terraform Registry.
- Two EC2 instances using the Terraform
countargument. - A Classic Load Balancer that distributes HTTP traffic between the two EC2 instances.
The project was created and tested locally from VS Code terminal on Windows.
| Task | Requirement | Implementation |
|---|---|---|
| Task 1 | Install Terraform, create project folder, configure AWS provider, initialize and apply Terraform project | Terraform was installed locally and added to Windows PATH. Project folder was created with main.tf, terraform.tfvars, .gitignore, and Terraform commands were executed from VS Code terminal |
| Task 2 | Create VPC using an appropriate Terraform Registry module | Used terraform-aws-modules/vpc/aws module to create VPC, public subnets, private subnets, route tables, and internet gateway |
| Task 3 | Create two EC2 instances using count |
Created two EC2 instances with count = 2 in private subnets |
| Task 4 | Create a Classic Load Balancer in AWS | Created aws_elb Classic Load Balancer and attached both EC2 instances to it |
The implemented AWS architecture includes:
- 1 VPC
- 2 public subnets
- 2 private subnets
- 2 EC2 instances
- 1 Classic Load Balancer
- Security groups for Load Balancer and EC2 instances
- Outputs for VPC ID, EC2 instance IDs, and Load Balancer DNS name
Basic traffic flow:
User / Browser
|
v
Classic Load Balancer
|
v
2 EC2 instances in private subnets
terraform-task/
├── main.tf
├── README.md
├── .gitignore
├── .terraform.lock.hcl
└── terraform-plan.txt # optional text version of Terraform plan
Files that should not be pushed to GitHub:
terraform.tfvars
terraform.tfstate
terraform.tfstate.*
.terraform/
tfplan
terraform.tfvars contains AWS credentials, so it must stay local and should not be committed.
The AWS provider was configured to work with AWS resources.
provider "aws" {
region = var.aws_region
access_key = var.aws_access_key
secret_key = var.aws_secret_key
}Credentials were stored locally in terraform.tfvars.
Input variables were used to make the configuration more flexible.
variable "aws_region" {
type = string
}
variable "aws_access_key" {
type = string
sensitive = true
}
variable "aws_secret_key" {
type = string
sensitive = true
}
variable "instance_type" {
type = string
default = "t2.micro"
}A ready-made module from Terraform Registry was used to create the VPC.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = "student-vpc"
cidr = "10.0.0.0/16"
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.11.0/24", "10.0.12.0/24"]
enable_nat_gateway = false
}Two EC2 instances were created using count.
resource "aws_instance" "web" {
count = 2
ami = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
subnet_id = module.vpc.private_subnets[count.index]
vpc_security_group_ids = [aws_security_group.ec2_sg.id]
user_data = <<-EOF
#!/bin/bash
echo "Hello from EC2 instance ${count.index + 1}" > /home/ec2-user/index.html
cd /home/ec2-user
nohup python3 -m http.server 80 &
EOF
tags = {
Name = "student-ec2-${count.index + 1}"
}
}The Classic Load Balancer was created to distribute HTTP traffic across two EC2 instances.
resource "aws_elb" "student_lb" {
name = "student-classic-lb"
subnets = module.vpc.public_subnets
security_groups = [aws_security_group.lb_sg.id]
instances = aws_instance.web[*].id
listener {
lb_port = 80
lb_protocol = "http"
instance_port = 80
instance_protocol = "http"
}
health_check {
target = "HTTP:80/"
interval = 30
timeout = 3
healthy_threshold = 2
unhealthy_threshold = 2
}
}terraform versionterraform fmtterraform initterraform validateterraform plan -out=tfplanterraform show -no-color tfplan > terraform-plan.txtterraform apply tfplanterraform outputterraform state listterraform destroyThe infrastructure was verified in several ways:
- Terraform completed the apply operation successfully.
- Terraform output displayed:
- EC2 instance IDs
- Load Balancer DNS name
- VPC ID
- AWS Console showed:
- 2 running EC2 instances
- 1 Classic Load Balancer
- Load Balancer health checks with instances in service
- Browser test confirmed that the Load Balancer returned a response from an EC2 instance.
Example browser result:
Hello from EC2 instance 1
After verification, all created AWS resources were removed to avoid unnecessary costs.
terraform destroyAfter destroy, the Terraform state was checked:
terraform state listThe state list was empty, which confirmed that Terraform no longer tracked any created resources.
AWS credentials were not committed to the repository.
The following files were ignored:
.terraform/
terraform.tfvars
*.tfstate
*.tfstate.*
tfplan
crash.log
crash.*.logThis is important because:
terraform.tfvarscan contain AWS access keys.terraform.tfstatecan contain sensitive infrastructure data..terraform/contains downloaded providers and modules.
The practical task was completed successfully.
Implemented:
- AWS provider configuration
- VPC module from Terraform Registry
- Two EC2 instances using
count - Classic Load Balancer
- Security groups
- Terraform plan and apply workflow
- AWS Console verification
- Browser verification through Load Balancer DNS
- Cleanup using
terraform destroy
During this task I practiced:
- Installing and running Terraform locally.
- Working with Terraform files:
main.tf,terraform.tfvars,.gitignore. - Using input variables.
- Using Terraform Registry modules.
- Creating AWS infrastructure with Terraform.
- Checking Terraform execution plans.
- Applying Terraform changes.
- Reading Terraform outputs.
- Checking resources in AWS Console.
- Cleaning up resources with
terraform destroy.
This task helped me better understand how Infrastructure as Code works in practice and how Terraform can create, manage, verify, and destroy cloud infrastructure.