getreadystack's picture
Upload index.html with huggingface_hub
2456339 verified
Raw History Blame Contribute Delete
47.9 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>EKS Extended Support cost — check your Terraform free</title>
<style>
:root{color-scheme:light}body{margin:0;font:15px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:#faf9f5;color:#1a1512}
.wrap{max-width:960px;margin:0 auto;padding:28px 18px 60px}h1{font-size:26px;margin:0 0 6px}.lede{color:#4a403a;margin:0 0 16px}
textarea{width:100%;min-height:260px;font:13px/1.45 ui-monospace,Menlo,Consolas,monospace;padding:12px;border:1px solid #d9d0c4;border-radius:8px;box-sizing:border-box}
.bar{display:flex;gap:10px;align-items:center;margin:12px 0}button{font:600 15px system-ui;padding:10px 18px;border:0;border-radius:8px;background:#1a1512;color:#fff;cursor:pointer}
input[type=date]{font:14px system-ui;padding:8px;border:1px solid #d9d0c4;border-radius:6px}
table{border-collapse:collapse;width:100%;font-size:14px;margin-top:10px}th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #eee;vertical-align:top}th{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#7a6e65}
.sev.error{color:#a8551f;font-weight:700}.sev.warn,.sev.warning{color:#96691f}.ok{color:#2a6446;font-weight:600}.sum{font-weight:600}
.note{font-size:13px;color:#7a6e65;margin-top:18px}#paid{margin-top:22px;padding:14px 16px;border:1px solid #e2d8cb;border-radius:10px;background:#fffdfa}
</style>
<script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script>
<!--yj-canon-s101--><link rel="canonical" href="https://getreadystack.com/tools/aks-eks-support-cliff-lint"></head>
<body>
<div class="wrap">
<h1>EKS Extended Support cost — check your Terraform free</h1>
<p class="lede">Lints Terraform aws_eks_cluster and azurerm_kubernetes_cluster blocks against the 2026 EKS and AKS version calendars: extended-support fees, AKS LTS without Premium tier, forced upgrades. Runs entirely in your browser — nothing is uploaded.</p>
<textarea id="src" spellcheck="false"># payments-platform/clusters.tf
resource "aws_eks_cluster" "payments" {
name = "payments-prod"
role_arn = aws_iam_role.eks.arn
version = "1.32"
vpc_config {
subnet_ids = var.private_subnets
}
}
resource "aws_eks_cluster" "batch" {
name = "batch-prod"
role_arn = aws_iam_role.eks.arn
version = "1.31"
upgrade_policy {
support_type = "EXTENDED"
}
vpc_config {
subnet_ids = var.private_subnets
}
}
resource "aws_eks_cluster" "web" {
name = "web-prod"
role_arn = aws_iam_role.eks.arn
version = "1.34"
upgrade_policy {
support_type = "STANDARD"
}
vpc_config {
subnet_ids = var.private_subnets
}
}
resource "azurerm_kubernetes_cluster" "core" {
name = "aks-core-weu"
location = "westeurope"
resource_group_name = azurerm_resource_group.core.name
dns_prefix = "core"
kubernetes_version = "1.31"
sku_tier = "Standard"
support_plan = "AKSLongTermSupport"
default_node_pool {
name = "system"
node_count = 3
vm_size = "Standard_D4s_v5"
}
}
resource "azurerm_kubernetes_cluster" "legacy" {
name = "aks-legacy-weu"
location = "westeurope"
resource_group_name = azurerm_resource_group.core.name
dns_prefix = "legacy"
kubernetes_version = "1.33.2"
sku_tier = "Standard"
default_node_pool {
name = "system"
node_count = 2
vm_size = "Standard_D4s_v5"
}
}
resource "azurerm_kubernetes_cluster" "analytics" {
name = "aks-analytics-weu"
location = "westeurope"
resource_group_name = azurerm_resource_group.core.name
dns_prefix = "analytics"
kubernetes_version = "1.35"
sku_tier = "Premium"
support_plan = "AKSLongTermSupport"
default_node_pool {
name = "system"
node_count = 3
vm_size = "Standard_D4s_v5"
}
}</textarea>
<div class="bar"><button id="go">Check</button><label>as of <input type="date" id="today"></label></div>
<div id="out" aria-live="polite"></div>
<div id="paid"><strong>Free here:</strong> every EKS and AKS cluster block in the pasted .tf file, all 9 rules, with the dollars already billed. <strong>Full version:</strong> scan the whole workspace in VS Code and export a per-cluster CSV of fees, cliff dates and fixes. <a href="https://getreadystack.com/api/buy/cl/polar_cl_h4hStvanMbFQkOvKD4EQ6BWS54rfLlOpDYCBB0UJnAI">Get the full version — $29</a> ($29 once · one licence key per person or team seat. EKS extended support alone is $4,380 a year per cluster.)</div>
<p class="note">Same engine as the VS Code extension, byte for byte.</p>
</div>
<script>var SCL_RULES = [
{"id": "eks-extended-billing", "sev": "error", "title": "EKS version is in extended support and billed at $0.60 per cluster-hour instead of $0.10",
"source": "https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html",
"price_standard_hour": 0.10, "price_extended_hour": 0.60, "hours_per_month": 730,
"eks_calendar": {
"1.31": {"std_end": "2025-11-26", "ext_end": "2026-11-26"},
"1.32": {"std_end": "2026-03-23", "ext_end": "2027-03-23"},
"1.33": {"std_end": "2026-07-29", "ext_end": "2027-07-29"},
"1.34": {"std_end": "2026-12-02", "ext_end": "2027-12-02"},
"1.35": {"std_end": "2027-03-27", "ext_end": "2028-03-27"},
"1.36": {"std_end": "2027-08-02", "ext_end": "2028-08-02"}}},
{"id": "eks-forced-upgrade-soon", "sev": "error", "title": "EKS extended support ends within the warning window; AWS then upgrades the control plane with no notice", "window_days": 90},
{"id": "eks-past-extended", "sev": "error", "title": "EKS version is past end of extended support; the control plane is auto-upgraded and node groups are left behind"},
{"id": "eks-cliff-soon", "sev": "warning", "title": "EKS standard support ends within the warning window (auto-upgrade under STANDARD, 6x fee under EXTENDED)", "window_days": 90},
{"id": "aks-lts-needs-premium", "sev": "error", "title": "support_plan AKSLongTermSupport is only available on sku_tier Premium",
"source": "https://learn.microsoft.com/en-us/azure/aks/supported-kubernetes-versions",
"price_standard_hour": 0.10, "price_premium_hour": 0.60, "hours_per_month": 730,
"aks_calendar": {
"1.29": {"eol": "2025-03-31", "lts_eol": "2026-04-30"},
"1.30": {"eol": "2025-08-22", "lts_eol": "2026-07-31"},
"1.31": {"eol": "2025-11-01", "lts_eol": "2026-11-30"},
"1.32": {"eol": "2026-03-31", "lts_eol": "2027-03-31"},
"1.33": {"eol": "2026-07-31", "lts_eol": "2027-07-31"},
"1.34": {"eol": "2026-11-30", "lts_eol": "2027-11-30"},
"1.35": {"eol": "2027-03-31", "lts_eol": "2028-03-31"},
"1.36": {"eol": "2027-06-30", "lts_eol": "2028-06-30"},
"1.37": {"eol": "2027-10-31", "lts_eol": "2028-10-31"}}},
{"id": "aks-out-of-support", "sev": "error", "title": "AKS version is past community end of life without LTS: no security patches, no new clusters"},
{"id": "aks-lts-ended", "sev": "error", "title": "AKS version is past its LTS end of life"},
{"id": "aks-eol-soon", "sev": "warning", "title": "AKS community support ends within the warning window and LTS is not enabled", "window_days": 90},
{"id": "aks-premium-unused", "sev": "info", "title": "Premium tier bought for LTS while the version is still in community support"}
]
;</script>
<script>/* aks-eks-support-cliff-lint engine: Terraform aws_eks_cluster / azurerm_kubernetes_cluster vs the EKS and AKS version calendars. Runs in Node and the browser. */
(function () {
const RULES = (typeof module !== 'undefined') ? require('./rules.json') : window.SCL_RULES;
const R = {}; RULES.forEach(r => { R[r.id] = r; });
const EKS = R['eks-extended-billing'], AKS = R['aks-lts-needs-premium'];
const DAY = 86400000;
function d(s) { return new Date(s + 'T00:00:00Z'); }
function days(a, b) { return Math.round((d(b) - d(a)) / DAY); }
function usd(n) { return '$' + Math.round(n).toLocaleString('en-US'); }
function minor(v) { const m = /^(\d+)\.(\d+)/.exec(v || ''); return m ? m[1] + '.' + m[2] : null; }
function older(a, b) { const x = a.split('.').map(Number), y = b.split('.').map(Number); return x[0] < y[0] || (x[0] === y[0] && x[1] < y[1]); }
function oldestKey(cal) { return Object.keys(cal).sort((a, b) => older(a, b) ? -1 : 1)[0]; }
// Find resource blocks by brace matching; return {type, name, line, body, bodyLine}
function blocks(text) {
const out = [], re = /resource\s+"(aws_eks_cluster|azurerm_kubernetes_cluster)"\s+"([^"]+)"\s*\{/g;
let m;
while ((m = re.exec(text))) {
let depth = 1, i = re.lastIndex;
while (i < text.length && depth > 0) { const c = text[i]; if (c === '{') depth++; else if (c === '}') depth--; i++; }
const start = re.lastIndex;
out.push({ type: m[1], name: m[2], line: text.slice(0, m.index).split('\n').length, body: text.slice(start, i - 1), bodyLine: text.slice(0, start).split('\n').length });
}
return out;
}
function attr(b, key) {
const m = new RegExp('^[ \\t]*' + key + '[ \\t]*=[ \\t]*"([^"]*)"', 'm').exec(b.body);
if (!m) return null;
return { value: m[1], line: b.bodyLine + b.body.slice(0, m.index).split('\n').length - 1 };
}
function eks(b, today, F) {
const v = attr(b, 'version'); if (!v) return;
const k = minor(v.value); if (!k) return;
const st = attr(b, 'support_type');
const policy = st ? st.value.toUpperCase() : 'EXTENDED';
const how = st ? 'support_type = "' + policy + '"' : 'no upgrade_policy block, so AWS defaults to EXTENDED';
const cal = EKS.eks_calendar;
let row = cal[k];
if (!row) {
if (older(k, oldestKey(cal))) F.push({ check: 'eks-past-extended', sev: R['eks-past-extended'].sev, line: v.line,
msg: 'aws_eks_cluster.' + b.name + ' pins Kubernetes ' + k + ', older than every version EKS still supports (oldest: ' + oldestKey(cal) + '). The control plane is auto-upgraded; managed node groups stay behind.' });
return;
}
const diff = EKS.price_extended_hour - EKS.price_standard_hour;
if (today >= row.ext_end) {
F.push({ check: 'eks-past-extended', sev: R['eks-past-extended'].sev, line: v.line,
msg: 'aws_eks_cluster.' + b.name + ' pins ' + k + '; extended support ended ' + row.ext_end + '. The control plane is auto-upgraded; node groups stay on ' + k + '.' });
return;
}
if (today >= row.std_end && policy !== 'STANDARD') {
const billed = days(row.std_end, today) * 24 * diff;
F.push({ check: 'eks-extended-billing', sev: EKS.sev, line: v.line, extra_usd: Math.round(billed),
msg: 'aws_eks_cluster.' + b.name + ' pins ' + k + ' (' + how + '). Standard support ended ' + row.std_end + '; billed $0.60 instead of $0.10 per cluster-hour since then: ' + usd(billed) + ' extra by ' + today + ', ' + usd(diff * EKS.hours_per_month) + ' more each month.' });
const left = days(today, row.ext_end);
if (left <= R['eks-forced-upgrade-soon'].window_days)
F.push({ check: 'eks-forced-upgrade-soon', sev: R['eks-forced-upgrade-soon'].sev, line: v.line,
msg: 'aws_eks_cluster.' + b.name + ': extended support for ' + k + ' ends ' + row.ext_end + ' (' + left + ' days). After that AWS upgrades the control plane at any time with no notice.' });
return;
}
if (today >= row.std_end && policy === 'STANDARD') {
F.push({ check: 'eks-past-extended', sev: R['eks-past-extended'].sev, line: v.line,
msg: 'aws_eks_cluster.' + b.name + ' pins ' + k + ' with support_type = "STANDARD"; standard support ended ' + row.std_end + ', so AWS auto-upgrades this control plane and the pinned version drifts from state.' });
return;
}
const left = days(today, row.std_end);
if (left <= R['eks-cliff-soon'].window_days)
F.push({ check: 'eks-cliff-soon', sev: R['eks-cliff-soon'].sev, line: v.line,
msg: 'aws_eks_cluster.' + b.name + ': standard support for ' + k + ' ends ' + row.std_end + ' (' + left + ' days). ' +
(policy === 'STANDARD' ? 'support_type = "STANDARD": AWS auto-upgrades the control plane on that date.' : how + ': billing jumps from $0.10 to $0.60 per cluster-hour (' + usd(diff * EKS.hours_per_month) + ' a month).') });
}
function aks(b, today, F) {
const v = attr(b, 'kubernetes_version'); if (!v) return;
const k = minor(v.value); if (!k) return;
const tierA = attr(b, 'sku_tier'), planA = attr(b, 'support_plan');
const tier = tierA ? tierA.value : 'Free', lts = planA && planA.value === 'AKSLongTermSupport';
const cal = AKS.aks_calendar, row = cal[k];
const diff = AKS.price_premium_hour - AKS.price_standard_hour;
if (lts && tier !== 'Premium') {
F.push({ check: 'aks-lts-needs-premium', sev: AKS.sev, line: planA.line,
msg: 'azurerm_kubernetes_cluster.' + b.name + ': support_plan = "AKSLongTermSupport" with sku_tier = "' + tier + '". LTS is only available on the Premium tier ($0.60 vs $0.10 per cluster-hour).' });
return;
}
if (!row) {
if (older(k, oldestKey(cal))) F.push({ check: 'aks-lts-ended', sev: R['aks-lts-ended'].sev, line: v.line,
msg: 'azurerm_kubernetes_cluster.' + b.name + ' pins ' + k + ', older than every AKS version still supported, LTS included (oldest: ' + oldestKey(cal) + ').' });
return;
}
if (lts) {
if (today > row.lts_eol) F.push({ check: 'aks-lts-ended', sev: R['aks-lts-ended'].sev, line: v.line,
msg: 'azurerm_kubernetes_cluster.' + b.name + ' pins ' + k + '; its LTS end of life was ' + row.lts_eol + '. Premium tier no longer covers this version.' });
else if (today <= row.eol) F.push({ check: 'aks-premium-unused', sev: R['aks-premium-unused'].sev, line: tierA.line,
msg: 'azurerm_kubernetes_cluster.' + b.name + ': Premium tier for LTS, but ' + k + ' is in community support until ' + row.eol + '. Standard tier until then saves ' + usd(diff * AKS.hours_per_month) + ' a month.' });
return;
}
if (today > row.eol) {
F.push({ check: 'aks-out-of-support', sev: R['aks-out-of-support'].sev, line: v.line,
msg: 'azurerm_kubernetes_cluster.' + b.name + ' pins ' + k + '; community end of life was ' + row.eol + ' and LTS is off. No security patches, no new clusters at this version. Upgrade, or LTS (Premium) runs to ' + row.lts_eol + '.' });
return;
}
const left = days(today, row.eol);
if (left <= R['aks-eol-soon'].window_days)
F.push({ check: 'aks-eol-soon', sev: R['aks-eol-soon'].sev, line: v.line,
msg: 'azurerm_kubernetes_cluster.' + b.name + ': ' + k + ' leaves community support ' + row.eol + ' (' + left + ' days) and LTS is off.' });
}
function check(text, opts) {
const today = (opts && opts.today) || new Date().toISOString().slice(0, 10);
const findings = [];
blocks(String(text || '')).forEach(b => (b.type === 'aws_eks_cluster' ? eks : aks)(b, today, findings));
findings.sort((a, b) => a.line - b.line);
return { findings };
}
const api = { engine: { check }, RULES, RULE_COUNT: RULES.length };
if (typeof module !== 'undefined') module.exports = api;
if (typeof window !== 'undefined') window.SCLENGINE = api;
})();
</script>
<script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다.
'use strict';
function escapeHtml(s) { return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); }
function summaryLine(res) {
const f = (res && res.findings) || []; const e = f.filter(function (x) { return String(x.sev || 'error').toLowerCase().startsWith('err'); }).length;
return f.length ? (f.length + ' finding' + (f.length === 1 ? '' : 's') + ' (' + e + ' error' + (e === 1 ? '' : 's') + ')') : 'Clean — no findings.';
}
function toText(res, label) {
const f = (res && res.findings) || [];
const lines = ['== ' + (label || '') + ' — ' + summaryLine(res)];
f.forEach(function (x) { lines.push(' ' + String(x.sev || 'error').toUpperCase().slice(0, 4) + ' ' + (x.line ? 'L' + x.line + ' ' : '') + (x.check || x.id || '') + ' ' + (x.msg || x.message || '')); });
return lines.join('\n');
}
function toHtml(res) {
const f = (res && res.findings) || [];
if (!f.length) return '<p class="ok">' + escapeHtml(summaryLine(res)) + '</p>';
const rows = f.map(function (x) { return '<tr><td class="sev ' + escapeHtml(String(x.sev || 'error')) + '">' + escapeHtml(String(x.sev || 'error')) + '</td><td>' + (x.line ? 'L' + escapeHtml(x.line) : '') + '</td><td><code>' + escapeHtml(x.check || x.id || '') + '</code></td><td>' + escapeHtml(x.msg || x.message || '') + '</td></tr>'; }).join('');
return '<p class="sum">' + escapeHtml(summaryLine(res)) + '</p><table><thead><tr><th>Level</th><th>Line</th><th>Check</th><th>What</th></tr></thead><tbody>' + rows + '</tbody></table>';
}
var SCLREPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml };
if (typeof module !== 'undefined' && module.exports) module.exports = SCLREPORT;
else window.SCLREPORT = SCLREPORT;
</script>
<script>
(function(){
var src=document.getElementById('src'), out=document.getElementById('out'), go=document.getElementById('go'), today=document.getElementById('today');
today.value=new Date().toISOString().slice(0,10);
function run(){ try { var res=window.SCLENGINE.engine.check(src.value,{today:today.value}); out.innerHTML=window.SCLREPORT.toHtml(res); } catch(e){ out.innerHTML='<p class="sev error">Could not run: '+String(e.message||e)+'</p>'; } }
go.onclick=run; if (src.value.trim()) run();
})();
</script>
<section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://marketplace.visualstudio.com/items?itemName=ReadyStack.aks-eks-support-cliff-lint" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'aks-eks-support-cliff-lint',src:'mp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">VS Code Marketplace</a><a href="https://open-vsx.org/extension/readystack/aks-eks-support-cliff-lint" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'aks-eks-support-cliff-lint',src:'ovsx',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Open VSX (Cursor, VSCodium)</a><a href="https://www.npmjs.com/package/@readystack/aks-eks-support-cliff-lint" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'aks-eks-support-cliff-lint',src:'npm',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">npm</a><a href="https://hub.docker.com/r/getreadystack/aks-eks-support-cliff-lint" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'aks-eks-support-cliff-lint',src:'docker',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.aks-eks-support-cliff-lint
npx @readystack/aks-eks-support-cliff-lint &lt;file&gt;
docker run --rm -v &quot;$PWD:/w&quot; getreadystack/aks-eks-support-cliff-lint /w</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/team" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
<section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get the full rule table as a PDF</b><div style="opacity:.78;margin:.35rem 0 .8rem">All 9 rules AKS LTS &amp; EKS Extended Support Lint for Terraform checks, each with its source and date, on printable pages you can hand to your team or auditor. We email it now, and once more only if a rule changes. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Email me the PDF</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">Sent. It arrives within the hour - check spam too.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"aks-eks-support-cliff-lint",lang:"en",source:"rule_table"+((b.closest&&b.closest("section")&&b.closest("section").getAttribute("data-yj-moved"))?"_at_result":"")})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script><script>(function(){var e=document.getElementById("yjae"),s=e&&e.closest?e.closest("section"):null,o=document.getElementById("out");if(!s||!o)return;var d=false;function mv(ev){if(d)return;if(ev&&ev.target&&s.contains(ev.target))return;d=true;var b=o;while(b.parentNode&&b.parentNode!==document.body&&b.parentNode.tagName!=="MAIN"&&b.parentNode.tagName!=="ARTICLE")b=b.parentNode;if(!b.parentNode||b===s||b.contains(s))return;try{b.parentNode.insertBefore(s,b.nextSibling);s.setAttribute("data-yj-moved","1");}catch(_){}}document.addEventListener("input",mv,true);document.addEventListener("change",mv,true);})();</script></section>
<section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">Terraform EKS and AKS version check: sample clusters.tf on 2026-09-27 — $2,256 extra on EKS 1.32 since 2026-03-23, $3,660 on 1.31 since 2025-11-26, $5,916 total; 9 rules</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">Amazon EKS bills $0.60 per cluster-hour in extended support against $0.10 in standard support, so one cluster left on an old version costs $365 a month or $4,380 a year extra; AKS Premium tier for LTS is $0.60 against $0.10 for St</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_h4hStvanMbFQkOvKD4EQ6BWS54rfLlOpDYCBB0UJnAI" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section>
<!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script>
<script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script>
<script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div><section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><p style="font:400 13px/1.5 system-ui,sans-serif;color:#6b7680;margin:0 0 14px"><time datetime="2026-09-27">Updated 2026-09-27</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-09-27","author":{"@type":"Organization","name":"ReadyStack"}}</script><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Worked example</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 16px;color:#5b6570">Real numbers from this tool, line by line.</p><div class="yj-article"><p><img src="https://getreadystack.com/img/promo/sku326983_result_card.jpg" alt="AKS LTS &amp; EKS Extended Support Lint for Terraform" loading="lazy" style="max-width:100%;border-radius:6px"></p>
<p>$2,256 in extra EKS fees: that is what one Terraform-managed Amazon EKS cluster pinned to version = &quot;1.32&quot;, with no upgrade_policy block, had been billed on top of the standard rate between 2026-03-23 and 2026-09-27. This is for platform engineers, DevOps and SRE teams, and FinOps reviewers who run EKS or Azure Kubernetes Service (AKS) clusters as Terraform code.</p>
<h3>Where the money goes</h3>
<p>Amazon EKS gives each Kubernetes minor version 14 months of standard support, then 12 months of extended support. Standard support costs $0.10 per cluster-hour. Extended support costs $0.60 per cluster-hour. Billing switches at the start of the day standard support ends, in UTC. For version 1.32 that day was 2026-03-23.</p>
<p>The part most people miss: when an aws_eks_cluster block has no upgrade_policy, AWS treats the cluster as EXTENDED. terraform plan shows no diff. From 2026-03-23 to 2026-09-27 is 188 days, so 188 x 24 hours x $0.50 = $2,256. In the sample file used to build this tool, a second cluster pinned to 1.31 with support_type = &quot;EXTENDED&quot; had been in extended support since 2025-11-26: $3,660. Together that is $5,916, and the meter keeps running at $365 a month per cluster.</p>
<h3>The other side of the cliff</h3>
<p>Extended support does not last. EKS 1.31 extended support ends on 2026-11-26. After that date AWS upgrades the control plane on its own schedule, without a notice, and managed node groups stay on the old version. A cluster set to support_type = &quot;STANDARD&quot; avoids the fee but gets the auto-upgrade at the end of standard support instead: for 1.34 that is 2026-12-02.</p>
<p>AKS has its own version of the trap. Microsoft gives each version one year of community support and, with Long Term Support (LTS), one more year. LTS is only available on the Premium tier, which is $0.60 per cluster-hour against $0.10 for Standard. So support_plan = &quot;AKSLongTermSupport&quot; next to sku_tier = &quot;Standard&quot; is a request for something the tier does not include. A cluster on 1.33 without LTS left community support on 2026-07-31: platform support only, no Kubernetes security patches, and no new clusters at that version.</p>
<h3>What the lint does</h3>
<p>AKS LTS &amp; EKS Extended Support Lint for Terraform reads every aws_eks_cluster and azurerm_kubernetes_cluster block and checks version, upgrade_policy, sku_tier and support_plan against the EKS calendar (1.31 to 1.36) and the AKS calendar (1.29 to 1.37), both checked on 2026-09-27. It has 9 rules. On the sample clusters.tf it returned 7 findings:</p>
<ul><li>payments, 1.32, no upgrade_policy: $2,256 extra since 2026-03-23</li><li>batch, 1.31, EXTENDED: $3,660 extra since 2025-11-26</li><li>batch: forced control-plane upgrade after 2026-11-26, 60 days out</li><li>web, 1.34, STANDARD: auto-upgrade on 2026-12-02, 66 days out</li><li>core: AKSLongTermSupport on the Standard tier</li><li>legacy, 1.33.2 without LTS: past the 2026-07-31 end of life</li><li>analytics: Premium tier for LTS while 1.35 is in community support until 2027-03-31</li></ul>
<p>The corrected file (EKS 1.35 with STANDARD, AKS 1.32 on Premium with LTS, AKS 1.36 on Standard) returns zero findings.</p>
<h3>Why the usual checks miss it</h3>
<p>terraform validate checks syntax and provider schema. terraform plan compares state. Neither knows a date. The lint carries the dates as data and computes the dollar amount for the day you run it.</p>
<h3>Free and full version</h3>
<p>The free version lints the open .tf file in VS Code, or a pasted file in the web version, with all 9 rules and every message. The full version scans the whole workspace and exports a per-cluster CSV of fees, cliff dates and fixes for a platform or FinOps review.</p></div><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:30px 0 10px;color:#1b1f24">15 seconds — what it actually does</h2><video controls muted playsinline preload="none" poster="/img/promo/sku326983_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku326983_short.mp4" type="video/mp4"></video><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does AKS LTS &amp; EKS Extended Support Lint do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads Terraform aws_eks_cluster and azurerm_kubernetes_cluster blocks and compares the pinned Kubernetes version with the published EKS and AKS calendars. It reports extended-support fees already billed in dollars, forced control-plane upgrade dates, AKS versions past end of life, and support_plan AKSLongTermSupport set on a tier other than Premium, with the line number of each problem.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is this Terraform Kubernetes version lint for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Platform engineers, DevOps and SRE teams, and FinOps reviewers who manage Amazon EKS or Azure Kubernetes Service clusters as Terraform code. It suits teams that pin Kubernetes versions in .tf files and review changes in VS Code or in pull requests, and anyone who inherited clusters whose upgrade_policy or sku_tier nobody has looked at since creation.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why don&#x27;t terraform plan or a chatbot catch EKS extended support fees?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">terraform validate and terraform plan only check syntax and provider schema, so version = &quot;1.32&quot; passes even after standard support has ended. A missing upgrade_policy block defaults to EXTENDED, which bills $0.60 instead of $0.10 per cluster-hour. Chatbots often quote outdated version dates. This lint carries the dated EKS and AKS calendars checked on 2026-09-27.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what does the full version add?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">The free version lints the open .tf file with all 9 rules and shows every finding, including the dollar amount billed so far, with no key and no limit. The full version, $29 once, scans the whole workspace and exports a per-cluster CSV of fees, cliff dates and fixes that a platform team or FinOps review can file.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">How much does an EKS cluster left in extended support cost?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Amazon EKS bills $0.10 per cluster-hour in standard support and $0.60 in extended support, so one cluster left on an old version costs $365 more a month, or $4,380 a year. In the sample file, a 1.32 cluster had billed $2,256 extra by 2026-09-27 and a 1.31 cluster $3,660. AKS Premium tier for LTS is likewise $0.60 against $0.10.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just ask ChatGPT or another AI chat?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. AKS LTS &amp; EKS Extended Support Lint for Terraform checks the file you open against 9 rules from a rule set dated 2026-09-27, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does AKS LTS & EKS Extended Support Lint do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads Terraform aws_eks_cluster and azurerm_kubernetes_cluster blocks and compares the pinned Kubernetes version with the published EKS and AKS calendars. It reports extended-support fees already billed in dollars, forced control-plane upgrade dates, AKS versions past end of life, and support_plan AKSLongTermSupport set on a tier other than Premium, with the line number of each problem."}}, {"@type": "Question", "name": "Who is this Terraform Kubernetes version lint for?", "acceptedAnswer": {"@type": "Answer", "text": "Platform engineers, DevOps and SRE teams, and FinOps reviewers who manage Amazon EKS or Azure Kubernetes Service clusters as Terraform code. It suits teams that pin Kubernetes versions in .tf files and review changes in VS Code or in pull requests, and anyone who inherited clusters whose upgrade_policy or sku_tier nobody has looked at since creation."}}, {"@type": "Question", "name": "Why don't terraform plan or a chatbot catch EKS extended support fees?", "acceptedAnswer": {"@type": "Answer", "text": "terraform validate and terraform plan only check syntax and provider schema, so version = \"1.32\" passes even after standard support has ended. A missing upgrade_policy block defaults to EXTENDED, which bills $0.60 instead of $0.10 per cluster-hour. Chatbots often quote outdated version dates. This lint carries the dated EKS and AKS calendars checked on 2026-09-27."}}, {"@type": "Question", "name": "What is free and what does the full version add?", "acceptedAnswer": {"@type": "Answer", "text": "The free version lints the open .tf file with all 9 rules and shows every finding, including the dollar amount billed so far, with no key and no limit. The full version, $29 once, scans the whole workspace and exports a per-cluster CSV of fees, cliff dates and fixes that a platform team or FinOps review can file."}}, {"@type": "Question", "name": "How much does an EKS cluster left in extended support cost?", "acceptedAnswer": {"@type": "Answer", "text": "Amazon EKS bills $0.10 per cluster-hour in standard support and $0.60 in extended support, so one cluster left on an old version costs $365 more a month, or $4,380 a year. In the sample file, a 1.32 cluster had billed $2,256 extra by 2026-09-27 and a 1.31 cluster $3,660. AKS Premium tier for LTS is likewise $0.60 against $0.10."}}, {"@type": "Question", "name": "Why not just ask ChatGPT or another AI chat?", "acceptedAnswer": {"@type": "Answer", "text": "A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. AKS LTS & EKS Extended Support Lint for Terraform checks the file you open against 9 rules from a rule set dated 2026-09-27, and points at the exact line. For a filing, an audit or a client you need that dated result on your own files."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:326983,slug:"aks-eks-support-cliff-lint",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/rds-extended-support-cost-lint"><span class="yj-rel-t">RDS Extended Support Cost Lint for Terraform</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/robots-txt-ai-crawler-audit"><span class="yj-rel-t">AI Crawler Rules - robots.txt Audit for AI Search</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/bulk-sender-lint"><span class="yj-rel-t">Bulk Sender Lint - the Gmail, Yahoo and Outlook.com rules, checked in your mai</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/cloud-cost-landmine-lint"><span class="yj-rel-t">Cloud Cost Landmine Lint for Terraform, CloudFormation and Kubernetes</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/box12-tt-overtime-premium-audit"><span class="yj-rel-t">Box 12 Code TT Audit — 2026 W-2 Overtime Premium</span><span class="yj-rel-p">$60</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/terraform-module-kubernetes"><span class="yj-rel-t">Terraform Module: Kubernetes Hardened Namespace (PSA + default-deny NetworkPol</span><span class="yj-rel-p">$3</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section></body>
</html>