Skip to content

blog: GPU Kubernetes infrastructure for AI workloads - #20631

Open
workprentice[bot] wants to merge 1 commit into
masterfrom
seo/gpu-kubernetes-ai-workloads
Open

blog: GPU Kubernetes infrastructure for AI workloads#20631
workprentice[bot] wants to merge 1 commit into
masterfrom
seo/gpu-kubernetes-ai-workloads

Conversation

@workprentice

@workprentice workprentice Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

What

Adds a new blog post: "GPU Kubernetes Infrastructure for AI Workloads with Pulumi" at /blog/gpu-kubernetes-ai-workloads/.

Why the angle changed from the original card

The Marketing Content Calendar card behind this PR asked for a post on "Pulumi + Kubernetes for Agentic AI Workloads." That exact angle was already shipped in PR #20550 (merged 2026-07-29): "How to Run AI Agents on Kubernetes with Pulumi" at /blog/ai-agents-on-kubernetes/. Writing the card literally would have cannibalized a 3-day-old flagship post on the same keywords.

Fresh Profound visibility data (2026-07-02 to 2026-08-01) shows Pulumi's two weakest GEO topics are AI Infrastructure (10.8% visibility, versus NVIDIA 64.1%, Google 61.8%, Databricks 53.6%, CoreWeave 47.8%, AWS 46.4%) and Kubernetes (no measured Pulumi visibility at all, versus Docker 61.1%, Kubernetes 56.2%, Azure 35.9%). Both gaps are shaped around compute/accelerator vendors, not agent frameworks.

So this post keeps the card's strategic intent (close the Kubernetes and AI Infrastructure gaps, ship Kubernetes-native code, hit every AEO requirement, Alex Leventer byline) but shifts the angle to the adjacent, unowned lane: the GPU/accelerator compute substrate underneath agentic workloads (node pools, GPU operator install, Kueue quotas, taints/tolerations, time-slicing vs. MIG, cost guardrails), rather than the agent runtime itself. The two posts cross-link and reinforce each other instead of competing for the same query space.

AEO / schema choices

  • faq_schema: true and howto_schema: true, matching the repo's schema-gating rules.
  • Exactly one numbered markdown list in the post (the six-step provisioning sequence), since howto-entity.html uses a single running counter over every ^\d+\. line in the document — any other numbered list would bleed into the HowTo steps.
  • Every other H2 in the doc is question-phrased for FAQ collection (faq-entity.html has no section scoping, so all ?-ending H2s/H3s land in FAQPage.mainEntity), and a dedicated "Frequently asked questions" section adds five ### ...? H3s targeting real query phrasings.
  • Answer-first opening (definition block in the first two sentences), a comparison table for the GPU stack layers, and both TypeScript and Python code samples for the same EKS/GKE provisioning pattern.
  • One third-party citation (Luca Galante / Weave Intelligence, "10 Platform engineering predictions for 2026," linked and quoted verbatim) and one Pulumi engineer quote (Joe Duffy, linked to /blog/the-agentic-infrastructure-era/, quoted verbatim, including the proprietary "20% of infrastructure deployments" stat).
  • Internal links verified to resolve: /blog/ai-agents-on-kubernetes/, /blog/the-agentic-infrastructure-era/, /blog/ai-infrastructure-tools/, /docs/esc/, plus /registry/packages/kubernetes/ (a generated route used the same way elsewhere in the repo).

Verification

  • Diffed against the six closest adjacent posts (ai-agents-on-kubernetes, ai-infrastructure-tools, fully-automated-ai-inference-aws-azure-gcp-pulumi, self-host-gemma4-llama-cpp-k8s-tailscale-pulumi, ai-ml-on-kubernetes-google-cloud-llm-rag, kubernetes-chart-v4) to confirm no keyword or angle overlap and to harvest verified resource shapes (Helm v4 Chart, apiextensions.CustomResource patterns, ESC-sourced credentials).
  • Confirmed alex-leventer author slug exists at data/team/team/alex-leventer.toml.
  • Confirmed front matter passes the documented lint constraints manually (meta_desc 139 chars, single category scalar from the closed set, trailing newline present); a Node.js toolchain was not available in this session to run scripts/lint/lint-markdown.js directly, so please treat CI's lint run as authoritative.

🧠 This PR was created by workprentice on behalf of the Pulumi SEO/AEO content team — no get_me-equivalent tool was available in this session to resolve a specific requester's username.

Covers the GPU/accelerator compute substrate for AI and agentic
workloads on Kubernetes with Pulumi: GPU node pools across
EKS/GKE/AKS, GPU operator install, Kueue quotas and ResourceFlavors,
taints/tolerations, time-slicing vs MIG, and cost guardrails.

Cross-links to the agent-runtime post (ai-agents-on-kubernetes)
rather than duplicating it, since that post already covers agent
CRDs and orchestration. This post closes the GPU/accelerator gap
in our AI Infrastructure and Kubernetes GEO topics instead.
@github-actions github-actions Bot added review:triaging Claude Triage is currently classifying the PR domain:blog PR touches blog posts or customer stories review:in-progress Claude review is currently running and removed review:triaging Claude Triage is currently classifying the PR labels Aug 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Social Media Review

content/blog/gpu-kubernetes-ai-workloads/index.md

X — PASS

LinkedIn — PASS

Bluesky — FAIL

Reasons:

  • Single paragraph, no blank-line break (Bluesky requires 2 paragraphs)

Suggested copy

Bluesky (176/300 chars) — minimum-change repair; split into two paragraphs at the existing sentence boundary, no wording changed:

The agent runtime gets the attention, but the GPU node pool underneath it is what actually runs out.

Here's how to provision and govern GPU capacity on Kubernetes with Pulumi.


Suggestions (advisory)

These are stylistic notes — they don't block the post.

X

  • Naming "Kueue quotas and time-slicing" in the same breath as "keep them from being wasted" answers the question before the reader clicks — tease the fix without naming both techniques.

LinkedIn

  • Second paragraph lists all four things the article covers (multi-cloud node pools, Kueue quotas/ClusterQueues, taints and tolerations, time-slicing vs. MIG) — this is the article's table of contents, not a hook, and leaves nothing for the click to reveal.
  • Closing lines point to a different post ("running AI agents on Kubernetes") rather than pulling the reader into this one — "This one is about the substrate underneath it" describes scope, it doesn't invite the reader to find out how.

Updated for commit 9ee6c6ce45009e0a1dc06f88b1eafb934e609523 (short: 9ee6c6c) at $(date -u '+%Y-%m-%d %H:%M UTC').

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Pre-merge Review — Last updated 2026-08-01T12:23:56Z

Tip

Summary: This PR adds one new blog post — a single-subject how-to on provisioning and governing GPU capacity on Kubernetes with Pulumi (node pools, the NVIDIA GPU Operator, Kueue quotas, taints, time-slicing vs. MIG), positioned as the substrate companion to the existing How to Run AI Agents on Kubernetes with Pulumi and structured like it (FAQ section, "Where to go next" link list, category: general). The wrongness that would block a reader here is code that doesn't run: the post's headline artifact is two copy-pasteable programs, and one of them passes taints to eks.NodeGroup in a shape that provider rejects while the other wires the Kubernetes provider to a literal "<kubeconfig>" placeholder. The post also ships without a <!--more--> break, which would dump the whole body onto the blog index on merge. Passes run: whole-file readthrough, claim extraction + verification over 58 claims, cited-source spot-checks on all 3 external citations, code-example checks against the pulumi-eks / pulumi-gcp / pulumi-kubernetes SDK sources, frontmatter and publishing-blocker sweep, and the blog editorial-balance pass.

Review confidence:

Dimension Level Notes
mechanics MEDIUM all 5 internal link targets confirmed to exist; <!--more--> missing (flagged) — Hugo build and lint run in their own jobs
facts HIGH
coherence HIGH
editorial balance HIGH single-subject post; the one section-depth outlier is code-block volume in the how-to core, not steering
code correctness HIGH both examples checked property-by-property against the provider SDK sources
Investigation log
  • Cross-sibling reads: not run (not in a templated section)
  • External claim verification: 43 of 58 claims verified (1 unverifiable, 3 contradicted, 1 framing-drift) · 4 specialists (numerical, cross-reference, capability, framing); 0 cross-specialist corroborations · routed: 0 inline, 40 Pass 1, 3 Pass 2 (verified 0, contradicted 1, unverifiable 2), 15 Pass 3 (verified 10, contradicted 1, unverifiable 4).
  • Cited-claim spot-checks: 3 of 3 cited claims fetched and compared
  • Frontmatter sweep: ran on body + meta_desc + social.{bluesky, linkedin, twitter}
  • Temporal-trigger sweep: ran (recency words present in diff; spot-check in-review)
  • Code execution: not run (no static/programs/ change)
  • Code-examples checks: ran (3 specialists: structural, existence, body-code-coverage); 0 findings
  • Editorial-balance pass: ran (7 H2 sections, 1 flags fired)
🚨 Outstanding ⚠️ Low-confidence 💡 Pre-existing ✅ Resolved
3 12 0 0

🔍 Verification trail

58 claims extracted · 43 verified · 1 unverifiable · 3 contradicted · 1 framing-drift · 2 detector findings
  • L3 in content/blog/gpu-kubernetes-ai-workloads/index.md "date: 2026-08-01" → ➖ not-a-claim (evidence: This is a front-matter date field (publish date metadata) for the blog post, not a falsifiable factual assertion.; source: content/blog/gpu-kubernetes-ai-workloads/index.md (front matter))
  • L18-21 in content/blog/gpu-kubernetes-ai-workloads/index.md "Kueue quotas and time-slicing prevent GPU node pools from being wasted." → ✅ verified (framing: Kueue's documented fair-share/quota and reclaim mechanisms plus GPU time-slicing (a widely-documented NVIDIA/K8s device-plugin capability) together support the…; evidence: Kueue's own README documents exactly this functionality: "Advanced Resource management: Comprising: resource flavor fungibility, Fair Sharing, cohorts and preemption" and "Partial admission and dynamic reclaim: mechanisms to run a job with…; source: gh api repos/kubernetes-sigs/kueue/readme)
  • L19 in content/blog/gpu-kubernetes-ai-workloads/index.md "GPU capacity is what actually runs out first underneath agent frameworks, rather than the agent frameworks themselves." (also L29) → ➖ not-a-claim (evidence: This is a subjective positioning/opinion statement authored by the blog post itself (an argument about what constrains AI infrastructure scaling), not a falsifiable factual assertion citing an external source or measurable statistic.; source: content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L22-27 in content/blog/gpu-kubernetes-ai-workloads/index.md "This blog post covers GPU node pools on EKS, GKE, and AKS with Pulumi." → ➖ not-a-claim (evidence: The post itself states it covers "GPU node pools on EKS, GKE, and AKS with Pulumi" (social/linkedin blurb) and the body walks through provisioning steps and code samples for EKS with references to GKE/AKS equivalents (NodeGroup, NodePool,…; source: repo:content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L22-27 in content/blog/gpu-kubernetes-ai-workloads/index.md "Kueue-based quotas and ClusterQueues can be used so teams don't starve each other of GPU capacity." → ✅ verified (framing: Source describes ClusterQueue/quota mechanism generally preventing one team from starving others of GPU/TPU resources; claim states the same capability in blog…; evidence: (escalated from pass1) Kueue's core design uses ClusterQueue objects to hold quota (CPU/memory/GPU) per team, addressing the exact problem described: as one source states, without quota governance "one team can consume all GPUs/TPUs while…; source: https://easontechtalk.com/kueue-quick-start-fair-sharing-gpu-tpu-kubernetes/ ; https://kueue.sigs.k8s.io/docs/tasks/manage/administer_cluster_quotas/)
  • L22-27 in content/blog/gpu-kubernetes-ai-workloads/index.md "Taints and tolerations can be used to keep GPU nodes reserved for GPU work." → ✅ verified (evidence: Taints and tolerations are a standard Kubernetes mechanism documented in Kubernetes docs specifically for reserving nodes (e.g., GPU nodes) for specific workloads by tainting the node and adding matching tolerations to pods that should run…; source: Kubernetes documentation on taints and tolerations (general K8s concept, consistent with common GPU node pool reservation patterns))
  • L22-27 in content/blog/gpu-kubernetes-ai-workloads/index.md "Time-slicing and MIG are two alternative approaches for when a workload doesn't need a whole GPU card." → ✅ verified (evidence: This is standard, well-documented NVIDIA/Kubernetes technical knowledge (not a Pulumi-specific claim): NVIDIA's GPU Operator documentation describes time-slicing (sharing GPU compute cycles across pods) and MIG (Multi-Instance GPU, partiti…; source: content/blog/gpu-kubernetes-ai-workloads/index.md (line 170); general NVIDIA GPU Operator / Kubernetes device plugin documentation on time-slicing vs. MIG)
  • L25 in content/blog/gpu-kubernetes-ai-workloads/index.md "This blog post covers Kueue-based quotas and ClusterQueues, taints and tolerations, and time-slicing vs. MIG." → ➖ not-a-claim (evidence: The blog post's own body explicitly covers these topics: "Quota and scheduling | Enforces per-team or per-namespace GPU limits... | Kueue ClusterQueue/ResourceFlavor", "Taints and tolerations | Keeps non-GPU workloads off expensive GPU…; source: repo:content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L32 in content/blog/gpu-kubernetes-ai-workloads/index.md "On any major cloud, Pulumi provisions GPU-backed node pools, device plugins, quotas, taints, and cost guardrails, cluster and node pool alike, in the same prog…" → ✅ verified (evidence: Confirmed against pulumi-eks SDK source that NodeGroup/ManagedNodeGroup resources expose a taints property (e.g. "The Kubernetes taints to be applied to the nodes in the node group"), and the article itself documents matching resources a…; source: gh search code --owner pulumi repo:pulumi/pulumi-eks "taints" (sdk/nodejs/managedNodeGroup.ts); content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L34 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi has published a blog post titled 'The Agentic Infrastructure Era' at /blog/the-agentic-infrastructure-era/ arguing that infrastructure needs to be verif…" (also L206-211) → ✅ verified (evidence: Confirmed the post exists at pulumi.com/blog/the-agentic-infrastructure-era/ and argues for verifiable, policy-checked infrastructure amid rising agent-authored code: "But as the AI tsunami whips up reams of code, what happens to it become…; source: https://www.pulumi.com/blog/the-agentic-infrastructure-era/)
  • L36 in content/blog/gpu-kubernetes-ai-workloads/index.md "## Why the compute substrate is the new platform boundary" → ➖ not-a-claim (evidence: This is a section heading in a blog post, not a falsifiable assertion; it expresses the author's own framing/opinion, not a checkable fact.; source: content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L38-40 in content/blog/gpu-kubernetes-ai-workloads/index.md "Luca Galante wrote in '10 platform engineering predictions for 2026' (platformengineering.org) that 'Agentic infrastructure becomes standard architecture. AI a…" → 🤷 unverifiable (evidence: The pre-fetched page returns HTTP 200 but the truncated body only contains navigation/menu boilerplate ('Community Community Overview...Events...Reports...Jobs') with no visible article text or the quoted passage about 'Agentic infrastruct…; source: https://platformengineering.org/blog/10-platform-engineering-predictions-for-2026)
  • L50-51 in content/blog/gpu-kubernetes-ai-workloads/index.md "The device plugin or GPU operator layer exposes GPUs as a schedulable Kubernetes resource named nvidia.com/gpu, typically installed via a kubernetes.helm.v4.Ch…" → ✅ verified (evidence: kubernetes.helm.v4.Chart is a real, actively-used Pulumi Kubernetes provider resource for installing Helm charts (confirmed in pulumi-kubernetes SDK source sdk/nodejs/helm/v4/chart.ts and multiple Pulumi docs/blog examples like `conten…; source: gh search code --owner pulumi "helm.v4.Chart"; repos/pulumi/pulumi-kubernetes/contents/sdk/nodejs/helm/v4)
  • L50 in content/blog/gpu-kubernetes-ai-workloads/index.md "GPU node pools are typically provisioned via the Pulumi resources aws.eks.NodeGroup, gcp.container.NodePool, and azure-native.containerservice.AgentPool." → ✅ verified (evidence: Confirmed all three resources exist in the respective Pulumi provider SDKs: pulumi-aws:sdk/nodejs/eks/nodeGroup.ts exports class NodeGroup, pulumi-gcp:sdk/nodejs/container/nodePool.ts exports class NodePool, and `pulumi-azure-nativ…; source: gh search code --owner pulumi "class NodeGroup" --repo pulumi/pulumi-aws; "class NodePool" --repo pulumi/pulumi-gcp; "AgentPool" --repo pulumi/pulumi-azure-native)
  • L50 in content/blog/gpu-kubernetes-ai-workloads/index.md "NVIDIA A100, H100, and L4 are examples of GPU accelerators that can be attached to node pools." → ✅ verified (evidence: Google Cloud docs confirm GKE node pools support attaching NVIDIA A100, H100, and L4 GPUs: "GKE offers a range of NVIDIA GPUs (including H100, A100, L4, B200, GB200 and T4 GPUs) that can be attached to nodes in your clusters." Another GKE…; source: https://www.vcluster.com/blog/gcp-gke-gpu-cluster; https://docs.cloud.google.com/kubernetes-engine/docs/tutorials/serve-gemma-gpu-vllm)
  • L51 in content/blog/gpu-kubernetes-ai-workloads/index.md "The Kubernetes scheduler exposes GPUs as a schedulable resource under the name nvidia.com/gpu." → ✅ verified (evidence: Pulumi's own examples and provider SDKs consistently use nvidia.com/gpu as the extended resource name for scheduling GPUs, e.g. pulumi/examples aws-ts-eks-gpu-dra/index.ts uses key nvidia.com/gpu, and pulumi-aws docs state 'the support…; source: gh search code --owner pulumi "nvidia.com/gpu" (pulumi/examples aws-ts-eks-gpu-dra/index.ts, pulumi/pulumi-aws sdk/python/pulumi_aws/batch/_inputs.py))
  • L53 in content/blog/gpu-kubernetes-ai-workloads/index.md "Per-team or per-namespace GPU quota and fair-share queuing is enforced via a Kueue ClusterQueue/ResourceFlavor (through apiextensions.CustomResource) or a kube…" → ✅ verified (evidence: Pulumi's Kubernetes provider ships both apiextensions.CustomResource (the standard mechanism for applying CRDs like Kueue's ClusterQueue/ResourceFlavor — used this way in pulumi/examples and pulumi/docs blog posts) and `k8s.core.v1.Resou…; source: gh search code --owner pulumi "apiextensions.CustomResource"; gh search code --owner pulumi "core.v1.ResourceQuota")
  • L53 in content/blog/gpu-kubernetes-ai-workloads/index.md "kubernetes.core.v1.ResourceQuota is a Pulumi resource type that can enforce per-team or per-namespace GPU limits." → ✅ verified (framing: Source describes general "aggregate quota restrictions enforced per namespace" (which can include GPU resource requests/limits); claim narrows this to GPU limi…; evidence: pulumi-kubernetes SDK defines kubernetes:core/v1:ResourceQuota (e.g. sdk/nodejs/core/v1/resourceQuota.ts) with doc comment "ResourceQuota sets aggregate quota restrictions enforced per namespace" — matching hard limits on resources like…; source: gh search code --owner pulumi "ResourceQuota" repo:pulumi/pulumi-kubernetes)
  • L55 in content/blog/gpu-kubernetes-ai-workloads/index.md "KServe provides an InferenceService resource for running model or agent workloads against provisioned GPU capacity." → ✅ verified (framing: Source confirms InferenceService as a model-serving CRD; claim's mention of "or agent workloads" is a reasonable generalization since InferenceService can host…; evidence: KServe's source confirms type InferenceService struct defined in pkg/apis/serving/v1beta1/inference_service.go, the core CRD KServe provides for deploying model serving workloads on Kubernetes (typically on GPU-backed nodes).; source: gh search code "type InferenceService struct" --repo kserve/kserve)
  • L57 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi provisions GPU node pools, device plugins, taints, quotas, sharing strategy, and serving layer all as ordinary resources in the same program, with the s…" → ➖ not-a-claim (evidence: This is the blog post's own summary of the table it just built (GPU node pools, device plugins, taints, quotas, sharing strategy, serving layer — each mapped to concrete Pulumi/Kubernetes provider resources like aws.eks.NodeGroup, kubernet…; source: content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L63 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi offers a ManagedCluster-style resource for provisioning or referencing an existing Kubernetes cluster (EKS, GKE, or AKS) depending on cloud." → 🌀 framing-drift (framing: overclaim — "ManagedCluster" is the literal Azure resource name (azure-native.containerservice.ManagedCluster) generalized into a fictitious cross-cloud patt…; evidence: Only Azure's resource is actually named ManagedCluster (azure-native.containerservice.ManagedCluster); AWS uses eks.Cluster and GCP uses gcp.container.Cluster/google-native equivalents. The blog's own code sample at line 77 insta…; source: gh search code --owner pulumi "ManagedCluster" (pulumi-azure-native containerservice.ManagedCluster); repo:content/blog/gpu-kubernetes-ai-workloads/index.md line 77 uses eks.Cluster; intuition: Claim invents a generic "ManagedCluster-style" naming convention that doesn't exist outside Azure's specific resource t…)
  • L64 in content/blog/gpu-kubernetes-ai-workloads/index.md "Standard_NC24ads_A100_v4 is an example GPU virtual machine size on Azure." → ✅ verified (evidence: Microsoft's official Azure docs confirm Standard_NC24ads_A100_v4 is a real VM size in the NC A100 v4 series, featuring an NVIDIA A100 GPU, part of "a new addition to the Azure GPU family."; source: https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/gpu-accelerated/nca100v4-series)
  • L65 in content/blog/gpu-kubernetes-ai-workloads/index.md "A taint such as nvidia.com/gpu=present:NoSchedule can be applied to a GPU node pool so only pods with a matching toleration are scheduled there." → ✅ verified (evidence: Multiple independent sources confirm this is the standard GKE/Kubernetes GPU node pool taint pattern: "GKE natively taints GPU nodes with nvidia.com/gpu=present:NoSchedule so that only GPU-tolerating workloads are scheduled on them" — ma…; source: gh search code "nvidia.com/gpu=present:NoSchedule" (cloudpilot-ai/karpenter-provider-gcp:docs/gpu-nodes.md, GoogleCloudPlatform/cluster-toolkit))
  • L66 in content/blog/gpu-kubernetes-ai-workloads/index.md "The NVIDIA GPU Operator (or a cloud-managed device plugin) can be installed via a Helm chart so the Kubernetes scheduler can see and allocate nvidia.com/gpu as…" → ✅ verified (evidence: Pulumi's own SDKs/examples (e.g. pulumi/examples aws-ts-eks-gpu-dra, pulumi-aws Batch EKS properties) consistently reference nvidia.com/gpu as the standard Kubernetes extended resource name for GPU scheduling, which is exactly what the N…; source: gh search code --owner pulumi "nvidia.com/gpu")
  • L67 in content/blog/gpu-kubernetes-ai-workloads/index.md "Kueue's ResourceFlavor and ClusterQueue (or a Kubernetes ResourceQuota) can cap how many GPUs a namespace or team can claim at once." → ✅ verified (evidence: This describes standard, well-documented Kueue architecture: a ClusterQueue defines nominal quotas of resources (via ResourceFlavor) that namespaces/teams (via LocalQueues) can consume, with fair-share queuing when demand exceeds capacity…; source: Kueue project documentation (kubernetes-sigs/kueue) ClusterQueue/ResourceFlavor concepts; Kubernetes ResourceQuota API)
  • L68 in content/blog/gpu-kubernetes-ai-workloads/index.md "A KServe InferenceService or a training Job can be deployed as a GPU-requesting workload with a toleration for the GPU taint and a resource request for nvid…" → ✅ verified (evidence: This describes standard Kubernetes GPU scheduling mechanics: KServe InferenceServiceand KubernetesJobare ordinary pod-spec-based CRDs/resources, and NVIDIA's device plugin exposes GPUs as the schedulable resourcenvidia.com/gpu`, r…; source: content/blog/gpu-kubernetes-ai-workloads/index.md (internal consistency) + general KServe/NVIDIA device-plugin/Kubernetes taint-toleration documentation)
  • L72-108 in content/blog/gpu-kubernetes-ai-workloads/index.md "The provided TypeScript example uses @pulumi/aws, @pulumi/eks, and @pulumi/kubernetes to create an EKS cluster, a GPU node group using g5.xlarge instan…" → ❌ contradicted (framing: Claim asserts the example installs the gpu-operator chart from this exact repo URL; the URL is dead (404).; evidence: The cited Helm repo URL https://helm.ngc.nvidia.com/nvidia returns HTTP 404 with an empty body, so the claim's referenced Helm chart source cannot be confirmed as live/valid.; source: https://helm.ngc.nvidia.com/nvidia)
  • L84-97 in content/blog/gpu-kubernetes-ai-workloads/index.md "The eks.NodeGroup resource in the example accepts properties cluster, instanceType, amiType, desiredCapacity, minSize, maxSize, labels, and ta…" → ❌ contradicted (framing: shifted — actual NodeGroup taints API is a keyed map {value, effect}; claim/example asserts an array of {key, value, effect} objects, which is the ManagedNodeG…; evidence: The blog's TypeScript example uses taints: [{key: "nvidia.com/gpu", value: "present", effect: "NO_SCHEDULE"}](an array with akeyfield) foreks.NodeGroup, but pulumi-eks's own NodeGroup TaintArgs type is taints?: pulumi.Input<{[ke…; source: gh api repos/pulumi/pulumi-eks/contents/sdk/nodejs/nodeGroup.ts and repos/pulumi/pulumi-eks/contents/examples/nodegroup/index.ts; intuition: Code example mixes two different taints API shapes (array-with-key vs. keyed-map) across pulumi-eks resource variants;…)
  • L99-101 in content/blog/gpu-kubernetes-ai-workloads/index.md "The Pulumi Kubernetes provider (k8s.Provider) accepts a kubeconfig argument sourced from an eks.Cluster's kubeconfig output." → ✅ verified (evidence: pulumi-kubernetes SDK defines k8s.Provider's kubeconfig arg (sdk/python/pulumi_kubernetes/provider.py: kubeconfig: pulumi.Input[Optional[_builtins.str]] = None), and pulumi-eks's Cluster exposes a kubeconfig output (Java SDK: `Ou…; source: gh search code --owner pulumi repo:pulumi/pulumi-kubernetes kubeconfig: ; gh search code --owner pulumi repo:pulumi/pulumi-eks kubeconfig)
  • L112-160 in content/blog/gpu-kubernetes-ai-workloads/index.md "The provided Python example uses pulumi_gcp and pulumi_kubernetes to create a GKE cluster with remove_default_node_pool=True, a GPU node pool using machi…" → ✅ verified (evidence: Confirmed pulumi_gcp Python SDK exposes remove_default_node_pool on gcp.container.Cluster and NodePoolNodeConfigGuestAcceleratorArgs on gcp.container.NodePool (gh search hits: "remove_default_node_pool=True" in pulumi-gcp sdk/python/pulumi…; source: gh search code --owner pulumi "remove_default_node_pool" / "NodePoolNodeConfigGuestAcceleratorArgs"; repo:content/blog/gpu-kubernetes-ai-workloads/index.md L112-160)
  • L117-121 in content/blog/gpu-kubernetes-ai-workloads/index.md "gcp.container.Cluster accepts initial_node_count and remove_default_node_pool arguments." → ✅ verified (evidence: The official pulumi/templates kubernetes-gcp-python template creates gke_cluster = gcp.container.Cluster("gke-cluster", ..., initial_node_count=1, ..., remove_default_node_pool=True, ...), confirming both arguments are valid on `gcp.cont…; source: gh api repos/pulumi/templates/contents/kubernetes-gcp-python/main.py (base64 decoded))
  • L123-144 in content/blog/gpu-kubernetes-ai-workloads/index.md "gcp.container.NodePool accepts cluster, node_count, autoscaling (via NodePoolAutoscalingArgs with min_node_count/max_node_count), and node_confi…" → ✅ verified (evidence: pulumi-gcp SDK confirms gcp.container.NodePooland its input classes exactly as described:NodePoolAutoscalingArgs(dotnet/java/python sources) is used with min_node_count/max_node_count in the NodePool.autoscaling field, andNodePool…; source: gh search code --owner pulumi "NodePoolNodeConfigArgs"/"NodePoolAutoscalingArgs"/"NodePoolNodeConfigGuestAcceleratorArgs"/"NodePoolNodeConfigTaintArgs" in pulumi/pulumi-gcp)
  • L133-136 in content/blog/gpu-kubernetes-ai-workloads/index.md "gcp.container.NodePoolNodeConfigGuestAcceleratorArgs accepts type and count fields, and nvidia-tesla-a100 is a valid accelerator type value." → ✅ verified (evidence: Decoded pulumi-gcp source for NodePoolNodeConfigGuestAcceleratorArgs.cs shows: [Input("count", required: true)] public Input<int> Count and [Input("type", required: true)] public Input<string> Type ("The accelerator type resource name.…; source: gh api repos/pulumi/pulumi-gcp/contents/sdk/dotnet/Container/Inputs/NodePoolNodeConfigGuestAcceleratorArgs.cs)
  • L156 in content/blog/gpu-kubernetes-ai-workloads/index.md "repo='https://helm.ngc.nvidia.com/nvidia'," → ➖ not-a-claim (evidence: The line is a Helm chart repo URL used as a configuration value in code (repo="https://helm.ngc.nvidia.com/nvidia") within an IaC/Helm example, not a falsifiable assertion. However, since a URL was cited and pre-fetched, noting it returns…; source: https://helm.ngc.nvidia.com/nvidia; intuition: Bare HTTP GET to a Helm repo root commonly 404s even for valid repos since Helm clients request /index.yaml; treating t…)
  • L162 in content/blog/gpu-kubernetes-ai-workloads/index.md "Both the TypeScript and Python example programs request GPU-backed nodes, taint them so ordinary workloads can't land there by accident, and install the operat…" → ✅ verified (evidence: Both code blocks in the same file show this: TypeScript creates gpuNodeGroup with instanceType "g5.xlarge" and taints: [{key: "nvidia.com/gpu", value: "present", effect: "NO_SCHEDULE"}], then installs gpuOperator via k8s.helm.v4.Chart with…; source: repo:content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L162 in content/blog/gpu-kubernetes-ai-workloads/index.md "Credentials for the cluster in these examples should be pulled from Pulumi ESC rather than hardcoded as a kubeconfig, following the same pattern as the rest of…" → ➖ not-a-claim (evidence: This is the author's own stylistic/design recommendation embedded in the post ("Credentials for the cluster follow the same pattern as the rest of your Pulumi stack: pull them from Pulumi ESC rather than hardcoding a kubeconfig"), not a th…; source: content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L166 in content/blog/gpu-kubernetes-ai-workloads/index.md "A GPU node pool without quotas is a shared resource with no rules, and the first team to notice usually notices by having their job queued indefinitely behind…" → ➖ not-a-claim (evidence: This is an editorial/positioning statement expressing the author's own opinion and analogy about GPU node pool resource contention, not a falsifiable factual assertion citing an external source.; source: content/blog/gpu-kubernetes-ai-workloads/index.md (author's own commentary))
  • L168 in content/blog/gpu-kubernetes-ai-workloads/index.md "A plain Kubernetes ResourceQuota on requests.nvidia.com/gpu can be used to cover simpler GPU quota cases." → ✅ verified (evidence: Multiple independent sources (kubernetes/website docs, OpenShift docs) confirm ResourceQuota using requests.nvidia.com/gpu as the resource key is the standard Kubernetes pattern for capping extended GPU resources at the namespace level,…; source: gh search code "requests.nvidia.com/gpu" "ResourceQuota" (kubernetes/website:content/en/docs/concepts/policy/resource-quotas.md, openshift/openshift-docs))
  • L168 in content/blog/gpu-kubernetes-ai-workloads/index.md "A Kueue ClusterQueue paired with a ResourceFlavor scoped to a GPU node pool lets users cap how many GPUs each namespace or team can claim concurrently, wit…" → ✅ verified (framing: Source describes general ClusterQueue/ResourceFlavor/fair-sharing mechanics; claim applies this generically-documented capability specifically to GPU node pool…; evidence: (escalated from pass1) Kueue docs confirm: ResourceFlavor is a cluster-scoped API defining a resource flavor like a GPU model, and ClusterQueue is a cluster-scoped API that "define[s] resource pools by setting quotas for one or more Resour…; source: https://kubernetes.io/blog/2022/10/04/introducing-kueue/ and https://kueue.sigs.k8s.io/docs/tasks/manage/administer_cluster_quotas/)
  • L169 in content/blog/gpu-kubernetes-ai-workloads/index.md "Kubernetes labels tell the scheduler what a node has, while taints tell it what a node requires." → ⚔️ mismatch (framing: source frames taints as a repulsion/exclusion mechanism ('repel pods... unless matching toleration'), while claim recasts this as taints stating what a node 'r…; evidence: (escalated from pass1) Kubernetes sources describe labels as attracting pods (via affinity/selectors) and taints as repelling pods unless tolerated — not as taints expressing what a node "requires." As one source states, "Taints, on the ot…; source: https://www.plural.sh/blog/kubernetes-taint-best-practices/; intuition: The phrase "taints tell it what a node requires" is a loose simplification; technically taints don't express a node req…)
  • L170 in content/blog/gpu-kubernetes-ai-workloads/index.md "Time-slicing lets several pods share one GPU's compute cycles for latency-tolerant workloads." → ✅ verified (evidence: NVIDIA's k8s-device-plugin defines "time-slicing" as a GPU sharing-strategy (alongside "mps" and "none") specifically for allowing multiple pods/containers to share a single GPU's compute cycles via time-sliced scheduling, matching the cla…; source: gh search code "time-slicing" --repo NVIDIA/k8s-device-plugin; api/config/v1/sharing.go: SharingStrategyTimeSlicing = SharingStrategy("time-slicing"))
  • L170 in content/blog/gpu-kubernetes-ai-workloads/index.md "NVIDIA MIG partitions a single GPU into isolated, right-sized instances when workloads need dedicated memory and stronger isolation." → ✅ verified (evidence: NVIDIA's own documentation describes Multi-Instance GPU (MIG) as a feature that partitions a single GPU (e.g., A100/H100) into multiple isolated instances, each with dedicated memory, cache, and compute cores, providing hardware-level isol…; source: NVIDIA MIG public documentation (docs.nvidia.com/datacenter/tesla/mig-user-guide) — general technical knowledge of MIG architecture)
  • L171 in content/blog/gpu-kubernetes-ai-workloads/index.md "Setting minSize: 0 on a GPU node pool allows idle capacity to scale to zero between jobs." → ✅ verified (evidence: pulumi-eks's NodeGroup/NodeGroupV2 resources expose minSize as a standard autoscaling group floor, and pulumi-eks's own changelog records "Fix node group's minSize and desiredSize cannot be 0" — confirming minSize: 0 is a supported…; source: gh search code --owner pulumi minSize pulumi-eks (CHANGELOG_OLD.md: "Fix node group's minSize and desiredSize cannot be 0"))
  • L176 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi has published a blog post titled 'How to Run AI Agents on Kubernetes with Pulumi' at /blog/ai-agents-on-kubernetes/ covering agent CRDs, orchestration,…" → ✅ verified (evidence: The file content/blog/ai-agents-on-kubernetes/index.md exists with title "How to Run AI Agents on Kubernetes with Pulumi," and its content covers kagent's Agent/ModelConfig/RemoteMCPServer CRDs, orchestration (provisioning GPU-enabled node…; source: repo:content/blog/ai-agents-on-kubernetes/index.md)
  • L176 in content/blog/gpu-kubernetes-ai-workloads/index.md "A KServe InferenceService requests nvidia.com/gpu the same way any other pod does and lands on the tainted GPU node pool because it carries the matching to…" → ✅ verified (evidence: KServe's own docs state: "if you deploy an InferenceService with a predictor that requests 1 GPU, then kubernetes will detect a request of 1 GPU and add to the predictor pod the nvidia.com/gpu toleration automatically," and that using the…; source: https://kserve.github.io/website/docs/model-serving/node-scheduling/isvc-node-scheduling)
  • L178-180 in content/blog/gpu-kubernetes-ai-workloads/index.md "Joe Duffy wrote in 'The Agentic Infrastructure Era' (at /blog/the-agentic-infrastructure-era/) that 'we're seeing something magical happen here at Pulumi: LLMs…" → ✅ verified (evidence: The Agentic Infrastructure Era blog post states: "we're seeing something magical happen here at Pulumi: LLMs are now doing over 20% of the infrastructure deployments, up from virtually zero a year ago."; source: https://www.pulumi.com/blog/the-agentic-infrastructure-era/)
  • L180 in content/blog/gpu-kubernetes-ai-workloads/index.md "> 'At the same time, we're seeing something magical happen here at Pulumi: LLMs are now doing over 20% of the infrastructure deployments, up from virtually zer…" → ✅ verified (evidence: Pulumi's own blog "The Agentic Infrastructure Era" contains the identical statement: "something magical happen here at Pulumi: LLMs are now doing over 20% of the infrastructure deployments, up from virtually zero a year a…; source: https://www.pulumi.com/blog/the-agentic-infrastructure-era/)
  • L182 in content/blog/gpu-kubernetes-ai-workloads/index.md "Over 20% of infrastructure deployments at Pulumi are now LLM-authored, up from virtually zero a year ago." → ✅ verified (framing: Source: "LLMs are now doing over 20% of the infrastructure deployments, up from virtually zero a year ago." Claim restates this with "LLM-authored" as a synony…; evidence: Pulumi's own blog post "The Agentic Infrastructure Era" by Joe Duffy states: "LLMs are now doing over 20% of the infrastructure deployments, up from virtually zero a year ago." This matches the claim's figures (over 20%, up from virtually…; source: https://www.pulumi.com/blog/the-agentic-infrastructure-era/)
  • L192 in content/blog/gpu-kubernetes-ai-workloads/index.md "Without a device plugin or GPU operator installed, Kubernetes has no way to know a node has an accelerator attached, and the scheduler will never place a GPU-r…" → ✅ verified (evidence: This matches the well-documented Kubernetes device plugin architecture: extended resources like nvidia.com/gpu are only advertised to the kubelet/scheduler via a device plugin (e.g., NVIDIA's k8s-device-plugin or GPU Operator); without it,…; source: Kubernetes device plugin framework / NVIDIA k8s-device-plugin documented behavior (extended resources require device plugin advertisement); cross-checked against content/blog/gpu-kubernetes-ai-workloads/index.md lines 51, 66, 161-162)
  • L198-200 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi's aws.eks.NodeGroup, gcp.container.NodePool, and azure-native.containerservice.AgentPool resources all support GPU-backed instance types, and can be pro…" → ✅ verified (evidence: Confirmed all three resources exist as named Pulumi resource types: azure-native:containerservice:AgentPool (class AgentPool in ContainerService, pulumi-azure-native), gcp:container/nodePool:NodePool (pulumi-gcp), and aws.eks.NodeGroup…; source: gh search code --owner pulumi "AgentPool" --repo pulumi/pulumi-azure-native; gh search code --owner pulumi "NodePool" --repo pulumi/pulumi-gcp)
  • L198-200 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi can provision GPU node pools across AWS, Azure, and Google Cloud from the same program alongside the operator, quota, and serving resources that sit on…" → ✅ verified (evidence: Pulumi's native providers (aws, gcp, azure-native, kubernetes) can all be used in a single program; pulumi-eks and other cloud SDKs confirm resources like aws.eks.NodeGroup exist, and the article itself demonstrates provisioning GPU node p…; source: gh search code --owner pulumi pulumi-eks (nodeGroup.ts); content/blog/gpu-kubernetes-ai-workloads/index.md table of Pulumi resources across AWS/GCP/Azure)
  • L202-204 in content/blog/gpu-kubernetes-ai-workloads/index.md "Time-slicing lets multiple pods share one GPU's compute cycles in turn, with no hard isolation between them, which suits latency-tolerant or bursty workloads." → ✅ verified (evidence: This describes NVIDIA's well-documented Kubernetes GPU time-slicing mechanism (via the NVIDIA device plugin/GPU Operator), which schedules multiple pods' contexts onto one physical GPU in a time-sliced round-robin fashion without memory or…; source: repo:content/blog/gpu-kubernetes-ai-workloads/index.md (lines 54, 170, 196) — internal consistency; general knowledge of NVIDIA GPU time-slicing device plugin behavior)
  • L202-204 in content/blog/gpu-kubernetes-ai-workloads/index.md "MIG (Multi-Instance GPU) physically partitions a supported NVIDIA GPU into isolated instances with dedicated memory, which suits workloads that need predictabl…" → ✅ verified (evidence: This describes NVIDIA's publicly documented MIG (Multi-Instance GPU) feature, which physically partitions supported GPUs (A100, H100, etc.) into isolated instances each with dedicated memory/compute slices — a well-established NVIDIA capab…; source: NVIDIA MIG public documentation (general technical knowledge); corroborated internally by content/blog/gpu-kubernetes-ai-workloads/index.md line 170)
  • L206-211 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi maintains Kubernetes provider documentation, including full resource reference for clusters, node pools, and workloads, at /registry/packages/kubernetes…" → ✅ verified (evidence: The pulumi/registry repo contains themes/default/content/registry/packages/kubernetes/_index.md plus faq.md, installation-configuration.md, and a how-to-guides directory, confirming /registry/packages/kubernetes/ is Pulumi's maintained Kub…; source: gh api repos/pulumi/registry/contents/themes/default/content/registry/packages/kubernetes)
  • L206-212 in content/blog/gpu-kubernetes-ai-workloads/index.md "Pulumi ESC can be used to broker cloud credentials into GPU-provisioning stacks without static keys, and is documented at /docs/esc/." → ✅ verified (evidence: The /docs/esc/ page exists and documents exactly this capability: "Login providers ... Issue short-lived OIDC credentials for AWS, Azure, GCP, GitHub, and more," which is ESC brokering cloud credentials without static keys.; source: repo:content/docs/esc/_index.md)
  • L208 in content/blog/gpu-kubernetes-ai-workloads/index.md "- How to Run AI Agents on Kubernetes with Pulumi — the agent runtime layer that consumes the capacity this post provisions." → ✅ verified (evidence: (escalated from pass3) The target file content/blog/ai-agents-on-kubernetes/index.md exists in the repo with title "How to Run AI Agents on Kubernetes with Pulumi", matching the link text exactly, and its content (agent CRDs, kagent, KServ…; source: repo:content/blog/ai-agents-on-kubernetes/index.md)
  • L209 in content/blog/gpu-kubernetes-ai-workloads/index.md "- The Agentic Infrastructure Era — why infrastructure needs to be verifiable code as more of it is agent-authored." → ✅ verified (evidence: The page at /blog/the-agentic-infrastructure-era/ exists and covers exactly this theme: it discusses agentic infrastructure, verifiability, and AI agents authoring code, e.g. "Built-in verifiability, policy enforcement, and audit trails ma…; source: https://www.pulumi.com/blog/the-agentic-infrastructure-era/)
  • L210 in content/blog/gpu-kubernetes-ai-workloads/index.md "- Best AI Infrastructure Tools — a broader look at the AI infrastructure landscape." → ➖ not-a-claim (evidence: This is an internal cross-link to another Pulumi blog post (/blog/ai-infrastructure-tools/), not a falsifiable factual assertion.; source: content/blog/gpu-kubernetes-ai-workloads/index.md)
  • L162 in content/blog/gpu-kubernetes-ai-workloads/index.md "pull them from Pulumi ESC rather than hardcoding a kubeconfig" → 🚩 flagged (readthrough: missing-step)
  • L34 in content/blog/gpu-kubernetes-ai-workloads/index.md "no <!--more--> break anywhere in the post body" → 🚩 flagged (blog: missing-more-break)

📊 Editorial balance

Section depth, mention distribution, recommendation steering
  • Section depth: 7 H2 sections (mean 18 lines, median 6, std 28.7). Outliers: How do you provision a GPU node pool on Kubernetes with Pulumi?: 88 (14.7× median).
  • Vendor / entity mentions: Kubernetes: 34 · Pulumi (incl. Pulumi ESC): 25 · NVIDIA (incl. MIG, GPU Operator): 21 · AWS/EKS: 16 · Google Cloud/GKE: 13 · Kueue: 8 · Azure/AKS: 6 · KServe: 3 · Terraform: 0. No competitor is named anywhere in the post, so there is no comparison set to weigh.
  • FAQ steering: 5 FAQ entries; 1 recommends Pulumi by name ("Can Pulumi manage GPU node pools across AWS, Azure, and Google Cloud?"); the other 4 steer to vendor-neutral Kubernetes/NVIDIA mechanisms (device plugin, minSize: 0 autoscaling, quotas, time-slicing vs. MIG). Single-vendor FAQ, so the ≥60%-steering threshold doesn't apply.

🚨 Outstanding in this PR

These must be resolved or refuted before merging.

  • [L84-97] content/blog/gpu-kubernetes-ai-workloads/index.md — the TypeScript example passes taints to eks.NodeGroup in the shape eks.ManagedNodeGroup expects, and amiType is not usable on eks.NodeGroup the way it's used here. This program does not typecheck, so a reader who copies it gets an error rather than a GPU node pool. Two distinct mismatches against pulumi-eks:

    1. taints shape. eks.NodeGroup's type is taints?: pulumi.Input<{[key: string]: pulumi.Input<TaintArgs>}> — a keyed map whose values are {value, effect} (the key is the taint key), and whose effect uses the Kubernetes spelling (NoSchedule), because it's rendered into the kubelet's --register-with-taints flag. The array-of-{key, value, effect} form with effect: "NO_SCHEDULE" in the post belongs to eks.ManagedNodeGroup, which passes taints through the AWS EKS API. (sdk/nodejs/nodeGroup.ts L360 + sdk/nodejs/types/input.ts TaintArgs; the shape in the post appears at sdk/nodejs/managedNodeGroup.ts L451.)
    2. amiType. On eks.NodeGroup, amiType is documented as "only applicable when setting an AMI ID that is of type arm64" and is mutually exclusive with gpu. The idiomatic way to get a GPU-optimized AMI on a self-managed node group is gpu: true, which selects the EKS GPU-optimized AMI for you.
    const gpuNodeGroup = new eks.NodeGroup("gpu-pool", {
        cluster: cluster,
        instanceType: "g5.xlarge",
        gpu: true,
        desiredCapacity: 1,
        minSize: 0,
        maxSize: 4,
        labels: { "workload-type": "gpu" },
        taints: {
            "nvidia.com/gpu": {
                value: "present",
                effect: "NoSchedule",
            },
        },
    });
    

    Switching the resource to eks.ManagedNodeGroup is the other valid fix — keep amiType: "AL2_x86_64_GPU" and the array-style taints with effect: "NO_SCHEDULE", but move desiredCapacity/minSize/maxSize into scalingConfig: { desiredSize, minSize, maxSize } and use instanceTypes: ["g5.xlarge"]. Either way, the post's prose at L162 ("taint them so ordinary workloads can't land there by accident") only holds once the taint actually applies.

  • [L162] content/blog/gpu-kubernetes-ai-workloads/index.md — the Python example's Kubernetes provider is wired to a placeholder, so the second of the post's two programs can't run either. L156-159 reads:

    provider = k8s.Provider(
        "gpu-cluster",
        kubeconfig=cluster.name.apply(lambda _: pulumi.Output.secret("<kubeconfig>")),
    )

    That apply discards the cluster name and hands the provider the literal string "<kubeconfig>". The prose two paragraphs later tells the reader to "pull them from Pulumi ESC rather than hardcoding a kubeconfig" but never shows how, so the one step the reader needs in order to get from the GKE node pool to a working provider is the step that's missing. Either build the kubeconfig from the cluster's outputs the way the TypeScript example does, or show the actual ESC read — e.g.:

    provider = k8s.Provider(
        "gpu-cluster",
        kubeconfig=pulumi.Config().require_secret("kubeconfig"),
    )
    

    …paired with a sentence naming the ESC environment that supplies kubeconfig, so "pull them from Pulumi ESC" resolves to something the reader can follow. A placeholder string is fine in a snippet that's explicitly elided; it is not fine in a program presented as the GKE counterpart of a complete AWS example.

  • [L34] content/blog/gpu-kubernetes-ai-workloads/index.md — the post has no <!--more--> break anywhere in its body, and it ships draft: false. Without the break, the entire 180-line post renders on the blog index page instead of a summary card. The break belongs after the two framing paragraphs and before the first H2, mirroring ai-agents-on-kubernetes (which places it at its own L40):

    That is the substrate question. It's a different question from "how do I run an AI agent on Kubernetes," which is about the runtime: agent CRDs, tool-calling controllers, and the orchestration loop that decides what an agent is allowed to do. If that's what you're after, [our post on running AI agents on Kubernetes](/blog/ai-agents-on-kubernetes/) covers it end to end. This post is about the layer underneath: the GPU capacity every agent, model server, and training job ultimately competes for.
    
    <!--more-->
    

⚠️ Low-confidence

Review each and resolve as appropriate — these don't block the PR.

  • [L38-40] content/blog/gpu-kubernetes-ai-workloads/index.md"Luca Galante wrote in '10 platform engineering predictions for 2026' (platformengineering.org) that 'Agentic infrastructure becomes standard architecture. AI a…" — verdict: unverifiable; evidence: The pre-fetched page returns HTTP 200 but the truncated body only contains navigation/menu boilerplate ('Community Community Overview...Events...Reports...Jobs') with no visible article text or the quoted passage about 'Agentic infrastruct…; source: https://platformengineering.org/blog/10-platform-engineering-predictions-for-2026

    Author question: the cited page served only navigation boilerplate when fetched, so the block quote and the attribution ("Luca Galante, Managing Director & Senior Analyst at Weave Intelligence") couldn't be confirmed against it. Please confirm the quote is verbatim and that the title and role are current as of publication. Not a blocker — the citation is present and linked inline, so a reader can follow it; this is a "check your transcription" note, not a missing-source finding.

  • [L63] content/blog/gpu-kubernetes-ai-workloads/index.md"Pulumi offers a ManagedCluster-style resource for provisioning or referencing an existing Kubernetes cluster (EKS, GKE, or AKS) depending on cloud." — verdict: framing-drift; framing: overclaim — "ManagedCluster" is the literal Azure resource name (azure-native.containerservice.ManagedCluster) generalized into a fictitious cross-cloud patt…; evidence: Only Azure's resource is actually named ManagedCluster (azure-native.containerservice.ManagedCluster); AWS uses eks.Cluster and GCP uses gcp.container.Cluster/google-native equivalents. The blog's own code sample at line 77 insta…; source: gh search code --owner pulumi "ManagedCluster" (pulumi-azure-native containerservice.ManagedCluster); repo:content/blog/gpu-kubernetes-ai-workloads/index.md line 77 uses eks.Cluster; intuition: Claim invents a generic "ManagedCluster-style" naming convention that doesn't exist outside Azure's specific resource t…

    ManagedCluster is Azure's specific resource name (azure-native.containerservice.ManagedCluster); AWS uses eks.Cluster and Google Cloud uses gcp.container.Cluster. Writing it as a cross-cloud pattern name invents a convention that doesn't exist, and the post's own examples contradict it eight lines later (new eks.Cluster(...) at L77, gcp.container.Cluster(...) at L117). Kept out of 🚨 because the code samples immediately below correct the impression and the phrasing doesn't ride the social.* frontmatter — but the step reads better without the invented name:

    1. Provision or reference an existing Kubernetes cluster with the cluster resource for your cloud of choice — `eks.Cluster` on AWS, `gcp.container.Cluster` on Google Cloud, or `azure-native.containerservice.ManagedCluster` on Azure.
    

Style findings

Found by pattern-based linting; Findings may be false positives.

  • line 32: [style] weasel word — 'fairly' is a weasel word!
  • line 32: [style] punctuation — Use the Oxford comma in 'On any major cloud, Pulumi provisions all of it, cluster and'.
  • line 32: [style] wordiness — 'all of' is too wordy.
  • line 46: [style] weasel word — 'usually' is a weasel word!
  • line 66: [style] wordiness — 'allocate' is too wordy.
  • line 166: [style] weasel word — 'usually' is a weasel word!
  • line 170: [style] weasel word — 'several' is a weasel word!
  • line 171: [style] difficulty qualifier — Avoid difficulty qualifier 'just' -- it judges difficulty for the reader (STYLE-GUIDE.md §Inclusive Language).
  • line 182: [style] substitution — Use 'select' instead of 'click' (STYLE-GUIDE.md).
  • line 209: [style] wordiness — 'it is' is too wordy.

  • Refresh this review — comment @claude #update-review. Say what you fixed, or which finding you dispute and why; both work in the same mention.
  • Ask for anything else — comment @claude with no hashtag (questions, one-off fixes). Leaves this review untouched.

Important

Please don't hide, resolve, or delete this comment! It breaks things!

📖 How pre-merge review works — the full lifecycle, short-circuits, and escape hatches.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

📋 Triaged verifier findings

I double-checked these and realized they weren't real findings — click to expand
  • [L72-108] content/blog/gpu-kubernetes-ai-workloads/index.md"The provided TypeScript example uses @pulumi/aws, @pulumi/eks, and @pulumi/kubernetes to create an EKS cluster, a GPU node group using g5.xlarge instan…"Spurious: the ❌ verdict rests entirely on https://helm.ngc.nvidia.com/nvidia returning 404 to a bare GET /. That's the expected response for an NVIDIA NGC Helm repository root — Helm clients request /index.yaml, not the root path, so a root 404 says nothing about the repo's validity. This is the canonical repositoryOpts.repo value for the NVIDIA GPU Operator chart and it's correct as written in both examples.

  • [L169] content/blog/gpu-kubernetes-ai-workloads/index.md"Kubernetes labels tell the scheduler what a node has, while taints tell it what a node requires."Spurious: the divergence was measured against a third-party blog's phrasing ("taints repel pods") rather than against a conflicting fact. The post's compression is accurate in substance — a taint is precisely a requirement the node imposes on pods (a matching toleration), which is the same mechanism described as repulsion from the pod's side — and the sentence immediately following it ("Use both, so a misconfigured pod … can't accidentally land on an expensive node") states the mechanism correctly.

💡 Pre-existing issues in touched files (optional)

No pre-existing issues in touched files.

✅ Resolved since last review

No items resolved since the last review.

📜 Review history

  • 2026-08-01T12:23:56Z — New GPU-on-Kubernetes blog post: both code examples are broken as written (eks.NodeGroup taints/amiType shape, placeholder kubeconfig in the Python program) and the post is missing its <!--more--> break; 43 of 58 claims verified, two verifier findings triaged as spurious. (9ee6c6c)

  • Refresh this review — comment @claude #update-review. Say what you fixed, or which finding you dispute and why; both work in the same mention.
  • Ask for anything else — comment @claude with no hashtag (questions, one-off fixes). Leaves this review untouched.

Important

Please don't hide, resolve, or delete this comment! It breaks things!

📖 How pre-merge review works — the full lifecycle, short-circuits, and escape hatches.

@github-actions github-actions Bot added review:outstanding-issues Claude review completed; outstanding has author-actionable findings and removed review:in-progress Claude review is currently running labels Aug 1, 2026
@pulumi-bot

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain:blog PR touches blog posts or customer stories review:outstanding-issues Claude review completed; outstanding has author-actionable findings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants