Introduction
Your report application needs a separate disk for its report file. You will create an Amazon EBS volume, attach it to an EC2 instance, format and mount its filesystem, and serve a report from that volume. You will then unmount, detach and delete the resources you created.
You should already know EC2 launch and SSH. Each lab starts fresh; this environment supplies its own application image, network and key pair.
Certification Relevance
This lab practices selecting block storage for an EC2 workload, supporting storage concepts in Task 3.6 of the AWS Certified Cloud Practitioner CLF-C02 Domain 3 objectives.
Launch the Storage Server
In this step, you will launch the application instance and identify its Availability Zone.
Start in your workspace and load the supplied resource IDs:
cd /home/labex/project
source launch.env
Launch one instance named storage-server. The image already contains a report application; your work will supply its data volume:
aws ec2 \
run-instances \
--image-id "$AMI_ID" \
--instance-type t3.micro \
--subnet-id "$SUBNET_ID" \
--security-group-ids "$SECURITY_GROUP_ID" \
--key-name report-key \
--count 1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=storage-server}]'
Capture the instance ID from its name tag:
INSTANCE_ID=$(aws ec2 \
describe-instances \
--filters Name=tag:Name,Values=storage-server \
--query 'Reservations[0].Instances[0].InstanceId' \
--output text)
Wait for the instance to run:
aws ec2 \
wait instance-running \
--instance-ids "$INSTANCE_ID"
An Availability Zone is an isolated location within a Region. An EBS volume attaches to an instance in the same Availability Zone. Retrieve the instance's zone rather than guessing it:
AVAILABILITY_ZONE=$(aws ec2 \
describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[0].Instances[0].Placement.AvailabilityZone' \
--output text)
Inspect the state and zone:
aws ec2 \
describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name,Zone:Placement.AvailabilityZone}'
Confirm running. Open AWS View, click Refresh resources, select storage-server and click Check application. Confirm HTTP 200 before adding storage.
Create and Attach the Data Volume
In this step, you will create a separate EBS data volume and attach it to the running server.
Amazon EBS provides block storage for EC2. A volume is a disk-like resource, while a filesystem organizes files on that disk. Attaching a volume makes its block device available; it does not create a filesystem. The EBS volume guide describes volume attachment and persistence.
Create a small, empty general-purpose SSD volume. gp3 selects the volume type, --size 1 requests one GiB, and the zone variable places it alongside your instance. Capture its ID for later operations:
VOLUME_ID=$(aws ec2 \
create-volume \
--availability-zone "$AVAILABILITY_ZONE" \
--size 1 \
--volume-type gp3 \
--tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=report-data}]' \
--query 'VolumeId' \
--output text)
Wait until the new volume is available:
aws ec2 \
wait volume-available \
--volume-ids "$VOLUME_ID"
Attach it using the API device name /dev/sdf:
aws ec2 \
attach-volume \
--volume-id "$VOLUME_ID" \
--instance-id "$INSTANCE_ID" \
--device /dev/sdf
Wait for attachment:
aws ec2 \
wait volume-in-use \
--volume-ids "$VOLUME_ID"
Inspect the volume and attachment:
aws ec2 \
describe-volumes \
--volume-ids "$VOLUME_ID" \
--query 'Volumes[].{Volume:VolumeId,State:State,Zone:AvailabilityZone,Size:Size,Type:VolumeType,Attachments:Attachments}'
Confirm in-use, size 1, type gp3 and an attachment to your instance. Refresh AWS View and inspect its volume row. The root volume is separate from the new data volume.
Mount the Volume and Serve a Report
In this step, you will initialize the empty data volume and make a report available to the application.
Retrieve the instance's current public address:
PUBLIC_IP=$(aws ec2 \
describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[0].Instances[0].PublicIpAddress' \
--output text)
Connect using the supplied SSH configuration:
ssh -F ssh_config ubuntu@"$PUBLIC_IP"
Inside the instance, inspect the newly attached device. Its Linux name in this lab is /dev/xvdf; device names can differ from the API attachment name. Other EC2 images may expose NVMe names, so identify a disk before operating on it. The official Linux volume preparation guide explains this distinction.
lsblk -f /dev/xvdf
Confirm the device has no filesystem type. Create an ext4 filesystem only on this newly created, empty data volume. Formatting a volume with existing data would erase it:
sudo mkfs.ext4 /dev/xvdf
A mount point is the directory through which you access a filesystem. Mount the new filesystem at the report application's prepared directory:
sudo mount /dev/xvdf /srv/reports
Confirm the source device, filesystem and mount point:
findmnt /srv/reports
Look for /dev/xvdf, ext4 and /srv/reports. Create a synthetic CSV report. sudo tee writes to the administrator-owned filesystem; the quoted here-document preserves the two lines:
sudo tee /srv/reports/report.csv <<'CSV'
period,total
Q1,320
CSV
Read the file back:
cat /srv/reports/report.csv
Return to the LabEx terminal:
exit
In AWS View, select storage-server and click Read volume report. Confirm HTTP 200 and the CSV text period,total and Q1,320. This response demonstrates that the application can read the file from the mounted volume.
The mount in this lab is manual. A reboot does not automatically restore a manual mount; production setups typically configure a filesystem UUID in /etc/fstab after testing the entry.
Unmount, Detach and Delete
In this step, you will remove the data volume and the application instance in a controlled order.
First reconnect to the application instance:
ssh -F ssh_config ubuntu@"$PUBLIC_IP"
Unmount the filesystem before detaching its disk. This stops filesystem access and flushes pending writes:
sudo umount /srv/reports
Confirm that it is no longer mounted:
findmnt /srv/reports
An unmounted directory produces no output and a nonzero exit status from findmnt; that is expected here. Return to the LabEx terminal:
exit
Detach only your data volume:
aws ec2 \
detach-volume \
--volume-id "$VOLUME_ID" \
--instance-id "$INSTANCE_ID" \
--device /dev/sdf
Wait until the volume is available again:
aws ec2 \
wait volume-available \
--volume-ids "$VOLUME_ID"
Delete the detached volume. This permanently removes its data, so retain important files or a backup before deleting a production volume:
aws ec2 \
delete-volume \
--volume-id "$VOLUME_ID"
Terminate the application instance:
aws ec2 \
terminate-instances \
--instance-ids "$INSTANCE_ID"
Wait for termination:
aws ec2 \
wait instance-terminated \
--instance-ids "$INSTANCE_ID"
Inspect the final instance state:
aws ec2 \
describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name}'
Confirm terminated, then list remaining volumes:
aws ec2 \
describe-volumes \
--query 'Volumes[].{Volume:VolumeId,State:State}'
Expect []: your data volume was explicitly deleted, and this instance's root volume was deleted on termination. Refresh AWS View and confirm the server is no longer a running target and the volume list is empty. Leave the prepared network and key pair in place.
Summary
You created an EBS data volume in the same Availability Zone as an EC2 instance, attached it, formatted an empty filesystem and mounted it for the application. You verified a real report response, then unmounted, detached and deleted the volume before terminating the server.



