Skip to main content

querying-yandex-cloud

Read Yandex Cloud through its REST API. Applies to any question about VMs, metrics, logs, audit events, Kubernetes, managed databases, serverless, networking or any other Yandex Cloud resource. Never shell out to the `yc` CLI — it is not how this agent reaches Yandex Cloud and is usually not installed.

Source facts

Repository
tracer-cloud/opensre
Last source activity
October 20, 2026 at 15:32
Detected SKILL.md language
English
Stars
12,485
Forks
1,827

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
querying-yandex-cloud
description
Read Yandex Cloud through its REST API. Applies to any question about VMs, metrics, logs, audit events, Kubernetes, managed databases, serverless, networking or any other Yandex Cloud resource. Never shell out to the `yc` CLI — it is not how this agent reaches Yandex Cloud and is usually not installed.
tools
["find_yc_api","execute_yc_operation"]
# querying-yandex-cloud Three rules first, because they are the ones that waste a whole investigation when they are missed. **Read `kubernetes_get_events` before naming a cause** for any pod that is not Running. The pod list shows only *that* it is stuck. Every reason looks identical there — out of memory, unschedulable, an image that will not pull, a volume that will not mount. The event carries the actual message, and guessing between them produces a confident wrong answer that sends someone to check node capacity when the registry was refusing the pull. `Pending` with no events about resources is an image or volume problem, not a scheduling one. **A pod is not a Yandex Cloud resource.** The Yandex Cloud API knows the Kubernetes *cluster* — version, health, node groups, read with `execute_yc_operation` on `/managed-kubernetes/` — and nothing about what runs inside it. Neither `execute_yc_operation` nor `find_yc_api` can reach a pod, an event or a container log, and no `/managed-kubernetes/` path returns one. Read those with `kubernetes_list_pods`, `kubernetes_get_events`, `kubernetes_get_pod_logs` and `kubernetes_list_nodes`, which talk to the cluster's own API server. If those tools are absent, Managed Kubernetes access was not connected during setup — say so rather than trying the Yandex Cloud API instead. **Never run `yc` via a shell tool.** It is normally not installed, it needs its own separate authentication, and it can mutate. If you catch yourself writing `yc ...` to answer a question, use `execute_yc_operation` instead. **But do write the `yc ...` command out when something should change.** These tools only read. When the finding calls for an action — resize, restart, rebalance, change a setting — end with the exact `yc ...` command an operator can paste, not a description of what to do. Writing the command is correct; running it is not. Everything else reaches Yandex Cloud over its REST API with the configured credential. There is no CLI step and no shell step. ## What a connected `yandex_cloud` means `yandex_cloud` appears once in the connected-integrations list, but it is an umbrella. When it is connected you can already read **all** of this — do not tell the user a piece of it "is not configured": | Ask about | Reach it with | | --- | --- | | Metrics, CPU, memory, disk, saturation | `query_yc_metrics`, `list_yc_metrics` | | Logs (Cloud Logging) | `read_yc_logs`, `list_yc_log_groups` | | Logs of a managed database | `read_yc_db_logs` — a separate store, see below | | Audit events, who changed what | not readable yet — audit trails write to a sink | | VMs, disks, images, instance groups | `list_yc_instances`, `get_yc_instance_diagnostics`; otherwise `execute_yc_operation` | | Load balancer target health | `get_yc_lb_health` | | Kubernetes **clusters and node groups** | `execute_yc_operation` on `/managed-kubernetes/` | | Kubernetes **pods, events, pod logs, nodes** | `kubernetes_list_pods`, `kubernetes_get_events`, `kubernetes_get_pod_logs`, `kubernetes_list_nodes` | | Managed PostgreSQL/MySQL/ClickHouse/Valkey/StoreDoc/Kafka/OpenSearch | `list_yc_db_clusters`, `get_yc_db_cluster` | | Functions, containers, triggers, API gateways | `execute_yc_operation` | | Networks, subnets, security groups | `execute_yc_operation` | | Anything else in the API | `find_yc_api`, then `execute_yc_operation` | | Which services exist at all | `find_yc_api` with no query | Monitoring is configured whenever Yandex Cloud is configured — it shares one credential. Cloud Logging *group* lists use that same REST credential. Reading **log entries** needs the optional install extra `opensre[yandex_cloud_logs]` (gRPC stubs for the log reader host). Without it, `read_yc_logs` fails closed and tells you to install the extra; do not tell the user logging "is not configured" when the umbrella integration is connected and only the entry-reader extra is missing. ## Reading anything `find_yc_api` indexes ~940 read endpoints across 68 services, generated from Yandex's own protobuf definitions. It is the answer to "what is the path for X", so use it rather than guessing: 1. `find_yc_api` with the resource in plain words — `security groups`, `postgresql clusters`, `node group`, `certificates`. 2. `execute_yc_operation` with the `service` and `path` it returned. 3. A path with a `{placeholder}` needs an id. Call the list endpoint on the same service first and take the id from there. Reads only. Every mutating operation uses a different HTTP verb and the client refuses those, so there is no way to change anything here. When the answer is that something *should* change, give the user the exact `yc ...` command to run themselves — writing that command out is correct, running it is not. ## Kubernetes workloads are not in the Yandex Cloud API The Yandex Cloud API knows about the *cluster* — its version, health, node groups, maintenance window. It knows nothing about what runs inside it. There is no endpoint for pods, and searching for one wastes the investigation: > A pod is not a Yandex Cloud resource. `execute_yc_operation` and `find_yc_api` > cannot reach one, and neither can any `/managed-kubernetes/` path. Workloads are read with the `kubernetes_*` tools, which talk to the cluster's own API server: | Ask about | Reach it with | | --- | --- | | Which pods exist, and their state | `kubernetes_list_pods` | | Why a pod is not starting | `kubernetes_describe_pod`, `kubernetes_get_events` | | What a container logged | `kubernetes_get_pod_logs` | | Node pressure, NotReady nodes | `kubernetes_list_nodes` | | Deployments, services, statefulsets, ingresses | `kubernetes_list_deployments` and friends | | Anything else in the cluster | `kubernetes_get_resource` | So an incident in a Managed Kubernetes cluster is usually two reads, in this order: 1. `execute_yc_operation` on `/managed-kubernetes/v1/clusters` — is the control plane itself healthy? A degraded master explains everything below it, and nothing else needs checking. 2. `kubernetes_list_pods` and `kubernetes_get_events` — what is actually wrong with the workload. These tools appear only when a cluster was connected during setup. If they are absent, say that Managed Kubernetes access is not configured and that `opensre integrations setup kubernetes` connects it — do not fall back to `execute_yc_operation` and report that pods cannot be read. A pod stuck in `Pending` has no logs at all: the container never started, so the API answers `400`, not `403`. Read its events instead — that is where the reason is. ## Logs live in four different places There is no single log store, so **an empty `read_yc_logs` is a statement about Cloud Logging and nothing else.** Where to look depends on who wrote the log: | Written by | Read with | Reaches Cloud Logging? | | --- | --- | --- | | A managed database engine | `read_yc_db_logs` | Only if export was switched on | | A container in Kubernetes | `kubernetes_get_pod_logs` | Only if a log agent was deployed | | A serverless function or container | `read_yc_logs` | Yes, by default | | Your own application, sending to Cloud Logging | `read_yc_logs` | Yes, that is what it is | So the search order for "why did this break" is: ask the owning service first, then Cloud Logging. Doing it the other way round produces a confident "no logs found" for a database that has been logging all along. A managed database keeps several streams and serves one at a time, so name the one the question is about: MySQL answers with its error log unless `MYSQL_SLOW_QUERY` is asked for, and a question about slow queries otherwise gets a confident empty answer. The result lists the other streams. Export to Cloud Logging is optional and off unless someone enabled it. If a managed service has no log group, that is a configuration fact worth reporting — not evidence the service is silent. **Before saying something cannot be read, ask `find_yc_api`.** Never answer by telling the user to install or run the `yc` CLI. If the CLI can read it, so can this agent — the CLI is a client of the same REST API, and the path is in the index. ## A past incident needs an explicit window Every reader defaults to a window ending now. Asked about an incident on a given date, **pass that date as the window that reader actually accepts** — `query_yc_metrics` takes `from_time` and `to_time`; `read_yc_logs` takes `since` and `until`. `window_minutes` counts back from the present and will silently return nothing for anything older, which reads as "no evidence" rather than "wrong window". Retention differs by source, and an empty result means different things: | Source | Kept | An empty result means | | --- | --- | --- | | Cloud Logging (`read_yc_logs`) | ~31 days | Beyond retention if the date is older — say so, do not call it "no evidence" | | Managed-database logs (`read_yc_db_logs`) | per cluster | A separate store from Cloud Logging, so Cloud Logging's silence says nothing about it | | Monitoring (`query_yc_metrics`) | months | Genuinely no data for that window, if the window was right | So for an incident weeks back, metrics are usually the only surviving evidence, and they are worth querying with the exact window before concluding anything. Cluster operation history (`/managed-*/v1/clusters/{id}/operations`) outlives logs too and shows maintenance and failovers. ## Answering well - **Query first, then answer.** Infrastructure questions are answered from live reads, never from what you remember about Yandex Cloud in general. - **Say what you actually read.** Name the folder, the resource ids, the time window. "CPU on `build-vm` averaged 140% over the last hour (2 cores)" beats "CPU looks high". - **An empty list is an answer.** "No managed database clusters in this folder" is a finding; do not present it as a failure or a missing integration. - **One folder at a time.** Every read is scoped to the configured folder. Reading a different one means passing `folderId` explicitly to `execute_yc_operation`; the folder list is at `/resource-manager/v1/folders` with `cloudId`. - **A bare 404 usually means a wrong parameter**, not a missing resource — a single-resource read rejects `folderId` and `pageSize`. Re-read the path shape before telling the user the resource does not exist. ## Metrics `query_yc_metrics` takes a Yandex Monitoring query: `"cpu_usage"{service="compute"}`, narrowed by labels such as `resource_id`, `device`, `subcluster_name`. **It is not PromQL.** `sum by (...)`, `rate(x[5m])` and `topk(...)` come back as parse errors, not empty results. Aggregate with Yandex's own functions: | Want | Write | | --- | --- | | Total across series | `series_sum("metric"{...})` | | Average across series | `series_avg("metric"{...})` | | Highest n series | `top_max(5, "metric"{...})` | | Drop gaps | `drop_nan("metric"{...})` | | Name the result | `alias(..., "label")` | **The folder label is `folder_id`.** Writing `folderId` is accepted and matches nothing, so it looks like the metric has no data rather than like a mistake. **Metrics the user pushes themselves live under `service="custom"`, and the default metric listing does not include them.** So `list_yc_metrics` returning nothing is not evidence a metric is missing — search again with `selectors='service="custom"'` before saying it does not exist. The tool says so in its own output when a search comes back empty; believe it rather than repeating the same call with a different name filter.
View on GitHub