AWS S3 Bucket Creation and Management

AWS S3 Bucket:
Amazon S3 (Simple Storage Service) is a highly scalable, durable, and secure object storage service provided by AWS. It allows you to store and retrieve any amount of data from anywhere.
Key Features of S3:
Scalability – Automatically scales storage based on demand.
Durability – Provides 99.999999999% (11 nines) durability.
Security – Supports encryption, IAM policies, and access control.
Data Management – It offers versioning, lifecycle policies, and replication.
Cost-Effective – Multiple storage classes (Standard, Glacier, Intelligent-Tiering, etc.) to optimize costs.
Common Use Cases:
Backup and Restore – Store backups securely with lifecycle rules.
Static Website Hosting – Host static websites directly from S3.
Big Data Analytics – Stores large datasets for processing.
Media Storage – Keep images, videos, and documents.
Log Storage – Centralized storage for logs and analytics.
Task 1
Create an S3 bucket using Terraform.
Configure the bucket to allow public read access.
Create an S3 bucket policy that allows read-only access to a specific IAM user or role.
Enable versioning on the S3 bucket.
Below is the Terraform script to create an S3 bucket with the following configurations:
Creates an S3 bucket
Allows public read access
Adds a bucket policy for read-only access to a specific IAM user/role
Enables versioning on the bucket
Terraform Configuration for S3 Bucket
provider "aws" {
region = "us-east-1" # Change the region as needed
}
# Create S3 Bucket
resource "aws_s3_bucket" "my_bucket" {
bucket = "my-terraform-s3-bucket-1234" # Change this to a unique bucket name
}
# Enable Versioning on the Bucket
resource "aws_s3_bucket_versioning" "versioning" {
bucket = aws_s3_bucket.my_bucket.id
versioning_configuration {
status = "Enabled"
}
}
# Public Read Access Policy
resource "aws_s3_bucket_public_access_block" "public_access" {
bucket = aws_s3_bucket.my_bucket.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
# S3 Bucket Policy to Allow Public Read Access
resource "aws_s3_bucket_policy" "public_read" {
bucket = aws_s3_bucket.my_bucket.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.my_bucket.arn}/*"
}
]
})
}
# Read-Only Access for a Specific IAM User or Role
resource "aws_s3_bucket_policy" "read_only_access" {
bucket = aws_s3_bucket.my_bucket.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::123456789012:user/MyUser" # Replace with actual IAM User or Role ARN
}
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.my_bucket.arn}/*"
}
]
})
}
Steps to Deploy
Initialize Terraform
terraform init
Plan the Deployment
terraform plan
Apply the Configuration
terraform apply -auto-approve
Scaling with Terraform
Understanding Scaling:
Scaling in cloud computing refers to adjusting resources to efficiently handle increased or decreased workloads. It ensures that applications remain performant and cost-effective.
Types of Scaling
1. Vertical Scaling (Scaling Up/Down)
Definition: Increasing or decreasing the capacity of a single instance or resource.
How? Upgrading CPU, RAM, or storage.
Example:
Upgrading an EC2 instance from t2.micro to t2.large
Increasing the RDS database storage capacity
Pros: Simple, no architectural changes
Cons: Hardware limitations, downtime may be required
2. Horizontal Scaling (Scaling Out/In)
Definition: Adding or removing multiple instances to distribute the load.
How? Increasing the number of servers dynamically.
Example:
Adding more EC2 instances behind an Elastic Load Balancer (ELB)
Expanding an Auto Scaling Group (ASG) when traffic spikes
Pros: High availability, fault tolerance, no hardware limitations
Cons: Requires proper load balancing and stateless applications
Scaling in AWS Services
Auto Scaling – Automatically adjusts EC2 instances based on demand.
Elastic Load Balancing (ELB) – Distributes traffic across multiple instances.
Amazon RDS Scaling – Vertical scaling is done by increasing the DB instance size.
Amazon S3 Scaling – Object storage that scales automatically with demand.
AWS Lambda Scaling – Automatically scales based on function invocation.
Choosing the Right Scaling Strategy
For high-traffic applications → Horizontal Scaling (Auto Scaling Groups)
For memory-intensive workloads → Vertical Scaling (Larger EC2 instance)
For unpredictable workloads → Serverless Scaling (AWS Lambda)
Task 2: Create an Auto Scaling Group
Auto Scaling Groups are used to automatically add or remove EC2 instances based on the current demand. Follow these steps to create an Auto Scaling Group:
In your main.tf file, add the following code to create an Auto Scaling Group:
resource "aws_launch_configuration" "web_server_as" {
image_id = "ami-005f9685cb30f234b"
instance_type = "t2.micro"
security_groups = [aws_security_group.web_server.name]
user_data = <<-EOF
#!/bin/bash
echo "<html><body><h1>You're doing really Great</h1></body></html>" > index.html
nohup python -m SimpleHTTPServer 80 &
EOF
}
resource "aws_autoscaling_group" "web_server_asg" {
name = "web-server-asg"
launch_configuration = aws_launch_configuration.web_server_lc.name
min_size = 1
max_size = 3
desired_capacity = 2
health_check_type = "EC2"
load_balancers = [aws_elb.web_server_lb.name]
vpc_zone_identifier = [aws_subnet.public_subnet_1a.id, aws_subnet.public_subnet_1b.id]
}
Terraform applies to create the Auto Scaling Group.
Your Terraform script has a few issues that need correction before running terraform apply
:
Issues in the Code
Incorrect Launch Configuration Reference:
launch_configuration = aws_launch_configuration.web_server_
lc.name
The resource is named
web_server_as
, notweb_server_lc
.
Deprecated Launch Configuration:
aws_launch_configuration
is deprecated. Useaws_launch_template
instead.
Incorrect Load Balancer Reference:
load_balancers
is used for Classic Load Balancers (ELB).For an Application Load Balancer (ALB), use
target_group_arns
instead.
Security Group Reference:
aws_security_group.web_
server.name
should beaws_security_group.web_
server.id
.
Corrected Code Using Launch Template
resource "aws_launch_template" "web_server_lt" {
name = "web-server-launch-template"
image_id = "ami-005f9685cb30f234b"
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.web_server.id]
user_data = base64encode(<<-EOF
#!/bin/bash
echo "<html><body><h1>You're doing really Great</h1></body></html>" > index.html
nohup python -m SimpleHTTPServer 80 &
EOF
)
}
resource "aws_autoscaling_group" "web_server_asg" {
name = "web-server-asg"
min_size = 1
max_size = 3
desired_capacity = 2
vpc_zone_identifier = [aws_subnet.public_subnet_1a.id, aws_subnet.public_subnet_1b.id]
launch_template {
id = aws_launch_template.web_server_lt.id
version = "$Latest"
}
target_group_arns = [aws_lb_target_group.web_server_tg.arn]
health_check_type = "EC2"
}
Steps to Deploy
Initialize Terraform:
terraform init
Validate the configuration:
terraform validate
Plan the deployment:
terraform plan
Apply the configuration:
terraform apply -auto-approve
This will create an Auto Scaling Group with an ALB target group and ensure smooth scaling of instances.
Task 3: Test Scaling
Go to the AWS Management Console and select the Auto Scaling Groups service.
Select the Auto Scaling Group you just created and click on the "Edit" button.
Increase the "Desired Capacity" to 3 and click on the "Save" button.
Wait a few minutes for the new instances to be launched.
Go to the EC2 Instances service and verify that the new instances have been launched.
Decrease the "Desired Capacity" to 1 and wait a few minutes for the extra instances to be terminated.
Go to the EC2 Instances service and verify that the extra instances have been terminated.
Testing Auto Scaling in AWS
Once you've deployed your Auto Scaling Group using Terraform, follow these steps to test its scaling behavior:
Step 1: Increase Desired Capacity
Open the AWS Management Console.
Navigate to EC2 > Auto Scaling Groups.
Find and select the web-server-asg Auto Scaling Group.
Click the Edit button.
Change the Desired Capacity from 2 to 3.
Click Save.
Wait a few minutes for the new instance to be launched.
Step 2: Verify Instance Scaling
Go to EC2 Dashboard.
Click on Instances in the left panel.
Check if a new instance has been added.
Ensure the instance is running.
Step 3: Decrease Desired Capacity
Navigate back to Auto Scaling Groups.
Click on the web-server-asg Auto Scaling Group.
Click Edit and set the Desired Capacity to 1.
Click Save.
Wait a few minutes for the extra instances to be terminated.
Step 4: Verify Termination
Go back to the EC2 Instances page.
Check if the extra instances have been terminated.
Only one instance should remain running.
This test confirms that the Auto Scaling Group dynamically adjusts the number of instances based on the configured desired capacity.
Meta-Arguments in Terraform
count → It creates multiple instances of a resource.
resource "aws_instance" "web" { count = 3 }
➝ Creates 3 EC2 instances.
for_each → Iterates over a map or set.
resource "aws_instance" "web" { for_each = toset(["dev", "staging", "prod"]) }
➝ Creates instances named dev, staging, and prod.
depends_on → Defines resource dependencies.
depends_on = [aws_security_group.web_sg]
➝ Ensure the security group is created before the EC2 instance.
lifecycle → Controls resource behavior.
lifecycle { prevent_destroy = true }
➝ Prevents accidental deletion.
provider → Specifies which provider to use.
provider = aws.west
➝ Deploys in the us-west-2 region.
Count:
The count
Meta-argument allows you to create multiple instances of a resource dynamically based on a specified number.
Basic Usage
resource "aws_instance" "web" {
count = 3
ami = "ami-005f9685cb30f234b"
instance_type = "t2.micro"
}
Creates 3 EC2 instances.
- Access them using
aws_instance.web[0]
,aws_instance.web[1]
, etc.
Conditional Resource Creation
resource "aws_instance" "web" {
count = var.enable_instance ? 1 : 0
ami = "ami-005f9685cb30f234b"
instance_type = "t2.micro"
}
Creates 1 instance if enable_instance
is true
, otherwise creates none.
Using count.index
resource "aws_instance" "web" {
count = 3
ami = "ami-005f9685cb30f234b"
instance_type = "t2.micro"
tags = {
Name = "Instance-${count.index}"
}
}
tag instances as Instance-0, Instance-1, and Instance-2.
When to Use count
?
When creating multiple identical resources.
When enabling/disabling a resource conditionally.
for_each:
The for_each
meta-argument is used to create multiple resources dynamically from a set or map, giving more control than count
.
1. Using for_each with a Set
resource "aws_instance" "web" {
for_each = toset(["dev", "staging", "prod"])
ami = "ami-005f9685cb30f234b"
instance_type = "t2.micro"
tags = {
Name = each.key
}
}
Creates three instances with names dev, staging, and prod.
2. Using for_each with a Map
resource "aws_instance" "web" {
for_each = {
dev = "t2.micro"
staging = "t2.small"
prod = "t3.medium"
}
ami = "ami-005f9685cb30f234b"
instance_type = each.value
tags = {
Name = each.key
}
}
Creates three instances with different instance types.
3. Using for_each with a List of Objects
variable "instances" {
type = list(object({
name = string
type = string
}))
default = [
{ name = "dev", type = "t2.micro" },
{ name = "staging", type = "t2.small" },
{ name = "prod", type = "t3.medium" }
]
}
resource "aws_instance" "web" {
for_each = { for inst in var.instances : inst.name => inst }
ami = "ami-005f9685cb30f234b"
instance_type = each.value.type
tags = {
Name = each.key
}
}
Creates instances dynamically from a list of objects.
Terraform Modules
A Terraform module is a reusable collection of Terraform resources that helps organize and manage infrastructure efficiently.
Key Benefits of Modules:
Reusability – Use the same code for multiple projects/environments.
Maintainability – Easier updates and modifications.
Scalability – Manage large infrastructures efficiently.
Types of Modules:
Root Module – The main Terraform configuration where submodules are called.
Child Modules – Reusable, self-contained configurations stored separately.
Using Modules:
Modules can be stored locally, in GitHub, or the Terraform Registry.
To use a module, specify the
source
inmain.tf
:module "example" { source = "./modules/example-module" }
Best Practice: Use modules for VPC, EC2, S3, RDS, IAM, etc., to simplify Terraform projects.
Task-04
Write about different modules of Terraform.
Difference between Root Module and Child Module.
Are modules and Namespaces are same? Justify your answer for both Yes/No
1. Different Modules in Terraform
Terraform modules are categorized into two main types:
A. Root Module
This is the main Terraform configuration where execution starts.
It typically includes
.tf
files (e.g.,main.tf
,variables.tf
,outputs.tf
).Calls child modules to structure the infrastructure.
B. Child Module
A reusable, self-contained module that can be used within the root module.
Helps in organizing and managing infrastructure efficiently.
It can be stored locally, in a Git repository, or on the Terraform Registry.
2. Difference Between Root Module and Child Module
Feature | Root Module | Child Module |
Definition | The main Terraform configuration where execution starts. | A reusable module used within the root module. |
Usage | Calls child modules or defines resources directly. | Provides pre-defined infrastructure components. |
Location | Stored in the project’s main directory. | Stored in a separate directory or external source (Git, Terraform Registry). |
Example | main.tf , variables.tf , outputs.tf in the project root. | modules/vpc/ main.tf , modules/ec2/ main.tf |
3. Are Modules and Namespaces the Same?
No, Modules and Namespaces Are Not the Same
Modules: A logical grouping of resources that can be reused (e.g., VPC module, EC2 module).
Namespaces: A way to organize resources uniquely, often used in Kubernetes or cloud services (e.g., AWS IAM namespaces).
Justification: Modules help structure Terraform configurations, while namespaces help manage resource identification and isolation.
Subscribe to my newsletter
Read articles from Vanshika Sharma directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Vanshika Sharma
Vanshika Sharma
I am currently a B.Tech student pursuing Computer Science with a specialization in Data Science at I.T.S Engineering College. I am always excited to learn and explore new things to increase my knowledge. I have good knowledge of programming languages such as C, Python, Java, and web development.