<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="en">
  <title>Ricardo Covo - Blog</title>
  <subtitle>Sharing is caring</subtitle>
  <link href="https://ricardocovo.com/feed.xml" rel="self"/>
  <link href="https://ricardocovo.com/"/>
  <updated>2026-04-13T00:00:00Z</updated>
  <id>https://ricardocovo.com/</id>
  <author>
    <name>Ricardo Covo</name>
    <email>ricardo.covo@gmail.com</email>
  </author>
  
  <entry>
    <title>Ricardo Covo - Blog - Ephemeral Intelligence: Running On-Demand Copilot Agents in GitHub Workflows</title>
    <link href="https://ricardocovo.com/blog/ephemeral-intelligence-running-on-demand-copilot-agents-in-github-workflows/"/>
    <updated>2026-04-13T00:00:00Z</updated>
    <id>https://ricardocovo.com/blog/ephemeral-intelligence-running-on-demand-copilot-agents-in-github-workflows/</id>
    <content type="html">
&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: ⚡GitHub Copilot CLI + &lt;a href=&quot;https://github.com/microsoft/apm&quot; target=&quot;_blank&quot;&gt;APM (Agent Package Manager)&lt;/a&gt; lets you drop portable, on-demand agent intelligence into any GitHub Actions workflow — no permanent changes to the target repository needed. Here&#39;s how I used it to run standardized architecture discovery across 100+ repositories without losing my mind.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;section&gt;
  &lt;h2&gt;The Challenge: Agent Configuration at Scale&lt;/h2&gt;
  &lt;p&gt;Over the past few weeks, I hav been thinking about how to assess the architecture and technical health of every repository across an organization — think 100s of repos — and produce a standardized set of outputs: Tech stack summaries. Dependency inventories. Risk flags. Improvement opportunities. The kind of artifacts that, taken together, would give us a coherent picture of the whole landscape and a defensible starting point for modernization planning.&lt;/p&gt;
  &lt;p&gt;With GitHub Copilot I knew it could accelerate the analysis dramatically. But here was the real problem: every time I would need update the repo with the &lt;em&gt;right&lt;/em&gt; set of prompts, skills, and instructions for architecture discover. It was a bit tedious: Copying files over. Tweaking instructions. Not to mentioned the maintainability of these assets.&lt;/p&gt;
  &lt;p&gt;That friction is what led me to APM — and it changed how I think about agentic workflows entirely.&lt;/p&gt;
&lt;/section&gt;

&lt;section&gt;
  &lt;h2&gt;📦 APM: Think &#39;npm&#39; for Agent Primitives (custom agents, instructions, prompts, skills, etc.)&lt;/h2&gt;
  &lt;p&gt;&lt;a href=&quot;https://github.com/microsoft/apm&quot; target=&quot;_blank&quot;&gt;APM (Agent Package Manager)&lt;/a&gt; is an open-source tool that does for AI agent configuration what npm does for Node.js dependencies, or pip does for Python. Instead of telling every developer to manually set up their Copilot instructions and prompts, you declare them in a manifest file.&lt;/p&gt;
  &lt;p&gt;Simply run &lt;code&gt;apm install&lt;/code&gt;, and APM resolves and installs everything: custom instructions (&lt;code&gt;.instructions.md&lt;/code&gt;), skills (&lt;code&gt;.skill.md&lt;/code&gt;), prompts (&lt;code&gt;.prompt.md&lt;/code&gt;), agents (&lt;code&gt;.agent.md&lt;/code&gt;), and more.&lt;/p&gt;
  &lt;p&gt;But here&#39;s the thing that really unlocked the use case for me: 💡&lt;strong&gt;agent primitives don&#39;t have to live permanently in the target repository&lt;/strong&gt;. You can bring them in at workflow time, use them, and leave no trace. Ephemeral, intentional, and fully reproducible.&lt;/p&gt;
&lt;/section&gt;

&lt;section&gt;
  &lt;h2&gt;⚙️ The Setup: A Discovery Factory&lt;/h2&gt;
  &lt;p&gt;The architecture I landed on has two moving parts:&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;1. A central discovery package&lt;/strong&gt; — I have around 20 primitives I use for the repository discovery, I packaged them all into a &lt;code&gt;repo-metadata-generator&lt;/code&gt; pack.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;2. A reusable GitHub Actions workflow&lt;/strong&gt; that can be dispatched against any target repository. It checks out the repo, installs Copilot CLI and APM, pulls in our discovery pack, runs the prompts, and uploads the results as artifacts.&lt;/p&gt;
  &lt;p&gt;You can check out the full &lt;a href=&quot;https://github.com/ricardocovo/agentic-web-spec/blob/main/.github/workflows/architect-metadata-generator.yml&quot; target=&quot;_blank&quot;&gt;workflow&lt;/a&gt;. Here are the interesting bits:&lt;/p&gt;

  &lt;pre data-language=&quot;yaml&quot; class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;name: Generate Architect Metadata
...
jobs:
  discover:
    ....
    - name: Download repo-metadata-generator pack
      run: |
        curl -L -o repo-metadata-generator-1.0.0.tar.gz &#92;
            &quot;https://github.com/.../repo-metadata-generator-1.0.0.tar.gz&quot;

    - name: Install GitHub Copilot CLI
      run: npm i -g @github/copilot

    - name: Install APM and Unpack Metadata Generator
      run: |
        curl -sSL https://aka.ms/apm-unix | sh
        apm unpack repo-metadata-generator-1.0.0.tar.gz

    - name: Run Documentation
      env:
        COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
      run: |
        set -euo pipefail

        copilot --agent repo-analyzer -p &quot;/fleet Run all the prompts in the .github/prompts&quot;
    ...&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;We&#39;re injecting our own discovery-specific manifest, pulling in exactly the primitives we need for this job, doing the analysis, and uploading the results. &lt;strong&gt;The target repo is unchanged&lt;/strong&gt;. The workflow is stateless. You can run it against a repo today, improve the discovery pack tomorrow, bump the version, and re-run.&lt;/p&gt;
&lt;/section&gt;

&lt;section&gt;
  &lt;h2&gt;🔍 What&#39;s Inside the Discovery Pack&lt;/h2&gt;
  &lt;p&gt;If you are interested, you can check out the contents of the &lt;a href=&quot;https://github.com/ricardocovo/agent-primitives/tree/main/packs&quot; target=&quot;_blank&quot;&gt;repo-metadata-generator&lt;/a&gt; pack. But be aware this is only a &lt;strong&gt;sample pack&lt;/strong&gt;.&lt;/p&gt;
&lt;/section&gt;

&lt;section&gt;
  &lt;h2&gt;🧠 The Mental Model Shift That Matters&lt;/h2&gt;
  &lt;p&gt;What excites me about this pattern isn&#39;t the specific tools. It&#39;s what it represents.&lt;/p&gt;
  &lt;p&gt;We&#39;ve spent years building reusable code: shared libraries, internal npm packages, Artifactory registries. We&#39;ve invested heavily in CI/CD so that quality checks, security scans, and deployments are automated and consistent. But AI agent configuration has been the wild west — per-developer, per-project, copy-pasted, undocumented, and completely non-reproducible.&lt;/p&gt;
  &lt;p&gt;APM brings the same engineering discipline we apply to code dependencies to agent configuration. And when you combine it with GitHub Copilot CLI and GitHub Actions, you get &lt;strong&gt;agentic workflows that are portable, versioned, auditable, and scalable&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;The same pattern extends naturally to:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;✅ &lt;strong&gt;Automated PR review checklists&lt;/strong&gt; — different skill packs for different service types (API, frontend, data pipeline)&lt;/li&gt;
    &lt;li&gt;🔒 &lt;strong&gt;Security audit workflows&lt;/strong&gt; — triggered automatically when a new repo is created&lt;/li&gt;
    &lt;li&gt;📝 &lt;strong&gt;Release note generators&lt;/strong&gt; — with org-specific tone, format, and audience targeting&lt;/li&gt;
    &lt;li&gt;🚀 &lt;strong&gt;Developer onboarding agents&lt;/strong&gt; — that generate a tailored &quot;getting started&quot; guide for each codebase, pulled fresh every time&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;In every case: define your primitives once, package them, version them, let the workflow do the rest.&lt;/p&gt;
&lt;/section&gt;</content>
  </entry>
  
  <entry>
    <title>Ricardo Covo - Blog - GitHub Copilot Learning Path</title>
    <link href="https://ricardocovo.com/blog/github-copilot-learning-path/"/>
    <updated>2026-02-19T00:00:00Z</updated>
    <id>https://ricardocovo.com/blog/github-copilot-learning-path/</id>
    <content type="html">  &lt;p&gt;
    GitHub Copilot is quickly becoming a must‑have tool for modern development teams—but learning how to use it effectively can feel overwhelming. With dozens of modules, features, and enterprise considerations, it’s not always clear where to start or how to progress beyond basic code completion. This post outlines a simple, structured learning sequence for GitHub Copilot, guiding developers and organizations from foundational concepts through practical, day‑to‑day usage and into advanced and enterprise‑ready capabilities. Whether you’re an individual developer, a team lead, or supporting adoption at scale, this sequence is designed to help you learn Copilot in the right order and get real value faster.
  &lt;/p&gt;

  &lt;section&gt;
    &lt;h2&gt;1) Prerequisites (Recommended)&lt;/h2&gt;
    &lt;p class=&quot;note&quot;&gt;Build basics so Copilot suggestions make sense in real workflows.&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/intro-to-git/&quot; target=&quot;_blank&quot;&gt;Introduction to Git&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/introduction-to-github/&quot; target=&quot;_blank&quot;&gt;Introduction to GitHub&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/github-introduction-products/&quot; target=&quot;_blank&quot;&gt;Introduction to GitHub&#39;s products&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;2) Core GitHub Copilot Fundamentals&lt;/h2&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/introduction-to-github-copilot/&quot; target=&quot;_blank&quot;&gt;Introduction to GitHub Copilot&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/get-started-github-copilot/&quot; target=&quot;_blank&quot;&gt;Get started with GitHub Copilot&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/github-copilot-across-environments/&quot; target=&quot;_blank&quot;&gt;GitHub Copilot Across Environments: IDE, Chat, GitHub.com, and Command Line Techniques&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;3) Prompting &amp; Responsible Usage&lt;/h2&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/introduction-prompt-engineering-with-github-copilot/&quot; target=&quot;_blank&quot;&gt;Introduction to prompt engineering with GitHub Copilot&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/responsible-ai-with-github-copilot/&quot; target=&quot;_blank&quot;&gt;Responsible AI with GitHub Copilot&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;4) Language-Specific Practical Development (Pick your stack)&lt;/h2&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/introduction-copilot-python/&quot; target=&quot;_blank&quot;&gt;Using GitHub Copilot with Python&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/introduction-copilot-javascript/&quot; target=&quot;_blank&quot;&gt;Using GitHub Copilot with JavaScript&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;5) Day-to-Day Developer Productivity&lt;/h2&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/develop-code-features-using-github-copilot-tools/&quot; target=&quot;_blank&quot;&gt;Develop code features using GitHub Copilot tools&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/implement-code-improvements-using-github-copilot-tools/&quot; target=&quot;_blank&quot;&gt;Implement code improvements using GitHub Copilot tools&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/develop-unit-tests-using-github-copilot-tools/&quot; target=&quot;_blank&quot;&gt;Develop unit tests using GitHub Copilot tools&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/generate-documentation-using-github-copilot-tools/&quot; target=&quot;_blank&quot;&gt;Generate documentation using GitHub Copilot tools&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/paths/accelerate-app-development-using-github-copilot/&quot; target=&quot;_blank&quot;&gt;Guided project - Accelerate app development using GitHub Copilot tools&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;6) Advanced Capabilities&lt;/h2&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/advanced-github-copilot/&quot; target=&quot;_blank&quot;&gt;Using advanced GitHub Copilot features&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/building-applications-github-copilot-agent-mode/&quot; target=&quot;_blank&quot;&gt;Building applications with GitHub Copilot agent mode&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;7) Enterprise, Admin, Governance&lt;/h2&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/introduction-to-github-copilot-for-business/&quot; target=&quot;_blank&quot;&gt;Introduction to GitHub Copilot Business&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/introduction-to-github-copilot-enterprise/&quot; target=&quot;_blank&quot;&gt;Introduction to GitHub Copilot Enterprise&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/training/modules/github-copilot-management-and-customizations/&quot; target=&quot;_blank&quot;&gt;Management and customization considerations with GitHub Copilot&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;

  &lt;section&gt;
    &lt;h2&gt;Quick Suggested Paths&lt;/h2&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Individual Developers:&lt;/strong&gt; Sections 1 → 2 → 3 → 5 → 4 (as needed) → 6&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Enterprise Customers / Decision Makers:&lt;/strong&gt; Sections 1 → 2 → 3 → 7&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Hands-on Workshop / Demo:&lt;/strong&gt; Sections 2 → 5 → 6&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/section&gt;</content>
  </entry>
  
  <entry>
    <title>Ricardo Covo - Blog - GitHub Copilot for Every Role</title>
    <link href="https://ricardocovo.com/blog/github-copilot-for-everyone/"/>
    <updated>2026-02-17T00:00:00Z</updated>
    <id>https://ricardocovo.com/blog/github-copilot-for-everyone/</id>
    <content type="html">&lt;p&gt;
    GitHub Copilot is more than just a tool for developers—it&#39;s a powerful AI assistant that&#39;s transforming how
    cross-functional teams work. From drafting user stories to generating SQL queries and writing test cases, Copilot
    helps non-developers and technical specialists alike work faster, reduce manual effort, and improve quality.
&lt;/p&gt;
&lt;p&gt;
    Whether you&#39;re a Product Owner, Business Analyst, Tester, or Data Engineer, Copilot can automate repetitive tasks,
    bridge technical gaps, and accelerate your workflow. Teams using Copilot have reported significant productivity
    gains, with some achieving over 20% increases in feature velocity and ROI exceeding 1,500%.
&lt;/p&gt;

&lt;h2 class=&quot;heading&quot;&gt;Comparison of Copilot&#39;s Benefits and Applications by Role&lt;/h2&gt;
&lt;table style=&quot;width: 100%; border-collapse: collapse; margin: 20px 0;&quot;&gt;
    &lt;thead style=&quot;background-color: #f0f0f0;&quot;&gt;
        &lt;tr&gt;
            &lt;th style=&quot;border: 1px solid #ddd; padding: 12px; text-align: left;&quot;&gt;&lt;strong&gt;Role&lt;/strong&gt;&lt;/th&gt;
            &lt;th style=&quot;border: 1px solid #ddd; padding: 12px; text-align: left;&quot;&gt;&lt;strong&gt;Key Copilot Assistance&lt;/strong&gt;&lt;/th&gt;
            &lt;th style=&quot;border: 1px solid #ddd; padding: 12px; text-align: left;&quot;&gt;&lt;strong&gt;Example Applications&lt;/strong&gt;&lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;&lt;strong&gt;Product Owners&lt;/strong&gt; (Product Managers)&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;Drafts and formats product documents, user stories, and specs; explains code in plain English.&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;PRDs, user stories, release notes, stakeholder summaries.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;&lt;strong&gt;Business Analysts&lt;/strong&gt;&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;Translates business needs into structured artifacts like diagrams, SQL, and documentation.&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;Process flows, SQL queries, validation rules, traceability matrices.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;&lt;strong&gt;Testers / QA&lt;/strong&gt;&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;Auto-generates unit and integration tests; suggests edge cases and test data.&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;Unit tests, Gherkin scenarios, mocks, test coverage expansion.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;&lt;strong&gt;Data Engineers&lt;/strong&gt;&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;Speeds up data pipeline development and query generation; suggests optimizations.&lt;/td&gt;
            &lt;td style=&quot;border: 1px solid #ddd; padding: 12px;&quot;&gt;ETL scripts, SQL queries, data transformations, documentation.&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 class=&quot;heading&quot;&gt;Sources &amp; Further Reading&lt;/h2&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.blog/ai-and-ml/github-copilot/not-just-for-developers-how-product-and-security-teams-can-use-github-copilot/&quot; target=&quot;_blank&quot;&gt;Not just for developers: How product and security teams can use GitHub Copilot – GitHub Blog&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://dxrf.com/blog/2026/01/28/github-copilot-user-personas-guide/&quot; target=&quot;_blank&quot;&gt;GitHub Copilot for Every Role: Use Cases Beyond Software Development – Caffeine, Code &amp; Chaos&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/orgs/community/discussions/163538&quot; target=&quot;_blank&quot;&gt;GitHub Copilot for Business Analysts: 10 Practical Use Cases – GitHub Community&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://docs.github.com/en/copilot/tutorials/roll-out-at-scale/drive-downstream-impact/increase-test-coverage&quot; target=&quot;_blank&quot;&gt;Increasing test coverage in your company with GitHub Copilot – GitHub Docs&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.tothenew.com/blog/github-copilot-a-game-changer-for-qa-automation/&quot; target=&quot;_blank&quot;&gt;GitHub Copilot: A Game-Changer for QA Automation – TO THE NEW Blog&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://www.tigeranalytics.com/perspectives/blog/exploring-github-copilot-for-data-engineering/&quot; target=&quot;_blank&quot;&gt;Exploring GitHub Copilot for Data Engineering – Tiger Analytics&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://guageai.com/blog/github-copilot-impact-engineering-teams&quot; target=&quot;_blank&quot;&gt;GitHub Copilot Impact on Engineering Teams: Real Data – GuageAI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  
  <entry>
    <title>Ricardo Covo - Blog - How to save BIG on Azure with Spot Instances</title>
    <link href="https://ricardocovo.com/blog/how-to-save-big-on-azure-with-spot-instances/"/>
    <updated>2023-11-16T00:00:00Z</updated>
    <id>https://ricardocovo.com/blog/how-to-save-big-on-azure-with-spot-instances/</id>
    <content type="html">&lt;p&gt;
    I have been working with Azure for a long time… So I am ashamed to say that I did not know about Spot instances
    until I saw an announcement this summer about them being available for Azure Container Instances (ACI). Now, I
    use them in many scenarios and save a ton of money for myself and my clients.
&lt;/p&gt;
&lt;h2 class=&quot;heading&quot;&gt;What are Spot Instances?&lt;/h2&gt;
&lt;p&gt;First things first, Azure Spot Instances are a way to get cheap and scalable computing power on the Azure cloud.
    They run on unused Azure capacity and can be up to 90% cheaper than the regular price. However, they can also be
    evicted at any time if Azure needs the capacity back or if the price goes above your limit. So, they are best
    for workloads that can handle interruptions, like testing, batch processing, or analytics.&lt;/p&gt;
&lt;p&gt;Currently, Spot Instances are being offered on Azure Virtual Machines and Azure Container Instances (&lt;a href=&quot;https://azure.microsoft.com/en-ca/updates/public-preview-azure-container-instancesaci-spot-containers/&quot;&gt;ACIs
        are on
        public preview&lt;/a&gt; and only available in West Europe, East US, and West US2).&lt;/p&gt;
&lt;h2 class=&quot;heading&quot;&gt;How does it work?&lt;/h2&gt;
&lt;p&gt;When you create your instance, you will have the option to “Run with Azure Spot discount”. The image below shows
    an example of creating a VM, but a similar option appears when creating ACIs:&lt;/p&gt;
&lt;figure class=&quot;image-container&quot;&gt;
    &lt;img src=&quot;https://ricardocovo.com/images/blog-posts/azure-spot-setup.png&quot; alt=&quot;Spot Instances Setup&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Once you select your Discount, you can decide the Eviction Type and the Eviction Policy, according to your needs.

    As a reminder, Spot instances are operating on excess capacity; if resources are needed by Azure, you can and
    will get evicted. So, these should only be used on non-critical workloads, or on workloads where interruptions
    are needed. &lt;/p&gt;
&lt;h2 class=&quot;heading&quot;&gt;Benefit$$$?&lt;/h2&gt;
&lt;p&gt;The main benefit is cost. You can run with tons of computing power, paying only a fraction of the cost. Imagine,
    for
    example, a rendering job that runs sporadically but requires powerful machines; you can use Spot Instances to
    get
    the job done, at a low cost, and then stop the machine yourself or let it be deallocated. You can use Spot
    Advisor
    to calculate your potential savings, but in most cases, the savings are simply amazing:&lt;/p&gt;
&lt;figure class=&quot;image-container&quot;&gt;
    &lt;img src=&quot;https://ricardocovo.com/images/blog-posts/azure-spot-instance-sample-savings.webp&quot; alt=&quot;Sample Savings for Spot VMS&quot; /&gt;
    &lt;figcaption&gt;Sample Savings for Spot VMS&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Besides the possibility of getting evicted, Spot Instances are basically identical to the regular service:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Fast and reliable. They use the latest hardware and software technologies to deliver high performance and
        availability.&lt;/li&gt;
    &lt;li&gt;Secure and compliant. They are protected by multiple layers of security, including encryption, firewalls,
        and identity management.&lt;/li&gt;
    &lt;li&gt;Scalable and flexible. You can easily scale up or down depending on your workload and demand.&lt;/li&gt;
    &lt;li&gt;Cost-effective and convenient. They have a pay-as-you-go pricing model, which means you only pay for what
        you use.You can also save money by using reserved instances, spot instances, or hybrid benefit options.&lt;/li&gt;
    &lt;li&gt;Plus, you can access your virtual machines from anywhere using the Azure portal, CLI, or SDK.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 class=&quot;heading&quot;&gt;Where have I used them?&lt;/h2&gt;
&lt;p&gt;I am currently using a Spot VM Machine to run a client application that we are modernizing. The application is
    running as a reference for our development team, so it is not critical, however, it does require a bit of
    compute power. Having a Spot Instance just made sense, we have been running it for a month or so and have not
    been evicted once.&lt;/p&gt;
&lt;p&gt;We are also using ACI. We have a nightly process that manages images, it requires a fair bit of computing power,
    but in the right environment should only run for an hour or so. The ACI running our image is started/stopped
    programmatically, and because it knows how to stop/resume its process, we are not very concerned about being
    evicted in the middle of a run.&lt;/p&gt;
&lt;p&gt;I am sure there are many other scenarios where this can be used, now that I know about them, I keep my eyes open
    to cost savings 😄&lt;/p&gt;
&lt;p&gt;Is worth saying again: Really think about the scenario before you jump into Spot Instances, no critical workloads
    should be running on them.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Ricardo Covo - Blog - Writing a simple API in minutes with Azure Functions and SQL</title>
    <link href="https://ricardocovo.com/blog/writing-a-simple-api-in-minutes-with-azure-functions-and-sql/"/>
    <updated>2023-06-27T00:00:00Z</updated>
    <id>https://ricardocovo.com/blog/writing-a-simple-api-in-minutes-with-azure-functions-and-sql/</id>
    <content type="html">&lt;p&gt;For a long time, developers using SQL Server have felt forgotten when it comes to Azure Functions. While Cosmos DB
    bindings have been available since the beginning, the equivalent SQL Server ones have been lagging.&lt;/p&gt;
&lt;p&gt;Last month (May 2023), the General Availability of SQL Bindings for Azure functions was finally announced and I
    could&#39;t wait to jump into it. If you have used the CosmosDB bindings, there won’t be many surprises, they have done
    a good job in keeping things consistent.
&lt;/p&gt;
&lt;p&gt;To summarize, this is what they have made available:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Input / Output bindings (General Availability) — You can use Text Commands or Stored Procedures.&lt;/li&gt;
    &lt;li&gt;Track Changes Trigger (&lt;span class=&quot;strikethrough&quot;&gt;In Preview&lt;/span&gt;)&lt;br /&gt;
        &lt;strong&gt;Update Dec 6, 2023&lt;/strong&gt;: Now Generally Available.
        (&lt;a href=&quot;https://azure.microsoft.com/en-us/updates/ga-azure-sql-trigger-for-azure-functions/&quot; target=&quot;_blank&quot;&gt;annoucement&lt;/a&gt;)
    &lt;/li&gt;
&lt;/ul&gt;I decided to write a simple API using these new capabilities, I am working with a model
&lt;code class=&quot; language-css&quot;&gt;Listing&lt;/code&gt;, and aim to create a
RESTful API for it. I am using SQL Server running on a container on my machine, but this should work with
Azure SQL
as well.
&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Here we go:&lt;/p&gt;
&lt;h2 class=&quot;heading&quot;&gt;Get All Listings&lt;/h2&gt;
&lt;p&gt;Using the input binding, it selects all active listings from my table.&lt;/p&gt;
&lt;pre data-language=&quot;csharp&quot; class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;
[FunctionName(&quot;GetListings&quot;)]
public static IActionResult Run(
  [HttpTrigger(AuthorizationLevel.Function, &quot;get&quot;, Route = &quot;listing&quot;)] HttpRequest req,
  [Sql(&quot;SELECT * FROM [dbo].[Listings] WHERE IsActive = 1&quot;, &quot;SqlConnectionString&quot;)] IEnumerable&amp;lt;Object&amp;gt; result,
  ILogger log)
{ 
  return new OkObjectResult(result);
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 class=&quot;heading&quot;&gt;Get Single Listing&lt;/h2&gt;
&lt;p&gt;Using the input binding again, using the route parameter (Id) to query the database.&lt;/p&gt;
&lt;pre data-language=&quot;csharp&quot; class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;
[FunctionName(&quot;GetListing&quot;)]
public static IActionResult Run(
  [HttpTrigger(AuthorizationLevel.Function, &quot;get&quot;, Route = &quot;listing/{id}&quot;)] HttpRequest req,
  [Sql(&quot;SELECT * FROM [dbo].[Listings] WHERE Id = @Id&quot;, &quot;SqlConnectionString&quot;, &quot;@Id={id}&quot;)] IEnumerable&amp;lt;Object&amp;gt; result,
  ILogger log)
{
  return result.Count() == 0 ?
      new NotFoundResult() : 
      new OkObjectResult(result.First());
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 class=&quot;heading&quot;&gt;Create Listing&lt;/h2&gt;
&lt;p&gt;Using the output binding with an ASync collector. It&#39;s important to notice the &lt;code class=&quot;language-css&quot;&gt;AddItem&lt;/code&gt; is actually an upsert. We will use it on updates as well.&lt;/p&gt;
&lt;pre data-language=&quot;csharp&quot; class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;
[FunctionName(&quot;CreateListing&quot;)]
public static async Task&lt;CreatedResult&gt; Run(
    [HttpTrigger(AuthorizationLevel.Function, &quot;post&quot;, Route = &quot;listing&quot;)] HttpRequest req,            
    ILogger log,
    [Sql(&quot;[dbo].[Listings]&quot;, &quot;SqlConnectionString&quot;)] IAsyncCollector&amp;lt;Listing&amp;gt; listings)
{
    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    var listing = JsonConvert.DeserializeObject&amp;lt;Listing&amp;gt;(requestBody);
    listing.Id = Guid.NewGuid();
    listing.CreatedDate = listing.UpdatedDate = DateTime.Now;
    listing.IsActive = true;
    
    await listings.AddAsync(listing);
    await listings.FlushAsync();
    
    return new CreatedResult($&quot;/listing&quot;, listing);
}
&lt;/CreatedResult&gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 class=&quot;heading&quot;&gt;Update Listing&lt;/h2&gt;
&lt;p&gt;Output binding again, but with some validation on the input to compare to the route param (Id). There are
    many ways
    to be creative with the update, let me say this is just a simple example.&lt;/p&gt;
&lt;pre data-language=&quot;csharp&quot; class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;
[FunctionName(&quot;UpdateListing&quot;)]
public static async Task&lt;IActionResult&gt; Run(
    [HttpTrigger(AuthorizationLevel.Function, &quot;put&quot;, Route = &quot;listing/{id}&quot;)] HttpRequest req,
    Guid id,
    ILogger log,
    [Sql(&quot;[dbo].[Listings]&quot;, &quot;SqlConnectionString&quot;)] IAsyncCollector&amp;lt;Listing&amp;gt; listings)
{
    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
    var listing = JsonConvert.DeserializeObject&amp;lt;Listing&amp;gt;(requestBody);
    if (id != listing.Id) {
    return new BadRequestResult();
    
    }
    //prepare
    listing.UpdatedDate = DateTime.Now;
    //Update  
    await listings.AddAsync(listing);
    await listings.FlushAsync();
    
    return new OkObjectResult(listing);
}
&lt;/IActionResult&gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 class=&quot;heading&quot;&gt;Delete Listing&lt;/h2&gt;
&lt;p&gt;Output binding as well. Output Bindings are flexible, although I am using a SQL Text command, you can
    also use Stored
    Procedures for all of these.&lt;/p&gt;
&lt;pre data-language=&quot;csharp&quot; class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;
[FunctionName(&quot;DeleteListing&quot;)]
public static IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, &quot;delete&quot;, Route = &quot;listing/{id}&quot;)] HttpRequest req,
    [Sql(&quot;DELETE FROM [dbo].[Listings] WHERE Id = @Id&quot;, &quot;SqlConnectionString&quot;, &quot;@Id={id}&quot;)] IEnumerable&amp;lt;Object&amp;gt; result,
    ILogger log)
{
    return new OkResult();
}
&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 class=&quot;heading&quot;&gt;Track Changes Trigger&lt;/h2&gt;
&lt;p&gt;You will also need to enable change tracking on your database:&lt;/p&gt;
&lt;pre data-language=&quot;sql&quot; class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;
ALTER DATABASE [Database]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[Table]
ENABLE CHANGE_TRACKING;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;The Change Feed trigger basically allows you to get notified when something happens in your database, it
    is very
    useful if you are in an event-driven/distributed architecture. Here is what the code looks like:&lt;/p&gt;
&lt;pre data-language=&quot;csharp&quot; class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;
[FunctionName(&quot;ChangeFeedTrigger&quot;)]
public static void Run(
    [SqlTrigger(&quot;[dbo].[Listings]&quot;, &quot;SqlConnectionString&quot;)]
    IReadOnlyList&lt;SqlChange&lt;Listing&gt;&gt; changes,
    ILogger logger)
{
    foreach (SqlChange&lt;Listing&gt; change in changes)
    {
        Listing listing = change.Item;
        //Do your action
        logger.LogInformation($&quot;Change operation: {change.Operation}&quot;);
        logger.LogInformation($&quot;Id: {listing.Id}, Title: {listing.Name}&quot;);
    }
}
&lt;/Listing&gt;&lt;/SqlChange&lt;Listing&gt;&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;For this particular code, here is a sample output after I insert and then update a record:&lt;/p&gt;
&lt;pre data-language=&quot;powershell&quot; class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;
[2023-06-23T17:29:20.743Z] Change operation: Insert
[2023-06-23T17:29:20.744Z] Id: 0e5d476f-f450-4f09-965b-54c4ae5f1c96, Title: Casa Amore - Merida

[2023-06-23T17:31:11.349Z] Change operation: Update
[2023-06-23T17:31:11.350Z] Id: 7e4e7b10-6d5d-4b02-903d-1ffc93333f55, Title: Casa Amore - Merida
&lt;/code&gt;
&lt;/pre&gt;
&lt;h2 class=&quot;heading&quot;&gt;That&#39;s a Wrap&lt;/h2&gt;
&lt;p&gt;That is it, pretty simple and straightforward, it took way too long for this functionality to come to
    Azure Functions
    but is finally here.&lt;/p&gt;
&lt;p&gt;Here is my &lt;a href=&quot;https://github.com/ricardocovo/AzurePlayground/tree/main/Functions-SqlBindings&quot; target=&quot;_blank&quot;&gt;source code&lt;/a&gt; for your reference. Remember is just a playground 😄&lt;/p&gt;
&lt;p&gt;Here is the &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-azure-sql&quot; target=&quot;_blank&quot;&gt;official documentation&lt;/a&gt; and more &lt;a href=&quot;https://github.com/Azure/azure-functions-sql-extension/tree/main/samples/&quot; target=&quot;_blank&quot;&gt;sample code
        (from MS).&lt;/a&gt;&lt;/p&gt;

&lt;h2 class=&quot;heading&quot;&gt;Last thoughts…&lt;/h2&gt;
&lt;p&gt;Every time I do a RestAPI with Azure Functions I put them behind an API Management (APIM) service. Just
    saying….
&lt;/p&gt;
&lt;p&gt;Hope this helps 😎&lt;/p&gt;</content>
  </entry>
</feed>