<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Simon Foster</title>
    <description>The latest articles on Forem by Simon Foster (@funkysi1701).</description>
    <link>https://forem.com/funkysi1701</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F135123%2F43b0bdb7-8d56-4050-b9a8-c55e762a5020.jpg</url>
      <title>Forem: Simon Foster</title>
      <link>https://forem.com/funkysi1701</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/funkysi1701"/>
    <language>en</language>
    <item>
      <title>AI Won't Replace Developers, But It Will Redefine Us</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Sat, 14 Mar 2026 09:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/ai-wont-replace-developers-but-it-will-redefine-us-n5m</link>
      <guid>https://forem.com/funkysi1701/ai-wont-replace-developers-but-it-will-redefine-us-n5m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction – The Shift We are Living Through
&lt;/h2&gt;

&lt;p&gt;As I write this, I have just been made redundant. AI is not being used to explain this particular redundancy, but it is being used to explain many redundancies across the industry.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I just got laid off..... Again...... I am still in shock. I loved my new job and was creating great impact but here we are again. Layoffs are not personal so I am ok but yeh will be looking for something new...... Again......&lt;/p&gt;

&lt;p&gt;— Debbie O'Brien (&lt;a class="mentioned-user" href="https://dev.to/debs_obrien"&gt;@debs_obrien&lt;/a&gt;) &lt;a href="https://twitter.com/debs_obrien/status/2027171846743892254?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;February 27, 2026&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;I listened to an excellent talk at &lt;a href="https://www.funkysi1701.com/ndc-london-2026" rel="noopener noreferrer"&gt;NDC London&lt;/a&gt;by Debbie O’Brien about using AI to do amazing things with &lt;a href="https://youtu.be/Numb52aJkJw" rel="noopener noreferrer"&gt;Playwright MCP&lt;/a&gt;. If people who are using AI to its fullest are losing their jobs to AI, what hope is there for our industry? Are we all going to be writing AI prompts and that’s it?&lt;/p&gt;

&lt;p&gt;But let’s stop for a minute. Software development is an ever-changing industry. There is always something new to learn and this AI craze is no different.&lt;/p&gt;

&lt;p&gt;The role of the developer has always shifted as tools improved. We moved from writing assembly to high-level languages, from manual deployments to automated pipelines, and from managing servers to deploying infrastructure with a few commands.&lt;/p&gt;

&lt;p&gt;The real question is how our role is changing and how we need to adapt and make the most of the new tools available to us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Actually Changed?
&lt;/h2&gt;

&lt;p&gt;There’s a lot of noise around AI in software development. Headlines swing between “AI will replace developers” and “AI is just autocomplete.” The truth, as usual, sits somewhere in the middle.&lt;/p&gt;

&lt;p&gt;But something real has changed. Not just the tools we use, but the speed, shape, and workflow of software development.&lt;/p&gt;

&lt;h3&gt;
  
  
  From Reactive to Proactive
&lt;/h3&gt;

&lt;p&gt;For years, developer productivity tools focused on helping us type faster.&lt;/p&gt;

&lt;p&gt;We had IntelliSense, snippets, code generation tools, and IDE refactorings. These were useful, but they were fundamentally reactive. They waited for the developer to start typing and then offered suggestions.&lt;/p&gt;

&lt;p&gt;AI coding tools have crossed a different threshold.&lt;/p&gt;

&lt;p&gt;Instead of simply completing the next line, they can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate entire classes or modules&lt;/li&gt;
&lt;li&gt;Suggest architecture patterns&lt;/li&gt;
&lt;li&gt;Write tests&lt;/li&gt;
&lt;li&gt;Perform multi-file refactors&lt;/li&gt;
&lt;li&gt;Explain unfamiliar codebases&lt;/li&gt;
&lt;li&gt;Propose fixes for bugs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important shift is this:&lt;/p&gt;

&lt;p&gt;The tool is no longer just responding to the code — it’s responding to the intent.&lt;/p&gt;

&lt;p&gt;You describe a goal, and the AI attempts to produce the implementation.&lt;/p&gt;

&lt;p&gt;This moves AI from being an autocomplete engine to something closer to an execution partner.&lt;/p&gt;

&lt;p&gt;It’s not autonomous in the sense of replacing developers, but it does change the relationship between the developer and the code.&lt;/p&gt;

&lt;p&gt;We’re no longer writing every line ourselves. Increasingly, we are directing the creation of code rather than manually constructing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cost of a First Draft Has Collapsed
&lt;/h3&gt;

&lt;p&gt;Historically, one of the hidden costs of software development was simply getting started.&lt;/p&gt;

&lt;p&gt;Creating a prototype involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up project structure&lt;/li&gt;
&lt;li&gt;Writing boilerplate&lt;/li&gt;
&lt;li&gt;Defining models&lt;/li&gt;
&lt;li&gt;Creating basic tests&lt;/li&gt;
&lt;li&gt;Wiring components together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this work was intellectually difficult, but it took time.&lt;/p&gt;

&lt;p&gt;AI tools have dramatically reduced the cost of that first draft.&lt;/p&gt;

&lt;p&gt;You can now describe a feature and quickly get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A rough implementation&lt;/li&gt;
&lt;li&gt;Basic unit tests&lt;/li&gt;
&lt;li&gt;A starting architecture&lt;/li&gt;
&lt;li&gt;A prototype that actually runs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This doesn’t mean the output is perfect. In fact, it often isn’t. But the barrier to experimentation has dropped significantly.&lt;/p&gt;

&lt;p&gt;Ideas that might have taken half a day to prototype can now be explored in minutes.&lt;/p&gt;

&lt;p&gt;And that has a subtle but powerful effect on development culture:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When experimentation becomes cheap, developers try more ideas.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This encourages iteration, exploration, and rapid feedback in ways that previously required more discipline and effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing Code Is No Longer the Bottleneck
&lt;/h3&gt;

&lt;p&gt;One of the most surprising outcomes of AI coding tools is that they reveal something many experienced developers already suspected:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Typing code was never the hardest part of software development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The real difficulty lies elsewhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding the problem&lt;/li&gt;
&lt;li&gt;Designing a clean solution&lt;/li&gt;
&lt;li&gt;Managing complexity&lt;/li&gt;
&lt;li&gt;Communicating intent to other developers&lt;/li&gt;
&lt;li&gt;Maintaining systems over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can produce large volumes of code very quickly. But that doesn’t automatically translate into good software.&lt;/p&gt;

&lt;p&gt;If anything, it shifts the constraint.&lt;/p&gt;

&lt;p&gt;The bottleneck is no longer how fast code can be written.&lt;/p&gt;

&lt;p&gt;The bottleneck is now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How clearly can problems be defined&lt;/li&gt;
&lt;li&gt;How well can systems be designed&lt;/li&gt;
&lt;li&gt;How effectively can code be reviewed and maintained&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, AI accelerates the mechanical part of development, but the thinking part becomes even more important.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Hasn’t Changed (But People Think It Has)
&lt;/h2&gt;

&lt;p&gt;With every major technological shift, there’s a temptation to assume everything is different now. AI has amplified that feeling in software development. When tools can generate large amounts of code in seconds, it’s easy to believe the fundamentals of the profession have been rewritten.&lt;/p&gt;

&lt;p&gt;But when you look closely at real software projects, something interesting appears: many of the hardest parts of software development haven’t changed at all.&lt;/p&gt;

&lt;p&gt;AI has accelerated the mechanics of coding, but the underlying challenges of building reliable, useful software are still very much human problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Requirements Is Still the Hardest Problem
&lt;/h3&gt;

&lt;p&gt;Software projects rarely fail because developers can’t write code. They fail because the problem wasn’t clearly understood in the first place.&lt;/p&gt;

&lt;p&gt;AI tools can generate implementations, but they rely entirely on the input they’re given. If the requirement is vague, incomplete, or contradictory, the output will reflect that.&lt;/p&gt;

&lt;p&gt;Consider how requirements often arrive in real projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A stakeholder describes a problem in business language.&lt;/li&gt;
&lt;li&gt;Important edge cases are discovered later.&lt;/li&gt;
&lt;li&gt;Different teams have slightly different expectations.&lt;/li&gt;
&lt;li&gt;Requirements evolve as users interact with the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this has changed with AI.&lt;/p&gt;

&lt;p&gt;The ability to ask the right questions, clarify ambiguity, and translate business needs into technical solutions remains one of the most valuable skills a developer can have.&lt;/p&gt;

&lt;p&gt;In fact, as code generation becomes easier, clear problem definition becomes even more important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture and Trade-Offs Still Matter
&lt;/h3&gt;

&lt;p&gt;AI can suggest design patterns, propose architectures, and generate project structures. But good software architecture isn’t just about picking the right pattern.&lt;/p&gt;

&lt;p&gt;It’s about making trade-offs.&lt;/p&gt;

&lt;p&gt;Questions like these still require human judgment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should this be a microservice or part of the monolith?&lt;/li&gt;
&lt;li&gt;Is the added complexity of caching worth the performance gain?&lt;/li&gt;
&lt;li&gt;What level of abstraction will make this system maintainable in five years?&lt;/li&gt;
&lt;li&gt;Where should the boundaries between components sit?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These decisions depend heavily on context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Team size&lt;/li&gt;
&lt;li&gt;Deployment environment&lt;/li&gt;
&lt;li&gt;Operational constraints&lt;/li&gt;
&lt;li&gt;Long-term maintenance costs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can offer suggestions, but it cannot fully understand the organisational and operational realities of the system it’s helping to build.&lt;/p&gt;

&lt;p&gt;That responsibility still sits with the developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accountability Doesn’t Disappear
&lt;/h3&gt;

&lt;p&gt;One thing that definitely hasn’t changed is ownership.&lt;/p&gt;

&lt;p&gt;When software breaks in production, nobody blames the IDE. The same principle applies to AI.&lt;/p&gt;

&lt;p&gt;If an AI-generated query deletes the wrong data, or a generated implementation introduces a subtle performance issue, the responsibility still lies with the developer who reviewed and shipped the code.&lt;/p&gt;

&lt;p&gt;Production systems still require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Careful testing&lt;/li&gt;
&lt;li&gt;Monitoring and observability&lt;/li&gt;
&lt;li&gt;Security awareness&lt;/li&gt;
&lt;li&gt;Performance tuning&lt;/li&gt;
&lt;li&gt;Ongoing maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI can assist with many of these areas, but it doesn’t remove the need for human accountability.&lt;/p&gt;

&lt;p&gt;At the end of the day, someone has to understand the system well enough to take responsibility for it.&lt;/p&gt;

&lt;p&gt;And that hasn’t changed at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  The New Developer Skill Stack
&lt;/h2&gt;

&lt;p&gt;If we accept that AI has collapsed the cost of a first draft, then the skill stack shifts upward.&lt;/p&gt;

&lt;p&gt;Not because the old skills are irrelevant, but because they’re no longer the limiting factor as often.&lt;/p&gt;

&lt;p&gt;Syntax still matters. Fundamentals still matter. But the competitive advantage moves towards the parts of the job that are hard to automate: precision, judgment, and system-level thinking.&lt;/p&gt;

&lt;p&gt;Think of it as an evolution of the same craft.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompting as a Technical Skill
&lt;/h3&gt;

&lt;p&gt;“Prompting” sounds fluffy until you realise what it actually is in practice: specifying a problem clearly enough that another agent (human or machine) can make progress without guessing.&lt;/p&gt;

&lt;p&gt;The better you are at being precise, the more useful the tool becomes.&lt;/p&gt;

&lt;p&gt;That means getting specific about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The goal (what “done” looks like)&lt;/li&gt;
&lt;li&gt;The constraints (performance, security, backward compatibility, tech stack)&lt;/li&gt;
&lt;li&gt;Inputs/outputs and edge cases&lt;/li&gt;
&lt;li&gt;The environment (language version, framework, database, deployment model)&lt;/li&gt;
&lt;li&gt;The trade-offs you care about (simplicity vs flexibility, latency vs cost)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you ask an AI to “build a feature”, you’ll get a lot of code, but it will almost always bake in assumptions you didn’t mean to make.&lt;/p&gt;

&lt;p&gt;The best results come when you treat it like a junior developer with infinite typing speed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ask it to propose an approach first&lt;/li&gt;
&lt;li&gt;Get it to list assumptions and risks&lt;/li&gt;
&lt;li&gt;Then implement one slice at a time (and keep the changes small)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, iterative refinement becomes the workflow.&lt;/p&gt;

&lt;p&gt;You rarely get the best output on the first prompt. But you can converge quickly if you review the result, point out what is wrong or missing, and re-run with tighter guidance.&lt;/p&gt;

&lt;p&gt;In other words, prompting is less about “magic words” and more about feedback loops.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Review Becomes Critical Thinking
&lt;/h3&gt;

&lt;p&gt;When AI can generate 200 lines of code in seconds, reviewing becomes the high-leverage skill.&lt;/p&gt;

&lt;p&gt;That review can’t just be “does it compile” or “does it look idiomatic”. It has to be critical thinking.&lt;/p&gt;

&lt;p&gt;AI-generated code often fails in ways that are subtle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It handles the happy path beautifully and ignores weird real-world inputs&lt;/li&gt;
&lt;li&gt;It silently changes behaviour (especially around dates, nulls, and defaults)&lt;/li&gt;
&lt;li&gt;It introduces concurrency bugs that only show up under load&lt;/li&gt;
&lt;li&gt;It uses a library/API incorrectly but convincingly&lt;/li&gt;
&lt;li&gt;It passes tests that are too shallow to be meaningful&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most important thing to review is not the code itself, but the assumptions underneath it.&lt;/p&gt;

&lt;p&gt;I find it useful to explicitly ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does this code assume about the data?&lt;/li&gt;
&lt;li&gt;What does it assume about ordering, timing, and retries?&lt;/li&gt;
&lt;li&gt;What happens when dependencies fail?&lt;/li&gt;
&lt;li&gt;What would I see in logs/metrics if this breaks in production?&lt;/li&gt;
&lt;li&gt;What tests would convince me this is correct?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where experienced developers become even more valuable: not because they can type faster, but because they’ve seen how systems fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Systems Thinking &amp;gt; Syntax Knowledge
&lt;/h3&gt;

&lt;p&gt;AI is good at syntax and local patterns. It is much worse at understanding the bigger picture.&lt;/p&gt;

&lt;p&gt;The developers who thrive in this shift will be the ones who can hold the system in their head:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How data flows through the application&lt;/li&gt;
&lt;li&gt;Where the boundaries are between components&lt;/li&gt;
&lt;li&gt;What needs to be observable in production (logs, metrics, traces)&lt;/li&gt;
&lt;li&gt;What makes the codebase maintainable for the next person&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Systems thinking is what stops an AI-generated “solution” from becoming a future incident.&lt;/p&gt;

&lt;p&gt;It’s also why the old advice from &lt;a href="https://www.funkysi1701.com/pragmatic-programmer" rel="noopener noreferrer"&gt;The Pragmatic Programmer&lt;/a&gt;matters even more now: remember the big picture.&lt;/p&gt;

&lt;p&gt;Not “can we generate this function”, but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this the simplest thing that could work?&lt;/li&gt;
&lt;li&gt;Can we operate it at 2am?&lt;/li&gt;
&lt;li&gt;Can we change it safely in six months?&lt;/li&gt;
&lt;li&gt;Are we making the system easier to understand or harder?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI accelerates output, but it doesn’t automatically improve outcomes, and that creates real risk if we aren’t careful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Risk: Shallow Engineers
&lt;/h2&gt;

&lt;p&gt;The biggest danger is not that AI replaces us.&lt;/p&gt;

&lt;p&gt;The biggest danger is that it makes us lazy.&lt;/p&gt;

&lt;p&gt;If we outsource too much thinking to tools, we can accidentally create a generation of engineers who can ship quickly but cannot explain what they shipped, why it works, or how to fix it when it fails.&lt;/p&gt;

&lt;p&gt;That risk shows up in subtle ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copying generated code without understanding the trade-offs&lt;/li&gt;
&lt;li&gt;Accepting tests because they are green, even when they don’t test anything meaningful&lt;/li&gt;
&lt;li&gt;Mistaking confidence in the AI’s tone for correctness in the implementation&lt;/li&gt;
&lt;li&gt;Losing touch with fundamentals like debugging, data structures, networking, and performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is especially dangerous under delivery pressure. If a team rewards speed above all else, AI can amplify the wrong behaviour: lots of output, little understanding.&lt;/p&gt;

&lt;p&gt;And that debt compounds.&lt;/p&gt;

&lt;p&gt;Six months later, nobody trusts the codebase, incidents increase, and every change becomes risky.&lt;/p&gt;

&lt;p&gt;So yes, AI can make us faster. But if we use it without discipline, it can also make us shallow.&lt;/p&gt;

&lt;p&gt;The antidote is simple, even if not always easy: use AI to accelerate execution, not to bypass understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Opportunity: Increased Leverage (For the Right People)
&lt;/h2&gt;

&lt;p&gt;The upside is huge for developers who combine AI with strong engineering habits.&lt;/p&gt;

&lt;p&gt;When you can generate a solid first draft in minutes, you can spend more time where value actually lives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better problem framing&lt;/li&gt;
&lt;li&gt;Better architecture decisions&lt;/li&gt;
&lt;li&gt;Better test strategy&lt;/li&gt;
&lt;li&gt;Better operational design&lt;/li&gt;
&lt;li&gt;Better developer experience for your team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where leverage appears.&lt;/p&gt;

&lt;p&gt;One thoughtful developer with AI support can now do the kind of end-to-end work that used to require more hand-offs and more waiting.&lt;/p&gt;

&lt;p&gt;Not because they became magically smarter overnight, but because the mechanical drag has been reduced.&lt;/p&gt;

&lt;p&gt;If your fundamentals are strong, AI multiplies your impact.&lt;/p&gt;

&lt;p&gt;If your fundamentals are weak, AI multiplies your mistakes.&lt;/p&gt;

&lt;p&gt;That is the real divide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Advice for Developers
&lt;/h2&gt;

&lt;p&gt;If you want to stay relevant and thrive in this shift, here is what I would do right now.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Treat AI Output as a Draft, Not Truth
&lt;/h3&gt;

&lt;p&gt;Assume every generated answer is a proposal.&lt;/p&gt;

&lt;p&gt;Read it. Challenge it. Test it.&lt;/p&gt;

&lt;p&gt;Never merge code you cannot explain to another developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Strengthen Your Core Engineering Muscles
&lt;/h3&gt;

&lt;p&gt;Double down on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;Testing strategy&lt;/li&gt;
&lt;li&gt;System design&lt;/li&gt;
&lt;li&gt;Observability&lt;/li&gt;
&lt;li&gt;Performance and security fundamentals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are durable skills and AI makes them more valuable, not less.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Get Better at Problem Framing
&lt;/h3&gt;

&lt;p&gt;Before asking AI to implement anything, write down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The problem in one sentence&lt;/li&gt;
&lt;li&gt;The constraints&lt;/li&gt;
&lt;li&gt;The non-goals&lt;/li&gt;
&lt;li&gt;The acceptance criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This habit improves both the AI output and your own clarity.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Work in Small, Reviewable Slices
&lt;/h3&gt;

&lt;p&gt;Ask AI for smaller changes, not giant rewrites.&lt;/p&gt;

&lt;p&gt;Small slices make it easier to reason about behaviour, review quality, and rollback safely.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Raise the Bar for Code Reviews
&lt;/h3&gt;

&lt;p&gt;Review assumptions, failure modes, and operational impact, not just style.&lt;/p&gt;

&lt;p&gt;A useful question in every review: “What breaks first in production?”&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Build a Personal AI Workflow
&lt;/h3&gt;

&lt;p&gt;Create repeatable prompt patterns for tasks you do often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing tests&lt;/li&gt;
&lt;li&gt;Refactoring legacy code&lt;/li&gt;
&lt;li&gt;Generating migration scripts&lt;/li&gt;
&lt;li&gt;Creating docs from code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Treat these as reusable tools in your engineering toolbox.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Keep Shipping Real Things
&lt;/h3&gt;

&lt;p&gt;The best learning still comes from production reality.&lt;/p&gt;

&lt;p&gt;Build, deploy, monitor, and improve. Feedback from real users teaches lessons no model can replace.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means for Juniors vs Seniors
&lt;/h2&gt;

&lt;p&gt;AI changes the game for everyone, but not in exactly the same way.&lt;/p&gt;

&lt;p&gt;For junior developers, AI can be a force multiplier for learning if used correctly.&lt;/p&gt;

&lt;p&gt;It can explain unfamiliar concepts, generate examples, and speed up experimentation. But juniors still need mentorship and deliberate practice to build judgment.&lt;/p&gt;

&lt;p&gt;If you skip the fundamentals and rely only on generated output, you’ll progress fast on paper and slowly in reality.&lt;/p&gt;

&lt;p&gt;For senior developers, the expectation shifts from individual output to system-level impact.&lt;/p&gt;

&lt;p&gt;Seniors become the multipliers of multipliers: setting standards, designing guardrails, mentoring teams, and ensuring AI usage improves quality rather than eroding it.&lt;/p&gt;

&lt;p&gt;In short:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Juniors should use AI to learn faster&lt;/li&gt;
&lt;li&gt;Seniors should use AI to scale better decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both groups win when curiosity stays high and ego stays low.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Question: Are We Becoming Directors Instead of Builders?
&lt;/h2&gt;

&lt;p&gt;Partly, yes, and that is not a bad thing.&lt;/p&gt;

&lt;p&gt;More of our time is moving toward direction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defining intent&lt;/li&gt;
&lt;li&gt;Making trade-offs&lt;/li&gt;
&lt;li&gt;Reviewing outputs&lt;/li&gt;
&lt;li&gt;Orchestrating systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But we are still builders.&lt;/p&gt;

&lt;p&gt;Good directors in software are grounded in reality. They understand implementation details, constraints, and failure modes. They can still get into the code when needed.&lt;/p&gt;

&lt;p&gt;So the role is not “director instead of builder.” It is “builder with broader leverage.”&lt;/p&gt;

&lt;p&gt;We are not giving up craftsmanship.&lt;/p&gt;

&lt;p&gt;We are applying craftsmanship at a higher level of abstraction.&lt;/p&gt;

&lt;p&gt;But let’s be honest about the uncomfortable part of this question.&lt;/p&gt;

&lt;p&gt;If one developer with AI can now do the work that previously required three, the natural business response is to hire fewer developers. That is already happening. It is likely to continue.&lt;/p&gt;

&lt;p&gt;The optimistic framing — that AI creates more software demand and therefore more developer jobs — is plausible in the long run. But it does not help the developer who is looking for work today, and it does not guarantee the transition is smooth or fair.&lt;/p&gt;

&lt;p&gt;I am not going to pretend the economics are simple.&lt;/p&gt;

&lt;p&gt;What I do believe is that developers who understand systems, take ownership of quality, and use AI as a serious tool will remain competitive for the work that does exist. That work will increasingly require judgment, not just output.&lt;/p&gt;

&lt;p&gt;The shift is real. The disruption is real. But the craft is not going away — it is just raising its entry bar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion – My Opinion
&lt;/h2&gt;

&lt;p&gt;I do not believe AI will eliminate software developers.&lt;/p&gt;

&lt;p&gt;I do believe it will split the field.&lt;/p&gt;

&lt;p&gt;Developers who keep learning, think in systems, and take ownership of outcomes will become more effective — not despite AI, but partly because of it.&lt;/p&gt;

&lt;p&gt;Developers who treat AI as a shortcut, blindly trusting its output without understanding the system underneath, will increasingly struggle to hold ground.&lt;/p&gt;

&lt;p&gt;The disruption happening right now is real. But I think the long-term demand for engineers who can reason clearly, design well, and take responsibility for what they ship is going to hold.&lt;/p&gt;

&lt;p&gt;The path forward is straightforward even if the road is uncertain: stay curious, deepen the fundamentals, use AI seriously, and never stop questioning the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Call to Action
&lt;/h2&gt;

&lt;p&gt;As mentioned at the start of this article, I am a .NET developer looking for my next role. If you know of any opportunities where I could help, please reach out.&lt;/p&gt;

&lt;p&gt;And if you are in the same position, message me as well. We are stronger when we support each other.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>career</category>
      <category>engineering</category>
    </item>
    <item>
      <title>Azure Container Registry vs AWS Elastic Container Registry: A Developer's Comparison</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 23 Feb 2026 20:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/azure-container-registry-vs-aws-elastic-container-registry-a-developers-comparison-mkf</link>
      <guid>https://forem.com/funkysi1701/azure-container-registry-vs-aws-elastic-container-registry-a-developers-comparison-mkf</guid>
      <description>&lt;p&gt;As someone who works with both Azure and AWS regularly, I’ve had hands-on experience with both &lt;strong&gt;Azure Container Registry (ACR)&lt;/strong&gt; and &lt;strong&gt;AWS Elastic Container Registry (ECR)&lt;/strong&gt;. Recently, while migrating my blog’s deployment pipeline to use ECR, I encountered some interesting differences that are worth sharing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Basics
&lt;/h2&gt;

&lt;p&gt;Both services provide secure, private Docker container registries that integrate seamlessly with their respective cloud ecosystems. They’re designed to store, manage, and deploy container images for your applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure Container Registry (ACR)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fully managed Docker registry service&lt;/li&gt;
&lt;li&gt;Integrated with Azure Kubernetes Service (AKS), Azure Container Instances, and other Azure services&lt;/li&gt;
&lt;li&gt;Supports Docker images and OCI artifacts&lt;/li&gt;
&lt;li&gt;Available in multiple tiers: Basic, Standard, Premium&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Elastic Container Registry (ECR)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fully managed Docker container registry&lt;/li&gt;
&lt;li&gt;Integrated with Amazon ECS, EKS, and AWS Lambda&lt;/li&gt;
&lt;li&gt;Supports Docker images and OCI artifacts&lt;/li&gt;
&lt;li&gt;Single pricing model with pay-as-you-go&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;OCI artifacts&lt;/strong&gt; are container-related objects that follow the Open Container Initiative (OCI) specifications. Originally, OCI defined standards for Docker container images, but now it covers a broader range of artifacts—including Helm charts, software bill of materials (SBOMs), and other files—stored in container registries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing Comparison
&lt;/h2&gt;

&lt;p&gt;This is where things get interesting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure Container Registry
&lt;/h3&gt;

&lt;p&gt;ACR uses a &lt;strong&gt;tiered pricing model&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basic&lt;/strong&gt; : £4.23/month + storage (£0.083/GB) + bandwidth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard&lt;/strong&gt; : £16.93/month + storage (£0.083/GB) + bandwidth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Premium&lt;/strong&gt; : £42.32/month + storage (£0.083/GB) + bandwidth + geo-replication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Premium tier adds features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Geo-replication across Azure regions&lt;/li&gt;
&lt;li&gt;Content trust for image signing&lt;/li&gt;
&lt;li&gt;Private link with private endpoints&lt;/li&gt;
&lt;li&gt;Enhanced throughput&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Elastic Container Registry
&lt;/h3&gt;

&lt;p&gt;ECR uses &lt;strong&gt;simple pay-as-you-go pricing&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Storage&lt;/strong&gt; : $0.10/GB per month (£0.08/GB)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Transfer&lt;/strong&gt; : Standard AWS data transfer pricing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No base fee&lt;/strong&gt; - you only pay for what you use&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authentication &amp;amp; Setup
&lt;/h2&gt;

&lt;p&gt;This is where I hit some friction with ECR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure Container Registry
&lt;/h3&gt;

&lt;p&gt;ACR authentication is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Login using Azure CLI
az acr login --name myregistry

# Or use service principal
docker login myregistry.azurecr.io -u $SP_ID -p $SP_PASSWORD

# In pipelines, it's seamless with Azure DevOps tasks

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Azure DevOps integration is particularly smooth - the &lt;code&gt;Docker@2&lt;/code&gt; task handles authentication automatically when using service connections.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Elastic Container Registry
&lt;/h3&gt;

&lt;p&gt;ECR authentication requires an extra step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Get login password and pipe to docker login
aws ecr get-login-password --region eu-north-1 | \
 docker login --username AWS --password-stdin \
 111111111111.dkr.ecr.eu-north-1.amazonaws.com

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my Azure Pipelines, I had to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install AWS CLI (not included by default)&lt;/li&gt;
&lt;li&gt;Configure AWS credentials as environment variables&lt;/li&gt;
&lt;li&gt;Run the login command manually
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- task: CmdLine@2
 displayName: "Install AWS CLI"
 inputs:
 script: |
 curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
 unzip -q awscliv2.zip
 ./aws/install --bin-dir ~/.local/bin --install-dir ~/.local/aws-cli

- task: CmdLine@2
 displayName: "Login to ECR"
 env:
 AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID)
 AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
 inputs:
 script: |
 export PATH=$HOME/.local/bin:$PATH
 aws ecr get-login-password --region eu-north-1 | \
 docker login --username AWS --password-stdin \
 111111111111.dkr.ecr.eu-north-1.amazonaws.com

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Winner&lt;/strong&gt; : ACR (simpler authentication, especially in Azure DevOps)&lt;/p&gt;

&lt;h2&gt;
  
  
  Image Naming &amp;amp; URLs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Azure Container Registry
&lt;/h3&gt;

&lt;p&gt;Clean, predictable naming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myregistry.azurecr.io/myapp:v1.0.0
myregistry.azurecr.io/namespace/myapp:latest

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AWS Elastic Container Registry
&lt;/h3&gt;

&lt;p&gt;Includes your AWS account ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;111111111111.dkr.ecr.eu-north-1.amazonaws.com/funkysi1701/blog:10.1.1.123-develop

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The account ID in the URL may pose a security consideration - it’s visible to anyone who has access to your images or deployment configs. Attackers could use the account ID for targeted phishing, social engineering, or brute-force attacks. If combined with leaked credentials or misconfigured permissions, it makes it easier for someone to identify and target your AWS resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Winner&lt;/strong&gt; : ACR (cleaner URLs)&lt;/p&gt;

&lt;h2&gt;
  
  
  Features Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;ACR&lt;/th&gt;
&lt;th&gt;ECR&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Image Scanning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Premium tier&lt;/td&gt;
&lt;td&gt;✅ Included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vulnerability Scanning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Premium tier&lt;/td&gt;
&lt;td&gt;✅ Basic + Enhanced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Geo-Replication&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Premium tier&lt;/td&gt;
&lt;td&gt;❌ Manual setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Webhooks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ All tiers&lt;/td&gt;
&lt;td&gt;✅ Included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Image Retention Policies&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ All tiers&lt;/td&gt;
&lt;td&gt;✅ Lifecycle policies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Private Endpoints&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Premium tier&lt;/td&gt;
&lt;td&gt;✅ VPC endpoints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Image Signing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Content Trust&lt;/td&gt;
&lt;td&gt;✅ AWS Signer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cross-Region Replication&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Premium&lt;/td&gt;
&lt;td&gt;❌ Requires manual setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Import from Docker Hub&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Built-in&lt;/td&gt;
&lt;td&gt;❌ Manual&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Integration with Kubernetes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ACR + AKS
&lt;/h3&gt;

&lt;p&gt;Seamless integration with Azure Kubernetes Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Attach ACR to AKS cluster
az aks update --name myaks --resource-group mygroup --attach-acr myregistry

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AKS nodes can pull images without credentials. Magical.&lt;/p&gt;

&lt;h3&gt;
  
  
  ECR + EKS
&lt;/h3&gt;

&lt;p&gt;Also integrated, but requires IAM roles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Attach IAM policy to EKS node role
aws iam attach-role-policy \
 --role-name eksNodeRole \
 --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works well once configured, but requires understanding of AWS IAM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Winner&lt;/strong&gt; : Tie (both integrate well with their respective K8s offerings)&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer Experience
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I Like About ACR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Simple authentication in Azure DevOps&lt;/li&gt;
&lt;li&gt;Clean, readable image URLs&lt;/li&gt;
&lt;li&gt;Excellent documentation&lt;/li&gt;
&lt;li&gt;Azure Portal UI is intuitive&lt;/li&gt;
&lt;li&gt;Helm chart support is first-class&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I Like About ECR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No minimum cost - truly pay-per-use&lt;/li&gt;
&lt;li&gt;Built-in vulnerability scanning at all levels&lt;/li&gt;
&lt;li&gt;AWS CLI is powerful and ubiquitous&lt;/li&gt;
&lt;li&gt;Great for multi-cloud strategies&lt;/li&gt;
&lt;li&gt;Excellent API and automation support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pain Points
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ACR&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Premium tier gets expensive for features that should be standard&lt;/li&gt;
&lt;li&gt;Minimum £4/month even for tiny projects&lt;/li&gt;
&lt;li&gt;Geo-replication requires Premium tier (£42/month)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Geo-replication is important because it allows your container images and artifacts to be stored and accessed in multiple geographic regions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ECR&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication is more complex outside AWS&lt;/li&gt;
&lt;li&gt;Account ID in image URL&lt;/li&gt;
&lt;li&gt;Requires AWS CLI installation in non-AWS CI/CD&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Real-World Experience
&lt;/h2&gt;

&lt;p&gt;For my blog’s deployment pipeline, I recently migrated from ACR to ECR primarily for &lt;strong&gt;cost reasons&lt;/strong&gt;. Here’s what I learned:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Migration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before (ACR)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cost: ~£4.50/month (Basic tier + minimal storage)&lt;/li&gt;
&lt;li&gt;Authentication: Seamless in Azure DevOps&lt;/li&gt;
&lt;li&gt;Image URLs: Clean and simple&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After (ECR)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cost: £0/month (due to free trial)&lt;/li&gt;
&lt;li&gt;Authentication: Required custom pipeline steps&lt;/li&gt;
&lt;li&gt;Image URLs: Include AWS account ID&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Was It Worth It?
&lt;/h3&gt;

&lt;p&gt;For my small personal project, &lt;strong&gt;yes&lt;/strong&gt; - saving money is meaningful. But the setup was more complex than I expected.&lt;/p&gt;

&lt;p&gt;For enterprise workloads, I’d still choose ACR Premium if I needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Geo-replication&lt;/li&gt;
&lt;li&gt;Content trust&lt;/li&gt;
&lt;li&gt;Azure-native integration&lt;/li&gt;
&lt;li&gt;Enterprise support&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recommendations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Choose ACR if
&lt;/h3&gt;

&lt;p&gt;✅ You’re heavily invested in Azure ecosystem&lt;br&gt;&lt;br&gt;
✅ You need geo-replication&lt;br&gt;&lt;br&gt;
✅ You want seamless AKS integration&lt;br&gt;&lt;br&gt;
✅ You value simplified authentication&lt;br&gt;&lt;br&gt;
✅ You need Azure-native compliance features&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose ECR if
&lt;/h3&gt;

&lt;p&gt;✅ You want zero minimum costs&lt;br&gt;&lt;br&gt;
✅ You’re on AWS or multi-cloud&lt;br&gt;&lt;br&gt;
✅ You need built-in vulnerability scanning&lt;br&gt;&lt;br&gt;
✅ You prefer pay-per-use pricing&lt;br&gt;&lt;br&gt;
✅ You’re comfortable with IAM and AWS CLI&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Both ACR and ECR are excellent services. Your choice should depend on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Your cloud platform&lt;/strong&gt; - Use the registry that matches your deployment target&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your budget&lt;/strong&gt; - ECR wins for small projects, ACR Premium for enterprise features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your team’s expertise&lt;/strong&gt; - Stick with what your team knows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your requirements&lt;/strong&gt; - Need geo-replication? ACR Premium. Need low-cost? ECR.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For my personal projects, I’m happy with ECR’s cost savings. For enterprise work, I still recommend ACR Premium for its advanced features and Azure integration.&lt;/p&gt;

&lt;p&gt;What’s your experience with container registries? Let me know in the comments!&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/container-registry/" rel="noopener noreferrer"&gt;Azure Container Registry Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/ecr/" rel="noopener noreferrer"&gt;AWS ECR Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-gb/pricing/details/container-registry/" rel="noopener noreferrer"&gt;ACR Pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/ecr/pricing/" rel="noopener noreferrer"&gt;ECR Pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>azure</category>
      <category>aws</category>
      <category>docker</category>
      <category>containers</category>
    </item>
    <item>
      <title>NDC London 2026</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 02 Feb 2026 20:46:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/ndc-london-2026-1cp6</link>
      <guid>https://forem.com/funkysi1701/ndc-london-2026-1cp6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5h62r8fs3rm73oxw3zry.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5h62r8fs3rm73oxw3zry.jpg" alt="Volunteering at NDC London 2026" width="738" height="896"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the second year running, I had the privilege of volunteering at NDC London – one of Europe’s premier software development conferences. This year’s event was packed with insights on AI, accessibility, testing automation, and the future of software development. If you’re interested in my first experience, check out my &lt;a href="https://www.funkysi1701.com/posts/2025/volunteering-at-ndc/" rel="noopener noreferrer"&gt;2025 report&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The volunteer experience was just as rewarding as last year – the team was fantastic, the energy was incredible, and the sense of community was palpable. In this post, I’ll focus on the talks I attended and the key insights I gained from them.&lt;/p&gt;

&lt;p&gt;As I mentioned last year, volunteering gave me a &lt;strong&gt;superpower&lt;/strong&gt; : increased confidence to network with speakers, vendors, fellow volunteers, and attendees. The connections you make at conferences like this are invaluable, and being part of the team made it even easier to engage with the community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wednesday
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Let’s Break Some WCAG Rules (Speaker: Elise Kristiansen)
&lt;/h3&gt;

&lt;p&gt;This eye-opening talk examined how pervasively websites violate Web Content Accessibility Guidelines (WCAG). For those unfamiliar, WCAG provides a framework to make web content accessible to everyone, including people with disabilities. The guidelines are organized into three conformance levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Level A&lt;/strong&gt; - The bare minimum requirements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level AA&lt;/strong&gt; - The legal requirement (what most laws mandate)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level AAA&lt;/strong&gt; - The gold standard, aspirational but not legally required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The statistics Elise shared were sobering: 15-25% of people have some form of disability (whether permanent, temporary, or situational), yet a staggering &lt;strong&gt;94.8% of websites contain at least one WCAG AA violation&lt;/strong&gt; – meaning they’re actually breaking the law.&lt;/p&gt;

&lt;p&gt;One of the most powerful demonstrations was a colour blindness test where only colour blind individuals could read certain numbers. It really drove home how design choices can inadvertently exclude significant portions of our users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WCAG compliance isn’t optional – it’s a legal requirement and moral imperative&lt;/li&gt;
&lt;li&gt;Stop using &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; for everything; HTML is semantically rich for a reason&lt;/li&gt;
&lt;li&gt;Consider learning to use a screen reader to understand user experiences better&lt;/li&gt;
&lt;li&gt;Accessibility benefits everyone, not just those with disabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Social Engineering: Hacking Humans (Speaker: Pawel Sucholbiak)
&lt;/h3&gt;

&lt;p&gt;A timely reminder that as soon as humans enter the equation, social engineering becomes a significant security risk. This talk explored various tactics malicious actors use to manipulate people into divulging confidential information or performing actions that compromise security.&lt;/p&gt;

&lt;p&gt;Pawel demonstrated real-world scenarios like phishing emails that appear to come from trusted colleagues, pretexting phone calls where attackers impersonate IT support, and how seemingly innocent information shared on social media can be weaponized. The human element remains the weakest link in any security chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supercharged Testing: AI-Powered Workflows with Playwright + MCP (Speaker: Debbie O’Brien)
&lt;/h3&gt;

&lt;p&gt;I’d heard Debbie discuss the Playwright MCP (Model Context Protocol) on .NET Rocks, but seeing it demonstrated live was transformative. This session showed how AI can dramatically enhance testing workflows by understanding test intent and generating Playwright test code.&lt;/p&gt;

&lt;p&gt;I’ve already started using it to write some tests for this very website!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experiment with the Playwright MCP – it’s a game-changer for test automation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Undersea Cable Network (Speaker: Richard Campbell)
&lt;/h3&gt;

&lt;p&gt;Richard took us on a fascinating journey through the history of undersea telecommunications cables – the literal backbone of the internet. He explored how these cables are laid, maintained, and the significant challenges when they’re damaged (whether accidental or deliberate). It’s humbling to realize that our globally connected world depends on physical cables crossing ocean floors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Java Sucks (So C# Didn’t Have To) (Speaker: Adele Carpenter)
&lt;/h3&gt;

&lt;p&gt;An entertaining and insightful exploration of Java’s history, examining how its early popularity locked in certain design decisions that became problematic over time. Adele showed how C# learned from Java’s mistakes and made different choices that enabled better evolution. The key lesson: early success can create technical debt that’s nearly impossible to pay down.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://speakerdeck.com/97adele/java-sucks-so-c-number-didnt-have-to" rel="noopener noreferrer"&gt;View the slides&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Think Like a User: Practical UX Design Tips for Developers (Speaker: Lex Lofthouse)
&lt;/h3&gt;

&lt;p&gt;This session challenged developers to shift perspectives and consider user experience from the ground up. Lex provided practical, actionable advice for creating more intuitive interfaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.figma.com/deck/FgeSzQhT74JlnxW3iiONqj/UX-Tips?node-id=1-42&amp;amp;t=h9PIcTBhU6KRDMNU-1" rel="noopener noreferrer"&gt;View the slides&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended Reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;The Design of Everyday Things&lt;/em&gt; by Don Norman&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Thursday
&lt;/h2&gt;

&lt;h3&gt;
  
  
  OpenTelemetry At Scale 101: Intro to OpAMP (Speakers: Aakansha Priya and Adriana Villela)
&lt;/h3&gt;

&lt;p&gt;This session introduced OpAMP (Open Agent Management Protocol) for managing OpenTelemetry collectors at scale. While the scale discussed was beyond my current needs, it was valuable to understand the challenges and solutions for production observability in large distributed systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Defence of Technical Excellence (Speaker: Chris Simon)
&lt;/h3&gt;

&lt;p&gt;Chris made a compelling argument for maintaining high technical standards even under pressure to deliver quickly. Technical excellence isn’t about perfectionism – it’s about sustainable, maintainable code that serves the business long-term.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chrissimon.au/speaking/talks/a-defence-of-technical-excellence/?read-more=1" rel="noopener noreferrer"&gt;Read more about this talk&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Git Away with Murder (Speaker: Sergès Goma)
&lt;/h3&gt;

&lt;p&gt;A humorous yet practical look at Git workflows and how to recover from common (and not-so-common) Git disasters. The Q&amp;amp;A session at the end turned into a group therapy session where attendees shared their most spectacular Git mishaps and recovery stories. If you’ve ever accidentally force-pushed to main, this talk was for you!&lt;/p&gt;

&lt;h3&gt;
  
  
  Code That Writes Code: .NET Source Generators (Speaker: Glenn F. Henriksen)
&lt;/h3&gt;

&lt;p&gt;Source generators are one of .NET’s most powerful yet underutilized features. Glenn demonstrated how they can eliminate boilerplate, improve performance by moving work to compile-time, and create type-safe code generation patterns. This is definitely an area I need to explore more for my own projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Warm and Fuzzy: Semantic Search in .NET (Speaker: Jonathan “J.” Tower)
&lt;/h3&gt;

&lt;p&gt;Jonathan delivered an excellent introduction to implementing semantic search using vector databases. He covered several options for .NET developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SQL Server 2025&lt;/strong&gt; with native vector support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Cosmos DB&lt;/strong&gt; for NoSQL vector storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qdrant&lt;/strong&gt; as a specialized vector database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The talk also touched on &lt;strong&gt;Semantic Kernel&lt;/strong&gt; , which is now part of the Microsoft Agent Framework – a significant development for building intelligent applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action Items:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement semantic search for my blog to improve content discovery&lt;/li&gt;
&lt;li&gt;Explore the &lt;a href="https://github.com/trailheadtechnology/dotnet-semantic-search/tree/main/code" rel="noopener noreferrer"&gt;demo code on GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Coding 4 Fun: 8-bit Game Emulation in .NET (Speaker: Alex Thissen)
&lt;/h3&gt;

&lt;p&gt;Pure fun! Alex walked through building an 8-bit game emulator in .NET, demonstrating low-level programming concepts in a modern language. A great reminder that not everything we build needs to be “enterprise-ready” – sometimes coding is just about learning and enjoyment. Lots of shifting bytes around, so a great example of the different things you can do with .NET.&lt;/p&gt;

&lt;h2&gt;
  
  
  Friday
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keynote: AI-Powered App Development (Speaker: Steve Sanderson)
&lt;/h3&gt;

&lt;p&gt;Steve Sanderson delivered an inspiring keynote on how AI is transforming application development. The &lt;a href="https://github.com/features/copilot/cli" rel="noopener noreferrer"&gt;GitHub Copilot CLI&lt;/a&gt;was demonstrated, with a new feature added in front of our eyes. Hundreds of Pull Requests can be generated with AI, but they all need reviewing and maintaining by Software Developers and there are no easy answers for managing that.&lt;/p&gt;

&lt;h3&gt;
  
  
  What in the Hunger Games is Happening with Recruitment? (Speaker: Suzi Edwards-Alexander)
&lt;/h3&gt;

&lt;p&gt;A frank and often amusing look at the current state of tech recruitment. Suzi traced how we arrived at today’s challenging hiring landscape – from the first interview questions created by Thomas Edison, to the rise of LinkedIn and modern recruitment processes. Recruitment is broken, and there are no easy ways of fixing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Great Brain Robbery: Navigating the Dark Future of Online Manipulation (Speaker: Jeff Watkins)
&lt;/h3&gt;

&lt;p&gt;A sobering examination of how online platforms use psychological manipulation and dark patterns to exploit users’ attention and data. Jeff didn’t just highlight the problems – he offered strategies for recognizing and resisting these tactics, both as developers and as users. This talk was rather bleak reinforcing the notion that you can not trust anything you see or read online.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beyond the AI Hype: What’s Real, What’s Next (Speaker: Richard Campbell)
&lt;/h3&gt;

&lt;p&gt;Richard cut through the AI hype to examine what’s genuinely transformative versus what’s just marketing. He explored current capabilities, realistic near-term developments, and the fundamental limitations we need to understand. A perfect counterbalance to the morning’s optimistic keynote – both perspectives are necessary for making informed decisions about AI adoption.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resilient by Design (Speaker: Chris Ayers)
&lt;/h3&gt;

&lt;p&gt;The final session I attended focused on building resilient systems in Azure from the ground up. Chris covered how much downtime you can have if your SLA is 99.99% (8.6s a day see &lt;a href="https://uptime.is" rel="noopener noreferrer"&gt;uptime.is&lt;/a&gt;) – but more importantly, the mindset shift required to design for failure rather than just success. In production, it’s not &lt;em&gt;if&lt;/em&gt; things will fail, but &lt;em&gt;when&lt;/em&gt; and &lt;em&gt;how gracefully&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Networking Break: JetBrains Rider Team
&lt;/h3&gt;

&lt;p&gt;I skipped one session to have an extended conversation with the &lt;a href="https://www.jetbrains.com/rider" rel="noopener noreferrer"&gt;JetBrains Rider&lt;/a&gt;team at their booth. These unstructured conversations are often where you get the most value at conferences – I am a big fan of Visual Studio, but I have never tried Rider, this informal chat has encouraged me to download Rider and give it a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;NDC London 2026 was another incredible experience. The breadth of topics – from accessibility and UX to AI, observability, and system resilience – reflects the diverse skills modern developers need.&lt;/p&gt;

&lt;p&gt;My key takeaways from this year:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility is non-negotiable&lt;/strong&gt; – both legally and morally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI tools are here to stay&lt;/strong&gt; – learn to leverage them effectively&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical excellence matters&lt;/strong&gt; – shortcuts today become tomorrow’s technical debt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community is everything&lt;/strong&gt; – the conversations between sessions were as valuable as the talks themselves&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Huge thanks to the NDC organizing team, my fellow volunteers, all the speakers who shared their knowledge, and the attendees who made this such an engaging event. If you get the chance to attend (or volunteer at) &lt;a href="https://ndcconferences.com/" rel="noopener noreferrer"&gt;NDC Conferences&lt;/a&gt;, I highly recommend it.&lt;/p&gt;

&lt;p&gt;Interested in attending NDC London 2027? Follow &lt;a href="https://twitter.com/NDC_Conferences" rel="noopener noreferrer"&gt;@NDC_Conferences&lt;/a&gt;for updates!&lt;/p&gt;

&lt;p&gt;See you at NDC London 2027! 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F945hu0t6na3rxpwnacbi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F945hu0t6na3rxpwnacbi.jpg" alt="The Awesome Volunteer Team at NDC London" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ndclondon</category>
      <category>conference</category>
      <category>dotnet</category>
      <category>ai</category>
    </item>
    <item>
      <title>2025 in Review and Goals for 2026</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Thu, 01 Jan 2026 09:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/2025-in-review-and-goals-for-2026-2753</link>
      <guid>https://forem.com/funkysi1701/2025-in-review-and-goals-for-2026-2753</guid>
      <description>&lt;h2&gt;
  
  
  2025 in Review
&lt;/h2&gt;

&lt;p&gt;What a year 2025 has been! I published 24 blog posts covering a wide range of topics from cloud-native technologies to AI experiments, and even some personal reflections. Here are the key themes and highlights from my blogging year:&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloud-Native and DevOps
&lt;/h3&gt;

&lt;p&gt;This was a major focus area for me in 2025, not really surprising as I moved into a DevOps role this year, with deep dives into modern infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/learning-kubernetes/" rel="noopener noreferrer"&gt;&lt;strong&gt;Learning Kubernetes&lt;/strong&gt;&lt;/a&gt;- Started my journey into container orchestration and shared my beginner experiences&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/deploying-hugo-with-helm/" rel="noopener noreferrer"&gt;&lt;strong&gt;Deploying Hugo with Helm&lt;/strong&gt;&lt;/a&gt;- Deployed this very blog to Kubernetes using Helm charts&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/kubernetes-and-letsencrypt/" rel="noopener noreferrer"&gt;&lt;strong&gt;Kubernetes and Let’s Encrypt&lt;/strong&gt;&lt;/a&gt;- Tackled SSL certificate management in Kubernetes&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/nagios-monitoring-with-docker/" rel="noopener noreferrer"&gt;&lt;strong&gt;Monitoring with Nagios Docker&lt;/strong&gt;&lt;/a&gt;- Explored monitoring solutions in containerized environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  .NET and Development
&lt;/h3&gt;

&lt;p&gt;My bread and butter continues to be .NET development, with several posts exploring new features and tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/blazor-and-dotnet10/" rel="noopener noreferrer"&gt;&lt;strong&gt;Blazor and .NET 10&lt;/strong&gt;&lt;/a&gt;- Covered breaking changes, fixes, and new features in the latest .NET release&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/adding-elasticsearch-with-aspire/" rel="noopener noreferrer"&gt;&lt;strong&gt;Adding Elasticsearch with .NET Aspire&lt;/strong&gt;&lt;/a&gt;- Integrated search capabilities using Aspire&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/what-is-new-in-aspire-9.2/" rel="noopener noreferrer"&gt;&lt;strong&gt;Aspire 9.2&lt;/strong&gt;&lt;/a&gt;- Explored the latest Aspire release&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/central-package-management-with-nuget/" rel="noopener noreferrer"&gt;&lt;strong&gt;NuGet Central Package Management&lt;/strong&gt;&lt;/a&gt;- Streamlined dependency management&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/whats-new-csharp/" rel="noopener noreferrer"&gt;&lt;strong&gt;What’s New in C#&lt;/strong&gt;&lt;/a&gt;- Covered the latest language features&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/exceptions/" rel="noopener noreferrer"&gt;&lt;strong&gt;Exceptions&lt;/strong&gt;&lt;/a&gt;- Best practices for error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Observability and Monitoring
&lt;/h3&gt;

&lt;p&gt;Understanding what’s happening in production became a key theme:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/getting-started-with-opentelemetry/" rel="noopener noreferrer"&gt;&lt;strong&gt;Getting Started with OpenTelemetry&lt;/strong&gt;&lt;/a&gt;- Made observability easy with modern tracing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/adding-opentelemetry-logs-to-grafana/" rel="noopener noreferrer"&gt;&lt;strong&gt;OpenTelemetry Logs&lt;/strong&gt;&lt;/a&gt;- Extended observability to include logging&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/posts/2025/setting-up-grafana/" rel="noopener noreferrer"&gt;&lt;strong&gt;Setting up Grafana&lt;/strong&gt;&lt;/a&gt;- Built dashboards for monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cloud Platforms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/merge-two-projects-into-one/" rel="noopener noreferrer"&gt;&lt;strong&gt;Merging Two Projects into One&lt;/strong&gt;&lt;/a&gt;- Shared my experience consolidating codebases&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI and Creativity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/fun-with-ai/" rel="noopener noreferrer"&gt;&lt;strong&gt;Fun with AI&lt;/strong&gt;&lt;/a&gt;- Explored ChatGPT’s image generation capabilities&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/using-ai/" rel="noopener noreferrer"&gt;&lt;strong&gt;Using AI&lt;/strong&gt;&lt;/a&gt;- Practical applications of AI in daily work&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/mandelbrot-set/" rel="noopener noreferrer"&gt;&lt;strong&gt;Mandelbrot Set&lt;/strong&gt;&lt;/a&gt;- A fun mathematical exploration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Professional Development
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/pragmatic-programmer/" rel="noopener noreferrer"&gt;&lt;strong&gt;The Pragmatic Programmer&lt;/strong&gt;&lt;/a&gt;- Book review of this classic software development book&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/the-hacker-ethic/" rel="noopener noreferrer"&gt;&lt;strong&gt;The Hacker Ethic&lt;/strong&gt;&lt;/a&gt;- Reflections on developer culture and values&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/stepping-outside-my-comfort-zone/" rel="noopener noreferrer"&gt;&lt;strong&gt;Stepping Outside Your Comfort Zone&lt;/strong&gt;&lt;/a&gt;- Personal growth and career development&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/volunteering-at-ndc-london/" rel="noopener noreferrer"&gt;&lt;strong&gt;Volunteering at NDC London&lt;/strong&gt;&lt;/a&gt;- My experience at this major .NET conference&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/periodic-table-of-devops-15c7/" rel="noopener noreferrer"&gt;&lt;strong&gt;Periodic Table of DevOps 2025&lt;/strong&gt;&lt;/a&gt;- A visual guide to the DevOps ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fun Projects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.funkysi1701.com/festive-naughty-or-nice-checker/" rel="noopener noreferrer"&gt;&lt;strong&gt;Festive Naughty or Nice Checker&lt;/strong&gt;&lt;/a&gt;- A seasonal AI-powered fun project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you to everyone who read, commented, and shared my posts throughout the year. Your engagement and feedback mean the world to me!&lt;/p&gt;

&lt;h2&gt;
  
  
  2025 by the Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;24 blog posts&lt;/strong&gt; published&lt;/li&gt;
&lt;li&gt;Major topics: Kubernetes, .NET, OpenTelemetry, AI&lt;/li&gt;
&lt;li&gt;New skills acquired: Helm, Kubernetes, observability tools&lt;/li&gt;
&lt;li&gt;Conferences attended: NDC London (as a volunteer) and DDD North&lt;/li&gt;
&lt;li&gt;Submitted content to &lt;a href="https://festivetechcalendar.com" rel="noopener noreferrer"&gt;https://festivetechcalendar.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Goals for 2026
&lt;/h2&gt;

&lt;p&gt;Looking ahead to 2026, I’m excited to build on this momentum. Here are my blogging and technical goals:&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Goals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Publish at least 24 posts&lt;/strong&gt; - Maintain the pace from 2025&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep dive into AI/ML&lt;/strong&gt; - Go beyond experimentation to practical implementations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More hands-on tutorials&lt;/strong&gt; - Provide step-by-step guides that readers can follow along with&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Technical Skills
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Master Kubernetes&lt;/strong&gt; - Move from beginner to intermediate proficiency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced observability&lt;/strong&gt; - Implement comprehensive monitoring across distributed systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-native patterns&lt;/strong&gt; - Explore microservices, event-driven architectures, and service mesh&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI integration&lt;/strong&gt; - Build practical AI-powered features into applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Platform engineering&lt;/strong&gt; - Create better developer experiences and internal platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Walking
&lt;/h2&gt;

&lt;p&gt;At the end of 2024 I made the following goal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2024 took an unusual turn. In June, I walked a half marathon across the Peak District, and since then,
I have been doing lots of walks. Walking is good for my physical and mental health,
so I intend to do more of it in 2025. I have a 5k scheduled for January,
which should be lots of fun as it is around the wildlife park.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well I enjoyed my walk in January 2025, which then led to two 10k walks (in July and September) and a 7.5k night walk (in Blackpool to see the Illuminations). This led me to explore &lt;a href="https://www.parkrun.com/" rel="noopener noreferrer"&gt;parkrun&lt;/a&gt;and I completed my 8th run this morning. I say run, not walk as I am slowly becoming more of a runner and less of a walker.&lt;/p&gt;

&lt;p&gt;So my goal here is to keep doing this, as I am so far enjoying getting out and about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Would You Like to See?
&lt;/h2&gt;

&lt;p&gt;I’d love to hear from you! What topics would you like me to cover in 2026? Are there specific technologies, patterns, or problems you’d like to see explored?&lt;/p&gt;

&lt;p&gt;Drop a comment below, reach out on social media, or send me a message. Your feedback helps shape the content direction for the year ahead.&lt;/p&gt;

&lt;p&gt;Here’s to a fantastic 2026 filled with learning, building, and sharing! 🚀&lt;/p&gt;

</description>
      <category>retrospective</category>
      <category>goals</category>
      <category>yearlyreview</category>
      <category>blogging</category>
    </item>
    <item>
      <title>Creating a Festive Naughty or Nice Checker Using Semantic Kernel and .NET</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Fri, 12 Dec 2025 10:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/creating-a-festive-naughty-or-nice-checker-using-semantic-kernel-and-net-5181</link>
      <guid>https://forem.com/funkysi1701/creating-a-festive-naughty-or-nice-checker-using-semantic-kernel-and-net-5181</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vyi7gr3bffdlgiptlkv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vyi7gr3bffdlgiptlkv.png" alt="Festive Tech Calendar" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I’m excited to be taking part in this year’s &lt;a href="https://festivetechcalendar.com/" rel="noopener noreferrer"&gt;Festive Tech Calendar&lt;/a&gt;, a community-driven advent calendar showcasing amazing technical content throughout December. Make sure to check out the other excellent posts created by developers from around the world!&lt;/p&gt;

&lt;p&gt;In this festive tutorial, we’ll build a fun “Naughty or Nice” checker using Microsoft’s Semantic Kernel and .NET. This playful AI-powered tool analyzes text descriptions and delivers a verdict on whether someone has been naughty or nice this year—perfect for adding some holiday cheer to your portfolio! Whether you’re new to AI integration or looking to explore Semantic Kernel, this beginner-friendly guide will walk you through creating a complete working application from scratch. By the end, you’ll have a deployable web app and understand how to integrate large language models into your .NET projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Take on AI
&lt;/h2&gt;

&lt;p&gt;Before diving into code, I want to share a quick perspective on using AI in development. While building this demo, I used &lt;a href="https://github.com/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt; to transform a basic UI into something more festive.&lt;/p&gt;

&lt;p&gt;Starting with a simple, functional interface:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcpxqptl5r4w000xtueox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcpxqptl5r4w000xtueox.png" alt="boring looking application" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a few prompts to Copilot, I had a Christmas-themed demo with loading spinners and festive icons:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgflar8zxoehtmi2bft0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgflar8zxoehtmi2bft0.png" alt="Christmas version" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Could I have coded this myself? Absolutely. But I’d rather focus my energy on the backend Semantic Kernel integration than wrestling with CSS animations. &lt;strong&gt;This is where AI shines—handling the tedious parts so you can focus on the interesting problems.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Reality Check
&lt;/h3&gt;

&lt;p&gt;That said, AI isn’t magic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hallucinations happen&lt;/strong&gt; - I’ve lost time chasing incorrect suggestions, so don’t retire your search engine just yet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ownership questions remain&lt;/strong&gt; - Who owns AI-generated code? This is still being figured out&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It’s a tool, not a replacement&lt;/strong&gt; - AI augments developers; it doesn’t replace critical thinking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My approach: Use AI as a productivity multiplier, but always verify, understand, and own what you ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Semantic Kernel?
&lt;/h2&gt;

&lt;p&gt;Semantic Kernel is an open-source SDK from Microsoft that makes it easy to integrate AI models into your .NET applications. It allows you to use large language models (LLMs) for tasks like text analysis, summarization, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;We’ll create a simple web app that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accepts a name or short description of someone’s behaviour&lt;/li&gt;
&lt;li&gt;Uses Semantic Kernel to analyze the input&lt;/li&gt;
&lt;li&gt;Returns a festive verdict: Naughty or Nice&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;.NET 10 (I am not using any .NET 10 specific features so could probably be rewritten with older versions)&lt;/li&gt;
&lt;li&gt;Semantic Kernel (NuGet package)&lt;/li&gt;
&lt;li&gt;An OpenAI API key - ⚠️ &lt;strong&gt;Note&lt;/strong&gt; : API usage costs ~$0.01-0.05 per request&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  OpenAI and Costs
&lt;/h3&gt;

&lt;p&gt;For this example I have used an OpenAI API Key. This is not free, however while writing this example I have only spent a few pounds in tokens. For more information about OpenAI head over to &lt;a href="https://platform.openai.com/" rel="noopener noreferrer"&gt;https://platform.openai.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this reason I have not provided a live demo, (I don’t want you all using my API key), and no API keys are included in my example code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;Create a new Blazor Web App:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new blazor -n NaughtyOrNiceChecker
cd NaughtyOrNiceChecker

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the required NuGet packages: (Microsoft.SemanticKernel.Connectors.OpenAI Version 1.67.1 as I write this)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your OpenAI configuration to appsettings.json:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "OpenAI": {
    "Key": "your-api-key-here", // Head over to https://platform.openai.com/settings/organization/api-keys
    "Model": "gpt-5" // I am using gpt-5 but feel free to experiment with other models
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔒 &lt;strong&gt;Security&lt;/strong&gt; : Never commit API keys to GitHub. Use user secrets or environment variables.&lt;/p&gt;

&lt;p&gt;The code for my project can be found on GitHub at &lt;a href="https://github.com/funkysi1701/FestiveTechCalendar2025" rel="noopener noreferrer"&gt;https://github.com/funkysi1701/FestiveTechCalendar2025&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Integrate Semantic Kernel
&lt;/h2&gt;

&lt;p&gt;Configure Semantic Kernel to use your LLM provider (OpenAI). In the &lt;code&gt;Program.cs&lt;/code&gt; file you will see the following code, this loads the OpenAI key and model from your &lt;code&gt;appsettings.json&lt;/code&gt; config file, and allows it to be used by Semantic Kernel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var key = builder.Configuration.GetValue&amp;lt;string&amp;gt;("OpenAI:Key");
var model = builder.Configuration.GetValue&amp;lt;string&amp;gt;("OpenAI:Model");
if (!string.IsNullOrEmpty(key))
{
    builder.Services.AddOpenAIChatCompletion(
        modelId: model ?? throw new ApplicationException("Missing OpenAI Config"),
        apiKey: key
    );
}
builder.Services.AddKernel();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Create the Blazor Component
&lt;/h2&gt;

&lt;p&gt;Create a new file &lt;code&gt;Components/Pages/NaughtyOrNice.razor&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@page "/naughty-or-nice"
@inject Kernel _kernel
@rendermode InteractiveServer

&amp;lt;PageTitle&amp;gt;Naughty or Nice Checker&amp;lt;/PageTitle&amp;gt;

&amp;lt;h3&amp;gt;🎅 Naughty or Nice Checker&amp;lt;/h3&amp;gt;

&amp;lt;div class="card"&amp;gt;
    &amp;lt;div class="card-body"&amp;gt;
        &amp;lt;input @bind="input" 
               placeholder="Describe their behavior..." 
               class="form-control mb-3" /&amp;gt;
        &amp;lt;button @onclick="CheckStatus" 
                class="btn btn-primary"&amp;gt;
            Check Status
        &amp;lt;/button&amp;gt;

        @if (!string.IsNullOrEmpty(response))
        {
            &amp;lt;div class="alert alert-@alertClass mt-3"&amp;gt;
                &amp;lt;h4&amp;gt;@response&amp;lt;/h4&amp;gt;
            &amp;lt;/div&amp;gt;
        }
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

@code {
    private string childsName = "";
    private string response = "";
    private string alertClass =&amp;gt; response == "Naughty" ? "danger" : "success";
    private bool isLoading = false;

    public async Task CheckStatus()
    {
        isLoading = true;
        await InvokeAsync(StateHasChanged);
        response = string.Empty;
        try
        {
            var input = (childsName).Trim();
            if (string.IsNullOrEmpty(input))
            {
                return;
            }

            using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
            var prompt = "You are Santa's assistant. Given the child's name or short description, " + 
            "decide if they are Naughty or Nice for Christmas. " + 
            "Respond only with one word: Naughty or Nice. " +
            "No punctuation, no explanation. Input: {{$input}}";
            var classifyFunc = _kernel.CreateFunctionFromPrompt(prompt);
            var aiResponse = await _kernel.InvokeAsync(
                classifyFunc, 
                new() 
                { 
                    ["input"] = input 
                }, 
                cts.Token
            );
            var text = aiResponse.GetValue&amp;lt;string&amp;gt;()?.Trim();

            // Normalize and enforce strict output
            if (string.Equals(text, "naughty", StringComparison.OrdinalIgnoreCase))
            {
                response = "Naughty";
            }
            else if (string.Equals(text, "nice", StringComparison.OrdinalIgnoreCase))
            {
                response = "Nice";
            }
            else
            {
                // Fallback: default to Naughty to avoid leaking other content
                response = "Naughty";
            }
        }
        finally
        {
            isLoading = false;
            await InvokeAsync(StateHasChanged);
        }
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The _kernel is injected automatically because we registered it in Program.cs with builder.Services.AddKernel().&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Crafting the Perfect Prompt
&lt;/h2&gt;

&lt;p&gt;Getting AI to return exactly what you want requires iteration. I’ll walk you through my prompt engineering journey from verbose outputs to production-ready responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iteration 1: Too Verbose
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var aiResponse = await _kernel.InvokePromptAsync(
    $"You are a tool to help Santa identify if children have been naughty or nice. " +
    $"Has {input} been naughty or nice this year?",
    cancellationToken: cancellationToken.Token
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Santa&lt;/td&gt;
&lt;td&gt;Short answer: Nice. Why: - Spreads joy and generosity globally - Works hard with his team, treats elves and reindeer well - Answers letters and keeps promises (on-time deliveries) Minor demerits (lighthearted): - Excess cookie consumption - Occasional chimney soot prints Verdict: Firmly on the Nice List. Want a fun “Official Nice Report” for Santa you can share?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Darth Vader&lt;/td&gt;
&lt;td&gt;Not exactly a child, but Santa checks everyone. Darth Vader’s record this year includes Force-choking subordinates and aiding Imperial oppression—firmly Naughty. Mitigating note: he did protect his son and turn against the Emperor, which earns a small mercy. Final verdict: Naughty list (with a tiny redemption candy cane).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;James&lt;/td&gt;
&lt;td&gt;I don’t have access to Santa’s list or personal data, so I can’t say for sure about James. But I can help you decide with a quick Naughty/Nice check: Score each item: - Kind and helpful to family/classmates most of the time? (Yes +2, Sometimes +1, No 0) - Tells the truth and takes responsibility? (Yes +2, Sometimes +1, No 0) - Apologizes and makes things right after mistakes? (Yes +2, Sometimes +1, No 0) - Respects rules and others (no bullying or deliberate harm)? (Yes +2, Sometimes +1, No 0; deduct 2 if there’s repeated serious harm) - Does generous things (sharing, chores, helping the community)? (Yes +2, Sometimes +1, No 0) Totals: - 8–10: Nice List - 5–7: Mostly Nice (keep it up) - 2–4: Mixed (needs a December boost) - 0–1 or repeated serious harm: Naughty-for-now (with room to improve) If James needs a boost: make amends where needed, do one unprompted kindness or chore daily, be honest about mistakes right away, and share/donate something or help someone weekly. Share a few examples of James’s year and I’ll help you make the call.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skeletor&lt;/td&gt;
&lt;td&gt;Verdict: Naughty. Why: - Repeated attempts to conquer Eternia and seize Castle Grayskull - Habitual scheming, lying, and bullying his own minions - Frequent unleashing of dangerous magic on innocents Path back to the Nice List: - Call a truce with He-Man and protect Eternia for a season - Return stolen artifacts and undo harmful spells - Treat his minions fairly and do a few good deeds without expecting power in return&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is far too wordy, I really just want a Naughty or Nice response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iteration 2: Constraining the Output
&lt;/h3&gt;

&lt;p&gt;Then I tried:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var aiResponse = await _kernel.InvokePromptAsync(
    $"Given the following description, decide if the person is Naughty or Nice for Christmas. " +
    $"Respond only with 'Naughty' or 'Nice'. " +
    $"Description: {input}",
    cancellationToken: cancellationToken.Token
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Santa&lt;/td&gt;
&lt;td&gt;Nice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Darth Vader&lt;/td&gt;
&lt;td&gt;Naughty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;James&lt;/td&gt;
&lt;td&gt;Nice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skeletor&lt;/td&gt;
&lt;td&gt;Naughty&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is better but every name I tried is giving me a Nice, so let’s see if we can try something a bit more clever. However if instead of only including a name, we include some naughty or nice actions we get some interesting results.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Santa delivered some presents&lt;/td&gt;
&lt;td&gt;Nice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Darth Vader destroyed Alderaan&lt;/td&gt;
&lt;td&gt;Naughty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;James tidied his room&lt;/td&gt;
&lt;td&gt;Nice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skeletor got cross with Evil Lynn&lt;/td&gt;
&lt;td&gt;Naughty&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Version 3: Non-AI Approach (Plugin Example)
&lt;/h3&gt;

&lt;p&gt;This version demonstrates Semantic Kernel’s plugin system without using AI. While it doesn’t actually help Santa (it just generates a hash-based result), it shows how you can integrate traditional .NET code into Semantic Kernel workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why show this?&lt;/strong&gt; To illustrate that Semantic Kernel isn’t just for AI—you can mix AI calls with regular code execution in the same pipeline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var aiResponse = await _kernel.InvokeAsync(
    pluginName, 
    "GenerateHash", 
    new KernelArguments
    {
        ["input"] = input
    }
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version invokes a semantic kernel plugin function called GenerateHash. The function itself is defined in a separate class with a KernelFunction attribute, it is really simple just generates a hash from the input string. This is just an example of how you can call .NET code from Semantic Kernel. The kernel function requires an extra line to wire up correctly I have placed this in the OnInitialized method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protected override void OnInitialized()
{
  var rngPlugin = new ExamplePlugin();
  _kernel.ImportPluginFromObject(rngPlugin, pluginName);
}


public class ExamplePlugin
{
    [KernelFunction]
    public int GenerateHash(string input)
    {
        if (input == null)
        {
            throw new ArgumentNullException(nameof(input));
        }
        var hash = input.GetHashCode();

        return hash &amp;gt; 0 ? 0 : 1;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Final Version: Production-Ready Implementation
&lt;/h3&gt;

&lt;p&gt;My last example is very similar to Version 2 but let’s have a look at it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var prompt = "You are Santa's assistant. Given the child's name or short description, " + 
            "decide if they are Naughty or Nice for Christmas. Respond only with one word: Naughty or Nice. " +
            "No punctuation, no explanation. Input: {{$input}}";
            var classifyFunc = _kernel.CreateFunctionFromPrompt(prompt);
            var aiResponse = await _kernel.InvokeAsync(
                classifyFunc, 
                new() 
                { 
                    ["input"] = input 
                }, 
                cancellationToken.Token
            );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have a bit more error checking to make sure we have entered a valid string before calling OpenAI. This time we use the CreateFunctionFromPrompt method to pass in a prompt, we then invoke the prompt along with the string that has been entered.&lt;/p&gt;

&lt;p&gt;This time we check for naughty or nice in the response before returning that to the user, if neither is returned we return Naughty.&lt;/p&gt;

&lt;p&gt;This works quite well if we enter a more descriptive input.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Santa delivered some presents&lt;/td&gt;
&lt;td&gt;Nice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Darth Vader destroyed Alderaan&lt;/td&gt;
&lt;td&gt;Naughty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;James tidied his room&lt;/td&gt;
&lt;td&gt;Nice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skeletor got cross with Evil Lynn&lt;/td&gt;
&lt;td&gt;Naughty&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see if we describe the actions of someone we can categorize them as naughty or nice, which is basically what Santa does, so this tool should be a great help to him.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib5422uzu7rz6e1a36u5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fib5422uzu7rz6e1a36u5.png" alt="Is Santa Naughty or Nice?" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing All Versions
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Version&lt;/th&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Open-ended prompt&lt;/td&gt;
&lt;td&gt;Rich explanations&lt;/td&gt;
&lt;td&gt;Too verbose&lt;/td&gt;
&lt;td&gt;Learning/debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Constrained output&lt;/td&gt;
&lt;td&gt;Concise&lt;/td&gt;
&lt;td&gt;Needs context&lt;/td&gt;
&lt;td&gt;Simple classifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Hash-based (no AI)&lt;/td&gt;
&lt;td&gt;No API costs&lt;/td&gt;
&lt;td&gt;Not intelligent&lt;/td&gt;
&lt;td&gt;Plugin example only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Validated prompts&lt;/td&gt;
&lt;td&gt;Reliable, safe&lt;/td&gt;
&lt;td&gt;More code&lt;/td&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we built a festive AI-powered application using Semantic Kernel and .NET. Here’s what we accomplished:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Integrated OpenAI with Semantic Kernel in a Blazor app&lt;/li&gt;
&lt;li&gt;✅ Learned prompt engineering through iteration (4 versions!)&lt;/li&gt;
&lt;li&gt;✅ Implemented proper error handling and output validation&lt;/li&gt;
&lt;li&gt;✅ Created a fun, interactive holiday application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have tried to highlight some of the different ways that you can use Semantic Kernel that you could use in your own projects. Some of my examples could be accomplished without the use of Semantic Kernel, for example randomly generating Naughty and Nice doesn’t need AI, however hopefully you can see that getting results from AI can then be augmented using traditional .NET code to execute other functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prompt engineering matters&lt;/strong&gt; - Notice how Version 4’s explicit instructions produced better results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation is essential&lt;/strong&gt; - Always sanitize LLM outputs before displaying to users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep it simple&lt;/strong&gt; - Complex doesn’t mean better (Version 3’s random approach was overkill)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cost Considerations
&lt;/h3&gt;

&lt;p&gt;During development, I spent only a few pounds on API tokens. For production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Azure OpenAI for predictable pricing&lt;/li&gt;
&lt;li&gt;Implement caching for common queries&lt;/li&gt;
&lt;li&gt;Set up rate limiting to prevent abuse&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment Options
&lt;/h3&gt;

&lt;p&gt;This Blazor app can be deployed to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Azure Static Web Apps&lt;/strong&gt; (free tier includes 2 custom domains)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure App Service&lt;/strong&gt; (full .NET hosting)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker containers&lt;/strong&gt; (run anywhere)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;p&gt;Want to extend this project? Try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a database to track naughty/nice history&lt;/li&gt;
&lt;li&gt;Implement user authentication&lt;/li&gt;
&lt;li&gt;Deploy to Azure Static Web Apps&lt;/li&gt;
&lt;li&gt;Add more context (age, location) for better AI decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding and Merry Christmas! 🎄&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/microsoft/semantic-kernel" rel="noopener noreferrer"&gt;Semantic Kernel GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/semantic-kernel/" rel="noopener noreferrer"&gt;Microsoft Semantic Kernel Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.openai.com/docs/api-reference" rel="noopener noreferrer"&gt;OpenAI API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/ai-services/openai/" rel="noopener noreferrer"&gt;Azure OpenAI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>net</category>
      <category>semantickernel</category>
      <category>ai</category>
      <category>christmas</category>
    </item>
    <item>
      <title>Blazor and .NET 10: Breaking Changes, Fixes, and New Features</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 17 Nov 2025 20:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/blazor-and-net-10-breaking-changes-fixes-and-new-features-27ad</link>
      <guid>https://forem.com/funkysi1701/blazor-and-net-10-breaking-changes-fixes-and-new-features-27ad</guid>
      <description>&lt;h2&gt;
  
  
  What’s New in .NET 10?
&lt;/h2&gt;

&lt;p&gt;.NET 10 was released this week and it is full of awesome new features. Check it out at &lt;a href="https://dotnet.microsoft.com/download/dotnet/10.0" rel="noopener noreferrer"&gt;.NET Download&lt;/a&gt;, there is also a new version of &lt;a href="https://visualstudio.microsoft.com/" rel="noopener noreferrer"&gt;Visual Studio&lt;/a&gt; which you should also check out.&lt;/p&gt;

&lt;p&gt;I quickly upgraded my .NET projects to take advantage of the new version, but my Blazor WebAssembly (Wasm) project encountered the following error in the browser console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System.NotSupportedException: net_http_synchronous_reads_not_supported
   at System.Net.Http.BrowserHttpReadStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.DelegatingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.StreamReader.ReadBuffer(Span`1 userBuffer, Boolean&amp;amp; readToUserBuffer)
   at System.IO.StreamReader.ReadSpan(Span`1 buffer)
   at System.IO.StreamReader.Read(Char[] buffer, Int32 index, Int32 count)
   at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append, Int32 charsRequired)
   at Newtonsoft.Json.JsonTextReader.ReadData(Boolean append)
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[MyResult](JsonReader reader)
   at MyAPI.Client.MyClient.&amp;lt;ReadObjectResponseAsync&amp;gt;d__57`1[[MyAPI.Client.MyResult, MyAPI.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
   at MyAPI.Client.MyClient.MyAsync(MyRequest body, CancellationToken cancellationToken)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error was getting thrown on a Blazor Wasm page when it tried to make a call to my API. This worked fine in .NET 9 so my suspicion was this might be a breaking change.&lt;/p&gt;

&lt;p&gt;The list of new features for .NET 10 can be found &lt;a href="https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-10.0?view=aspnetcore-9.0" rel="noopener noreferrer"&gt;.NET 10 Release Notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  HttpClient Response Streaming: Breaking Change in Blazor
&lt;/h2&gt;

&lt;p&gt;I found the following new feature which I suspect is related to my issue:&lt;/p&gt;

&lt;p&gt;HttpClient response streaming enabled by default&lt;/p&gt;

&lt;p&gt;In prior Blazor releases, response streaming for HttpClient requests was opt-in. Now, response streaming is enabled by default.&lt;/p&gt;

&lt;p&gt;This is a breaking change because calling &lt;code&gt;HttpContent.ReadAsStreamAsync&lt;/code&gt; for an &lt;code&gt;HttpResponseMessage.Content&lt;/code&gt; (&lt;code&gt;response.Content.ReadAsStreamAsync()&lt;/code&gt;) returns a &lt;code&gt;BrowserHttpReadStream&lt;/code&gt; and no longer a &lt;code&gt;MemoryStream&lt;/code&gt;. &lt;code&gt;BrowserHttpReadStream&lt;/code&gt; doesn’t support synchronous operations, such as &lt;code&gt;Stream.Read(Span&amp;lt;Byte&amp;gt;)&lt;/code&gt;. If your code uses synchronous operations, you can opt-out of response streaming or copy the &lt;code&gt;Stream&lt;/code&gt; into a &lt;code&gt;MemoryStream&lt;/code&gt; yourself.&lt;/p&gt;

&lt;p&gt;To opt-out of response streaming globally, use either of the following approaches:&lt;/p&gt;

&lt;p&gt;Add the  property to the project file with a value of false:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;WasmEnableStreamingResponse&amp;gt;false&amp;lt;/WasmEnableStreamingResponse&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the DOTNET_WASM_ENABLE_STREAMING_RESPONSE environment variable to false or 0.&lt;/p&gt;

&lt;p&gt;To opt-out of response streaming for an individual request, set &lt;code&gt;SetBrowserResponseStreamingEnabled&lt;/code&gt; to false on the &lt;code&gt;HttpRequestMessage&lt;/code&gt; (&lt;code&gt;requestMessage&lt;/code&gt; in the following example):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;requestMessage.SetBrowserResponseStreamingEnabled(false);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more information, see HttpClient and HttpRequestMessage with Fetch API request options (Call web API article).&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Fix the Streaming Issue in Blazor
&lt;/h2&gt;

&lt;p&gt;To test out if this was the culprit I added &lt;code&gt;&amp;lt;WasmEnableStreamingResponse&amp;gt;false&amp;lt;/WasmEnableStreamingResponse&amp;gt;&lt;/code&gt; to my csproj file and sure enough this fixed my issue.&lt;/p&gt;

&lt;p&gt;Do check out the docs for a complete list of new features and any other potential breaking changes. &lt;a href="https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-10.0?view=aspnetcore-10.0" rel="noopener noreferrer"&gt;.NET 10 Release Notes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blazor</category>
      <category>net10</category>
      <category>webassembly</category>
    </item>
    <item>
      <title>Periodic Table of DevOps 2025</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 29 Sep 2025 20:00:45 +0000</pubDate>
      <link>https://forem.com/funkysi1701/periodic-table-of-devops-2025-agd</link>
      <guid>https://forem.com/funkysi1701/periodic-table-of-devops-2025-agd</guid>
      <description>&lt;p&gt;DevOps has transformed the way teams build, deploy, and manage software. Over the years, the tools we use have evolved rapidly—some have become industry standards, while others have faded away or emerged to solve new challenges. In this post, I revisit the concept of a “Periodic Table of DevOps” to compare the landscape in 2016 with 2025, highlight key changes, and reflect on what these shifts mean for developers, IT professionals, and organizations embracing modern workflows.&lt;/p&gt;

&lt;p&gt;The periodic table lists all the chemical elements and groups them together based on some key properties. In 2016 I found an article about the &lt;a href="https://xebialabs.com/periodic-table-of-devops-tools/" rel="noopener noreferrer"&gt;periodic table of DevOps&lt;/a&gt; and wrote a blog &lt;a href="https://www.funkysi1701.com/posts/2016/periodic-table-devops/" rel="noopener noreferrer"&gt;post&lt;/a&gt; about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Periodic Table of DevOps Tools 2025
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5wq997z4xvqh1rre36ms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5wq997z4xvqh1rre36ms.png" alt="Periodic Table of DevOps 2025" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Periodic Table of DevOps Tools 2016
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsf559mo1xttdy16nk3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsf559mo1xttdy16nk3v.png" alt="Periodic Table of DevOps 2016" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I thought it might be interesting to see what tools are still in use, and what are new.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Control
&lt;/h2&gt;

&lt;p&gt;Git, the most popular source control system, is on both charts, in 2016 it was at position 3, and in 2025 it is at 2. GitHub, the most widely used web-based git repository, is also on both charts, moving from 1 to 10. Bitbucket (now owned by Atlassian) was a hosted git repository I used to use and is still on the chart, moving from 11 to 36. Subversion, a source control system I started my career with, has vanished off the chart in 2025. Not really a surprise due to the popularity of git now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Platforms
&lt;/h2&gt;

&lt;p&gt;In 2016 we had a whole column of Cloud Platforms, including Rackspace and OpenShift, in 2025 this has been reduced to the big three (Azure, AWS and GCP) plus OpenShift.&lt;/p&gt;

&lt;h2&gt;
  
  
  Containerization
&lt;/h2&gt;

&lt;p&gt;In 2016 we had a column of tools like Docker, Docker Swarm and Kubernetes. In 2025 there are far more tools in this space, with the addition of tools like Helm and the various ways you can host containers on cloud platforms (like Azure AKS).&lt;/p&gt;

&lt;h2&gt;
  
  
  Build and Deploy tools
&lt;/h2&gt;

&lt;p&gt;In 2016 Azure DevOps was still called Team Foundation Server, so this has spread out into the various ways you can use Azure DevOps, such as Pipelines and Code. Also since 2016 GitHub Actions has appeared on the market.&lt;/p&gt;

&lt;p&gt;In 2016 I was also dabbling with TeamCity, this is no longer used that much so isn’t on the chart in 2025. Jenkins is still around on both charts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comms Tools
&lt;/h2&gt;

&lt;p&gt;In 2025 Slack and MS Teams are the go-to tools for communicating with distributed teams, Slack was around in 2016, but Teams wasn’t a thing back then.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Tools
&lt;/h2&gt;

&lt;p&gt;New tools for monitoring like Grafana have appeared; back in 2016 I was exclusively using Application Insights from Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion &amp;amp; Key Takeaways
&lt;/h2&gt;

&lt;p&gt;The DevOps landscape has changed dramatically over the past decade. Some tools have stood the test of time, while others have faded or emerged to meet new challenges. Here are the key takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Git remains the backbone of source control&lt;/strong&gt; , with platforms like GitHub and Bitbucket continuing to thrive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud platforms (Azure, AWS, GCP) have become central&lt;/strong&gt;, reflecting the shift to cloud-native development and operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containerization and orchestration (Docker, Kubernetes, Helm) are now essential&lt;/strong&gt;, enabling scalable, flexible deployments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and collaboration tools have evolved&lt;/strong&gt; , with newcomers like Grafana and MS Teams joining established solutions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legacy tools are disappearing&lt;/strong&gt; , showing the importance of adaptability in tech.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As DevOps continues to evolve, staying curious and open to new tools is key. The periodic table analogy reminds us that the right mix of technologies can empower teams to build, deploy, and manage software more effectively. What tools will shape the next decade? Only time will tell.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tools</category>
      <category>cloud</category>
      <category>containerization</category>
    </item>
    <item>
      <title>The Mandelbrot Set</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 15 Sep 2025 20:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/the-mandelbrot-set-89n</link>
      <guid>https://forem.com/funkysi1701/the-mandelbrot-set-89n</guid>
      <description>&lt;h2&gt;
  
  
  The Mandelbrot Set: Beauty, Chaos, and Mathematical Art
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8r6r2zaitktx91j07ig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8r6r2zaitktx91j07ig.png" alt="The Mandelbrot set" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Mandelbrot set is one of the most iconic images in mathematics—a mesmerizing swirl of fractal patterns, infinite complexity, and unexpected beauty. But what exactly is the Mandelbrot set, and why has it captured the imagination of mathematicians, artists, and curious minds alike?&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the Mandelbrot Set?
&lt;/h2&gt;

&lt;p&gt;At its core, the Mandelbrot set is a collection of complex numbers. It’s defined by a simple equation, but the results are anything but simple. The definition is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A complex number &lt;strong&gt;c&lt;/strong&gt; is in the Mandelbrot set if, when you start with &lt;strong&gt;z = 0&lt;/strong&gt; and repeatedly apply the function &lt;code&gt;z = z² + c&lt;/code&gt;, the value of &lt;strong&gt;z&lt;/strong&gt; remains bounded (does not go to infinity), no matter how many times you iterate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, for each point &lt;strong&gt;c&lt;/strong&gt; on the complex plane, you check: if you keep plugging it into this formula, does it stay small, or does it spiral out of control? If it stays small forever, it’s in the Mandelbrot set.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Simple Formula to Stunning Images
&lt;/h2&gt;

&lt;p&gt;The real magic happens when you visualize the Mandelbrot set on a computer. Each point in the complex plane is coloured based on whether it belongs to the set or how quickly it escapes to infinity. The result is a black, bulbous shape surrounded by intricate, infinitely detailed patterns that resemble swirling galaxies, seahorses, or lightning bolts—the Mandelbrot set and its “fractal boundary.”&lt;/p&gt;

&lt;p&gt;Zooming in on the edge reveals ever-more complexity, with shapes that are reminiscent of the original set at different scales. This property, a form of self-similarity, is a hallmark of fractals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Is the Mandelbrot Set Important?
&lt;/h2&gt;

&lt;p&gt;The Mandelbrot set is more than just a pretty picture. It’s a window into the world of &lt;strong&gt;complex dynamics&lt;/strong&gt; and &lt;strong&gt;chaos theory&lt;/strong&gt;. The set’s boundary is infinitely complex, showing how simple mathematical rules can generate unexpected and beautiful complexity.&lt;/p&gt;

&lt;p&gt;It also has deep implications in mathematics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fractals:&lt;/strong&gt; The Mandelbrot set is the most famous example of a fractal—a shape that shows similar, though not identical, patterns at every scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chaos Theory:&lt;/strong&gt; It illustrates sensitive dependence on initial conditions, where tiny changes can lead to drastically different outcomes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex Numbers:&lt;/strong&gt; It brings to life the beauty of complex numbers, which are usually abstract concepts in math classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Mandelbrot Set in Art and Culture
&lt;/h2&gt;

&lt;p&gt;Thanks to its stunning visuals, the Mandelbrot set has become a cultural icon. It’s inspired digital art, music, and even jewellery. It also serves as a symbol for how complexity and order can emerge from simple rules, a concept that resonates in fields from biology to computer science.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;Many websites and software tools let you explore the Mandelbrot set interactively. Try zooming in and discover new shapes and patterns emerging at every level. It’s a fantastic way to experience the intersection of math, art, and chaos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I have been fascinated by fractals since I was young. I remember seeing them generated on a &lt;a href="https://www.funkysi1701.com/posts/2021/back-to-basic/" rel="noopener noreferrer"&gt;Lynx computer&lt;/a&gt; and the process was slow, one pixel at a time, after a few hours you would see a complete mandelbrot set. More recently I have looked at generating them in the browser (using .NET’s Blazor WebAssembly technology), and the image at the start of this post took only a few seconds to generate.&lt;/p&gt;

&lt;p&gt;I’ve also created an &lt;a href="https://mandelbrot.funkysi1701.com/" rel="noopener noreferrer"&gt;interactive Mandelbrot set generator&lt;/a&gt;. It’s a work in progress, but you can already generate a set and zoom in using the buttons at the top or by clicking with your mouse. I plan to add more features in the coming weeks.&lt;/p&gt;

&lt;p&gt;The Mandelbrot set reminds us that even the simplest equations can produce infinite complexity and beauty. It stands as an enduring inspiration—proof that mathematics is not just about numbers, but about wonder, creativity, and the endless possibilities hidden within the fabric of reality.&lt;/p&gt;

</description>
      <category>mandelbrotset</category>
      <category>fractals</category>
      <category>mathematics</category>
      <category>chaostheory</category>
    </item>
    <item>
      <title>The Hacker Ethic</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 01 Sep 2025 20:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/the-hacker-ethic-4ikh</link>
      <guid>https://forem.com/funkysi1701/the-hacker-ethic-4ikh</guid>
      <description>&lt;h2&gt;
  
  
  The Hacker Ethic: Principles That Shaped the Digital Age
&lt;/h2&gt;

&lt;p&gt;When most people hear the word “hacker,” they imagine shadowy figures breaking into computer systems. But the original meaning of “hacker” is far richer, rooted in curiosity, creativity, and a set of values that have profoundly shaped technology and culture. This philosophy, known as the &lt;strong&gt;hacker ethic&lt;/strong&gt; , remains a powerful force driving innovation and openness in our digital world.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the Hacker Ethic?
&lt;/h2&gt;

&lt;p&gt;The term “hacker ethic” was popularized by Steven Levy in his book &lt;em&gt;Hackers: Heroes of the Computer Revolution&lt;/em&gt;. I have just finished listening to the audio version, and highly recommend it. The book describes a set of beliefs and practices developed by early computer enthusiasts at places like MIT, Stanford, and the Homebrew Computer Club. Far from criminality, the hacker ethic is about playful exploration, sharing knowledge, and questioning limits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagkp034l7kfcbgt02fbb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagkp034l7kfcbgt02fbb.jpg" alt="Hackers: Heroes of the Computer Revolution" width="800" height="1235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Principles
&lt;/h2&gt;

&lt;p&gt;The hacker ethic can be distilled into several key tenets:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Access to Computers Should Be Unlimited and Total
&lt;/h3&gt;

&lt;p&gt;Hackers believe that information and tools for learning should be open to all. They value environments where curiosity is encouraged and barriers to entry are low. This spirit led to the creation of open-source software, free educational resources, and collaborative online communities.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. All Information Wants to Be Free
&lt;/h3&gt;

&lt;p&gt;While not advocating for stealing proprietary data, hackers champion the free flow of information. They believe that sharing code, knowledge, and discoveries accelerates progress and empowers individuals. This principle underlies movements like open data, Creative Commons, and Wikipedia.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Mistrust Authority—Promote Decentralization
&lt;/h3&gt;

&lt;p&gt;Hackers are skeptical of gatekeepers and centralized control. They prefer systems that empower individuals and distribute power. This mindset has influenced everything from peer-to-peer networks to blockchain technology.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Hackers Should Be Judged by Their Hacking, Not Bogus Criteria
&lt;/h3&gt;

&lt;p&gt;Hackers value skill, creativity, and contribution over credentials or status. In hacker culture, what matters is what you build, solve, or improve—not your job title, age, or background. This meritocratic ideal helped shape the egalitarian ethos of the internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. You Can Create Art and Beauty on a Computer
&lt;/h3&gt;

&lt;p&gt;Hackers see computers not only as tools, but as canvases for creativity. From elegant code to digital art, they celebrate the artistry inherent in technology and design.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Computers Can Change Your Life for the Better
&lt;/h3&gt;

&lt;p&gt;Hackers believe in the transformative potential of technology. They see computers as instruments of empowerment, education, and community—tools that can solve meaningful problems and improve lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Hacker Ethic Matters Today
&lt;/h2&gt;

&lt;p&gt;The hacker ethic is alive in open-source communities, maker spaces, and digital activism. It challenges us to question closed systems, embrace sharing, and use technology for good. In a world increasingly shaped by algorithms and artificial intelligence, the hacker ethic reminds us that human creativity, curiosity, and collaboration are still at the heart of progress.&lt;/p&gt;

&lt;p&gt;After listening to the book it is very clear to me that many of today’s security problems stem from this ethic. Early computers and software were built by design without security in mind. The hackers featured in the book strongly disliked passwords and locks, they believed information and systems should be open to all. I had incorrectly assumed that it was just an oversight and wasn’t needed back then.&lt;/p&gt;

&lt;p&gt;The growth of open source software can clearly be seen as an extension to the sharing of code started by these early hackers, instead of looking in a drawer for paper tape containing the code you want to improve, we go to GitHub, but the principle is the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The hacker ethic is far more than a technical mindset—it’s a philosophy of openness, empowerment, and playful problem-solving. By understanding and embracing these principles, we can build a digital future that is more inclusive, innovative, and free.&lt;/p&gt;

&lt;p&gt;The more I think about my career with computers, the more I feel I fit more as a hacker than a programmer or any other job title. I started hacking together simple web pages, I then hacked away at networks and active directory, now I hack at dotnet and kubernetes.&lt;/p&gt;

</description>
      <category>hacking</category>
      <category>ethics</category>
      <category>hackerculture</category>
      <category>technology</category>
    </item>
    <item>
      <title>Automating SSL for Kubernetes with Let's Encrypt and Cert Manager</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 07 Jul 2025 20:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/automating-ssl-for-kubernetes-with-lets-encrypt-and-cert-manager-2b12</link>
      <guid>https://forem.com/funkysi1701/automating-ssl-for-kubernetes-with-lets-encrypt-and-cert-manager-2b12</guid>
      <description>&lt;p&gt;I have blogged before about how cool &lt;a href="https://www.funkysi1701.com/posts/2018/lets-encrypt-is-awesome/" rel="noopener noreferrer"&gt;Let’s Encrypt&lt;/a&gt; is for getting your web things running under https. However I have just got myself a local kubernetes cluster and it is super easy to spin up new web services with SSL certs.&lt;/p&gt;

&lt;p&gt;The basic instructions can be found &lt;a href="https://www.slingacademy.com/article/how-to-set-up-ssl-with-lets-encrypt-in-kubernetes/" rel="noopener noreferrer"&gt;here&lt;/a&gt; but let’s look at what was involved.&lt;/p&gt;

&lt;p&gt;First of all lets get Cert Manager installed on kubernetes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.18.1/cert-manager.yaml

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the cert manager pods are up, you need to create an issuer which communicates with the lets encrypt API. The first code snippet uses the lets encrypt staging environment to avoid any API limits, the second uses production and uses the cloudflare API to authorize SSL requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          ingressClassName: nginx


apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              key: api-key
              name: cloudflare-api-token-secret
            email: your-email@example.com

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that is all configured all I need to do is update my helm chart and any pod I like can have a sub domain of funkysi1701.com with a lets encrypt SSL cert.&lt;/p&gt;

&lt;p&gt;This is a section from my helm chart which defines the domain name to use and what issuer to use for the certificate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  devHost: helloworld-dev.funkysi1701.com
  testHost: helloworld-test.funkysi1701.com
  tls:
    - secretName: helloworld-dev.funkysi1701.com
      hosts:
        - helloworld-dev.funkysi1701.com
    - secretName: helloworld-test.funkysi1701.com
      hosts:
        - helloworld-test.funkysi1701.com

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All I need to do now is add similar code like this to every helm chart I publish and my pod will request a SSL certificate. The only manual step I have is to set up a DNS record pointing to the IP address of my cluster for any domain I want to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Setting up Let’s Encrypt with Kubernetes and Cert Manager has made it incredibly easy to secure my web services with SSL certificates. With just a few YAML configurations and some simple Helm chart updates, I can automatically provision and renew certificates for any subdomain I need. This approach not only saves time but also ensures my services are always protected with up-to-date encryption. If you’re running Kubernetes, I highly recommend giving Cert Manager and Let’s Encrypt a try for hassle-free SSL management.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>letsencrypt</category>
      <category>ssl</category>
      <category>certmanager</category>
    </item>
    <item>
      <title>Stepping Outside My Comfort Zone: An Adventure Holiday Experience</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 02 Jun 2025 20:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/stepping-outside-my-comfort-zone-an-adventure-holiday-experience-16d5</link>
      <guid>https://forem.com/funkysi1701/stepping-outside-my-comfort-zone-an-adventure-holiday-experience-16d5</guid>
      <description>&lt;p&gt;Stepping outside my comfort zone doesn’t come naturally to me. I’m happiest behind my laptop, but every now and then, I know it’s important to try something new. This year, my family and I decided to do just that—and it turned out to be one of our most memorable weeks ever. Curious about what happens when you swap routine for adventure? Read on!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This week was our family holiday. Normally, we’d book a cottage somewhere nice and explore at our own pace. But this often leads to disagreements—everyone wants something different, and sometimes the places we visit aren’t as exciting as we hoped (especially for two kids aged 7 and 9 who get bored easily).&lt;/p&gt;

&lt;p&gt;This time, we chose a different path: a family adventure holiday with &lt;a href="https://www.highadventureholidays.co.uk/" rel="noopener noreferrer"&gt;High Adventure&lt;/a&gt;. The itinerary was packed: climbing, caving, hiking, water sports, archery, zip wires, and countless other activities. All meals, accommodation, equipment, and expert instructors were included, making it feel both safe and exciting.&lt;/p&gt;

&lt;p&gt;I’ll admit, I was anxious before we set off. I’m not an adventurous person—I like &lt;a href="https://www.funkysi1701.com/charity-hike" rel="noopener noreferrer"&gt;walking&lt;/a&gt;, but I’d never tried anything like this. My nine-year-old son was dreading it, while my more adventurous seven-year-old was quietly excited. I worried that if the kids hated it, it would be a waste of money. But as soon as we arrived, those fears melted away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Saturday
&lt;/h2&gt;

&lt;p&gt;We arrived on Saturday afternoon and were shown to our room. My only real complaint from the whole week: the room was tiny. With two bunk beds and four of us plus a week’s worth of clothes, it was a challenge to keep things tidy. Thankfully, the rest of the facility was spacious, and our room was right next to the games room—a bonus.&lt;/p&gt;

&lt;p&gt;Dinner was served at 6pm every evening, always a home-cooked meal. While I enjoyed the food, my fussy eaters weren’t always convinced, but there was usually something for everyone. We met the other family we’d be doing activities with.&lt;/p&gt;

&lt;p&gt;After dinner, we explored the Games Room and took on the Labyrinth—a tight, dark maze constructed under the floor. Helmets were required! I found it a bit tight, but my boys absolutely loved it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sunday
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8ym6sfj7okyx0alwwir.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8ym6sfj7okyx0alwwir.jpg" alt="Abseiling" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every day began with a cooked breakfast and a make-your-own sandwich station for lunch. Sunday morning kicked off with climbing and abseiling. I’d never climbed before, so I was surprised—and proud—to make it all the way to the top of the 8-meter wall. My boys didn’t quite reach the top, but they pushed themselves higher than I expected. Abseiling was fun too, and a great way to come down after the climb.&lt;/p&gt;

&lt;p&gt;After lunch, we tried archery. I’d done it once before at my boys’ Scout group, but it took a while to hit the target consistently. Then came bushcraft: foraging for wood, using a knife to make kindling, and lighting a fire with a ferrocerium rod. My nine-year-old and I managed to get a fire going—definitely a memorable moment, especially when we roasted marshmallows.&lt;/p&gt;

&lt;p&gt;The evening’s activity was Nightline: a blindfolded obstacle course. This was a bit much for me, but the boys loved it. My job was to guide them through the course, describing what to climb over, under, or through, and when to stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monday
&lt;/h2&gt;

&lt;p&gt;Monday started with a walk up the hill to Wainman’s Pinnacle and some “squirreling” through the rocks—a favourite for the boys, especially since they’d done it before with Scouts. I skipped most of the squirreling but enjoyed the walk.&lt;/p&gt;

&lt;p&gt;In the afternoon, it was time for high ropes and a zip wire. We were safely roped in at all times, but stepping off a high ledge still required a leap of faith. My eldest was nervous and had to climb down at first, but after watching me try, he gave it another go—and loved it. That’s what this week was about: encouraging all of us to try new things.&lt;/p&gt;

&lt;p&gt;The evening activity was Eggbert: designing a contraption to protect an egg dropped from a height. We worked as a family, but failed to consider that the weight would flip the egg so it landed the wrong way up. Oops! We didn’t win, but it was great fun seeing everyone’s creative designs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tuesday
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmzan147ipzouqzrjmcs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmzan147ipzouqzrjmcs.jpg" alt="Caving" width="720" height="978"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tuesday was our first full day offsite. The instructors drove us in a minibus to the Yorkshire Three Peaks area, where we explored underground caves. Wearing cave suits, wellies, and helmets, we were ready for adventure. I foolishly thought I wouldn’t need a change of clothes—turns out, crawling through water-filled tunnels means your wellies fill up fast! I wasn’t the biggest fan of being soaked, but the boys loved climbing and sliding through the narrow passages. We finished the day with ice cream and hot chocolate in Settle—a well-deserved treat.&lt;/p&gt;

&lt;p&gt;That evening, we tried circus skills and gathered around a campfire. The boys were entertained for ages, trying juggling and balance activities. I didn’t master anything, but I enjoyed relaxing by the fire with my wife and the other parents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wednesday
&lt;/h2&gt;

&lt;p&gt;By Wednesday, tiredness was catching up with me! We tackled a five-mile walk around Malham Cove, taking in stunning views and great weather. The route included Gordale Scar and Janet’s Foss, a lovely waterfall where many people swam or paddled. We hadn’t brought towels, but that didn’t stop my boys from getting soaked. It’s a holiday—why not?&lt;/p&gt;

&lt;p&gt;Wednesday evening was supposed to be a parents’ night off, but we had to cut it short due to a family emergency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thursday
&lt;/h2&gt;

&lt;p&gt;Thursday was water sports day, but we decided on a quieter option and visited Haworth instead. The town is famous for the Brontë sisters, and we enjoyed its picturesque streets, a museum, and a play area for the kids—a great way to wind down after so much activity.&lt;/p&gt;

&lt;p&gt;The final evening was a quiz night, complete with questions about the week’s adventures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Friday
&lt;/h2&gt;

&lt;p&gt;Friday was going-home day, but not before one last challenge: orienteering. As a former university orienteering club member, I couldn’t resist joining in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This week was truly about stepping outside my comfort zone and embracing new experiences. From climbing and caving to bushcraft and zip lines, every activity challenged me and helped me grow. I discovered that pushing your boundaries can be both exciting and rewarding—and creates memories that last a lifetime. If you ever get the chance to try something new, even if it feels a bit daunting, I highly recommend taking the leap. You might just surprise yourself!&lt;/p&gt;

</description>
      <category>adventure</category>
      <category>family</category>
      <category>personalgrowth</category>
      <category>travel</category>
    </item>
    <item>
      <title>Deploying My Blog to Kubernetes with Helm Charts</title>
      <dc:creator>Simon Foster</dc:creator>
      <pubDate>Mon, 26 May 2025 20:00:00 +0000</pubDate>
      <link>https://forem.com/funkysi1701/deploying-my-blog-to-kubernetes-with-helm-charts-40pi</link>
      <guid>https://forem.com/funkysi1701/deploying-my-blog-to-kubernetes-with-helm-charts-40pi</guid>
      <description>&lt;p&gt;Helm allows you to package your Kubernetes resources, manage configuration, and deploy updates with a single command.&lt;/p&gt;

&lt;p&gt;In this post, I’ll share how I used Helm to deploy my Hugo blog, making it easy to manage updates and spin up new environments. Full disclosure: My blog currently runs on an Azure Static Web App, but now that I know how to deploy to a Kubernetes cluster, I have the option to switch if needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Helm?
&lt;/h2&gt;

&lt;p&gt;Helm is the package manager for Kubernetes. It lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Template&lt;/strong&gt; your Kubernetes YAML files for reuse and configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version&lt;/strong&gt; your deployments for easy rollbacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share&lt;/strong&gt; your charts with others or use community charts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a Helm Chart for Hugo
&lt;/h2&gt;

&lt;p&gt;First, I scaffolded a new Helm chart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm create hugo-blog

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a directory structure with templates for deployments, services, and ingress.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customizing the Chart
&lt;/h3&gt;

&lt;p&gt;I edited &lt;code&gt;values.yaml&lt;/code&gt; to set my image and service details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image:
  repository: mydockerhubusername/hugo-blog # Docker image repository
  tag: latest # Use the latest tag for the image
  pullPolicy: IfNotPresent # Pull the image only if it’s not already present

service:
  type: NodePort # Expose the service on a specific port
  port: 80 # Internal port for the service
  nodePort: 30081 # External port for accessing the service

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploying the Blog
&lt;/h3&gt;

&lt;p&gt;To deploy the blog, I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm install my-hugo-blog ./hugo-blog

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Helm rendered the templates and created the necessary Kubernetes resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating the Blog
&lt;/h3&gt;

&lt;p&gt;When I rebuild and push a new Docker image, I can upgrade my deployment with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm upgrade my-hugo-blog ./hugo-blog

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This triggers a rolling update in Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Docker Image of my Blog
&lt;/h3&gt;

&lt;p&gt;This all assumes that I have a container image of my Hugo blog. Creating this was half the work.&lt;/p&gt;

&lt;p&gt;I had been using a docker-compose file to build my blog; however, this doesn’t copy my files into the container it creates a volume to share my files with the container. I needed a Dockerfile that would copy my source code into a container and then save it into a container registry.&lt;/p&gt;

&lt;p&gt;This is the Dockerfile I created. As you can see, it is a two-stage build. First, it takes the Hugo base image, copies my files into it, and builds Hugo. Then the NGINX web server is run, and the default web port 80 is exposed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Step 1: Build the Hugo site
FROM floryn90/hugo:0.119.0 AS builder

# Set working directory inside the container
WORKDIR /src

# Copy site files to the container
COPY . .

# Build the Hugo site
RUN hugo --minify --config config.toml

# Step 2: Serve with nginx
FROM nginx:alpine

# Remove the default nginx static files
RUN rm -rf /usr/share/nginx/html/*

# Copy the generated site from the builder stage
COPY --from=builder /src/public /usr/share/nginx/html

# Expose port 80
EXPOSE 80

# Start nginx
CMD ["nginx", "-g", "daemon off;"]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repeatable Deployments:&lt;/strong&gt; Easily spin up new environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration Management:&lt;/strong&gt; Override values for different clusters or environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy Updates:&lt;/strong&gt; Upgrade with a single command.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Helm charts have made deploying my Hugo blog to Kubernetes a seamless and efficient process. With features like templating, versioning, and easy updates, Helm is a must-have tool for Kubernetes deployments.&lt;/p&gt;

&lt;p&gt;If you’re managing static sites or microservices, give Helm a try and see how it can simplify your workflow!&lt;/p&gt;

&lt;p&gt;Have you used Helm for static sites or blogs? Share your experience in the comments below!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>helm</category>
      <category>devops</category>
      <category>hugo</category>
    </item>
  </channel>
</rss>
