Have you ever dreamed of having your own private Netflix—complete with your personal movie collection, TV shows, or even home videos—accessible anytime, anywhere? Today, we’re going to make that a reality using AWS services like S3, Elemental MediaConvert, and ECS, all tied together with a Terraform automation twist. Oh, and we’ll lock it down with Cognito for secure access. Let’s get streaming!

What Are We Building?

Imagine a lightweight, cloud-powered media streaming service tailored just for you (and maybe your family or friends). Here’s the stack:

  • Amazon S3: A scalable, durable storage bucket for your raw video files and transcoded outputs.
  • AWS Elemental MediaConvert: A professional-grade transcoding service to convert your videos into streamable formats (like HLS or MP4).
  • ECS (Elastic Container Service): A simple web app running on ECS to serve your media library and stream content to your devices.
  • Amazon Cognito: User authentication to keep your collection private and secure.
  • Terraform: Infrastructure-as-code to automate the setup—because who has time to click through the AWS console?

By the end, you’ll have a slick setup where you can upload videos, transcode them automatically, and stream them through a custom web interface. Plus, we’ll package it all into a GitHub repo for easy deployment.

Why Bother?

You might be thinking, “Why not just use Plex or upload to YouTube?” Fair question! Here’s why this DIY approach rocks:

  1. Full Control: No third-party limitations—organize your library your way, with cloud scalability.
  2. Cost Efficiency: Pay only for what you use with AWS (S3 storage is cheap, and MediaConvert is per-minute).
  3. Learning Opportunity: Master AWS services and Terraform while building something practical.
  4. Privacy: Keep your media off public platforms, secured behind Cognito authentication.

Whether it’s archiving family videos, curating a personal film collection, or experimenting with cloud tech, this project is a win.

The Terraform Twist: Automating the Magic

Manual AWS setup is tedious. Enter Terraform—our IaC savior. We’ll automate:

  • S3 Buckets: One for raw uploads, another for transcoded outputs, with proper bucket policies.
  • ECS Cluster: A Fargate-backed cluster for our web app, complete with a load balancer.
  • MediaConvert Job Templates: Predefined transcoding settings for consistency.
  • Cognito User Pool: Authentication setup with minimal fuss.

Let’s break it down with some code snippets (don’t worry, the full repo will be linked at the end!).

Step 1: S3 Buckets

We create two private buckets with unique names (thanks to a random suffix). The raw bucket holds uploads; the transcoded one stores streamable files.
resource "aws_s3_bucket" "raw_videos" { bucket = "my-media-raw-${random_string.suffix.result}" acl = "private" } resource "aws_s3_bucket" "transcoded_videos" { bucket = "my-media-transcoded-${random_string.suffix.result}" acl = "private" } resource "random_string" "suffix" { length = 8 special = false }

We create two private buckets with unique names (thanks to a random suffix). The raw bucket holds uploads; the transcoded one stores streamable files.

Step 2: MediaConvert Job Template

resource "aws_media_convert_job_template" "hls_template" {
  name = "hls-720p"
  settings_json = jsonencode({
    "OutputGroups": [{
      "Name": "Apple HLS",
      "Outputs": [{
        "Preset": "System-Generic_Hd_Mp4_Avc_Aac_16x9_1280x720p_24Hz_4.5Mbps",
        "NameModifier": "_720p"
      }],
      "OutputGroupSettings": {
        "Type": "HLS_GROUP_SETTINGS",
        "HlsSettings": {
          "SegmentLength": 10
        }
      }
    }],
    "Inputs": [{
      "FileInput": "s3://${aws_s3_bucket.raw_videos.bucket}/{input_file}"
    }]
  })
}

This template transcodes videos to 720p HLS (HTTP Live Streaming), perfect for adaptive streaming. You can tweak resolution or codecs as needed.

Step 3: ECS Web App

resource "aws_ecs_cluster" "media_app" {
  name = "media-streaming-cluster"
}

resource "aws_ecs_task_definition" "web_app" {
  family                   = "media-web-app"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = "256"
  memory                   = "512"
  execution_role_arn       = aws_iam_role.ecs_execution_role.arn

  container_definitions = jsonencode([{
    name  = "web-app"
    image = "your-docker-image:latest" # Replace with your app’s image
    portMappings = [{
      containerPort = 80
      hostPort      = 80
    }]
  }])
}

resource "aws_ecs_service" "web_service" {
  name            = "media-web-service"
  cluster         = aws_ecs_cluster.media_app.id
  task_definition = aws_ecs_task_definition.web_app.arn
  launch_type     = "FARGATE"
  desired_count   = 1

  network_configuration {
    subnets         = aws_subnet.private[*].id
    security_groups = [aws_security_group.ecs_sg.id]
  }
}

This sets up a Fargate-based ECS service. The web app (a simple Node.js or Flask app you’d build) lists videos from the transcoded bucket and streams them.

Step 4: Cognito Security

resource "aws_cognito_user_pool" "media_users" {
  name = "media-streaming-users"
  password_policy {
    minimum_length = 8
  }
}

resource "aws_cognito_user_pool_client" "app_client" {
  name         = "media-web-client"
  user_pool_id = aws_cognito_user_pool.media_users.id
}

Cognito provides a user pool for authentication. Your web app integrates this to ensure only authorized users can log in.

Security is key. With Cognito, you get:

  • User Management: Sign-up, sign-in, and password recovery out of the box.
  • Integration: Add Cognito’s hosted UI or use the SDK in your ECS app.
  • S3 Access Control: Attach an IAM policy to Cognito roles, limiting S3 access to authenticated users.

For example, an IAM policy might look like this:

resource "aws_iam_role_policy" "cognito_s3_access" {
  role = aws_iam_role.cognito_role.id
  policy = jsonencode({
    "Statement": [{
      "Effect": "Allow",
      "Action": ["s3:GetObject"],
      "Resource": ["${aws_s3_bucket.transcoded_videos.arn}/*"]
    }]
  })
}

Putting It All Together

Here’s the workflow:

  1. Upload a video to the raw S3 bucket (manually or via the web app).
  2. Trigger a MediaConvert job (using the template) to transcode it.
  3. Store the output in the transcoded bucket.
  4. The ECS web app lists and streams the transcoded files, protected by Cognito login.

The GitHub Repo

Want to try this yourself? I’ve put all the Terraform code, a sample web app, and setup instructions in a GitHub repo: https://github.com/VPS-ZEN/Build-Your-Own-Netflix . Clone it, tweak the variables, run terraform apply, and you’re live.

Power Your Projects with vpszen.com VPS Solutions

Looking for reliable hosting to run your Linux servers and host your next big project? VpsZen.com has you covered with top-tier VPS options tailored to your needs.
Choose from ARM64 VPS Servers for energy-efficient performance, or Root VPS Servers for virtual servers with dedicated resources.