diff --git a/.gitignore b/.gitignore index 8e894d6..568bff5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,4 @@ -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -*.egg-info/ -dist/ -build/ -.venv/ -venv/ -.DS_Store -.idea/ -.vscode/ -*.swp -*.swo -*~ -.kiro/ +.platform/ +config.local.yaml +private/ +.local/ diff --git a/README.md b/README.md index 33b98d0..7beb1de 100644 --- a/README.md +++ b/README.md @@ -1,326 +1,131 @@ -# Agent Platform on Amazon EKS +# Open Agentic Platform on Amazon EKS -A production-ready, enterprise-grade AI agent platform built on Amazon EKS using [Kagent](https://kagent.dev), featuring comprehensive observability, intelligent gateway routing, and multi-agent orchestration. +A production-ready AI agent platform built on Amazon EKS, featuring KAgent, LiteLLM gateway, Langfuse observability, AgentGateway (MCP auth), and multi-agent orchestration. -## 🎯 Overview +## Quick Start -This project demonstrates a complete AI agent platform with: -- **Multiple agent patterns** - Simple agents, K8s operators, multi-tool agents, and multi-agent collaboration -- **Production observability** - LLM tracing, distributed tracing, cost tracking, and infrastructure metrics -- **Intelligent gateway** - Rate limiting, caching, fallbacks, and load balancing via LiteLLM -- **Real-world use case** - Financial services multi-agent system with agent-to-agent (A2A) communication +### Prerequisites -## πŸ—οΈ Architecture +- AWS account with Bedrock access +- [Task](https://taskfile.dev), kubectl, Helm 3.x, AWS CLI, `yq` +- Podman or Docker (for Kind-based bootstrap) -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Agent Platform β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Simple Agent β”‚ β”‚ K8s Ops β”‚ β”‚ Multi-Tool β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ Agent β”‚ β”‚ Agent β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Financial Services Multi-Agent β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Portfolio β”‚ β”‚ Risk β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ Analyst β”‚ β”‚ Assessment β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β”‚ β”‚ β”‚ β”‚ -β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ -β”‚ β”‚ β”‚ Financial β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ Advisor β”‚ β”‚ β”‚ -β”‚ β”‚ β”‚ (Orchestrator) β”‚ β”‚ β”‚ -β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ LiteLLM Gateway β”‚ - β”‚ - Rate Limiting β”‚ - β”‚ - Caching (Redis) β”‚ - β”‚ - Fallbacks β”‚ - β”‚ - Cost Tracking β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ Amazon Bedrock β”‚ - β”‚ Claude 3.5 Sonnet β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - - Observability Stack - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ β”‚ β”‚ β”‚ - β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” - β”‚Langfuse β”‚ β”‚ Jaeger β”‚ β”‚Prometheusβ”‚ β”‚ Grafana β”‚ - β”‚LLM Traceβ”‚ β”‚Dist.Tracβ”‚ β”‚ Metrics β”‚ β”‚ Viz β”‚ - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -## πŸš€ What's Included - -### Agent Examples - -#### 1️⃣ **Simple Agent** (`01-first-agent/`) -Basic agent demonstrating core Kagent functionality with Bedrock integration. - -#### 2️⃣ **K8s Operations Agent** (`02-k8s-ops-agent/`) -Kubernetes-aware agent that can query and manage cluster resources. - -#### 3️⃣ **Multi-Tool Agent** (`03-multi-tool-agent/`) -Smart assistant with multiple capabilities via MCP (Model Context Protocol): -- **Calculator** - Mathematical computations -- **Web Search** - Real-time information retrieval -- **Weather** - Current weather data -- **DateTime** - Timezone-aware date/time operations - -#### 4️⃣ **Financial Services Multi-Agent System** (`04-multi-agents/financial-services/`) -Production-ready multi-agent system demonstrating agent-to-agent (A2A) collaboration: - -**Specialist Agents:** -- **Portfolio Analyst** - Portfolio valuation and analysis -- **Risk Assessment** - Risk evaluation and compliance -- **Market Data** - Real-time market information - -**Orchestrator:** -- **Financial Advisor** - Coordinates specialists to provide comprehensive financial advice - -**Example Interaction:** -``` -User: "I have 100 AAPL and 50 GOOGL shares. Is my portfolio balanced?" - -Financial Advisor (Orchestrator) - β”œβ”€β†’ Portfolio Analyst: Calculate total value - β”œβ”€β†’ Risk Assessment: Evaluate risk profile - β”œβ”€β†’ Market Data: Get current prices - └─→ Synthesizes response with actionable advice -``` - -### Observability Stack (`05-observability/`) - -#### **LiteLLM Gateway** -Intelligent proxy for LLM requests with enterprise features: -- βœ… **Rate Limiting** - 100 RPM, 100K TPM (configurable per agent) -- βœ… **Caching** - Redis-backed response caching (1-hour TTL) -- βœ… **Fallbacks** - Claude Sonnet β†’ Claude Haiku on failures -- βœ… **Load Balancing** - Distribute across multiple model instances -- βœ… **Cost Tracking** - Real-time token usage and cost monitoring - -#### **Langfuse** -LLM-specific observability platform: -- πŸ“Š **Trace every LLM call** - Prompts, completions, tokens, costs -- πŸ’° **Cost analytics** - Per-agent, per-model, per-request -- πŸ” **Debug conversations** - Full context and tool calls -- πŸ“ˆ **Usage trends** - Token consumption over time - -#### **Jaeger** -Distributed tracing for agent interactions: -- πŸ”— **Agent-to-agent traces** - A2A communication flows -- ⏱️ **Latency analysis** - Identify bottlenecks -- 🌐 **Request correlation** - End-to-end visibility - -#### **Prometheus + Grafana** -Infrastructure and application metrics: -- πŸ“‰ **Kagent controller metrics** - Reconciliation rates, errors -- πŸ–₯️ **Resource usage** - CPU, memory, network per agent -- 🚨 **Alerting** - High error rates, latency spikes - -## πŸ“‹ Prerequisites - -- Amazon EKS cluster (1.28+) -- kubectl configured -- Helm 3.x -- AWS credentials with Bedrock access -- Podman or Docker (for building custom tools) - -## πŸ› οΈ Quick Start - -### 1. Initial Setup - -```bash -# Install Kagent CRDs and operator -cd 00-initial-setup -kubectl apply -f bedrock-key.yaml -kubectl apply -f litellm-config.yaml -kubectl apply -f litellm-deploy.yaml - -# Install Kagent via Helm -helm install kagent-crds oci://public.ecr.aws/kagent-dev/kagent-crds --version 0.7.9 -n kagent --create-namespace -helm install kagent oci://public.ecr.aws/kagent-dev/kagent --version 0.7.9 -n kagent -f values.yaml -``` - -### 2. Deploy Observability Stack +### Install ```bash -cd 05-observability/langfuse - -# Deploy Langfuse -kubectl apply -f 00-langfuse-secrets.yaml -kubectl apply -f 01-postgres.yaml -kubectl apply -f 02-langfuse-deployment.yaml - -# Setup LiteLLM gateway features -./setup-gateway-features.sh - -# Deploy Jaeger -kubectl apply -f ../tracing/jaeger.yaml +# 1. Configure +cp config.yaml config.local.yaml +# Edit config.local.yaml with your values -# Deploy Prometheus ServiceMonitor -kubectl apply -f ../prometheus/kagent-servicemonitor.yaml +# 2. Install everything (platform + agentic components) +task install ``` -### 3. Deploy Agents - -```bash -# Simple agent -kubectl apply -f 01-first-agent/sample-agent.yaml - -# K8s ops agent -kubectl apply -f 02-k8s-ops-agent/k8s-ops-agent.yaml +That's it. The installer provisions an EKS hub cluster, deploys the base platform (ArgoCD, Crossplane, observability), then layers on the agentic components. -# Multi-tool agent -cd 03-multi-tool-agent -./deploy.sh +### Configuration -# Financial services multi-agent -cd 04-multi-agents/financial-services -./deploy.sh -``` - -### 4. Access UIs +Edit `config.local.yaml`: -```bash -# Kagent UI -kubectl port-forward -n kagent svc/kagent-ui 8080:8080 +| Section | Key Fields | Description | +|---------|-----------|-------------| +| `platform` | `repo`, `ref` | Base platform repo and version tag | +| `aws` | `region`, `accountId`, `profile` | AWS settings | +| `hub` | `clusterName`, `kubernetesVersion` | Hub cluster config | +| `domain` | | Ingress domain (must have ACM cert + Route53 zone) | +| `identityCenter` | `instanceArn`, `region`, `adminGroupId` | SSO for ArgoCD | +| `agenticRepo` | `url`, `revision`, `basepath` | This repo's git coordinates (for ArgoCD) | +| `components` | `kagent`, `litellm`, `langfuse`, etc. | Toggle agentic components | +| `spokes` | | Optional spoke clusters (see below) | -# Langfuse (LLM tracing & costs) -kubectl port-forward -n langfuse svc/langfuse 3000:3000 +### Spoke Clusters -# Jaeger (distributed tracing) -kubectl port-forward -n jaeger svc/jaeger 16686:16686 +Add spoke clusters for workload environments: -# Grafana (metrics) -kubectl port-forward -n monitoring svc/kube-prom-stack-grafana 3001:80 +```yaml +spokes: + dev: + region: us-west-2 + kubernetesVersion: "1.35" + vpcCidr: "10.1.0.0/16" + autoMode: true + prod: + region: us-west-2 + kubernetesVersion: "1.35" + vpcCidr: "10.2.0.0/16" + autoMode: true ``` -## πŸ“Š Observability in Action - -### View LLM Traces in Langfuse -1. Open http://localhost:3000 -2. Navigate to **Traces** -3. See every LLM call with: - - Input/output tokens - - Cost per request - - Latency - - Model used - - Cache hits (shows $0 cost) - -### View Agent Traces in Jaeger -1. Open http://localhost:16686 -2. Select service (e.g., `financial-advisor`) -3. See distributed traces showing: - - Agent-to-agent calls - - Tool invocations - - End-to-end latency - -### View Metrics in Grafana -1. Open http://localhost:3001 (admin/prom-operator) -2. Explore dashboards for: - - Kagent controller operations - - Agent resource usage - - Request rates and errors +Spokes are provisioned via Crossplane from the hub. Agentic components deploy to all clusters automatically. -## πŸŽ“ Key Concepts +## Available Commands -### Agent-to-Agent (A2A) Communication -Agents can call other agents as tools, enabling: -- **Specialization** - Each agent focuses on specific domain -- **Orchestration** - Coordinator agents delegate to specialists -- **Scalability** - Add new specialists without changing orchestrator +| Command | Description | +|---------|-------------| +| `task install` | Full install (platform + spokes + agentic) | +| `task platform:install` | Provision base EKS platform only | +| `task spokes:install` | Provision spoke clusters only | +| `task spokes:status` | Check spoke provisioning progress | +| `task agentic:install` | Deploy agentic components only | +| `task status` | Show ArgoCD application status | +| `task upgrade` | Upgrade everything | +| `task destroy` | Remove agentic components (keeps base platform) | +| `task spokes:destroy` | Delete spoke clusters | -### Model Context Protocol (MCP) -Standardized way for agents to access tools: -- **RemoteMCPServer** - Tools running as separate services -- **Tool Discovery** - Agents discover available tools dynamically -- **Streaming** - Real-time tool responses +## Architecture -### Gateway Pattern -LiteLLM acts as intelligent gateway: -- **Single endpoint** - All agents use same LLM endpoint -- **Centralized control** - Rate limits, caching, fallbacks -- **Observability** - Every request traced to Langfuse - -## πŸ”§ Configuration - -### Adjust Rate Limits -Edit `05-observability/langfuse/litellm-advanced-config.yaml`: -```yaml -litellm_settings: - rpm_limit: 100 # Requests per minute - tpm_limit: 100000 # Tokens per minute ``` - -### Configure Caching -```yaml -litellm_settings: - cache: true - cache_params: - ttl: 3600 # Cache duration in seconds -``` - -### Add Fallback Models -```yaml -router_settings: - fallbacks: - - bedrock-claude-3-5-sonnet: [bedrock-claude-3-haiku] +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ open-agentic-platform (this repo) β”‚ +β”‚ config.local.yaml β†’ task install β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ appmod-blueprintsβ”‚ β”‚ ArgoCD Applicationβ”‚ + β”‚ (base platform) β”‚ β”‚ (agentic addons) β”‚ + β”‚ read-only clone β”‚ β”‚ points to this repoβ”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ + β–Ό β–Ό + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ EKS Hub Cluster β”‚ + β”‚ ArgoCD ─── watches both repos (read-only) β”‚ + β”‚ Crossplane ─── provisions spoke clusters β”‚ + β”‚ β”‚ + β”‚ Agentic: KAgent, LiteLLM, Langfuse, Jaeger, β”‚ + β”‚ AgentGateway, Bifrost, AgentCore β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` -## πŸ“ˆ Monitoring & Alerts - -### Key Metrics to Watch -- **LLM Cost** - Track spend per agent in Langfuse -- **Cache Hit Rate** - Target >30% for cost savings -- **Error Rate** - Alert if >5% in Prometheus -- **Latency** - P95 should be <5s for good UX +## Components -### Cost Optimization -1. **Enable caching** - Saves on repeated queries -2. **Use fallbacks** - Haiku is 10x cheaper than Sonnet -3. **Set budgets** - Prevent runaway costs -4. **Monitor in Langfuse** - Identify expensive agents +| Component | Purpose | +|-----------|---------| +| **KAgent** | Kubernetes-native AI agent operator | +| **LiteLLM** | LLM gateway with rate limiting, caching, fallbacks | +| **Langfuse** | LLM observability β€” traces, costs, analytics | +| **Jaeger** | Distributed tracing for agent interactions | +| **AgentGateway** | MCP auth gateway with Keycloak OIDC | +| **Bifrost** | AI gateway for model routing | +| **AgentCore** | Crossplane compositions for Bedrock AgentCore | -## 🀝 Contributing +## Workshop -This is a reference implementation. Feel free to: -- Add new agent examples -- Enhance observability dashboards -- Improve documentation -- Share your use cases +The `workshop/` directory contains hands-on examples: -## πŸ“š Documentation +| Module | Description | +|--------|-------------| +| `00-initial-setup` | Bedrock + LiteLLM configuration | +| `01-first-agent` | Basic KAgent with Bedrock | +| `02-k8s-ops-agent` | Kubernetes operations agent | +| `03-multi-tool-agent` | Agent with MCP tool servers | +| `04-multi-agents` | Financial services multi-agent system | +| `05-observability` | Monitoring and tracing setup | -- **Langfuse Setup** - `05-observability/langfuse/INSTALL.md` -- **LiteLLM Gateway Features** - `05-observability/langfuse/LITELLM-GATEWAY-FEATURES.md` -- **Multi-Agent System** - `04-multi-agents/financial-services/README.md` +## Resources -## πŸ”— Resources - -- [Kagent Documentation](https://kagent.dev) -- [LiteLLM Docs](https://docs.litellm.ai) -- [Langfuse Docs](https://langfuse.com/docs) +- [KAgent](https://kagent.dev) +- [LiteLLM](https://docs.litellm.ai) +- [Langfuse](https://langfuse.com/docs) - [Amazon Bedrock](https://aws.amazon.com/bedrock) - -## πŸ“ License - -This project is provided as-is for educational and reference purposes. - ---- - -**Built with ❀️ using Kagent, Amazon EKS, and Amazon Bedrock** +- [appmod-blueprints](https://github.com/aws-samples/appmod-blueprints) (base platform) diff --git a/Taskfile.yml b/Taskfile.yml index c1d678a..29c2ae9 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,73 +1,219 @@ version: '3' +vars: + CONFIG_FILE: '{{.CONFIG_FILE | default "config.local.yaml"}}' + PLATFORM_DIR: '.platform' + + # Parsed from config + PLATFORM_REPO: + sh: yq -r '.platform.repo' {{.CONFIG_FILE}} + PLATFORM_REF: + sh: yq -r '.platform.ref' {{.CONFIG_FILE}} + CLUSTER_PROVIDER: + sh: yq -r '.platform.clusterProvider' {{.CONFIG_FILE}} + AWS_REGION: + sh: yq -r '.aws.region' {{.CONFIG_FILE}} + AWS_ACCOUNT_ID: + sh: yq -r '.aws.accountId' {{.CONFIG_FILE}} + AWS_PROFILE: + sh: yq -r '.aws.profile // "default"' {{.CONFIG_FILE}} + HUB_CLUSTER_NAME: + sh: yq -r '.hub.clusterName' {{.CONFIG_FILE}} + DOMAIN: + sh: yq -r '.domain' {{.CONFIG_FILE}} + RESOURCE_PREFIX: + sh: yq -r '.resourcePrefix' {{.CONFIG_FILE}} + IDC_INSTANCE_ARN: + sh: yq -r '.identityCenter.instanceArn' {{.CONFIG_FILE}} + IDC_REGION: + sh: yq -r '.identityCenter.region' {{.CONFIG_FILE}} + IDC_ADMIN_GROUP_ID: + sh: yq -r '.identityCenter.adminGroupId' {{.CONFIG_FILE}} + K8S_VERSION: + sh: yq -r '.hub.kubernetesVersion // "1.35"' {{.CONFIG_FILE}} + AGENTIC_REPO_URL: + sh: yq -r '.agenticRepo.url' {{.CONFIG_FILE}} + AGENTIC_REPO_REVISION: + sh: yq -r '.agenticRepo.revision' {{.CONFIG_FILE}} + AGENTIC_REPO_BASEPATH: + sh: yq -r '.agenticRepo.basepath' {{.CONFIG_FILE}} + tasks: - build-helm-dependencies: - desc: Build Helm chart dependencies for addon charts that require them + install: + desc: Install the full agentic platform (base platform + spokes + agentic components) + cmds: + - task: platform:install + - task: spokes:install + - task: agentic:install + + upgrade: + desc: Upgrade the platform, spokes, and agentic components + cmds: + - task: platform:upgrade + - task: spokes:install + - task: agentic:upgrade + + # ─── Platform (appmod-blueprints) ─────────────────────────────────────────── + + platform:clone: + desc: Clone or update the base platform repo cmds: - - echo "Adding required Helm repositories..." - - helm repo add fluxcd-community https://fluxcd-community.github.io/helm-charts || true - - helm repo update - - echo "Building dependencies for flux chart..." - - cd ./gitops/addons/charts/flux && helm dependency build - - echo "All Helm chart dependencies built successfully!" + - | + if [ -d "{{.PLATFORM_DIR}}/.git" ]; then + cd {{.PLATFORM_DIR}} && git fetch origin && git checkout {{.PLATFORM_REF}} && git pull origin {{.PLATFORM_REF}} 2>/dev/null || true + else + git clone --branch {{.PLATFORM_REF}} --single-branch {{.PLATFORM_REPO}} {{.PLATFORM_DIR}} + fi + status: + - test -d "{{.PLATFORM_DIR}}/.git" - test-applicationsets: - desc: Test ApplicationSet generation locally using helm template + platform:configure: + desc: Generate platform config.local.yaml from agentic config + deps: [platform:clone] cmds: - | - cd ./gitops/addons/charts/application-sets && \ - helm template test-appsets . \ - -f ../../bootstrap/default/addons.yaml \ - -f ../../environments/dev/addons.yaml \ - --set repoURLGit="https://github.com/your-org/sample-agent-platform-on-eks" \ - --set repoURLGitRevision="main" \ - --set repoURLGitBasePath="gitops/addons/" + cat > {{.PLATFORM_DIR}}/config.local.yaml </dev/null || true + - task: platform:configure + - cd {{.PLATFORM_DIR}} && task install - test-agent-core-chart: - desc: Test agent-core helm chart rendering + # ─── Spokes ────────────────────────────────────────────────────────────────── + + spokes:install: + desc: Provision spoke clusters via Crossplane PlatformCluster claims cmds: + - task: agentic:ensure-kubeconfig - | - cd ./gitops/addons/charts/agent-core && \ - helm template agent-core . \ - -f values.yaml \ - --set global.awsRegion=us-west-2 \ - --set global.eksClusterName=dev \ - --set global.projectName=test-agent \ - --set global.terraformRepoUrl=https://github.com/test/repo \ - --set mcpServer.image.repository=test-repo/mcp-server \ - --dry-run - - test-litellm-chart: - desc: Test LiteLLM helm chart rendering + SPOKES=$(yq -r '.spokes // {}' {{.CONFIG_FILE}}) + if [ "$SPOKES" = "{}" ] || [ "$SPOKES" = "null" ]; then + printf 'βœ“ No spokes configured (hub-only).\n' + exit 0 + fi + for SPOKE in $(yq -r '.spokes | keys | .[]' {{.CONFIG_FILE}}); do + REGION=$(yq -r ".spokes.${SPOKE}.region // \"{{.AWS_REGION}}\"" {{.CONFIG_FILE}}) + K8S_VER=$(yq -r ".spokes.${SPOKE}.kubernetesVersion // \"1.35\"" {{.CONFIG_FILE}}) + VPC_CIDR=$(yq -r ".spokes.${SPOKE}.vpcCidr // \"10.1.0.0/16\"" {{.CONFIG_FILE}}) + AUTO_MODE=$(yq -r ".spokes.${SPOKE}.autoMode // true" {{.CONFIG_FILE}}) + kubectl apply -f - </dev/null || printf 'No PlatformCluster claims found.\n' + + spokes:destroy: + desc: Delete spoke clusters cmds: + - task: agentic:ensure-kubeconfig - | - cd ./gitops/addons/charts/litellm && \ - helm template litellm . -f values.yaml --dry-run + for SPOKE in $(yq -r '.spokes | keys | .[]' {{.CONFIG_FILE}}); do + kubectl delete platformcluster.platform.gitops.io "${SPOKE}" -n crossplane-system --ignore-not-found + printf "βœ“ PlatformCluster claim deleted: %s\n" "$SPOKE" + done + + # ─── Agentic Platform ────────────────────────────────────────────────────── + + agentic:install: + desc: Deploy agentic platform components to the hub (and spokes via ArgoCD) + cmds: + - task: agentic:ensure-kubeconfig + - task: agentic:bootstrap + + agentic:upgrade: + desc: Sync agentic platform components (ArgoCD picks up changes automatically) + cmds: + - task: agentic:ensure-kubeconfig + - task: agentic:bootstrap - test-langfuse-chart: - desc: Test Langfuse helm chart rendering + agentic:ensure-kubeconfig: + desc: Ensure kubectl points to the hub cluster + cmds: + - aws eks update-kubeconfig --name {{.HUB_CLUSTER_NAME}} --region {{.AWS_REGION}} --profile {{.AWS_PROFILE}} + + agentic:label-clusters: + desc: Label cluster secrets to enable agentic platform targeting cmds: - | - cd ./gitops/addons/charts/langfuse && \ - helm template langfuse . -f values.yaml --dry-run + for secret in $(kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type=cluster -o name); do + kubectl label -n argocd "$secret" enable_agent_platform=true --overwrite + done + - printf 'βœ“ Cluster secrets labeled with enable_agent_platform=true\n' - test-all: - desc: Run all chart tests + agentic:bootstrap: + desc: Apply the agentic platform bootstrap Application to ArgoCD + env: + REPO_URL: "{{.AGENTIC_REPO_URL}}" + REVISION: "{{.AGENTIC_REPO_REVISION}}" + BASEPATH: "{{.AGENTIC_REPO_BASEPATH}}" + HUB_CLUSTER_NAME: "{{.HUB_CLUSTER_NAME}}" cmds: - - task: test-applicationsets - - task: test-agent-core-chart - - task: test-litellm-chart - - task: test-langfuse-chart + - task: agentic:label-clusters + - envsubst '${REPO_URL} ${REVISION} ${BASEPATH} ${HUB_CLUSTER_NAME}' < gitops/fleet/bootstrap/agent-platform-app.yaml | kubectl apply -f - + - printf '\nβœ“ Agentic platform bootstrap applied. ArgoCD will sync components to all clusters with enable_agent_platform=true label.\n' + + # ─── Utilities ────────────────────────────────────────────────────────────── - clean-helm-dependencies: - desc: Clean all generated Helm dependency files + status: + desc: Show status of agentic platform ArgoCD applications cmds: - - echo "Cleaning Chart.lock files and charts/ directories..." - - find ./gitops/addons/charts -name "Chart.lock" -delete - - find ./gitops/addons/charts -name "charts" -type d -exec rm -rf {} + 2>/dev/null || true - - echo "Cleaned all Helm dependency files" + - task: agentic:ensure-kubeconfig + - kubectl get applications.argoproj.io -n argocd -l "app.kubernetes.io/part-of=agent-platform" --no-headers 2>/dev/null || kubectl get applications.argoproj.io -n argocd --no-headers | grep -E "kagent|litellm|langfuse|jaeger|otel|bifrost|agentgateway|agent-gateway|crossplane-agentcore" - bootstrap: - desc: Bootstrap the agent platform on the current cluster + destroy: + desc: Remove agentic platform components (does not destroy the base platform) cmds: - - ./scripts/bootstrap.sh + - task: agentic:ensure-kubeconfig + - kubectl delete application agent-platform-addons -n argocd --ignore-not-found + - printf '\nβœ“ Agentic platform bootstrap removed. ArgoCD will prune agentic components.\n' diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000..e601ad3 --- /dev/null +++ b/config.yaml @@ -0,0 +1,58 @@ +# Open Agentic Platform Configuration +# Copy to config.local.yaml and customize for your environment. + +# Platform base (appmod-blueprints) +platform: + repo: "https://github.com/aws-samples/appmod-blueprints.git" + ref: "main" # Tag or branch (e.g., "v1.0.0") + clusterProvider: "kind-crossplane" + +# AWS +aws: + region: "us-west-2" + accountId: "" + profile: "default" + +# Hub cluster +hub: + clusterName: "" + kubernetesVersion: "1.35" + +# Domain and networking +domain: "" +resourcePrefix: "" + +# AWS Identity Center +identityCenter: + instanceArn: "" + region: "" + adminGroupId: "" + +# Agentic platform git repo (this repo β€” used by ArgoCD) +agenticRepo: + url: "https://github.com/aws-samples/sample-agent-platform-on-eks.git" + revision: "main" + basepath: "gitops/addons/" + +# Components to enable +components: + kagent: true + litellm: true + langfuse: true + jaeger: true + otelCollector: true + bifrost: true + agentGateway: true + agentCore: true + +# Spoke clusters (optional β€” hub-only by default) +# Each entry provisions a spoke cluster via Crossplane from the hub. +spokes: {} + # Example: + # spoke-dev: + # region: us-west-2 + # environment: dev + # kubernetesVersion: "1.35" + # vpcCidr: "10.1.0.0/16" + # autoMode: true + diff --git a/gitops/addons/bootstrap/default/addons.yaml b/gitops/addons/bootstrap/default/addons.yaml index fed33b5..8d8d902 100644 --- a/gitops/addons/bootstrap/default/addons.yaml +++ b/gitops/addons/bootstrap/default/addons.yaml @@ -113,7 +113,6 @@ langfuse: kind: ExternalSecret jsonPointers: - /spec/dataFrom - - /spec/data jaeger: enabled: false diff --git a/gitops/addons/charts/langfuse/templates/langfuse.yaml b/gitops/addons/charts/langfuse/templates/langfuse.yaml index 8944056..5e58cc4 100644 --- a/gitops/addons/charts/langfuse/templates/langfuse.yaml +++ b/gitops/addons/charts/langfuse/templates/langfuse.yaml @@ -194,5 +194,5 @@ spec: data: - secretKey: LANGFUSE_CLIENT_SECRET remoteRef: - key: {{ .Values.keycloak.secretManagerKey | default "hub/keycloak-clients" }} + key: {{ .Values.keycloak.secretManagerKey }} property: LANGFUSE_CLIENT_SECRET diff --git a/gitops/addons/charts/langfuse/values.yaml b/gitops/addons/charts/langfuse/values.yaml index 54cd9a7..0e033fa 100644 --- a/gitops/addons/charts/langfuse/values.yaml +++ b/gitops/addons/charts/langfuse/values.yaml @@ -14,7 +14,7 @@ keycloak: clientSecret: "" issuerUrl: "" disableSignup: "false" - secretManagerKey: "hub/keycloak-clients" + secretManagerKey: "" # Set dynamically by ApplicationSet: /keycloak-clients resources: requests: diff --git a/gitops/fleet/bootstrap/agent-platform-app.yaml b/gitops/fleet/bootstrap/agent-platform-app.yaml new file mode 100644 index 0000000..46dfaba --- /dev/null +++ b/gitops/fleet/bootstrap/agent-platform-app.yaml @@ -0,0 +1,40 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: agent-platform-addons + namespace: argocd +spec: + project: default + sources: + - ref: values + repoURL: "${REPO_URL}" + targetRevision: "${REVISION}" + - repoURL: "${REPO_URL}" + path: "${BASEPATH}charts/application-sets" + targetRevision: "${REVISION}" + helm: + releaseName: agent-platform-addons + ignoreMissingValueFiles: true + valueFiles: + - "$values/${BASEPATH}bootstrap/default/addons.yaml" + - "$values/${BASEPATH}environments/control-plane/addons.yaml" + valuesObject: + useSelectors: false + globalSelectors: + enable_agent_platform: "true" + repoURLGit: "${REPO_URL}" + repoURLGitRevision: "${REVISION}" + repoURLGitBasePath: "${BASEPATH}" + destination: + namespace: argocd + name: ${HUB_CLUSTER_NAME} + syncPolicy: + automated: + selfHeal: true + allowEmpty: true + prune: true + retry: + limit: 100 + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/00-initial-setup/bedrock-key.yaml b/workshop/00-initial-setup/bedrock-key.yaml similarity index 100% rename from 00-initial-setup/bedrock-key.yaml rename to workshop/00-initial-setup/bedrock-key.yaml diff --git a/00-initial-setup/bedrock-litellm.yaml b/workshop/00-initial-setup/bedrock-litellm.yaml similarity index 100% rename from 00-initial-setup/bedrock-litellm.yaml rename to workshop/00-initial-setup/bedrock-litellm.yaml diff --git a/00-initial-setup/litellm-config.yaml b/workshop/00-initial-setup/litellm-config.yaml similarity index 100% rename from 00-initial-setup/litellm-config.yaml rename to workshop/00-initial-setup/litellm-config.yaml diff --git a/00-initial-setup/litellm-deploy.yaml b/workshop/00-initial-setup/litellm-deploy.yaml similarity index 100% rename from 00-initial-setup/litellm-deploy.yaml rename to workshop/00-initial-setup/litellm-deploy.yaml diff --git a/00-initial-setup/values.yaml b/workshop/00-initial-setup/values.yaml similarity index 100% rename from 00-initial-setup/values.yaml rename to workshop/00-initial-setup/values.yaml diff --git a/01-first-agent/sample-agent.yaml b/workshop/01-first-agent/sample-agent.yaml similarity index 100% rename from 01-first-agent/sample-agent.yaml rename to workshop/01-first-agent/sample-agent.yaml diff --git a/02-k8s-ops-agent/k8s-ops-agent.yaml b/workshop/02-k8s-ops-agent/k8s-ops-agent.yaml similarity index 100% rename from 02-k8s-ops-agent/k8s-ops-agent.yaml rename to workshop/02-k8s-ops-agent/k8s-ops-agent.yaml diff --git a/03-multi-tool-agent/Dockerfile b/workshop/03-multi-tool-agent/Dockerfile similarity index 100% rename from 03-multi-tool-agent/Dockerfile rename to workshop/03-multi-tool-agent/Dockerfile diff --git a/03-multi-tool-agent/kagent-remotemcpserver.yaml b/workshop/03-multi-tool-agent/kagent-remotemcpserver.yaml similarity index 100% rename from 03-multi-tool-agent/kagent-remotemcpserver.yaml rename to workshop/03-multi-tool-agent/kagent-remotemcpserver.yaml diff --git a/03-multi-tool-agent/smart-assistant-agent.yaml b/workshop/03-multi-tool-agent/smart-assistant-agent.yaml similarity index 100% rename from 03-multi-tool-agent/smart-assistant-agent.yaml rename to workshop/03-multi-tool-agent/smart-assistant-agent.yaml diff --git a/03-multi-tool-agent/tools-server-deployment.yaml b/workshop/03-multi-tool-agent/tools-server-deployment.yaml similarity index 100% rename from 03-multi-tool-agent/tools-server-deployment.yaml rename to workshop/03-multi-tool-agent/tools-server-deployment.yaml diff --git a/03-multi-tool-agent/tools_server.py b/workshop/03-multi-tool-agent/tools_server.py similarity index 100% rename from 03-multi-tool-agent/tools_server.py rename to workshop/03-multi-tool-agent/tools_server.py diff --git a/04-multi-agents/README.md b/workshop/04-multi-agents/README.md similarity index 100% rename from 04-multi-agents/README.md rename to workshop/04-multi-agents/README.md diff --git a/04-multi-agents/financial-services/Dockerfile b/workshop/04-multi-agents/financial-services/Dockerfile similarity index 100% rename from 04-multi-agents/financial-services/Dockerfile rename to workshop/04-multi-agents/financial-services/Dockerfile diff --git a/04-multi-agents/financial-services/README.md b/workshop/04-multi-agents/financial-services/README.md similarity index 100% rename from 04-multi-agents/financial-services/README.md rename to workshop/04-multi-agents/financial-services/README.md diff --git a/04-multi-agents/financial-services/deploy.sh b/workshop/04-multi-agents/financial-services/deploy.sh similarity index 100% rename from 04-multi-agents/financial-services/deploy.sh rename to workshop/04-multi-agents/financial-services/deploy.sh diff --git a/04-multi-agents/financial-services/financial-advisor-agent.yaml b/workshop/04-multi-agents/financial-services/financial-advisor-agent.yaml similarity index 100% rename from 04-multi-agents/financial-services/financial-advisor-agent.yaml rename to workshop/04-multi-agents/financial-services/financial-advisor-agent.yaml diff --git a/04-multi-agents/financial-services/financial-tools-deployment.yaml b/workshop/04-multi-agents/financial-services/financial-tools-deployment.yaml similarity index 100% rename from 04-multi-agents/financial-services/financial-tools-deployment.yaml rename to workshop/04-multi-agents/financial-services/financial-tools-deployment.yaml diff --git a/04-multi-agents/financial-services/financial-tools-mcpserver.yaml b/workshop/04-multi-agents/financial-services/financial-tools-mcpserver.yaml similarity index 100% rename from 04-multi-agents/financial-services/financial-tools-mcpserver.yaml rename to workshop/04-multi-agents/financial-services/financial-tools-mcpserver.yaml diff --git a/04-multi-agents/financial-services/financial_tools_server.py b/workshop/04-multi-agents/financial-services/financial_tools_server.py similarity index 100% rename from 04-multi-agents/financial-services/financial_tools_server.py rename to workshop/04-multi-agents/financial-services/financial_tools_server.py diff --git a/04-multi-agents/financial-services/market-data-agent.yaml b/workshop/04-multi-agents/financial-services/market-data-agent.yaml similarity index 100% rename from 04-multi-agents/financial-services/market-data-agent.yaml rename to workshop/04-multi-agents/financial-services/market-data-agent.yaml diff --git a/04-multi-agents/financial-services/portfolio-analyst-agent.yaml b/workshop/04-multi-agents/financial-services/portfolio-analyst-agent.yaml similarity index 100% rename from 04-multi-agents/financial-services/portfolio-analyst-agent.yaml rename to workshop/04-multi-agents/financial-services/portfolio-analyst-agent.yaml diff --git a/04-multi-agents/financial-services/risk-assessment-agent.yaml b/workshop/04-multi-agents/financial-services/risk-assessment-agent.yaml similarity index 100% rename from 04-multi-agents/financial-services/risk-assessment-agent.yaml rename to workshop/04-multi-agents/financial-services/risk-assessment-agent.yaml diff --git a/05-observability/DEPLOYMENT.md b/workshop/05-observability/DEPLOYMENT.md similarity index 100% rename from 05-observability/DEPLOYMENT.md rename to workshop/05-observability/DEPLOYMENT.md diff --git a/05-observability/README.md b/workshop/05-observability/README.md similarity index 100% rename from 05-observability/README.md rename to workshop/05-observability/README.md diff --git a/05-observability/grafana/grafana-dashboards.yaml b/workshop/05-observability/grafana/grafana-dashboards.yaml similarity index 100% rename from 05-observability/grafana/grafana-dashboards.yaml rename to workshop/05-observability/grafana/grafana-dashboards.yaml diff --git a/05-observability/langfuse/00-langfuse-secrets.yaml b/workshop/05-observability/langfuse/00-langfuse-secrets.yaml similarity index 100% rename from 05-observability/langfuse/00-langfuse-secrets.yaml rename to workshop/05-observability/langfuse/00-langfuse-secrets.yaml diff --git a/05-observability/langfuse/01-postgres.yaml b/workshop/05-observability/langfuse/01-postgres.yaml similarity index 100% rename from 05-observability/langfuse/01-postgres.yaml rename to workshop/05-observability/langfuse/01-postgres.yaml diff --git a/05-observability/langfuse/02-langfuse-deployment.yaml b/workshop/05-observability/langfuse/02-langfuse-deployment.yaml similarity index 100% rename from 05-observability/langfuse/02-langfuse-deployment.yaml rename to workshop/05-observability/langfuse/02-langfuse-deployment.yaml diff --git a/05-observability/langfuse/03-agent-integration.yaml b/workshop/05-observability/langfuse/03-agent-integration.yaml similarity index 100% rename from 05-observability/langfuse/03-agent-integration.yaml rename to workshop/05-observability/langfuse/03-agent-integration.yaml diff --git a/05-observability/langfuse/INSTALL.md b/workshop/05-observability/langfuse/INSTALL.md similarity index 100% rename from 05-observability/langfuse/INSTALL.md rename to workshop/05-observability/langfuse/INSTALL.md diff --git a/05-observability/langfuse/LITELLM-GATEWAY-FEATURES.md b/workshop/05-observability/langfuse/LITELLM-GATEWAY-FEATURES.md similarity index 100% rename from 05-observability/langfuse/LITELLM-GATEWAY-FEATURES.md rename to workshop/05-observability/langfuse/LITELLM-GATEWAY-FEATURES.md diff --git a/05-observability/langfuse/LITELLM-INTEGRATION.md b/workshop/05-observability/langfuse/LITELLM-INTEGRATION.md similarity index 100% rename from 05-observability/langfuse/LITELLM-INTEGRATION.md rename to workshop/05-observability/langfuse/LITELLM-INTEGRATION.md diff --git a/05-observability/langfuse/get-keys.sh b/workshop/05-observability/langfuse/get-keys.sh similarity index 100% rename from 05-observability/langfuse/get-keys.sh rename to workshop/05-observability/langfuse/get-keys.sh diff --git a/05-observability/langfuse/litellm-advanced-config.yaml b/workshop/05-observability/langfuse/litellm-advanced-config.yaml similarity index 100% rename from 05-observability/langfuse/litellm-advanced-config.yaml rename to workshop/05-observability/langfuse/litellm-advanced-config.yaml diff --git a/05-observability/langfuse/litellm-langfuse-config.yaml b/workshop/05-observability/langfuse/litellm-langfuse-config.yaml similarity index 100% rename from 05-observability/langfuse/litellm-langfuse-config.yaml rename to workshop/05-observability/langfuse/litellm-langfuse-config.yaml diff --git a/05-observability/langfuse/setup-complete.sh b/workshop/05-observability/langfuse/setup-complete.sh similarity index 100% rename from 05-observability/langfuse/setup-complete.sh rename to workshop/05-observability/langfuse/setup-complete.sh diff --git a/05-observability/langfuse/setup-gateway-features.sh b/workshop/05-observability/langfuse/setup-gateway-features.sh similarity index 100% rename from 05-observability/langfuse/setup-gateway-features.sh rename to workshop/05-observability/langfuse/setup-gateway-features.sh diff --git a/05-observability/prometheus/kagent-servicemonitor.yaml b/workshop/05-observability/prometheus/kagent-servicemonitor.yaml similarity index 100% rename from 05-observability/prometheus/kagent-servicemonitor.yaml rename to workshop/05-observability/prometheus/kagent-servicemonitor.yaml diff --git a/05-observability/tracing/jaeger.yaml b/workshop/05-observability/tracing/jaeger.yaml similarity index 100% rename from 05-observability/tracing/jaeger.yaml rename to workshop/05-observability/tracing/jaeger.yaml