Web Development

Stop Clicking Through AWS Console: Why I Finally Automated My RAG Pipeline

A

Admin User

Author

Aug 7, 2026
5 min read
3 views
Stop Clicking Through AWS Console: Why I Finally Automated My RAG Pipeline

I spent three weeks last year building a "Chat with PDF" prototype. Manually. Through the AWS Console. Click by click, creating S3 buckets, configuring OpenSearch Serverless, wiring up Bedrock Knowledge Bases—the whole circus. It worked fine for a proof of concept, but then my manager asked if we could test a different vector database. I stared at my infrastructure for a moment and realized I'd just spent three weeks building something I couldn't easily reproduce or modify.

That's when I understood: the console is great for learning, terrible for iteration. And if you're actually shipping something with RAG and Bedrock, you're going to iterate. You'll want to compare vector dimensions, swap storage backends, adjust chunking strategies. Each manual rebuild is a day lost and a point of failure waiting to happen.

The Console Trap Is Real

I've watched this play out with junior developers on my team too. They prototype in the console, it works, then they panic when asked to deploy to staging. Infrastructure-as-Code isn't optional anymore—it's the baseline expectation for anything that needs to exist in more than one environment.

The original article tackles exactly this problem. It walks through automating a complete RAG pipeline with Terraform: S3 for documents, OpenSearch Serverless for vectors, Bedrock Knowledge Bases for orchestration, and Lambda functions for ingestion and queries. Everything provisioned through code. One terraform apply spins up the entire stack.

What I appreciated most was the author's honesty: they built this because they couldn't find an existing Terraform module that covered the full pipeline. That's real developer energy. Not "let me abstract everything into a reusable framework," but "I need this specific thing to work repeatably, so I'm building it."

Breaking Down The Architecture

The project structure matters here. Separate Terraform modules for storage, OpenSearch, Bedrock, and Lambda—each module owns one responsibility and exposes only what others need. This sounds like overkill until your Lambda deployment fails at 2 AM and you need to know if it's a permissions issue, a networking issue, or an actual code problem. Clear boundaries make debugging possible.

The remote state setup is something I always push teams on. Storing Terraform state locally means you can't collaborate, you can't deploy from CI/CD, and you're one laptop crash away from losing your source of truth. The bootstrap approach here—using S3 with native state locking (new in Terraform 1.10)—is exactly what production deployments should use.

My Take: The Details Matter More Than The Concept

The RAG pipeline itself isn't complex conceptually. Documents go in, get chunked, get embedded, get stored, queries retrieve relevant chunks, and the LLM generates answers with citations. Anyone can understand that in five minutes.

But executing it reliably? That's where most teams stumble. And that's where this Terraform approach wins. You're not just automating clicks—you're codifying decisions about vector dimensions (512 vs 1536 makes a real difference in cost and quality), encryption, versioning, access control, and Lambda concurrency.

I do want to flag one thing: the article mentions using least-privilege IAM permissions after bootstrap. This is correct, but I've seen teams skip this step. Don't. The bootstrap deployer policy is generous by necessity, but you should immediately swap to a scoped policy. It's tedious, but it's the difference between "we got breached" and "our infrastructure stayed secure."

A Code Pattern Worth Stealing

Here's what I'd do with this approach:

# Main stack passes outputs from one module to the next
module "storage" {
  source = "./modules/storage"
  project_name = var.project_name
  environment = var.environment
}

module "opensearch" {
  source = "./modules/opensearch"
  vpc_id = module.storage.vpc_id
  embedding_dimensions = var.embedding_dimensions
}

module "bedrock" {
  source = "./modules/bedrock"
  knowledge_base_name = "${var.project_name}-kb"
  vector_index_name = module.opensearch.index_name
  s3_bucket = module.storage.bucket_name
}

module "lambda" {
  source = "./modules/lambda"
  bedrock_kb_id = module.bedrock.knowledge_base_id
  opensearch_endpoint = module.opensearch.endpoint
  s3_bucket = module.storage.bucket_name
}

This composition pattern—where each module's outputs feed into the next module's inputs—is powerful. You can test modules independently, swap implementations, and reason about the system clearly.

What I'd Do Differently

I'd add Terraform outputs for the Lambda function endpoints and document the cost implications upfront. Serverless is great until you realize OpenSearch costs scale with data volume, and nobody told the team. Also, CI/CD integration and testing. Can you run terraform plan in your pull requests? Can engineers review infrastructure changes before they land?

The Real Question

Here's what I want to know: how many teams building RAG applications today are still clicking through consoles because they haven't invested in infrastructure-as-code? And how many of those teams are going to hit the exact wall I hit—needing to iterate on their pipeline but unable to because it's all manual?

If you're building anything serious with Bedrock, you need this pattern. Not eventually. Now.


Source: This post was inspired by "RAG Powered Apps with Amazon Bedrock, Part 2: Automating the RAG Pipeline with Terraform" by Dev.to. Read the original article

Share this article

Written by Adil Sher

Full stack developer building high-traffic platforms, AI services, and custom web applications. Explore my portfolio, learn about my background, or get in touch.

Related Articles

Stop Bolting AI Onto Your CMS—Make It Part of the System
Web Development Aug 9

Stop Bolting AI Onto Your CMS—Make It Part of the System

I spent three hours last week moving content between five different tools. A writer drafted in ChatGPT. Then it went into our headless CMS. Then localization happened in a separate app. Then SEO metadata got filled in by hand. Then a developer like me had to wire up the final out...

AI Didn't Replace Me—But It Did Change How I Think About My Job
Web Development Aug 8

AI Didn't Replace Me—But It Did Change How I Think About My Job

Three months ago, I caught myself staring at a pull request that an LLM generated. It was technically correct. The logic was sound. The performance was acceptable. And I realized I had absolutely no idea if it was *good* or just… passable. That moment stuck with me more than any...