<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Adventures in the cloud]]></title><description><![CDATA[Adventures in the cloud]]></description><link>https://blog.carlintveld.nl</link><generator>RSS for Node</generator><lastBuildDate>Tue, 06 Oct 2026 22:13:31 GMT</lastBuildDate><atom:link href="https://blog.carlintveld.nl/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[From vibe coding to craftsmanship: what Microsoft Build 2026 teaches us about AI and junior developers]]></title><description><![CDATA[Session: Scott and Mark learn... how agents reshape software engineering | BRK247


Microsoft Build 2026 featured an unusual breakout session: Mark and Scott — not next-gen engineers, but seasoned pra]]></description><link>https://blog.carlintveld.nl/from-vibe-coding-to-craftsmanship-what-microsoft-build-2026-teaches-us-about-ai-and-junior-developers</link><guid isPermaLink="true">https://blog.carlintveld.nl/from-vibe-coding-to-craftsmanship-what-microsoft-build-2026-teaches-us-about-ai-and-junior-developers</guid><dc:creator><![CDATA[Carl in 't Veld]]></dc:creator><pubDate>Thu, 11 Jun 2026 11:57:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/630fc30a75af73ad1f0622da/cd99fd44-67f7-482b-946f-4db18b1259f5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p><em>Session: Scott and Mark learn... how agents reshape software engineering | BRK247</em></p>
</blockquote>
<hr />
<p><em>Microsoft Build 2026 featured an unusual breakout session: Mark and Scott — not next-gen engineers, but seasoned practitioners — showed live how they work with Claude on real technical challenges. What I saw, I recognized immediately.</em></p>
<hr />
<h2>The gap nobody talks about out loud</h2>
<p>There is a significant leap from vibe-coded solo software to skilled engineering at world scale. AI makes it tempting to ignore that gap. You type a prompt, code rolls out, and it seems to work. But <em>seems to work</em> is not the same as <em>works correctly under load, in production, across multiple teams</em>.</p>
<p>Mark and Scott illustrated this honestly. What sets them apart is not speed or hype — it is deep domain knowledge, a sharp eye for when Claude goes wrong, and the discipline to stop and steer before things go off the rails.</p>
<hr />
<h2>What Mark managed to build</h2>
<p>With careful guidance, Mark delivered two impressive things:</p>
<h3>gRPC Shared Memory</h3>
<p>When two gRPC processes run on the same machine, there is no reason to communicate over TCP or Unix sockets. Serialization across the network costs time and CPU. With shared memory, you can eliminate that overhead entirely.</p>
<p>Mark delivered a working implementation for both <strong>Go</strong> and <strong>.NET</strong> — two ecosystems, one concept, significant performance gains. This is not a hello-world demo. This is the kind of optimization that makes a difference in production systems.</p>
<h3>Scrolling screenshots in ZoomIt</h3>
<p>In his spare time, Mark added a scrolling screenshot feature to ZoomIt, the well-known Sysinternals tool by Mark Russinovich. A small feature, but technically non-trivial — and a great example of what becomes possible when you use AI as a tool rather than a replacement.</p>
<hr />
<h2>The skill that deserves the most attention</h2>
<p>The most interesting part of the session was not the code being written, but the process around it. Mark demonstrated how important it is to:</p>
<ul>
<li><strong>Follow Claude's thinking process</strong> — not blindly accept what is being proposed</li>
<li><strong>Stop in time</strong> — as soon as Claude heads in the wrong direction, intervene before technical debt accumulates</li>
<li><strong>Steer with precision</strong> — not start over, but sharpen the context and guide Claude back on track</li>
</ul>
<p>This is a skill in itself. And it is precisely the skill that juniors currently lack.</p>
<hr />
<h2>The problem with junior developers in the AI era</h2>
<p>AI agents regularly do the wrong thing. Not always spectacularly wrong — sometimes subtly. A classic example that came up in the session: <strong>adding a <code>sleep</code> statement to fix a race condition</strong>.</p>
<p>This is the kind of solution that works in a demo and fails in production. A junior without sufficient context might accept it, because the tests go green. An experienced engineer sees it immediately: this is not a fix, this is hiding the problem.</p>
<p>The point is not that AI is bad. The point is that juniors today need more coaching than ever, not less. They are exposed to more code, more complexity, and more AI output that sounds convincing but can be structurally wrong. Without a strong technical mentor alongside them, the risk is high that they copy bad patterns without realizing it.</p>
<hr />
<h2>What this means for how we work</h2>
<p>If you are using AI in your engineering organization — and you are, whether you realize it or not — these are the lessons from Build 2026:</p>
<ol>
<li><strong>Domain knowledge remains irreplaceable.</strong> Mark could only steer because he understood what the code was supposed to do.</li>
<li><strong>Stop and reorient early.</strong> The further Claude heads in the wrong direction, the more expensive it is to come back.</li>
<li><strong>Train juniors on the process, not just the output.</strong> Teach them to read Claude's reasoning, not just accept the code.</li>
<li><strong>Sleep statements are a code smell, not a solution.</strong> If AI suggests this: stop, and analyze the underlying race condition.</li>
</ol>
<hr />
<h2>Conclusion</h2>
<p>Mark and Scott are seasoned engineers at the top of their craft. And that is exactly what makes this session stand out: instead of another AI hype demo, they show what it actually looks like to use AI responsibly as part of serious engineering.</p>
<p>The gap between vibe coding and world-scale engineering is real. AI does not make it smaller — AI makes it more visible. And the people who can bridge that gap are not those who write the fastest prompts. They are the ones who know when to intervene.</p>
<hr />
<p><em>Based on the Microsoft Build 2026 breakout session: <a href="https://youtu.be/1h8UU_OVRTE?si=B_ZwYv5cVkiO-TPy">Scott and Mark learn... how agents reshape software engineering | BRK247</a></em></p>
]]></content:encoded></item><item><title><![CDATA[Bring existing Azure infra under Terraform, fast]]></title><description><![CDATA[Bringing existing Azure infrastructure under Terraform management is one of those tasks that sounds simple until you actually do it. Terraform has supported import {} blocks since 1.5, but writing the]]></description><link>https://blog.carlintveld.nl/bring-existing-azure-infra-under-terraform-fast</link><guid isPermaLink="true">https://blog.carlintveld.nl/bring-existing-azure-infra-under-terraform-fast</guid><dc:creator><![CDATA[Carl in 't Veld]]></dc:creator><pubDate>Wed, 10 Jun 2026 07:26:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/630fc30a75af73ad1f0622da/a8db28f5-3ac2-4599-9033-f973dde5230a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Bringing existing Azure infrastructure under Terraform management is one of those tasks that sounds simple until you actually do it. Terraform has supported <code>import {}</code> blocks since 1.5, but writing them by hand is tedious: every block needs the exact Azure resource ID, and a lot of those IDs are surprisingly hard to look up.</p>
<p>I built a small tool to do it for you — straight from a binary <code>.plan</code> file, with no <code>terraform init</code>, no provider plugins, and no <code>terraform</code> CLI required. It's on PyPI as <a href="https://pypi.org/project/generate-imports-from-plan/"><code>generate-imports-from-plan</code></a>.</p>
<h2>The problem</h2>
<p>Say you have a Terraform configuration that describes resources which already exist in Azure. You run a plan, and Terraform wants to <em>create</em> everything — because it doesn't know those resources are already there. The fix is to write an <code>import {}</code> block per resource:</p>
<pre><code class="language-hcl">import {
  to = module.core.azurerm_resource_group.this
  id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-myapp-dev-we-01"
}
</code></pre>
<p>For a handful of resources, fine. For a real environment with dozens of resource groups, networks, role assignments and Entra ID apps, doing this by hand is a long afternoon of copy-pasting IDs out of the portal.</p>
<p>The obvious idea is to script it from <code>terraform show -json</code>. But there's a catch.</p>
<h2>Why <code>terraform show -json</code> isn't enough</h2>
<p><code>terraform show -json &lt;planfile&gt;</code> does not expose all planned attribute values. Computed fields — including things you need to build the resource ID, like the resource name or the resource group name — show up as "known after apply" and are simply absent from the JSON.</p>
<p>The values <em>are</em> in the plan, though. A <code>.plan</code> file is actually a ZIP containing:</p>
<ul>
<li><code>tfplan</code> — the planned changes, as protobuf</li>
<li><code>tfstate</code> — the prior state</li>
<li><code>tfconfig/</code> — the raw HCL of your configuration</li>
</ul>
<p>Inside <code>tfplan</code>, attribute values are msgpack-encoded, and they include the computed values that the JSON view drops. So instead of going through <code>terraform show</code>, this tool reads the binary plan directly: unzip, parse the protobuf, decode the msgpack attributes. No provider plugins needed, because nothing is being evaluated — the values are already sitting in the plan.</p>
<h2>How IDs get resolved</h2>
<p>Azure resource IDs come in a few flavours, and the tool handles each differently:</p>
<ol>
<li><p><strong>Formula-based IDs.</strong> Most ARM resources have a deterministic ID you can assemble from their attributes — subscription, resource group, provider namespace, name. These are built from a formula and emitted immediately, no prompting.</p>
</li>
<li><p><strong>Cross-plan IDs.</strong> Some resources have an ID that depends on <em>another</em> resource in the same plan — a subnet association needs the subnet ID, a DNS-servers resource needs the VNet ID. The tool reads the HCL references in <code>tfconfig/</code> and derives those IDs from the sibling resource, again without any external calls.</p>
</li>
<li><p><strong>Live IDs.</strong> A few resource types only get their ID assigned at creation time — Entra ID resources, Azure role assignments. For those, the tool calls the Azure CLI (<code>az</code>) to look up the real ID, and it shows you the exact command before running it.</p>
</li>
</ol>
<p>There's one more nice detail: the correct <strong>subscription ID is determined per resource</strong> by following the <code>azurerm</code> provider chain through the config. A plan that spans multiple subscriptions gets the right subscription on each resource — no single global assumption.</p>
<h2>Using it</h2>
<p>The tool is published to PyPI, so the quickest path (nothing installed permanently) is <code>uvx</code>:</p>
<pre><code class="language-bash">uvx generate-imports-from-plan terraform.plan &gt; imports.tf
</code></pre>
<p>If you don't have <a href="https://docs.astral.sh/uv/"><code>uv</code></a>, install it (<code>pip install uv</code>, or <code>winget install astral-sh.uv</code> on Windows), or install the tool directly with pip/pipx:</p>
<pre><code class="language-bash">pipx install generate-imports-from-plan
generate-imports-from-plan terraform.plan &gt; imports.tf
</code></pre>
<p>You'll need Python 3.11+ and — only for the live lookups — the Azure CLI.</p>
<h2>The workflow</h2>
<pre><code class="language-bash"># 1. Generate the plan
terraform plan -out terraform.plan

# 2. Generate import blocks interactively
generate-imports-from-plan terraform.plan &gt; imports.tf

# 3. Fill in any remaining placeholder IDs, then re-plan and apply
terraform plan -out terraform.plan
terraform apply terraform.plan
</code></pre>
<p>The tool is interactive and decides what to do per resource:</p>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Behaviour</th>
</tr>
</thead>
<tbody><tr>
<td>Complete formula-based ID</td>
<td>Emitted immediately, no prompt</td>
</tr>
<tr>
<td>Cross-plan ID (depends on another resource in the plan)</td>
<td>Resolved and emitted automatically</td>
</tr>
<tr>
<td>Entra ID resource or role assignment</td>
<td>Shows the <code>az</code> command and asks for confirmation</td>
</tr>
<tr>
<td>Unresolvable ID</td>
<td>Shows which attribute is computed and its HCL reference chain; asks whether to skip</td>
</tr>
<tr>
<td>Unsupported import (e.g. <code>azuread_application_password</code>)</td>
<td>Emits a comment block instead</td>
</tr>
</tbody></table>
<p>Use <code>--yes</code> to accept everything without prompting, or <code>--no</code> for a dry run.</p>
<p>Sample output:</p>
<pre><code class="language-hcl">import {
  to = module.core.azurerm_resource_group.this
  id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-myapp-dev-we-01"
}

import {
  to = module.core.azuread_application.default["my-app"]
  id = "/applications/00000000-0000-0000-0000-000000000000"
}

# import not supported for azuread_application_password:
# module.core.azuread_application_password.default["my-app"]
</code></pre>
<h2>Extending it</h2>
<p>Adding support for a new resource type is usually a one-line formula. For example, in <code>generate_imports/ids.py</code>:</p>
<pre><code class="language-python">"azurerm_my_resource":
    lambda a, s: _arm(s, _str(a, "resource_group_name"),
                      "Microsoft.MyNamespace/myResources", _str(a, "name")),
</code></pre>
<p>For the trickier cases there are also cross-plan resolvers (derive an ID from a sibling resource) and live resolvers (<code>az</code> CLI). The repo's <code>docs/resolvers.md</code> walks through all three.</p>
<h2>Links</h2>
<ul>
<li>📦 PyPI: <a href="https://pypi.org/project/generate-imports-from-plan/">generate-imports-from-plan</a></li>
<li>💻 Source &amp; docs: <a href="https://github.com/cveld/terraform-importer">github.com/cveld/terraform-importer</a></li>
</ul>
<p>If you try it on your own environment, I'd love to hear which resource types you hit that aren't covered yet — issues and PRs are welcome.</p>
]]></content:encoded></item><item><title><![CDATA[My blog platform history]]></title><description><![CDATA[https://www.linkedin.com/in/carlintveld/ - regular posts  
https://medium.com/@carl.intveld - last post November 2022
https://cveld.blogspot.com/ - last post September 2020]]></description><link>https://blog.carlintveld.nl/my-blog-platform-history</link><guid isPermaLink="true">https://blog.carlintveld.nl/my-blog-platform-history</guid><dc:creator><![CDATA[Carl in 't Veld]]></dc:creator><pubDate>Sun, 10 Sep 2023 16:06:43 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://www.linkedin.com/in/carlintveld/">https://www.linkedin.com/in/carlintveld/</a> - regular posts  </p>
<p><a href="https://medium.com/@carl.intveld">https://medium.com/@carl.intveld</a> - last post November 2022</p>
<p><a href="https://cveld.blogspot.com/">https://cveld.blogspot.com/</a> - last post September 2020</p>
]]></content:encoded></item></channel></rss>