Eks Recon logo

Eks Recon

Organization
aws-samples
eks-recon

EKS cluster reconnaissance and environment discovery — reports the raw FACTS of a cluster and its environment. Detects compute (Karpenter, MNG, Auto Mode, Fargate, nodes/AMI), networking (VPC/CNI, subnets, load balancers, DNS), security facts (auth mode, IRSA/Pod Identity, RBAC, encryption), add-ons/Helm, observability, workloads (Deployments, StatefulSets, PDBs, HPAs), storage (CSI, StorageClasses, PVs, backup tooling), IaC (Terraform, CDK, eksctl), CI/CD (Actions, ArgoCD, Flux), and cluster insights. Triggers on "what am I running", "tell me about my setup", "what version am I on", cluster inventory, or documenting current state before an upgrade/migration/design. Reports facts only; it does not score, rate, plan, or recommend, and overlapping facts with other skills is fine. Route elsewhere for a judgment or artifact — readiness scoring/deprecated-API checks (eks-upgrade-check), GREEN/AMBER/RED audits (eks-operation-review), design docs/diagrams (eks-design).

Overview

Publisheraws-samples
Repositorysample-apex-skills
Skill nameeks-recon
Stars
90
Forks
20
Bundled files
14
LicenseMIT-0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 14 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by aws-samples on GitHub. Read the source before you install it.

Installation

Install the Eks Recon AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/aws-samples/sample-apex-skills/tree/main/devops-agent/eks-recon
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/aws-samples/sample-apex-skills.git /tmp/sample-apex-skills
mkdir -p .claude/skills
cp -r /tmp/sample-apex-skills/devops-agent/eks-recon .claude/skills/eks-recon
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Eks Recon in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Eks Recon on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Eks Recon is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

EKS Reconnaissance — DevOps Agent Port

Overview

This skill discovers and documents the current state of an EKS cluster and its environment. It connects via AWS control-plane APIs and the Kubernetes API, runs detection across up to 11 modules, and produces a facts-only report: a markdown fact report (primary) plus a secondary YAML facts snapshot for inspection/export.

Recon answers the question: "What is this cluster, right now?" It reports facts only — it never scores, rates, plans, or recommends. Reporting a fact that also matters to another skill (upgrade, security, cost, design) is expected and fine; the dividing line is discovery-of-facts (here) vs. verdict/score/artifact (route elsewhere).

Execution model — fully autonomous. This skill runs autonomously with no interactive prompts. It proceeds through discovery and detection without pausing for user input. When the target cluster is ambiguous (multiple clusters, none named), it assesses all discovered clusters. When a non-recoverable error occurs (API permission failure, no clusters found), it logs the error in the report and terminates per the Step 0 decision table.

Prerequisites

Required IAM Permissions (Agent Space Role)

A ready-to-use IAM policy document is available at references/iam-policy.json — attach it directly to your Agent Space execution role. It grants read-only AWS control-plane access (EKS/EC2/ELB/IAM/Logs Describe/List/Get). It intentionally does not grant eks:AccessKubernetesApi — Kubernetes-API authentication is handled by the access entry below, not by IAM.

ServiceActions (read-only)Purpose
EKSListClusters, DescribeCluster, ListNodegroups, DescribeNodegroup, ListAddons, DescribeAddon, DescribeAddonVersions, ListFargateProfiles, DescribeFargateProfile, ListAccessEntries, ListPodIdentityAssociations, DescribePodIdentityAssociation, ListInsights, DescribeInsight, ListIdentityProviderConfigsCluster config, compute inventory, add-ons, access model, EKS insights
EC2DescribeInstances, DescribeVpcs, DescribeSubnets, DescribeSecurityGroups, DescribeNetworkInterfaces, DescribeLaunchTemplatesNodes, VPC/subnet topology, security groups, ENIs
ELBelasticloadbalancing:Describe*Load balancer inventory (ALB/NLB), target groups
IAMListRoles, GetRole, ListOpenIDConnectProviders, ListPolicies, GetPolicyVersionIRSA/Pod Identity roles, OIDC providers
CloudWatch Logslogs:DescribeLogGroupsControl-plane log group presence (observability facts)

Kubernetes API Access (via Agent Space Access Entry)

Kubernetes-API facts (nodes, CRDs, workloads, RBAC, StorageClasses, etc.) are read through an EKS Access Entry that binds the Agent Space role to the AWS-managed AmazonAIOpsAssistantPolicy cluster-access policy at cluster scope. This is provisioned by devops-agent/setup.sh (or manually — see the project README "EKS Access Setup").

  • The cluster's authenticationMode must include API (i.e. API or API_AND_CONFIG_MAP). A CONFIG_MAP-only cluster cannot be reached via the access entry.
  • The access entry (not an IAM action) provides the K8s-API authentication; the AmazonAIOpsAssistantPolicy provides the authorization (RBAC).
  • What AmazonAIOpsAssistantPolicy actually authorizes (read-only get/list): built-in API groups only — core (pods, services, nodes, namespaces, events, persistentvolumes, persistentvolumeclaims, configmaps), apps (deployments/replicasets/statefulsets/daemonsets), batch (jobs/cronjobs), events.k8s.io, networking.k8s.io (ingresses/ingressclasses), storage.k8s.io (storageclasses), and metrics.k8s.io. It grants NO CustomResourceDefinition groups (and not apiextensions.k8s.io).
  • Consequence for CRD-based facts: the managed policy alone does not authorize reading Karpenter (karpenter.sh, karpenter.k8s.aws), Auto Mode NodeClass (eks.amazonaws.com), TargetGroupBinding (elbv2.k8s.aws/eks.amazonaws.com), VolumeSnapshotClass (snapshot.storage.k8s.io), VerticalPodAutoscaler (autoscaling.k8s.io), Kyverno/Gatekeeper, Calico/Cilium, service-mesh, ArgoCD/Flux, Crossplane/ACK, or Velero CRDs. Under a plain AmazonAIOpsAssistantPolicy-only association those reads return 403 Forbidden. To capture CRD-based facts, bind the Agent Space role to a supplementary read-only ClusterRole granting get/list on the relevant CRD groups (or associate a broader access policy). Absent that, the CRD-dependent sub-facts are reported as unconfirmed per the hedge below — never as false/count: 0.

Availability hedge. When the access entry is absent (or authenticationMode excludes API), the skill degrades gracefully to AWS-control-plane-only facts — it still reports everything reachable via the EKS/EC2/ELB/IAM APIs. Each K8s-API-dependent module or sub-fact that cannot be read — whether because the access entry is missing, authenticationMode excludes API, or the RBAC (see above) does not authorize that resource (e.g. a CRD group) — is recorded as unavailable / unconfirmed in the report's Coverage section, never as false / count: 0.

When to Use

Activate when the goal involves:

  • Discovering or documenting an EKS cluster's current state — "what am I running?", "tell me about my setup"
  • Inventory before an upgrade, migration, or architecture change
  • Targeted current-state questions — "what version am I on?", "am I using Karpenter?"
  • Supplying raw cluster facts as input to another workflow

Out of scope — route elsewhere (these produce judgments/artifacts, not facts):

  • Upgrade readiness scoring / deprecated-API blocking → eks-upgrade-check. Recon discovers what version you're on; it does not assess whether you are ready to move.
  • Operational audits with GREEN/AMBER/RED maturity ratings → eks-operation-review. Recon inventories what exists; it does not rate maturity.
  • Architecture design documents or Mermaid diagrams → eks-design. Recon discovers current state; it does not produce design artifacts.
  • Creating or modifying cluster resources (this skill is strictly read-only).

Reconnaissance Workflow

Error output format (used by the Step 0 hard-stops):

## Recon Error — <one-line reason>
**Condition:** <which check failed>
**What was found:** <observed state>
**Recommendation:** <remediation guidance for next run>

Optional prior report: the caller may supply an earlier recon YAML artifact as accessible report content or an attachment. Load report-comparison.md when supplied. Use the artifact's attachment filename, asset name, or inline content as its source label; read it before generating outputs and do not assume local file or shell access. For multi-cluster discovery, compare only the cluster matching the prior artifact's ARN and explicitly mark other clusters as having no matching prior. If no discovered cluster matches, report the comparison as unavailable. Without a prior report, omit the Changes since section.

Step 0: Pre-flight — Cluster Discovery and Validation

Action 1 — Discover clusters. Use the EKS ListClusters API to discover available clusters in the target region.

ConditionAction
API call fails (auth/permission error)Abort with error — log "Cannot access EKS. The agent role requires eks:ListClusters for the configured region." and terminate.
Zero clusters returnedAbort with error — log "No EKS clusters found in this region." and terminate.
Exactly one cluster found, none named in requestProceed — state which cluster was auto-selected.
Multiple clusters found, one named in requestProceed — use the named cluster.
Multiple clusters found, none named in requestProceed — recon all discovered clusters. Note in the report that no specific cluster was targeted, so all clusters in the region are included.

Action 2 — Describe the selected cluster. Use DescribeCluster. Extract name, Kubernetes version, platform version, region, status, account ID, authenticationMode. This populates the shared cluster: and cluster_detail: blocks (references/cluster-basics.md).

Cluster StatusAction
ACTIVEProceed
CREATING / UPDATING / DELETINGSkip cluster — log "Cluster <name> is in <status> state; skipping." If it is the only cluster, terminate with error report.
FAILEDSkip cluster — log "Cluster <name> is in FAILED state." If it is the only cluster, terminate with error report.

Action 3 — Probe Kubernetes API reachability. Attempt one lightweight K8s-API read (e.g. list nodes). If it fails (access entry absent, authenticationMode excludes API, or 401/403), do not abort — set a k8s_api_available: false flag, continue with AWS-control-plane-only modules, and record every K8s-dependent module/sub-fact as unavailable/unconfirmed in Coverage.

Action 4 — Load references/cluster-basics.md first, then proceed to module selection. cluster-basics is always loaded first by every module — it provides the shared cluster context all other modules depend on.

Step 1: Select and Run Modules

Determine which modules to run from user intent using the routing table below. For a targeted query, load only the matching reference(s). For full recon, load all 11 references. Before running a module, read its reference file — the references carry detection order, edge cases, and the canonical output schema; skipping them produces shallow results.

Each reference describes detection declaratively as capability blocks (AWS API calls, and "Via Kubernetes API" blocks for K8s resources). There is no Agent tool and no subagents in this environment — module isolation is achieved by loading one reference at a time, not by spawning subagents.

Step 2: Generate the Report

Produce both artifacts (see Report Output below). The markdown fact report is the primary deliverable; the YAML is a secondary facts snapshot. When a prior report was supplied, append the comparison defined in report-comparison.md.


How to Use the References

references/cluster-basics.md is always loaded first. Load additional references only for the modules the request needs.

Intent / when to useReference file
Always first — name, region, version, platform version, endpoint, support type, zonal shift, encryption config, healthcluster-basics.md
Karpenter, nodes, scaling, Auto Mode, node groups, Fargate, self-managedcompute.md
VPC, ingress, CNI, service mesh, load balancer, connectivitynetworking.md
IAM, IRSA, Pod Identity, RBAC, policies, encryption, secrets, webhookssecurity.md
EKS-managed add-ons, Helm releases, plugins, "what's installed?"addons.md
Logging, metrics, monitoring, Container Insights, Prometheusobservability.md
Deployments, pods, services, ingresses, "what's running?"workloads.md
PVCs, EBS, EFS, StorageClasses, CSI drivers, volumes, snapshots, backup toolingstorage.md
Terraform, CloudFormation, CDK, eksctl, Pulumi, Crossplane, "how is it managed?"iac.md
GitHub Actions, GitLab CI, Jenkins, ArgoCD, Flux, GitOps, pipelinescicd.md
EKS-reported upgrade-readiness & configuration insights (raw findings)cluster-insights.md

For full recon, load all rows. For a targeted query (e.g. "am I using Karpenter?"), load only cluster-basics.md + the matching row (compute.md).


Report Output

Produce two artifacts. The markdown fact report is the primary deliverable (rendered inline to the user); the YAML is a secondary facts snapshot for inspection/export. The agent generates both directly — no external conversion tools or scripts.

Facts only. Both artifacts report what the cluster is. Never emit a verdict, score, readiness rating, or recommendation. A "Notable facts" line states an observation ("2 subnets have < 16 free IPs"); it never says "you should" or "this is a risk".

Use one actual UTC clock reading for both filenames, the Markdown _generated header (labelled UTC), and report.generated_at. No caller prefix is supported. If named destinations can be checked, a collision writes neither artifact and returns an error without prompting; current facts remain visible inline. If the service cannot inspect destinations, do not claim collision checks were performed.

Reports can contain cluster ARNs, account/resource identifiers and infrastructure details. Review and redact before sharing.

Markdown fact report (primary)

  • Filename: EKS-Recon-{cluster}-{YYYY-MM-DD}-{HHMM}.md

Render this structure, including only modules that actually ran:

markdown
# EKS Recon — <cluster> (<region>)
_generated <timestamp> · source: AWS API + K8s API · modules: N/N_

## Cluster summary
| Fact | Value |
|------|-------|
| version / platform | 1.31 / eks.5 |
| support type | STANDARD |
| status / created | ACTIVE / 2024-09-10 |
| authentication mode | API_AND_CONFIG_MAP |
| compute strategy | Karpenter + 1 MNG |
| IaC | Terraform (high confidence) |
| CI/CD | GitHub Actions + ArgoCD |

## Per-module facts
### Compute
<small fact table per module — one H3 per RUN module>
### Networking
...

## Notable facts
<flat bullets: co-occurring or absent facts, stated neutrally, ZERO verdicts>
- authentication_mode = API_AND_CONFIG_MAP; aws-auth ConfigMap present
- compute.strategy = Karpenter; security.iam_for_pods.irsa.detected = false
- 2 of 4 cluster subnets report < 16 available IPs

## Coverage
<modules that could not run + reason, AND sub-facts that ran but could not be confirmed>
- storage: unavailable (reason: K8s API access entry absent — AWS-API-only mode)
- addons.helm_releases: unconfirmed (reason: Helm release Secrets not readable) — reported as `unconfirmed`, not `count: 0`

Keep every absence claim within the successfully inspected scope. State that scope with the claim, including in summaries and Notable facts; Coverage caveats do not qualify broader wording elsewhere.

Machine YAML artifact

  • Filename: EKS-Recon-{cluster}-{YYYY-MM-DD}-{HHMM}.yaml

The YAML is a secondary, point-in-time facts snapshot, not a versioned API. Workflows may use its facts as context; that intended use does not establish a versioned schema hand-off. Preserve the canonical reference shapes for inspection, export and existing workflow guidance.

Assembly rules (inline and subagent execution):

  • Use cluster-basics for the shared cluster: block; deduplicate matching module blocks. For the same target, preserve module facts and record differing values and their sources in Markdown Coverage rather than silently overwriting them. Compare identity using target context (such as cluster ARN); a cosmetic endpoint difference such as a trailing / is not another cluster. If a module identifies another target cluster, retain its key as {unavailable: true, reason: "cluster context mismatch"}.
  • On full recon, collect cluster_detail: directly from cluster-basics, which has no subagent. Targeted queries may omit unrelated detail.
  • If a selected module returns no usable result, retain its key with unavailable: true and a short reason in either mode. Partial reads retain known facts alongside Coverage gaps. Unselected modules are out of scope.
  • For partial modules, retain observed facts and every schema-defined object/key, even when all its values are unreadable: use ingresses: {count: null, list: null}, not ingresses: null. Set unreadable leaf values to null and put reasons in Markdown Coverage. Use another representation only when the module reference explicitly prescribes it for that field and failure condition (for example, Helm or node_subnets); do not invent generic {unconfirmed, reason} wrappers. Carry each incomplete/denied read into report.unconfirmed_paths, even when its canonical value is null. For partial inventories, record the entire inventory path. Collect gaps alongside facts from every module result; never infer complete coverage from a successful module response. A GitOps status: unconfirmed records cicd.gitops, not just the status leaf.

Assemble one top-level key per module, each emitted verbatim in the canonical shape defined by that module's references/<module>.md "## Output Schema", plus the shared cluster: and cluster_detail: blocks (from references/cluster-basics.md). Unavailable modules become <module>: {unavailable: true, reason: "<short reason>"}.

Include a report metadata block alongside the canonical module blocks in every new YAML artifact. Capture generated_at from the actual UTC clock once for this report (reuse the filename's clock reading where applicable). Set schema_revision to eks-recon/2026-10-31, identifying the fact definitions used here, not a promised versioned API. Update this marker when fact types, value sets or meanings change, and document affected comparison boundaries in the comparison reference. unconfirmed_paths lists canonical dot-separated field paths whose reads were incomplete or denied; list the enclosing inventory path if only part of an inventory was collected. Use an empty list only when no collected sub-facts are unconfirmed. Omitted modules and explicit unavailable/unconfirmed markers remain authoritative coverage gaps. This metadata is not a recon module and is excluded from module counts and deltas.

yaml
report:
  schema_revision: "eks-recon/2026-10-31"
  generated_at: "2026-10-29T08:30:00Z"  # actual report time, not this example
  unconfirmed_paths: []                # e.g. [security.authentication.access_entries]

The reference Output Schemas are the single source of truth for each module's shape — do not hand-copy a schema. The fragment below shows only the envelope; the authoritative per-module shape lives in each reference.

yaml
# EKS Reconnaissance Report — illustrative envelope only.
# Canonical shape per module = references/<module>.md "## Output Schema".
report:              # metadata defined above; not a module
  schema_revision: "eks-recon/2026-10-31"
  generated_at: "2026-10-29T08:30:00Z"  # replace with actual report time
  unconfirmed_paths: []
cluster:              # shape: references/cluster-basics.md "## Shared Cluster Block"
  name: my-cluster
  region: us-west-2
  version: "1.31"
  platform_version: eks.5
  status: ACTIVE
cluster_detail:       # shape: references/cluster-basics.md "## Cluster Detail (full recon)"
  upgrade_policy: {support_type: STANDARD}
compute:              # shape: references/compute.md "## Output Schema"
  strategy: Karpenter
networking: { ... }   # shape: references/networking.md
storage:
  unavailable: true
  reason: "K8s API access entry absent — AWS-API-only mode"

Facts-Only Guardrails

  1. Report facts, never judgments. No scores, ratings, readiness verdicts, risk labels, or recommendations. "Notable facts" states observations; it never says "you should" or "this is a risk".
  2. Do NOT hardcode or guess cluster names. Always discover clusters via ListClusters first (Step 0).
  3. Do NOT retry a failed API call more than once. If it fails twice, record the gap in Coverage and continue.
  4. Always read the relevant reference before running a module. References carry detection order, edge cases, and the canonical output schema.
  5. Distinguish absence from unconfirmed. A fact that could not be checked is unconfirmed/unavailable (with a reason), never count: 0 or false.
  6. Never omit a schema key. Use null where a fact was not detected — preserve the full canonical shape from each reference.

This skill is provided as sample code for educational and demonstration purposes only. Findings are point-in-time facts and should be validated before acting on them. See the project's README and LICENSE for full terms.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Eks Recon AI skill do?

EKS cluster reconnaissance and environment discovery — reports the raw FACTS of a cluster and its environment. Detects compute (Karpenter, MNG, Auto Mode, Fargate, nodes/AMI), networking (VPC/CNI, subnets, load balancers, DNS), security facts (auth mode, IRSA/Pod Identity, RBAC, encryption), add-ons/Helm, observability, workloads (Deployments, StatefulSets, PDBs, HPAs), storage (CSI, StorageClasses, PVs, backup tooling), IaC (Terraform, CDK, eksctl), CI/CD (Actions, ArgoCD, Flux), and cluster insights. Triggers on "what am I running", "tell me about my setup", "what version am I on", cluste...

Why use Eks Recon on TypingMind?

Because you install it once and use it with any model. Eks Recon is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Eks Recon in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/aws-samples/sample-apex-skills/tree/main/devops-agent/eks-recon. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Eks Recon?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Eks Recon?

As many as you like. As long as a model supports skills, you can use Eks Recon with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Eks Recon AI skill free?

Yes. It is published on GitHub by aws-samples under the MIT-0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇