An agent without grounding makes things up. Associate a Knowledge Base with your Bedrock Agent and every response is backed by your actual documents - with citations. Here's how to wire it up with Terraform.
Through this series, we've built Bedrock Agents that can reason, call APIs via action groups, and coordinate with other agents. But ask one a question about your company's policies, and it either hallucinates or admits it doesn't know. The model has no access to your data.
Knowledge Base association changes that. When you attach a Knowledge Base to your agent, the agent automatically queries your vector store when it needs domain-specific information. It retrieves relevant chunks, uses them as context, and generates a grounded response with citations back to your source documents. No hallucination. No guessing. Real answers from real data. π―
ποΈ How Agent + Knowledge Base Works
User: "What is our return policy for electronics?"
β
Agent analyzes request β determines it needs domain knowledge
β
Agent queries Knowledge Base (vector search)
β
Knowledge Base returns relevant chunks from policies.pdf
β
Agent generates response grounded in retrieved context
β
User: "Electronics can be returned within 30 days with original
receipt. Items must be in original packaging. [Source:
return-policy-2024.pdf, page 3]"
The agent decides when to query the Knowledge Base based on the KB instruction you provide. If the question can be answered without domain data (general knowledge, action group results), the agent skips the KB query.
π§ What You Need
This post assumes you have:
- A Bedrock Agent deployed (from Day 9)
- A Knowledge Base with synced data (from Series 2, RAG Posts)
We're connecting the two. If you haven't built either, refer back to the earlier posts for the full setup.
π§ Terraform: Associate Knowledge Base with Agent
The association is a single Terraform resource:
# agent/kb_association.tf
resource "aws_bedrockagent_agent_knowledge_base_association" "this" {
agent_id = aws_bedrockagent_agent.this.agent_id
description = var.kb_instruction
knowledge_base_id = var.knowledge_base_id
knowledge_base_state = "ENABLED"
}
That's it. One resource. The description field is the most important part - it tells the agent when and how to use the Knowledge Base.
The KB Instruction
# variables.tf
variable "kb_instruction" {
description = "Instruction telling the agent when to use the Knowledge Base"
type = string
default = <<-EOT
Use this knowledge base to answer questions about company policies,
product information, and internal procedures. Query the knowledge
base when the user asks about policies, returns, warranties,
pricing, or any company-specific information. Do not answer these
questions from general knowledge.
EOT
}
This instruction drives retrieval quality. A vague instruction like "use this for questions" means the agent queries the KB for everything, wasting tokens on general knowledge questions. A specific instruction like the one above targets retrieval to domain-specific queries only.
Re-Prepare After Association
The agent must be re-prepared after associating a Knowledge Base:
resource "null_resource" "prepare_after_kb" {
triggers = {
kb_association = aws_bedrockagent_agent_knowledge_base_association.this.id
kb_instruction = var.kb_instruction
}
provisioner "local-exec" {
command = "aws bedrock-agent prepare-agent --agent-id ${aws_bedrockagent_agent.this.agent_id} --region ${var.region}"
}
depends_on = [aws_bedrockagent_agent_knowledge_base_association.this]
}
IAM: Agent Needs KB Access
The agent's service role needs permission to retrieve from the Knowledge Base:
# agent/iam.tf
resource "aws_iam_role_policy" "agent_kb_retrieve" {
name = "kb-retrieve"
role = aws_iam_role.agent.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = [
"bedrock:Retrieve",
"bedrock:RetrieveAndGenerate"
]
Resource = "arn:aws:bedrock:${var.region}:${data.aws_caller_identity.current.account_id}:knowledge-base/${var.knowledge_base_id}"
}]
})
}
π Full Agent with Action Groups + Knowledge Base
Here's the complete picture - an agent with both tools and grounding:
# agent/main.tf
resource "aws_bedrockagent_agent" "this" {
agent_name = "${var.environment}-${var.agent_name}"
agent_resource_role_arn = aws_iam_role.agent.arn
foundation_model = var.agent_model.id
instruction = var.agent_instruction
prepare_agent = false # Prepare manually after KB + action groups
idle_session_ttl_in_seconds = var.idle_session_ttl
tags = {
Environment = var.environment
Model = var.agent_model.display
}
}
# Action group for real-time API calls
resource "aws_bedrockagent_agent_action_group" "api_tools" {
action_group_name = "APITools"
agent_id = aws_bedrockagent_agent.this.agent_id
agent_version = "DRAFT"
description = "Real-time API operations"
action_group_executor {
lambda = aws_lambda_function.api_tools.arn
}
api_schema {
payload = file("${path.module}/schemas/api_tools.json")
}
}
# Knowledge Base for document grounding
resource "aws_bedrockagent_agent_knowledge_base_association" "docs" {
agent_id = aws_bedrockagent_agent.this.agent_id
description = var.kb_instruction
knowledge_base_id = var.knowledge_base_id
knowledge_base_state = "ENABLED"
}
# Prepare after everything is wired up
resource "null_resource" "prepare_agent" {
triggers = {
action_group = aws_bedrockagent_agent_action_group.api_tools.id
kb = aws_bedrockagent_agent_knowledge_base_association.docs.id
}
provisioner "local-exec" {
command = "aws bedrock-agent prepare-agent --agent-id ${aws_bedrockagent_agent.this.agent_id} --region ${var.region}"
}
depends_on = [
aws_bedrockagent_agent_action_group.api_tools,
aws_bedrockagent_agent_knowledge_base_association.docs,
]
}
resource "time_sleep" "wait_for_preparation" {
depends_on = [null_resource.prepare_agent]
create_duration = "15s"
}
resource "aws_bedrockagent_agent_alias" "live" {
agent_alias_name = "${var.environment}-live"
agent_id = aws_bedrockagent_agent.this.agent_id
depends_on = [time_sleep.wait_for_preparation]
}
The agent now has two capabilities: action groups for real-time API calls (live exchange rates, order lookups) and Knowledge Base for document-grounded answers (policies, product info). The agent decides which to use based on the user's question.
π§ͺ How the Agent Decides
When a user asks a question, the agent follows this decision flow:
- Can I answer from general knowledge? If yes, respond directly.
- Does this need a tool call? If the question requires live data (exchange rates, weather), invoke the action group.
- Does this need domain knowledge? If the question is about company-specific information, query the Knowledge Base.
- Do I need both? For complex questions, the agent can combine action group results with KB context.
The KB instruction and action group descriptions guide these decisions. Clear, non-overlapping descriptions produce the best routing.
π Multiple Knowledge Bases
An agent can have multiple Knowledge Bases, each for a different domain:
resource "aws_bedrockagent_agent_knowledge_base_association" "policies" {
agent_id = aws_bedrockagent_agent.this.agent_id
description = "Use for questions about company policies, returns, and warranties."
knowledge_base_id = var.policies_kb_id
knowledge_base_state = "ENABLED"
}
resource "aws_bedrockagent_agent_knowledge_base_association" "products" {
agent_id = aws_bedrockagent_agent.this.agent_id
description = "Use for questions about product specifications, features, and compatibility."
knowledge_base_id = var.products_kb_id
knowledge_base_state = "ENABLED"
}
Each KB instruction should clearly define its domain so the agent routes to the right KB. Overlapping instructions lead to incorrect retrieval.
β οΈ Gotchas and Tips
KB instruction quality is retrieval quality. A vague instruction means the agent queries the KB for everything, adding latency and cost to questions it could answer from general knowledge. Be specific about what types of questions should trigger a KB query.
Citations come free. When the agent uses KB context, the response includes source attributions with document names and page numbers. You don't need to build citation logic.
KB + action groups don't conflict. The agent can use both in a single conversation turn. For example: "Check my order status and tell me the return policy" might trigger an action group for order status and a KB query for the return policy.
Sync your KB before testing. The association works immediately, but the agent retrieves from whatever is currently indexed. If you haven't synced your data source recently, you'll get stale or empty results.
KB instruction updates require re-preparation. Changing the description field on the association triggers a Terraform update, but the agent must be re-prepared for the change to take effect.
βοΈ Series Complete!
This is Post 4 of the AWS AI Agents with Terraform series, and the final post of the entire multi-cloud series.
- Post 1: Deploy First Bedrock Agent π€
- Post 2: Action Groups - Connect to APIs π
- Post 3: Multi-Agent Orchestration π§
- Post 4: Agent + Knowledge Base Grounding (you are here) π
Your agent is now grounded. It reasons through complex requests, calls APIs for live data, coordinates with specialist agents, and answers domain questions from your actual documents with citations. From a simple endpoint to a fully autonomous, grounded AI agent - all in Terraform. π
Thanks for following the full series! Follow for what comes next. π¬
Top comments (0)