Date: June 2026 | Scope: Full Site Audit | Auditor: Claude (Cowork)
example42.com has a genuine and rare competitive moat — Alessandro Franceschi is credibly positioned as the world's longest-active Puppet consultant (since 2007) and that claim is front and center. The site also benefits from 174 blog posts, 22 podcast episodes, and solid technical foundations (HTTPS, Google Search Console verified, Open Graph tags, responsive layout). However, three problems are holding the site back significantly: 161 of 174 blog posts have no custom meta description (falling back to the generic site description), no canonical tags exist anywhere on the site, and the sitemap.xml is unrendered Jekyll template (Liquid variables ship raw to users). Fixing these three issues alone will produce meaningful ranking improvements. A fourth structural opportunity — creating dedicated landing pages for individual services and leveraging the Pabawi product launch — could meaningfully expand organic reach into adjacent keywords.
Top 3 priorities: (1) Add meta descriptions site-wide, especially to blog posts; (2) Fix the broken sitemap; (3) Create dedicated service landing pages with proper H1/H2 targeting.
| Keyword | Difficulty | Opportunity | Current Signal | Intent | Recommended Content |
|---|---|---|---|---|---|
| puppet consulting | Low-Medium | High | Homepage ranks | Commercial | Homepage + dedicated /services/ page |
| puppet consultant | Low | High | Homepage ranks | Commercial | Homepage, About/5Ws page |
| puppet support | Low | High | Services page | Commercial | Dedicated landing page |
| puppet training | Low-Medium | High | Services page | Commercial | Dedicated landing page |
| puppet health check | Very Low | High | Services page (H2) | Commercial | Dedicated landing page |
| puppet infrastructure kickstart | Very Low | High | Services page (H2) | Commercial | Dedicated landing page |
| puppet enterprise consulting | Low | High | Implicit only | Commercial | New service page |
| ansible to puppet migration | Very Low | High | Services page (H2) | Commercial | Dedicated landing page |
| puppet to ansible migration | Very Low | High | Services page (H2) | Commercial | Same as above |
| psick puppet control repo | Very Low | Medium | Blog + GitHub | Informational | Blog post / GitHub README |
| puppet hiera tutorial | Low | Medium | Blog post (2021) | Informational | Refresh/update existing post |
| puppet module development | Low | Medium | Implicit | Commercial | Blog + services page |
| devops podcast infrastructure | Medium | Medium | ADI podcast | Informational | ADI landing page SEO |
| abnormal devops iterations podcast | Very Low | Medium | ADI section | Navigational | ADI index page |
| puppet open source alternative | Medium | Medium | Not covered | Informational | New blog post |
| configuration management consulting | Medium | Medium | Weak | Commercial | Services page expansion |
| pabawi web frontend puppet | Very Low | High | Blog posts (2026) | Informational/Commercial | Pabawi dedicated page |
| pabawi puppet proxmox | Very Low | High | Blog posts | Informational | Pabawi blog series |
| tp desktop puppet | Very Low | Low | One blog post | Informational | Expand existing |
| puppet error unknown resource type | Very Low | Medium | 2022 post | Informational | Update/expand |
| puppet eyaml gpg hiera | Very Low | Medium | 2020 post | Informational | Update for current Puppet versions |
| Page | Issue | Severity | Fix |
|---|---|---|---|
All 161 blog posts without description: field |
No custom meta description — falls back to generic site description for every post | Critical | Add description: frontmatter to each post. Quick win for recent posts; batch-update older ones. |
| All 22 ADI episodes | head.html checks page.description only — episodes use summary: field, so all episode pages also fall back to generic site description |
Critical | Add {% elsif page.summary %}{{ page.summary }}{% endif %} fallback in head.html for episodes |
| Entire site | No <link rel="canonical"> tag anywhere |
High | Add <link rel="canonical" href="{{ page.url | prepend: site.url }}"> to _includes/head.html |
sitemap.xml |
Liquid template variables ({{ site.url }}, {% for post %}) are not being processed — raw template is served to crawlers |
High | Move sitemap generation to a Jekyll plugin or use the jekyll-sitemap gem; verify rendered output at /sitemap.xml |
| Homepage H1 | H1 is "Puppet | DevOps Professional Consulting" — vague, splits keyword with pipe, misses "consultant" and "Alessandro Franceschi" | High | Rewrite to something like: "Puppet & DevOps Consulting — Alessandro Franceschi, Puppet Expert Since 2007" |
| Services page | Single long page covering 6+ services — all services share one <title> and one H1; individual services have no dedicated URL |
High | Create /services/puppet-health-check/, /services/puppet-training/ etc. with dedicated titles and H1s |
| ADI episode pages | H1 in adi_detail.html has mismatched open/close tags: <h1>…</h2> |
Medium | Fix HTML: change closing </h2> to </h1> on line with guest/title |
| Blog posts | H1 rendered inside blog_detail.html from {{ page.title }} — good. But many posts have # Title markdown H1 in body too, creating two H1s |
Medium | Audit recent posts; remove leading # Title from post body markdown where layout already renders H1 |
robots.txt |
Disallows /img/ — prevents Google from crawling episode cover images and logo images used in OG tags |
Medium | Remove Disallow: /img/ — image crawling helps Google Images and OG previews; only block truly private paths |
| All pages | No structured data / JSON-LD schema markup | Medium | Add Organization schema to homepage; Person for Alessandro; Service for services page; PodcastEpisode for ADI episodes |
wwwww/ page |
URL is /wwwww/ — confusing, not guessable, and provides no keyword signal |
Low | Consider redirecting to /about/ with a cleaner slug and title |
| Blog index | No meta description on /blog/ index |
Low | Add description to blog/index.html frontmatter |
| Open Graph images | All pages fall back to /img/pic-logo.png unless page.image is set — blog posts have no per-post image |
Low | Add image: to blog post frontmatter for important/recent posts |
Why it matters: All six services live as anchor-linked sections on one /services/ page. Google cannot rank /services/#puppet-health-check separately from the main page. Competitors like SPK and Open Infrastructure Services have individual pages per service that can rank for long-tail commercial queries.
Recommended format: Dedicated pages at /services/puppet-health-check/, /services/puppet-training/, /services/ansible-puppet-migration/, etc.
Priority: High | Effort: Moderate (half a day per page)
Why it matters: The site has 5 Pabawi blog posts in 2026 but no standalone /pabawi/ page with a clear value proposition. pabawi.example42.com exists as a subdomain but is a separate site that doesn't build example42.com's domain authority. Pabawi users searching "pabawi puppet" or "pabawi web frontend" will land on blog posts, not a conversion-optimized page.
Recommended format: New /pabawi/ landing page with feature overview, screenshots, and links to GitHub + docs.
Priority: High | Effort: Moderate
Why it matters: "Ansible vs Puppet" is a high-volume commercial-intent query. Competitors (Red Hat, Spacelift, SPK) rank for this. example42 offers Ansible↔Puppet migration services and has the expertise to write definitively on this topic, but no content targets it. Recommended format: Long-form comparison blog post or guide Priority: High | Effort: Moderate (half day)
Why it matters: The most recent technical Puppet posts are from 2020-2022. Queries like "puppet 8 upgrade", "puppet 7 to 8 migration", "puppet open source 2025" are uncontested and highly relevant to the services offered. Recommended format: Blog post series on Puppet 7→8 upgrade path Priority: High | Effort: Moderate
Why it matters: The entire site targets decision-ready buyers. There's no content for the awareness funnel ("what is puppet", "why use puppet", "puppet vs chef"). These informational posts build authority and generate inbound links. Recommended format: Pillar page "What is Puppet and why it still matters in 2026" Priority: Medium | Effort: Moderate
Why it matters: The ADI podcast index page at /AbnormalDevOpsIterations/ has no meta description, no structured PodcastSeries schema, and episode pages are not using the summary: field for meta descriptions. Each episode with a notable guest (Michael Stahnke, Dennis Kliban, etc.) is a missed opportunity to rank for "[guest name] devops podcast".
Recommended format: Improve episode pages + add podcast schema
Priority: Medium | Effort: Quick wins (1-2 hours for schema; 1 hour for template fix)
Why it matters: Competitors like SPK prominently feature client testimonials and case studies. example42 references "world-class expertise" but has no concrete customer proof content, which both supports SEO (unique content, E-E-A-T signals) and conversion. Recommended format: Even 2-3 anonymized case study blog posts Priority: Medium | Effort: Substantial
| Check | Status | Details |
|---|---|---|
| HTTPS | ✅ Pass | Site served over HTTPS; GitHub Pages handles SSL |
| Mobile responsive | ✅ Pass | Bootstrap-based layout, viewport meta tag present |
| Google Search Console | ✅ Pass | Verification meta tag present |
| Open Graph / Twitter Cards | ✅ Pass | Tags in head.html; falls back to site-level defaults |
| Favicons | ✅ Pass | Full set of favicon sizes present |
| robots.txt | Disallows /img/ unnecessarily; blocks image crawling |
|
| Sitemap | ❌ Fail | Template variables not rendered; raw Liquid served to crawlers |
| Canonical tags | ❌ Fail | No <link rel="canonical"> anywhere on the site |
| Meta descriptions | ❌ Fail | Only 13/174 posts and 0/22 episodes have custom descriptions |
| Structured data (JSON-LD) | ❌ Fail | No schema markup anywhere |
| H1 uniqueness | ADI episode template has mismatched H1/H2 close tag | |
| Internal linking | Blog posts rarely link to the services page; homepage links to services but not to individual episodes | |
| Page speed | Bootstrap CSS + Font Awesome loaded synchronously; Google Fonts loaded with ?family= (render-blocking) — no preconnect hints |
|
| Image alt text | ✅ Pass | Layout templates include alt text on images; episode images use descriptive alt |
| URL structure | ✅ Pass | Clean pretty URLs (/blog/YYYY/MM/DD/title/, /AbnormalDevOpsIterations/NNN/) |
| XML feed | ✅ Pass | atom.xml present and covers all posts |
| Redirect behavior | ✅ Pass | example42.com/services → /services/ redirect works correctly |
| Google Fonts | Loaded via blocking <link> without display=swap; add &display=swap to the font URL |
| Dimension | example42.com | SPK and Associates (spkaa.com) | Open Infrastructure Services (openinfrastructure.co) |
|---|---|---|---|
| Puppet-specific focus | ✅ Pure Puppet/DevOps | ❌ Puppet is one of 20+ tools | ✅ Puppet + GCP |
| Service pages (dedicated URLs) | ❌ All on one page | ✅ Per-service pages | ✅ Per-service sub-pages |
| Content volume | ✅ 174 posts (though many old) | ✅ High volume, recent | |
| Structured data | ❌ None | ✅ Article schema on posts | ✅ Basic meta |
| Canonical tags | ❌ None | ✅ Present | ✅ Present |
| Client social proof | ❌ None visible | ✅ Named testimonials, case studies | |
| Podcast / multimedia | ✅ ADI podcast (unique asset) | ❌ None | ❌ None |
| Open source portfolio | ✅ Strong (PSICK, Tiny Puppet, Pabawi) | ❌ None | |
| Personal brand / E-E-A-T | ✅ Strongest ("since 2007") | ❌ Company brand | ✅ Strong (ex-Puppet Inc. founders) |
| Publishing recency | ✅ Active in 2026 | ✅ Active weekly | |
| Winner | Personal brand, OSS, podcast | Technical SEO, content ops | Niche depth |
-
Fix the episode meta description fallback — In
_includes/head.html, change the description meta to fall back topage.summaryfor episodes. One-line template change; covers all 22 episodes immediately.- Impact: High | Effort: 30 minutes
-
Add canonical tag to
head.html— Add<link rel="canonical" href="{{ page.url | prepend: site.url }}">to_includes/head.html. Prevents any duplicate content issues with category/tag pages.- Impact: High | Effort: 15 minutes
-
Fix robots.txt — Remove
Disallow: /img/. Images are public assets that help with Google Images discovery and OG preview rendering.- Impact: Medium | Effort: 5 minutes
-
Fix sitemap.xml — Install
jekyll-sitemapgem (add toGemfileand_config.yml), delete the broken manualsitemap.xml. GitHub Pages supports this gem natively.- Impact: High | Effort: 30 minutes
-
Fix ADI episode H1 tag — In
_includes/adi_detail.html, fix</h2>→</h1>on the guest/title line.- Impact: Medium | Effort: 5 minutes
-
Add descriptions to the 8 most recent blog posts — The 2024-2026 posts (Pabawi series, Swamp posts) are the most likely to receive traffic. Add
description:frontmatter now.- Impact: Medium | Effort: 1 hour
-
Add
&display=swapto Google Fonts URL — In_includes/head.html, change the Lato font URL to include&display=swapto prevent render-blocking.- Impact: Low-Medium | Effort: 5 minutes
-
Create dedicated service landing pages — Break the monolithic
/services/page into individual pages:/services/puppet-health-check/,/services/puppet-training/,/services/ansible-migration/, etc. Each gets its own<title>, H1, meta description, and internal links. This is the single highest-leverage SEO move for commercial keyword ranking.- Impact: High | Effort: 1 day | Dependency: Redesign navigation
-
Create
/pabawi/landing page — A dedicated page for Pabawi on example42.com to capture product-level searches and convert Pabawi users into consulting clients. Link from the homepage Open Source section and from the blog posts.- Impact: High | Effort: Half day
-
Write "Ansible vs Puppet" comparison post — Target the "ansible vs puppet" and "puppet to ansible migration" queries directly. Cite real experience; link to the migration service page.
- Impact: High | Effort: Half day
-
Write Puppet 8 upgrade guide — "Puppet 7 to 8 migration guide" is low competition, high relevance to customers. Example42's active Puppet expertise makes this authoritative.
- Impact: High | Effort: Half day to 1 day
-
Add JSON-LD schema markup — Add
Organization+Personschema to homepage,Serviceschema to each service page,PodcastSeriesto the ADI index,PodcastEpisodeto each episode. This supports Google's Knowledge Panel, rich results, and E-E-A-T signals.- Impact: Medium | Effort: Half day
-
Batch-add meta descriptions to blog posts — The
bin/get_quotes.pyscript already uses OpenAI to generate summaries from transcripts. A similar script targeting blog post content could batch-generatedescription:frontmatter for the ~161 posts missing it. Alternatively, manually write descriptions for the top 30 most-visited posts.- Impact: High | Effort: 1-2 days (script approach)
-
Build internal linking structure — Add "You might also like" or contextual links within blog posts pointing to related service pages. Particularly: any post mentioning Puppet health, migrations, or training should link to the relevant service section.
- Impact: Medium | Effort: Ongoing (1-2 hours per batch of posts)
Want me to draft content briefs for the service landing pages, write a Puppet 8 upgrade post, or generate meta descriptions for a batch of blog posts?