Ravindra BagaleCourses & study guides

16. Live Project: Building a Reels App with EC2, S3 and RDS

16.2 AWS Setup: S3 Bucket, IAM Role and RDS

Code chya aadhi teen AWS goshti ready kara. He sagle Chapter 14 aani 15 madhe detail madhe kela aahe – ithe fakt project sathi exact settings.

1. S3 bucket (private)

BUCKET=ravindra-reels-media-pune
aws s3api create-bucket --bucket $BUCKET --region ap-south-1 \
  --create-bucket-configuration LocationConstraint=ap-south-1
aws s3api put-public-access-block --bucket $BUCKET --public-access-block-configuration \
  BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
aws s3api put-bucket-versioning --bucket $BUCKET --versioning-configuration Status=Enabled
aws s3api put-bucket-policy --bucket $BUCKET --policy file://deny-http.json   # DenyInsecureTransport from 14.3

No CORS rule is needed: the page plays videos with a plain <video src="..."> tag and uploads go through PHP, not directly from JavaScript to S3.

2. IAM role for EC2 – reels-ec2-role, trusted entity EC2, with only this inline policy (no delete, no list, only the videos/ prefix):

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "ReelsVideosOnly",
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:GetObject"],
    "Resource": "arn:aws:s3:::ravindra-reels-media-pune/videos/*"
  }]
}

3. EC2 instance – Amazon Linux 2023 (or Ubuntu), t3.micro or similar, security group web-sg (22 from your IP, 80 and 443 from anywhere), IAM instance profile: reels-ec2-role, Metadata version: V2 only (token required), Elastic IP attached.

4. RDS MySQL – reels-db exactly as in Chapter 15: public access No, db-sg allows 3306 only from web-sg, encryption and deletion protection on, database reelsdb.

# on the EC2 instance – verify the role and the network before writing any code
aws sts get-caller-identity                     # should show assumed-role/reels-ec2-role/...
echo test > t.txt && aws s3 cp t.txt s3://ravindra-reels-media-pune/videos/t.txt && echo S3-OK
nc -zv reels-db.abcdefgh1234.ap-south-1.rds.amazonaws.com 3306

Why this matters for security

With IMDSv2 required, a server-side request forgery (SSRF) bug in the app cannot simply read the role credentials from http://169.254.169.254/ with a plain GET – the attacker also needs a PUT request to get a token. Together with a policy scoped to videos/*, even stolen role credentials can do very little.

Ravindra Bagale's Tip

You created the role but forgot to attach it to EC2 – then the SDK gives a "Could not load credentials" error and students put an access key in the code. Never! Run aws sts get-caller-identity: if the role doesn't show, use Actions → Security → Modify IAM role. These three tests (sts, s3 cp, nc) must pass before you touch the code.

Lab

Create the bucket, role, EC2 instance and RDS database. Run the three verification commands and save their output in your notes. Then try aws s3 ls s3://ravindra-reels-media-pune/ and explain why it is denied.