LLM Function Calling for DevOps Automation with Claude API
Use Claude API tool use (function calling) to build DevOps automation that intelligently calls kubectl, AWS CLI, and monitoring APIs ā with parallel tool execution, error handling, and real production patterns.
Function calling (tool use) lets Claude intelligently decide which commands to run and when ā instead of you hardcoding the logic. Here is how to build DevOps automation that uses Claude as the decision layer.
How Tool Use Works
You define tools (functions) with schemas. Claude decides when and how to call them. You execute the calls and return results. Claude synthesizes a response.
import anthropic
import subprocess
import json
client = anthropic.Anthropic()
# Define tools Claude can use
DEVOPS_TOOLS = [
{
"name": "run_kubectl",
"description": "Execute a kubectl command and return the output. Use for Kubernetes operations.",
"input_schema": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The kubectl command to run (without the 'kubectl' prefix)"
},
"namespace": {
"type": "string",
"description": "Kubernetes namespace (optional, use when relevant)"
}
},
"required": ["command"]
}
},
{
"name": "run_aws_cli",
"description": "Execute an AWS CLI command and return JSON output.",
"input_schema": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The aws CLI command (without the 'aws' prefix)"
}
},
"required": ["command"]
}
},
{
"name": "check_pod_logs",
"description": "Get recent logs from a pod or deployment.",
"input_schema": {
"type": "object",
"properties": {
"target": {"type": "string", "description": "Pod name or deployment name"},
"namespace": {"type": "string", "description": "Kubernetes namespace"},
"lines": {"type": "integer", "description": "Number of lines (default 50)"},
"filter": {"type": "string", "description": "Optional grep filter"}
},
"required": ["target", "namespace"]
}
},
{
"name": "scale_deployment",
"description": "Scale a Kubernetes deployment to a specific number of replicas.",
"input_schema": {
"type": "object",
"properties": {
"deployment": {"type": "string", "description": "Deployment name"},
"namespace": {"type": "string", "description": "Kubernetes namespace"},
"replicas": {"type": "integer", "description": "Target replica count"}
},
"required": ["deployment", "namespace", "replicas"]
}
}
]
def execute_tool(tool_name: str, tool_input: dict) -> str:
"""Execute a tool call and return the result."""
if tool_name == "run_kubectl":
cmd = tool_input["command"].split()
ns = tool_input.get("namespace")
if ns and "-n" not in cmd and "--namespace" not in cmd:
cmd = ["-n", ns] + cmd
result = subprocess.run(
["kubectl"] + cmd,
capture_output=True, text=True, timeout=30
)
return result.stdout or result.stderr or "No output"
elif tool_name == "run_aws_cli":
cmd = tool_input["command"].split()
if "--output" not in cmd:
cmd += ["--output", "json"]
result = subprocess.run(
["aws"] + cmd,
capture_output=True, text=True, timeout=60
)
return result.stdout or result.stderr or "No output"
elif tool_name == "check_pod_logs":
target = tool_input["target"]
namespace = tool_input["namespace"]
lines = tool_input.get("lines", 50)
filter_str = tool_input.get("filter")
cmd = ["kubectl", "logs", "-n", namespace, target, f"--tail={lines}"]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
logs = result.stdout or result.stderr
if filter_str:
filtered = [line for line in logs.split("\n") if filter_str.lower() in line.lower()]
return "\n".join(filtered) or f"No lines matching '{filter_str}'"
return logs
elif tool_name == "scale_deployment":
result = subprocess.run(
["kubectl", "scale", "deployment", tool_input["deployment"],
"-n", tool_input["namespace"],
f"--replicas={tool_input['replicas']}"],
capture_output=True, text=True, timeout=30
)
return result.stdout or result.stderr
return f"Unknown tool: {tool_name}"
def run_devops_agent(user_request: str, max_iterations: int = 10) -> str:
"""Run the DevOps agent with tool use loop."""
messages = [{"role": "user", "content": user_request}]
system = """You are an expert DevOps engineer with kubectl and AWS CLI access.
Diagnose and fix issues systematically:
1. Gather information first (don't make assumptions)
2. Check logs and events for errors
3. Apply fixes methodically
4. Verify the fix worked
Always explain what you're doing and why."""
for iteration in range(max_iterations):
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=2000,
system=system,
tools=DEVOPS_TOOLS,
messages=messages
)
messages.append({"role": "assistant", "content": response.content})
# Check if Claude is done
if response.stop_reason == "end_turn":
# Extract final text response
for block in response.content:
if hasattr(block, "text"):
return block.text
return "Task completed"
# Execute all tool calls
tool_results = []
for block in response.content:
if block.type == "tool_use":
print(f" ā Calling {block.name}: {json.dumps(block.input)[:100]}...")
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result[:3000] # Limit result size
})
if tool_results:
messages.append({"role": "user", "content": tool_results})
return "Max iterations reached"
if __name__ == "__main__":
# Example requests
requests = [
"The payment-service in production is showing high error rates. Diagnose the issue.",
"Scale the api-gateway deployment in production to 5 replicas and verify it's healthy.",
"Check if any pods in the production namespace are in CrashLoopBackOff and fix them.",
]
for req in requests[:1]: # Run first example
print(f"\nRequest: {req}")
print("-" * 60)
result = run_devops_agent(req)
print(f"\nResult:\n{result}")Example Interaction
Request: The payment-service in production is showing high error rates. Diagnose the issue.
ā Calling run_kubectl: {"command": "get pods -l app=payment-service", "namespace": "production"}
ā Calling check_pod_logs: {"target": "payment-service", "namespace": "production", "filter": "ERROR"}
ā Calling run_kubectl: {"command": "describe pod payment-service-xyz", "namespace": "production"}
Result:
The payment-service has 3 pods, all running. Logs show repeated errors:
"ERROR: connection to postgres:5432 refused ā max connections exceeded (100/100)"
Root cause: Database connection pool exhausted. The service is configured with
pool_size=50 per pod and 3 pods Ć 50 = 150 connections, but PostgreSQL max_connections=100.
Immediate fix options:
1. Restart one pod to free connections: kubectl rollout restart deployment/payment-service -n production
2. Reduce pool_size in env vars to 30 (3 Ć 30 = 90 < 100)
3. Increase PostgreSQL max_connections ā requires DB restart
I recommend option 2 for a permanent fix without downtime.
Safety Controls
Add approval gates for dangerous operations:
DANGEROUS_OPERATIONS = ["delete", "drain", "scale --replicas=0", "rollout undo"]
def execute_tool_with_approval(tool_name: str, tool_input: dict) -> str:
command = tool_input.get("command", "")
if any(op in command for op in DANGEROUS_OPERATIONS):
confirm = input(f"Confirm dangerous operation? '{command}' [y/N]: ")
if confirm.lower() != "y":
return "Operation cancelled by user"
return execute_tool(tool_name, tool_input)Tool use transforms LLM outputs from suggestions into actions ā Claude doesn't just tell you what to run, it runs it.
More AI DevOps automation? Read our Build AI deployment validator with OPA and LLM agents in production guide.
Today I Fixed
Short real fixes from production ā posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam ā just practical engineering content.
Related Articles
Agentic DevOps: How AI Agents Will Autonomously Manage Infrastructure in 2026
AI agents that detect incidents, diagnose root causes, execute remediation, and write postmortems without human intervention are already running in production. Here is what agentic DevOps looks like and where it is heading.
Build an AI AWS Cost Anomaly Detector with Claude API and Cost Explorer
Step-by-step tutorial to build an AI-powered AWS cost anomaly detector using Claude API and AWS Cost Explorer. Automatically identify unusual spending patterns, find the responsible service, and get plain-English explanations with fix recommendations.
Build an AI Cloud Cost Anomaly Detector with Claude API + AWS Cost Explorer
Cloud costs spike without warning. Build a Python bot using AWS Cost Explorer + Claude API that detects anomalies using Z-score analysis and explains the spike in plain English.