<?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>DEV Community: Darko Mesaroš ⛅️</title>
    <description>The latest articles on DEV Community by Darko Mesaroš ⛅️ (@darkosubotica).</description>
    <link>https://dev.to/darkosubotica</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%2F312143%2Fa6b4bf45-f236-4de5-a50c-3642174aee81.png</url>
      <title>DEV Community: Darko Mesaroš ⛅️</title>
      <link>https://dev.to/darkosubotica</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/darkosubotica"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Fri, 27 Feb 2026 18:01:22 +0000</pubDate>
      <link>https://dev.to/darkosubotica/-pfa</link>
      <guid>https://dev.to/darkosubotica/-pfa</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws/predicting-your-ai-agents-cost-6m9" class="crayons-story__hidden-navigation-link"&gt;Predicting Your AI Agent's Cost&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws"&gt;
            &lt;img alt="AWS logo" 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%2Forganization%2Fprofile_image%2F1726%2F2a73f1e6-7995-4348-ae37-44b064274c59.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/lausalin" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F2961139%2F1ef5780a-c649-4402-9b4f-d5f5be866b63.jpg" alt="lausalin profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/lausalin" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Laura Salinas
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Laura Salinas
                
              
              &lt;div id="story-author-preview-content-3288752" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/lausalin" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2961139%2F1ef5780a-c649-4402-9b4f-d5f5be866b63.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Laura Salinas&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws" class="crayons-story__secondary fw-medium"&gt;AWS&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws/predicting-your-ai-agents-cost-6m9" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 27&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws/predicting-your-ai-agents-cost-6m9" id="article-link-3288752"&gt;
          Predicting Your AI Agent's Cost
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/beginners"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;beginners&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws/predicting-your-ai-agents-cost-6m9" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;19&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws/predicting-your-ai-agents-cost-6m9#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>aws</category>
      <category>ai</category>
      <category>agents</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Rust: Custom Error types that actually work!</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Mon, 17 Nov 2025 22:56:01 +0000</pubDate>
      <link>https://dev.to/aws/learning-rust-custom-error-types-that-actually-work-4n03</link>
      <guid>https://dev.to/aws/learning-rust-custom-error-types-that-actually-work-4n03</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; &lt;a href="https://github.com/darko-mesaros/webone" rel="noopener noreferrer"&gt;GITHUB REPO&lt;/a&gt;. Tired of writing the same verbose error handling boilerplate in your Axum handlers? Me too! 🙄 By creating a custom &lt;code&gt;AppError&lt;/code&gt; newtype that wraps &lt;code&gt;anyhow::Error&lt;/code&gt; and implements &lt;code&gt;IntoResponse&lt;/code&gt; + &lt;code&gt;From&amp;lt;E&amp;gt;&lt;/code&gt;, you can ditch all those ugly match statements and embrace the beautiful &lt;code&gt;?&lt;/code&gt; operator. Your handler functions go from messy error-matching shenanigans to clean, readable code that automatically converts any error into proper HTTP responses. It's like magic, but with more crabs! 🦀 &lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Recently I've been digging a lot into the &lt;a href="https://crates.io/crates/axum" rel="noopener noreferrer"&gt;axum&lt;/a&gt; crate for any of my Rust web projects. There are plenty of options out there for Rust web applications, but it seems that &lt;a href="https://www.arewewebyet.org/" rel="noopener noreferrer"&gt;we&lt;/a&gt; have all settled on &lt;strong&gt;Axum&lt;/strong&gt; as the go to crate. Before you even start reading this, if you have not checked it out yet - &lt;em&gt;do so now&lt;/em&gt; ... I'll wait. &lt;/p&gt;

&lt;p&gt;Okay, you're back! Love it? YES! 🥳 Now, let's talk about a learning project I am working on. Ever since I've discovered &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;htmx&lt;/a&gt; I've been immersing myself in the world of web development with &lt;a href="https://en.wikipedia.org/wiki/HATEOAS" rel="noopener noreferrer"&gt;HATEOAS&lt;/a&gt; as my priority. Just the neatness of using hypermedia gives me a rush, and helps me with all that &lt;a href="https://medium.com/@ericclemmons/javascript-fatigue-48d4011b6fc4" rel="noopener noreferrer"&gt;JavaScript fatigue&lt;/a&gt;. I do suggest you go and give &lt;a href="https://hypermedia.systems/" rel="noopener noreferrer"&gt;hypermedia systems&lt;/a&gt; a read, a thing I have been doing over the past couple of weeks.&lt;/p&gt;

&lt;p&gt;So, in the spirit of this book, I was following along with building some hypermedia driven system. But instead of using Python and Flask as stated in the book, I've opted to put my crab hat on, and do it in Rust. Like the big boy I am. In this post I wont explain how I did that (link to a post from the future will go here), but rather explain how I used the amazing features of Rust to eliminate a lot of boilerplate code on my side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errors Errors
&lt;/h2&gt;

&lt;p&gt;In order to be a good web builder, you want to make sure to return the proper HTTP status codes. (I'm looking at you &lt;code&gt;200 OK&lt;/code&gt; with an error message). So in my &lt;a href="https://docs.rs/axum/0.8.7/axum/#handlers" rel="noopener noreferrer"&gt;handler&lt;/a&gt; functions I make sure to explicitly return the Status code as part of my return tuple. Something like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="c1"&gt;// Or an Error:&lt;/span&gt;
&lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error processing hello world"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would signal back to the user (and axum) that the request was either &lt;code&gt;200 OK&lt;/code&gt;, and here is the HTML, or &lt;code&gt;500 Internal Server Error&lt;/code&gt; and an angry string. Nifty!&lt;/p&gt;

&lt;p&gt;With the glory of Rust's &lt;a href="https://doc.rust-lang.org/rust-by-example/error/result.html" rel="noopener noreferrer"&gt;Result&lt;/a&gt; enum, we are equipped to handle any errors our back end may throw at us. So, I just &lt;code&gt;match&lt;/code&gt; on call that can fail, and return something back depending on that &lt;code&gt;Result&lt;/code&gt;.&lt;br&gt;
In practice, say in this handler function that finds a &lt;code&gt;Contact&lt;/code&gt; by its ID in the database, it would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[axum::debug_handler]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_edit_contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;State&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// The function signature tells us what we expect back&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// This call can fail so let's match its Result&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="py"&gt;.db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// We're good return back the `Contact` into the `contact` variable&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="c1"&gt;// We're NOT good, return the tuple with a status code of 500&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to find contact: {e}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;edit_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EditContactTemplate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// This can also fail, but we dont need to store it into a variable,&lt;/span&gt;
    &lt;span class="c1"&gt;// we just need to return.&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;edit_template&lt;/span&gt;&lt;span class="nf"&gt;.render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Looks good, return the HTML and 200 OK&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt;
        &lt;span class="c1"&gt;// Again 500 Bad, be angry here&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to render template: {e}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a &lt;em&gt;lot&lt;/em&gt; of boilerplate code. While I do enjoy the verbosity of Rust (makes me feel all safe and cozy), this gets real old real fast. Especially when you have multiple handler functions, that invoke multiple different calls that can fail. Let's bring in another amazing feature of rust the &lt;em&gt;newtype pattern&lt;/em&gt;, and simplify this 👏&lt;/p&gt;

&lt;h2&gt;
  
  
  Building my own Error type
&lt;/h2&gt;

&lt;p&gt;I wont go too much into newtypes, as there is an &lt;a href="https://www.howtocodeit.com/articles/ultimate-guide-rust-newtypes" rel="noopener noreferrer"&gt;excellent guide&lt;/a&gt; that I encourage all of you to read. Simply put, they are thin wrappers that allow you to extend functionality of existing Types not native to your crate. And I am gonna use it to extend the implement the &lt;code&gt;IntoResponse&lt;/code&gt; trait into a type I dubbed &lt;code&gt;AppError&lt;/code&gt;. And then allow it (what ever the Error is) to be converted into &lt;a href="https://crates.io/crates/anyhow" rel="noopener noreferrer"&gt;anyhow::Error&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's first create this wrapper newtype:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;AppError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I am wrapping &lt;code&gt;anyhow::Error&lt;/code&gt; into a new type called &lt;code&gt;AppError&lt;/code&gt;. I could do the same for any other type, and just create a wrapper around it (ie. a &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt; wrapper: &lt;code&gt;struct Wrapper(Vec&amp;lt;T&amp;gt;)&lt;/code&gt;). Now comes the fun part, implementing certain traits.&lt;/p&gt;

&lt;p&gt;To implement the &lt;code&gt;IntoResponse&lt;/code&gt; trait from &lt;a href="https://docs.rs/axum/latest/axum/response/trait.IntoResponse.html" rel="noopener noreferrer"&gt;axum&lt;/a&gt; into this new type, we only need to implement the &lt;code&gt;into_response&lt;/code&gt; function, which needs to return a &lt;code&gt;Response&amp;lt;Body&amp;gt;&lt;/code&gt; type. Let's look at some code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;IntoResponse&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;into_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.into_response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 3 &lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And just like that we've implemented our own way of returning an error response from a handler function. Let me explain the code a bit:&lt;br&gt;
1) The implementation block for &lt;code&gt;IntoResponse&lt;/code&gt; for &lt;code&gt;AppError&lt;/code&gt;&lt;br&gt;
2) This is the only function needed for &lt;code&gt;IntoResponse&lt;/code&gt; and we are simply returning a &lt;code&gt;Response&lt;/code&gt; from the axum crate&lt;br&gt;
3) We just return a tuple of a &lt;code&gt;StatusCode&lt;/code&gt; and a &lt;code&gt;String&lt;/code&gt; coming from element 0 of the &lt;code&gt;AppError&lt;/code&gt; struct. Oh, and convert all that into a &lt;code&gt;Response&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is a bit more &lt;strong&gt;complicated&lt;/strong&gt; version of the same code, this one uses a templating engine to return some nicely formatted web pages. This version just expands the above, but should demonstrate that this all works really nicely with the rest of your codebase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;IntoResponse&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;into_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Returning a HTML page for an error&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Error5xxTemplate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
            &lt;span class="c1"&gt;// Select element 0, as that is our anyhow::Error string and convert it so it works with our template&lt;/span&gt;
            &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="nf"&gt;.render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
            &lt;span class="c1"&gt;// If the template render is successful, return the HTML page with the error&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.into_response&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="c1"&gt;// The render has failed catastrophically - just return some string&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INTERNAL_SERVER_ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Internal Server Error"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.into_response&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, there is a lot more going on here. Most of it is the same as before, but let me break it down:&lt;/p&gt;

&lt;p&gt;1) Somewhere in my code base I have a &lt;code&gt;Error5xxTemplate&lt;/code&gt; struct that I use with the &lt;a href="https://crates.io/crates/askama" rel="noopener noreferrer"&gt;askama&lt;/a&gt; templating crate&lt;br&gt;
2) I make sure the template renders okay, if so - return the 5xx error page, if not I just give a &lt;code&gt;500&lt;/code&gt; error and the string back.&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%2Fkbccyidfv6dm9cxr5yqs.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%2Fkbccyidfv6dm9cxr5yqs.png" alt="Absolutely gorgeous error page" width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have an &lt;code&gt;IntoResponse&lt;/code&gt; implemented. Let's give our &lt;code&gt;AppError&lt;/code&gt; the ability to take errors from anywhere.&lt;/p&gt;
&lt;h2&gt;
  
  
  Converting other error types
&lt;/h2&gt;

&lt;p&gt;To make &lt;code&gt;AppError&lt;/code&gt; a bit more flexible, I wanted to be able to automatically convert any* (*I'll come back to this in a bit) error type. Let's look at some code and make sense of it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Into&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// 2 &lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are taking advantage of a &lt;em&gt;very&lt;/em&gt; powerful crate here, &lt;a href="https://crates.io/crates/anyhow" rel="noopener noreferrer"&gt;anyhow&lt;/a&gt;. Which allows us to work with errors in Rust way more efficiently. In our case we are using it's popularity and other crates ability to convert into this Error type.&lt;/p&gt;

&lt;p&gt;Let me explain this line by line:&lt;/p&gt;

&lt;p&gt;1) We are implementing &lt;code&gt;From&amp;lt;E&amp;gt;&lt;/code&gt; for &lt;code&gt;AppError&lt;/code&gt;. By using the generic type &lt;code&gt;E&lt;/code&gt; we can have a wider implementation. This would be the equivalent of &lt;code&gt;impl From&amp;lt;sqxl::Error&amp;gt; for AppError&lt;/code&gt;. Which converts the &lt;code&gt;sqlx::Error&lt;/code&gt; type into &lt;code&gt;AppError&lt;/code&gt;&lt;br&gt;
2) This is the &lt;em&gt;critical bit&lt;/em&gt;, and why it actually limits us to certain errors. By having this &lt;code&gt;where&lt;/code&gt; clause, we only allow the generic type &lt;code&gt;E&lt;/code&gt; to be the ones that already support the &lt;code&gt;Into&lt;/code&gt; trait from &lt;code&gt;anyhow::Error&lt;/code&gt;. Basically limiting us to types that already support the conversion into this error type. &lt;br&gt;
3) We only need to implement the &lt;code&gt;from&lt;/code&gt; function that takes an error and returns itself back. By using the support mentioned above, we can just take the error and run an &lt;code&gt;.into()&lt;/code&gt; conversion.&lt;/p&gt;

&lt;p&gt;By using this generic trait approach we are essentially creating the following Rust code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SQLX:&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;sqlx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// sqlx::Error -&amp;gt; anyhow::Error -&amp;gt; AppError&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// serde_json&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// serde_json::Error -&amp;gt; anyhow::Error -&amp;gt; AppError&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// reqwest&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="nb"&gt;From&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;reqwest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// reqwest::Error -&amp;gt; anyhow::Error -&amp;gt; AppError&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so on ... You get the picture!&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%2F9vh1g44028k0lo0b4h7u.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%2F9vh1g44028k0lo0b4h7u.png" alt="Error conversion" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Actual implementation
&lt;/h2&gt;

&lt;p&gt;Okay, so we have our newtype &lt;code&gt;AppError&lt;/code&gt;, it has all the things it needs to be converted to our Error type. How does it actually work? Well, let's go back to our &lt;code&gt;get_edit_contact&lt;/code&gt; handler function from before, and see what has changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[axum::debug_handler]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_edit_contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;State&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppState&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;AppError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="py"&gt;.db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sqlx::Error -&amp;gt; AppError&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;edit_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EditContactTemplate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;contact&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;edit_template&lt;/span&gt;&lt;span class="nf"&gt;.render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// askama::Error -&amp;gt; AppError&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;Html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whoa, that is way tighter than before. Yes, we are using the &lt;code&gt;?&lt;/code&gt; &lt;a href="https://doc.rust-lang.org/std/result/index.html" rel="noopener noreferrer"&gt;operator&lt;/a&gt; we &lt;em&gt;propagate the errors up the call stack&lt;/em&gt;. Meaning the value of the &lt;code&gt;Result&lt;/code&gt; returned by both &lt;code&gt;Contact::find_by_id&lt;/code&gt; and &lt;code&gt;.render()&lt;/code&gt; are returned back to axum as &lt;code&gt;AppError&lt;/code&gt; newtypes. &lt;/p&gt;

&lt;p&gt;This means we no longer have to deal with error handling within the function itself, and we are just returning the same error type back. Since it is the same error type, both function handler and axum are happy with receiving it! 🥳 Huzzah!&lt;/p&gt;

&lt;p&gt;If you want to see the full codebase in action, you can check out my GitHub repo &lt;a href="https://github.com/darko-mesaros/webone" rel="noopener noreferrer"&gt;here&lt;/a&gt;. And please ignore the mess, this is just a learning repo! 🙏&lt;/p&gt;

</description>
      <category>rust</category>
      <category>axum</category>
      <category>development</category>
    </item>
    <item>
      <title>Asynchronous Rust 🦀 - RustConf 2025 | Day 1</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Wed, 03 Sep 2025 05:49:16 +0000</pubDate>
      <link>https://dev.to/aws/asynchronous-rust-rustconf-2025-day-1-141n</link>
      <guid>https://dev.to/aws/asynchronous-rust-rustconf-2025-day-1-141n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;tl;dr&lt;br&gt;
I was at RustConf 2025, and attended a cool workshop on Rust asynchronous programming. You can check it out &lt;a href="https://github.com/thebracket/rustconf2025_async_fundamentals" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This year, for the first time, I've attended &lt;a href="https://rustconf.com/" rel="noopener noreferrer"&gt;RustConf&lt;/a&gt;. It's a time for me to meet the Rust community, learn some new skills, and check up on Ferris, and see how it's doing. Rust conf is an annual conference for all us Rustaceans, and this year it was held in Seattle, WA. A place I live in, so I could easily just pop in! 🥳&lt;/p&gt;

&lt;p&gt;Okay, let's get into day 1 - Workshop/Async day&lt;/p&gt;

&lt;h2&gt;
  
  
  Workshop - Async Fundamentals
&lt;/h2&gt;

&lt;p&gt;To start off the event, I attended the &lt;em&gt;Rust Async Fundamentals&lt;/em&gt; workshop by &lt;a href="https://www.linkedin.com/in/herbert-wolverson-98523346/" rel="noopener noreferrer"&gt;Herbert Wolverson&lt;/a&gt;. This gave me an opportunity to learn all about building asynchronous software in Rust. &lt;/p&gt;

&lt;p&gt;The workshop is really great and Herbert is an excellent teacher. What I enjoyed the most is how he broke down &lt;code&gt;tokio&lt;/code&gt; and other macros. Basically he showed us all what is exactly happening behind the scenes when you just add &lt;code&gt;#[tokio::main]&lt;/code&gt; above your &lt;code&gt;main()&lt;/code&gt; function. This made me realize how much heavy lifting Rust is doing, all while still giving you all the control you need! &lt;/p&gt;

&lt;p&gt;The workshop is actually public if you wanna take a crack at it yourself, but please give Herbert a follow and check out rest of his courses. The workshop can be found on &lt;a href="https://github.com/thebracket/rustconf2025_async_fundamentals" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But, what did I learn today? 🤔&lt;/p&gt;

&lt;h2&gt;
  
  
  Actor Model
&lt;/h2&gt;

&lt;p&gt;Okay, so I need to talk about something really neat I've learned today - and yeah, long time Rustaceans may scoff at me for this. But the &lt;em&gt;Actor Model&lt;/em&gt; is something that I am finding incredibly useful. So what is an &lt;em&gt;Actor Model&lt;/em&gt;? Well it's a pattern in Software Development when building concurrent programming. Basically what you are doing is organizing code around independent &lt;em&gt;actors&lt;/em&gt; that communicate with each other through passing messages (using stuff like &lt;code&gt;mpsc&lt;/code&gt;). The entire &lt;code&gt;actix&lt;/code&gt; &lt;a href="https://github.com/actix/actix" rel="noopener noreferrer"&gt;framework&lt;/a&gt; is an Actor framework for Rust (the one I used the most is &lt;code&gt;actix-web&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;It integrates seamlessly with Rusts onwership and concurrency principles. Since Rust &lt;strong&gt;has no Garbage Collector&lt;/strong&gt;, actors provide an elegant way to manage memory safety. Because actors communicate via shared channels, they do not share &lt;em&gt;mutable states&lt;/em&gt;, meaning this could help you avoid data races and concurrency bugs. 🔥&lt;/p&gt;

&lt;p&gt;Well, let me show you in the simplest way possible (I will add comments to the code so it makes sense in a single shot):&lt;/p&gt;

&lt;p&gt;&lt;em&gt;src/lib.rs&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// List of commands that can be sent to the Actor.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;SharedStateCommand&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Increment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;oneshot&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// oneshot is key here as this is how the information is sent back - via this channel&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// This now spawns an actor. This actor maintains the `counter` state. The way it processes commands is through the `Sender` it returns, and in a thread-safe manner.&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mpsc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Create our tx and rx channels with a buffer capacity of 32 messages&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;rx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mpsc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Initialize the counter&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Spawn the actor and move everythinng under it&lt;/span&gt;
    &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Process the commands being sent to it&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rx&lt;/span&gt;&lt;span class="nf"&gt;.recv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nn"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Increment&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="nn"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp_tx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp_tx&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;tx&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Function that gets the current counter value by using `oneshot` to send a command and wait for the return via the same channel&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mpsc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp_tx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resp_rx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;oneshot&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp_tx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;resp_rx&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This is a fire and forget function where it just tells the actor to increment the counter without waiting for the results&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mpsc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Increment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// we dont really care here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay and then how do we use this library crate now? Well here is an example using the &lt;code&gt;axum&lt;/code&gt; framework. More details in the comments below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;http&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Extension&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;shared_state_actor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mpsc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Start my actor here and get its handle - BTW I've imported my library here in Cargo.toml&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;my_actor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;shared_state_actor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Some Axum boilerplate as well as routes&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
        &lt;span class="nf"&gt;.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;routing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hello_json&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;.layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Extension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_actor&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// THIS IS KEY - Add the actor here, so it's available to all routes&lt;/span&gt;

    &lt;span class="c1"&gt;// Start the axum server&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;net&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;TcpListener&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1:3001"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;.await&lt;/span&gt;
        &lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(serde::Serialize,&lt;/span&gt; &lt;span class="nd"&gt;serde::Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;HelloJson&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;hello_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;Extension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_actor&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;Extension&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Sender&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SharedStateCommand&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Extract the layer here using Axum's extractors&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HelloJson&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Here is where we bump up the counter in the actor&lt;/span&gt;
    &lt;span class="nn"&gt;shared_state_actor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;increment_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;my_actor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Here is where we get the current counter (it uses the oneshot channel for this)&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;new_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;shared_state_actor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;my_actor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


    &lt;span class="c1"&gt;// Respond back&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HelloJson&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Counter: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_total&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This such a great way to handle concurrency fearlessly (tm). 🦀 Besides this, I've also learned about &lt;em&gt;Cancel Safety&lt;/em&gt; and &lt;em&gt;Select&lt;/em&gt; statements in Tokio. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;Overall feelings of Day 1 - I &lt;em&gt;love it&lt;/em&gt;! The fact that the content is extremely technical tickles my fancy. Even though this was an &lt;em&gt;essentials&lt;/em&gt; workshop, I felt I learned so much about Async patterns in Rust. Most of my workshop...mates(?) were incredibly skilled engineers, so even listening to their questions made me learn so many new things.&lt;/p&gt;

&lt;p&gt;I am looking forward to day 2 when I get to visit some shorter sessions and mingle with more Rust folks!&lt;/p&gt;

&lt;p&gt;Stay tuned for part 2.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>async</category>
      <category>programming</category>
      <category>rustconf</category>
    </item>
    <item>
      <title>Updates from AWS CDK! 🥳</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Fri, 13 Jun 2025 19:26:46 +0000</pubDate>
      <link>https://dev.to/darkosubotica/updates-from-aws-cdk-3m57</link>
      <guid>https://dev.to/darkosubotica/updates-from-aws-cdk-3m57</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws/aws-cdk-in-action-may-2025-empowered-deployments-governance-and-community-1gdb" class="crayons-story__hidden-navigation-link"&gt;AWS CDK in Action — May 2025: Empowered Deployments, Governance, and Community&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws"&gt;
            &lt;img alt="AWS logo" 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%2Forganization%2Fprofile_image%2F1726%2F2a73f1e6-7995-4348-ae37-44b064274c59.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/praneetaprakash" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F985752%2F6af16862-5e91-41f7-bedb-de0234e3ab3c.jpg" alt="praneetaprakash profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/praneetaprakash" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Praneeta Prakash
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Praneeta Prakash
                
              
              &lt;div id="story-author-preview-content-2585900" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/praneetaprakash" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F985752%2F6af16862-5e91-41f7-bedb-de0234e3ab3c.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Praneeta Prakash&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws" class="crayons-story__secondary fw-medium"&gt;AWS&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws/aws-cdk-in-action-may-2025-empowered-deployments-governance-and-community-1gdb" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 13 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws/aws-cdk-in-action-may-2025-empowered-deployments-governance-and-community-1gdb" id="article-link-2585900"&gt;
          AWS CDK in Action — May 2025: Empowered Deployments, Governance, and Community
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cdk"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cdk&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtools"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtools&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/infrastructureascode"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;infrastructureascode&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws/aws-cdk-in-action-may-2025-empowered-deployments-governance-and-community-1gdb" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;15&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws/aws-cdk-in-action-may-2025-empowered-deployments-governance-and-community-1gdb#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>aws</category>
      <category>cdk</category>
      <category>devtools</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Wed, 07 May 2025 14:40:05 +0000</pubDate>
      <link>https://dev.to/darkosubotica/-37ii</link>
      <guid>https://dev.to/darkosubotica/-37ii</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws-heroes/ai-agents-how-they-work-and-how-to-build-them-17if" class="crayons-story__hidden-navigation-link"&gt;AI Agents: how they work and how to build them&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws-heroes"&gt;
            &lt;img alt="AWS Heroes logo" 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%2Forganization%2Fprofile_image%2F2491%2Ff0c1a659-c959-42cd-bb12-cd25909dd9db.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/slobodan" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F65066%2F7bc82b67-45c1-462f-857a-da6b7d8f1038.jpeg" alt="slobodan profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/slobodan" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Slobodan Stojanović
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Slobodan Stojanović
                
              
              &lt;div id="story-author-preview-content-2456463" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/slobodan" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F65066%2F7bc82b67-45c1-462f-857a-da6b7d8f1038.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Slobodan Stojanović&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws-heroes" class="crayons-story__secondary fw-medium"&gt;AWS Heroes&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws-heroes/ai-agents-how-they-work-and-how-to-build-them-17if" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 3 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws-heroes/ai-agents-how-they-work-and-how-to-build-them-17if" id="article-link-2456463"&gt;
          AI Agents: how they work and how to build them
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/llm"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;llm&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws-heroes/ai-agents-how-they-work-and-how-to-build-them-17if" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;47&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws-heroes/ai-agents-how-they-work-and-how-to-build-them-17if#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              7&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            26 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>llm</category>
      <category>programming</category>
      <category>aws</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Tue, 15 Apr 2025 15:20:42 +0000</pubDate>
      <link>https://dev.to/darkosubotica/-2pn3</link>
      <guid>https://dev.to/darkosubotica/-2pn3</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/recursivecodes/using-the-momento-topics-http-api-to-update-nixie-tubes-3d18" class="crayons-story__hidden-navigation-link"&gt;Using the Momento Topics HTTP API to Update Nixie Tubes&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/recursivecodes" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F895331%2F59774920-1938-4c2e-b293-efa14fe46948.jpg" alt="recursivecodes profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/recursivecodes" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Todd Sharp
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Todd Sharp
                
              
              &lt;div id="story-author-preview-content-2402905" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/recursivecodes" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F895331%2F59774920-1938-4c2e-b293-efa14fe46948.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Todd Sharp&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/recursivecodes/using-the-momento-topics-http-api-to-update-nixie-tubes-3d18" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 15 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/recursivecodes/using-the-momento-topics-http-api-to-update-nixie-tubes-3d18" id="article-link-2402905"&gt;
          Using the Momento Topics HTTP API to Update Nixie Tubes
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/arduino"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;arduino&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/pubsub"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;pubsub&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/learning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;learning&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/momento"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;momento&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/recursivecodes/using-the-momento-topics-http-api-to-update-nixie-tubes-3d18" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/recursivecodes/using-the-momento-topics-http-api-to-update-nixie-tubes-3d18#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>arduino</category>
      <category>pubsub</category>
      <category>learning</category>
      <category>momento</category>
    </item>
    <item>
      <title>Amazon Q Developer CLI 1.7.3 - Now with VIM! 😍</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Fri, 11 Apr 2025 04:10:02 +0000</pubDate>
      <link>https://dev.to/aws/amazon-q-developer-cli-173-now-with-vim-4fj7</link>
      <guid>https://dev.to/aws/amazon-q-developer-cli-173-now-with-vim-4fj7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line.html?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;Amazon Q Developer CLI&lt;/a&gt; 1.7.3 introduces five key improvements: just type &lt;code&gt;q&lt;/code&gt; to launch; granular tool permission controls with &lt;code&gt;/tools trust/untrust&lt;/code&gt; commands; VIM integration via &lt;code&gt;/editor&lt;/code&gt; command for complex prompts; multi-line editing with Ctrl+J; and enhanced context management through the &lt;code&gt;/context&lt;/code&gt; command. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Hey there! 👋 Amazon Q developer CLI 1.7.3 is out, and this new version has a couple of really neat goodies that I really want to share with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Simplified Command
&lt;/h2&gt;

&lt;p&gt;Super simple but incredibly convenient - if you want to use Q CLI right now, you can just type &lt;code&gt;q&lt;/code&gt;. Yep, that's it! No longer need to type &lt;code&gt;q chat&lt;/code&gt; which is great. Saves me five characters, and makes it super snappy to kick off! 🥳&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%2Frup12.net%2Fdevto%2Fq173%2Fq_launch.gif" 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%2Frup12.net%2Fdevto%2Fq173%2Fq_launch.gif" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. New Tools Permissions Dialog
&lt;/h2&gt;

&lt;p&gt;This is really neat. Amazon Q Developer now has the a tools permissions/control dialog. If you do &lt;code&gt;/tools&lt;/code&gt;, it's going to give you the current available tools - these are the tools available to Q CLI (stuff that can read from disk, write to disk, use AWS API, and execute bash commands).&lt;/p&gt;

&lt;p&gt;You can now enter &lt;code&gt;/tools&lt;/code&gt; and then something like &lt;code&gt;untrust&lt;/code&gt; and &lt;code&gt;trust&lt;/code&gt; and &lt;code&gt;trustall&lt;/code&gt;. Simply put, when you &lt;code&gt;untrust&lt;/code&gt; a tool, that tool needs to ask for confirmation to do anything. So I can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/tools untrust fs_read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the FS read tool has per-request permissions. Anytime Q CLI tries to read something off the disk, it's going to ask me "Can I read this off the disk?" It's a really cool way for you to granularly control the permissions. Wonderful!&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%2Fgkirg2uod43wlva8j19j.gif" 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%2Fgkirg2uod43wlva8j19j.gif" alt="Gif animation of the /tools command being run and a demonstration of how we can untrust a specific tool. In this case the fs_read" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. VIM Integration
&lt;/h2&gt;

&lt;p&gt;This one I &lt;em&gt;really&lt;/em&gt; like. Say, you want to enter a more complicated prompt - something with multiple lines, bullet points, or something you'd normally edit somewhere else and paste in. 🤔 What if you could use &lt;strong&gt;objectively the best text editor in the world&lt;/strong&gt;: VIM, VI, Neovim (call it what you want) right in Amazon Q CLI? 👏&lt;/p&gt;

&lt;p&gt;Now you can use the &lt;code&gt;/editor&lt;/code&gt; command. This brings up your default set editor (in my case, it's vim), and I can just come here and literally paste or type out something inside. Once you are done save and quit (if you know how 😈), and once that's done, it automatically goes into the prompt and Q CLI can use it. Beautiful!&lt;/p&gt;

&lt;p&gt;To configure a custom editor (emacs, nano, joe, ed ... whatever). You can do so with the &lt;code&gt;export&lt;/code&gt; command. &lt;strong&gt;But make sure you do it in &lt;code&gt;bash&lt;/code&gt;, as Q CLI is using Bash&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;joe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Flsi315aqwc1husd73t9n.gif" 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%2Flsi315aqwc1husd73t9n.gif" alt="Gif animation of how the /editor command works. Opening up vim as the text editor as I enter in various lines of text that ultimately get saved as a prompt" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Multi-line Editing
&lt;/h2&gt;

&lt;p&gt;Speaking of multi-line editing, you can now do this in Amazon Q Developer. Instead of entering the editor using &lt;code&gt;/editor&lt;/code&gt; you can just hit &lt;code&gt;Ctrl + j&lt;/code&gt; and it will append a new line to your input. Hitting &lt;code&gt;Enter&lt;/code&gt; at the end of it will submit the prompt!&lt;/p&gt;

&lt;p&gt;You can do multi-line things now within the actual command line. Love it!&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%2F9yk8dykqain6rccuml3k.gif" 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%2F9yk8dykqain6rccuml3k.gif" alt="Gif animaton of me using ctrl+j in amazon q to add new lines to my prompt followed by submitting a prompt." width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Enhanced Context Controls
&lt;/h2&gt;

&lt;p&gt;Lastly, there are additional controls when it comes to managing the context. Within &lt;code&gt;q&lt;/code&gt; type &lt;code&gt;/context&lt;/code&gt;, and you can actually see additional commands and more clarifications about the context rules that are part of Q developer CLI.&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%2F22nkh44t6z1kg2nk8wyk.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%2F22nkh44t6z1kg2nk8wyk.png" alt="Screenshot of a terminal window showing amazon Q and the result of the /context command" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By typing &lt;code&gt;/context show&lt;/code&gt; it will show you how the current &lt;em&gt;global&lt;/em&gt; and &lt;em&gt;profile&lt;/em&gt; contexts are configured.&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%2Fv17rjswex4mkznv0xomm.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%2Fv17rjswex4mkznv0xomm.png" alt="Screenshot of a terminal window showing amazon q and showing more details of the /context show command" width="800" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This isn't anything new, but it's a cleaner way of having you work with your context now and looks way nicer inside of Q CLI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out today for free! 🚀
&lt;/h2&gt;

&lt;p&gt;So if you have not been using Amazon Q CLI up until now, &lt;em&gt;now&lt;/em&gt; is the perfect time to try it. It's free! Go ahead and use Amazon Q Developer CLI to build tools, automate stuff, deploy stuff, to even convert weird audio formats into &lt;code&gt;.wav&lt;/code&gt; or anything like that. (yes it can do that too).&lt;/p&gt;

</description>
      <category>aws</category>
      <category>developer</category>
      <category>programming</category>
      <category>news</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Thu, 10 Apr 2025 17:09:24 +0000</pubDate>
      <link>https://dev.to/darkosubotica/-48cg</link>
      <guid>https://dev.to/darkosubotica/-48cg</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws/standardizing-ai-tooling-with-model-context-protocol-mcp-nmj" class="crayons-story__hidden-navigation-link"&gt;Standardizing AI Tooling with Model Context Protocol (MCP)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws"&gt;
            &lt;img alt="AWS logo" 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%2Forganization%2Fprofile_image%2F1726%2F2a73f1e6-7995-4348-ae37-44b064274c59.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/debnsuma" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F281052%2F696d68b0-587b-4736-ba2a-9264af5d0536.jpeg" alt="debnsuma profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/debnsuma" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Suman Debnath
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Suman Debnath
                
              
              &lt;div id="story-author-preview-content-2394535" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/debnsuma" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F281052%2F696d68b0-587b-4736-ba2a-9264af5d0536.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Suman Debnath&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws" class="crayons-story__secondary fw-medium"&gt;AWS&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws/standardizing-ai-tooling-with-model-context-protocol-mcp-nmj" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 9 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws/standardizing-ai-tooling-with-model-context-protocol-mcp-nmj" id="article-link-2394535"&gt;
          Standardizing AI Tooling with Model Context Protocol (MCP)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/genai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;genai&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws/standardizing-ai-tooling-with-model-context-protocol-mcp-nmj" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;16&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws/standardizing-ai-tooling-with-model-context-protocol-mcp-nmj#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>mcp</category>
      <category>agents</category>
      <category>genai</category>
    </item>
    <item>
      <title>Making Makefiles for fun and profit</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Wed, 26 Mar 2025 15:18:57 +0000</pubDate>
      <link>https://dev.to/aws/making-makefiles-for-fun-and-profit-kl6</link>
      <guid>https://dev.to/aws/making-makefiles-for-fun-and-profit-kl6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Make is a 48-year-old build automation tool that's still incredibly useful today. This post explains how Makefiles work, why they're awesome despite their cryptic syntax, and shows practical examples for modern development workflows - from Terraform automation to local dev environments. You can even use &lt;a href="https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line.html?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;Amazon Q Developer CLI&lt;/a&gt; to generate Makefiles without becoming a Make expert! Stop hammering that up arrow key and start automating your development tasks. 🚀&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents:
&lt;/h2&gt;



&lt;ul&gt;
&lt;li&gt;
Why Makefiles

&lt;ul&gt;
&lt;li&gt;Makefile breakdown&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Common uses

&lt;ul&gt;
&lt;li&gt;Terraform automation&lt;/li&gt;
&lt;li&gt;Local Development Environment automation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Makefiles 48 years later

&lt;ul&gt;
&lt;li&gt;My link shortener CDK project&lt;/li&gt;
&lt;li&gt;Working with static websites&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Wrap up&lt;/li&gt;

&lt;/ul&gt;



&lt;p&gt;Alright, I am sure everyone has heard of &lt;code&gt;make&lt;/code&gt;, a critical tool in the world of software development that has been primarily used for build automation. But have you really used it? Like, have you seen what it can do? Well in this post, I will go over the history of &lt;code&gt;make&lt;/code&gt;, how it works, some cool use cases (besides just building C software) and how you can benefit from it in the year 2025.&lt;/p&gt;

&lt;p&gt;Believe it or not, &lt;code&gt;make&lt;/code&gt; is &lt;em&gt;48&lt;/em&gt; years old (at the time of writing) which makes it older than &lt;em&gt;DNS&lt;/em&gt;, &lt;em&gt;BSD Unix&lt;/em&gt;, and even &lt;em&gt;TCP/IP&lt;/em&gt;. It was made by &lt;a href="https://en.wikipedia.org/wiki/Stuart_Feldman" rel="noopener noreferrer"&gt;Stuart Feldman&lt;/a&gt; to solve a quite common problem at the time: &lt;em&gt;software developers were forgetting which files needed to be recompiled after making changes to the source code&lt;/em&gt;. And back then, you often had limited system time to do your debugging and compilations. Leading to, well, a terrible developer experience! &lt;/p&gt;

&lt;p&gt;While I do not have issues forgetting to compile files, I often forget what command does what to my stack and end up mercilessly slamming the up arrow key looking back in my Bash history, hoping the same command is there. Often that is not the case. So, let's see &lt;em&gt;why&lt;/em&gt; exactly &lt;code&gt;make&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Makefiles
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;But, Darko, why not just write a &lt;code&gt;deploy.sh&lt;/code&gt; or &lt;code&gt;build.sh&lt;/code&gt; script and be done with it?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Good catch dear reader, that &lt;em&gt;was&lt;/em&gt; the way it was done even back in Stuart's time, but it often involved very complex scripting that at times could be an overkill for your project. Also, the fact that simple scripts would often just brute force build your applications and just recompile everything, would just take too much time. Back then, compiling was expensive and time consuming so you had to be careful. &lt;code&gt;make&lt;/code&gt; actually solved that problem by only compiling source code files that have changed and creating an intricate system of dependencies to better orchestrate your build process.&lt;/p&gt;

&lt;p&gt;Let's have a look at one simple C project &lt;code&gt;Makefile&lt;/code&gt;. Oh yeah, &lt;code&gt;Makefile&lt;/code&gt; is a file where you outline how your build, deploy, or whatever is being done. It's what &lt;code&gt;make&lt;/code&gt; looks for when it's run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Define variables
&lt;/span&gt;&lt;span class="nv"&gt;CC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; gcc
&lt;span class="nv"&gt;CFLAGS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;span class="nv"&gt;TARGET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; myprogram

&lt;span class="c"&gt;# Source files
&lt;/span&gt;&lt;span class="nv"&gt;SRCS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; main.c utils.c
&lt;span class="nv"&gt;OBJS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;SRCS:.c&lt;span class="o"&gt;=&lt;/span&gt;.o&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Default target (build)
&lt;/span&gt;&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(TARGET)&lt;/span&gt;

&lt;span class="c"&gt;# Link object files to create the executable
&lt;/span&gt;&lt;span class="nl"&gt;$(TARGET)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(OBJS)&lt;/span&gt;
    &lt;span class="p"&gt;$(&lt;/span&gt;CC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CFLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="nv"&gt;$^&lt;/span&gt;

&lt;span class="c"&gt;# Compile source files into object files
&lt;/span&gt;&lt;span class="nl"&gt;%.o&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;%.c&lt;/span&gt;
    &lt;span class="p"&gt;$(&lt;/span&gt;CC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CFLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;

&lt;span class="c"&gt;# Clean up generated files
&lt;/span&gt;&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;TARGET&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;OBJS&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Declare phony targets (targets that don't represent files)
&lt;/span&gt;&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;all clean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... Well that looks scary! What is all that!? 🤯&lt;/p&gt;

&lt;h3&gt;
  
  
  Makefile breakdown
&lt;/h3&gt;

&lt;p&gt;Yes yes, I know! That does look byzantine. The &lt;a href="https://www.gnu.org/software/make/manual/make.html" rel="noopener noreferrer"&gt;declarative programming language&lt;/a&gt; it uses definitely is an artifact of its time, and it takes some getting used to. But I will give you a crash course of what this code does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Define variables
&lt;/span&gt;&lt;span class="nv"&gt;CC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; gcc
&lt;span class="nv"&gt;CFLAGS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;span class="nv"&gt;TARGET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; myprogram

&lt;span class="c"&gt;# Source files
&lt;/span&gt;&lt;span class="nv"&gt;SRCS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; main.c utils.c
&lt;span class="nv"&gt;OBJS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;SRCS:.c&lt;span class="o"&gt;=&lt;/span&gt;.o&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, we define all the variables! Actually, to add to the confusion, &lt;code&gt;make&lt;/code&gt; calls these macros, but whatever. They are basically variables. And here we define certain things up front so we dont have to manually make changes down in the file. Here we tell it what compiler we are using, what compiler flags we need to set up, and the name of our program. And, as you can see, we also tell it what source files it needs to compile.&lt;/p&gt;

&lt;p&gt;Lastly it has this cool little way of defining the &lt;code&gt;OBJS&lt;/code&gt; variable (macro, whatever): &lt;code&gt;$(SRCS:.c=.o)&lt;/code&gt; which simply put tells it, everything in the &lt;code&gt;SRCS&lt;/code&gt; macro but change the &lt;code&gt;.c&lt;/code&gt; with &lt;code&gt;.o&lt;/code&gt;, essentially making a macro that is equivalent to: &lt;code&gt;OBJS = main.o utils.o&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Default target (build)
&lt;/span&gt;&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(TARGET)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what we call a &lt;strong&gt;target&lt;/strong&gt;, basically a code block that will run and it's dependency. The &lt;code&gt;all&lt;/code&gt; target will run if we run &lt;code&gt;make all&lt;/code&gt; or even just &lt;code&gt;make&lt;/code&gt; without any parameter. Because we have &lt;code&gt;$(TARGET)&lt;/code&gt; in as it's prerequisite it will run that first. I will cover the way prerequisites work in a little bit. Speaking of &lt;code&gt;$(TARGET)&lt;/code&gt;...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Link object files to create the executable
&lt;/span&gt;&lt;span class="nl"&gt;$(TARGET)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(OBJS)&lt;/span&gt;
    &lt;span class="p"&gt;$(&lt;/span&gt;CC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CFLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt; &lt;span class="nv"&gt;$^&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the &lt;strong&gt;linking&lt;/strong&gt; happens. As you can see a bunch of macros are here, but also some weird new macros. Let me expand this code into what it would look like if we replaced all the macros with the actual values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;myprogram&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;main.o utils.o&lt;/span&gt;
    gcc &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; myprogram main.o utils.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well that makes more sense! The keys here are the built in macros:&lt;code&gt;$@&lt;/code&gt; and &lt;code&gt;$^&lt;/code&gt;. Which point to &lt;code&gt;$(TARGET)&lt;/code&gt; and &lt;em&gt;all the prerequisites&lt;/em&gt;, respectively. This makes it very dynamic, as it will include all the elements of the &lt;code&gt;$(OBJS)&lt;/code&gt; macro automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Compile source files into object files
&lt;/span&gt;&lt;span class="nl"&gt;%.o&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;%.c&lt;/span&gt;
    &lt;span class="p"&gt;$(&lt;/span&gt;CC&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;CFLAGS&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;$&amp;lt;&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, this is actually where the &lt;strong&gt;compilation&lt;/strong&gt; happens. And this is where we see a very powerful &lt;code&gt;make&lt;/code&gt; feature called &lt;em&gt;a pattern rule&lt;/em&gt;. What this rule says with this &lt;code&gt;%.o: %.c&lt;/code&gt; is: &lt;em&gt;"to build any file ending *&lt;/em&gt;.o** you need a file with the same name but ending in &lt;strong&gt;.c&lt;/strong&gt;"* - Magical! 🤩&lt;/p&gt;

&lt;p&gt;Lastly the actual compilation command just does a bunch of macro expands and appends the prerequisites and targets. For example in our current situation we will get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; main.c &lt;span class="nt"&gt;-o&lt;/span&gt; main.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AND, since there are two &lt;code&gt;*.c&lt;/code&gt; files, we also get this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; utils.c &lt;span class="nt"&gt;-o&lt;/span&gt; utils.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clean up generated files
&lt;/span&gt;&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;TARGET&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;OBJS&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is my &lt;strong&gt;favorite part&lt;/strong&gt; of a &lt;code&gt;Makefile&lt;/code&gt; - the &lt;code&gt;clean&lt;/code&gt; target! I love this, as no matter how much you start messing up with different compiled objects, you can just run &lt;code&gt;make clean&lt;/code&gt; and it will remove all the compiled binaries and objects. Here is where you actually get creative with, and define what &lt;code&gt;clean&lt;/code&gt; means for you.&lt;/p&gt;

&lt;p&gt;For our example, this command will do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; myprogram main.o utils.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Declare phony targets (targets that don't represent files)
&lt;/span&gt;&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;all clean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This last bit is also very important. The &lt;code&gt;.PHONY&lt;/code&gt; target is necessary in order to prevent conflicts with real files. Basically it tells &lt;code&gt;make&lt;/code&gt; that &lt;code&gt;all&lt;/code&gt; and &lt;code&gt;clean&lt;/code&gt; are not actual files to be created but rather names or commands to be executed.&lt;/p&gt;

&lt;p&gt;For example, if we did not have &lt;code&gt;.PHONY&lt;/code&gt; declared. And there was a file called &lt;code&gt;clean&lt;/code&gt; in your project directory. Running &lt;code&gt;make clean&lt;/code&gt; would check if the file &lt;code&gt;clean&lt;/code&gt; needs to be rebuilt, establish that the file exists and has no dependencies, and &lt;em&gt;just do nothing ...&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Remember kids, always define your &lt;code&gt;.PHONY&lt;/code&gt; targets! 👏&lt;/p&gt;

&lt;h2&gt;
  
  
  Common uses
&lt;/h2&gt;

&lt;p&gt;Okay, so is this thing only used by &lt;code&gt;C&lt;/code&gt; software developers? Do I need to whip out my UNIX System V license? Not at all friends, &lt;code&gt;make&lt;/code&gt; makes (pun so much intended) a great companion to many software development projects. Let me give you a few examples I've seen floating around.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terraform automation
&lt;/h3&gt;

&lt;p&gt;My good friend &lt;a href="https://www.linkedin.com/in/cobusbernard/" rel="noopener noreferrer"&gt;Cobus&lt;/a&gt;, a long time &lt;a href="https://developer.hashicorp.com/terraform" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; user has used &lt;code&gt;make&lt;/code&gt; and &lt;code&gt;Makefiles&lt;/code&gt; to further streamline the way he works with the stacks he manages. You can check out the full &lt;code&gt;Makefile&lt;/code&gt; &lt;a href="https://github.com/cobusbernard/hashitalks-africa-demo/blob/master/environments/Makefile" rel="noopener noreferrer"&gt;here&lt;/a&gt;, but here are some cool parts that stuck out for me:&lt;/p&gt;

&lt;p&gt;Checking for the operating system in question and setting specific macros based off that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nv"&gt;UNAME&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;shell &lt;span class="nb"&gt;uname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ifeq&lt;/span&gt; &lt;span class="nv"&gt;($(UNAME),Darwin)&lt;/span&gt;
        &lt;span class="nv"&gt;OS_X&lt;/span&gt;  &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
        &lt;span class="nv"&gt;SHELL&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; /bin/bash
&lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="nv"&gt;OS_DEB&lt;/span&gt;  &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
        &lt;span class="nv"&gt;SHELL&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; /bin/bash
&lt;span class="k"&gt;endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Giving the user the &lt;strong&gt;appropriate&lt;/strong&gt; amount of warning before running &lt;code&gt;terraform destroy&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;destroy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;check&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Switching to the [&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;value ENV&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] environment ..."&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;terraform workspace &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;value ENV&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"## 💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥 ##"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"Are you really sure you want to completely destroy [$(value ENV)] environment ?"&lt;/span&gt;
    &lt;span class="err"&gt;@echo&lt;/span&gt; &lt;span class="s2"&gt;"## 💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥💥 ##"&lt;/span&gt;
    &lt;span class="err"&gt;@read&lt;/span&gt; &lt;span class="err"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Press enter to continue"&lt;/span&gt;
    &lt;span class="err"&gt;@terraform&lt;/span&gt; &lt;span class="err"&gt;destroy&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
        &lt;span class="nv"&gt;-var-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"env_vars/&lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;value ENV&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;.tfvars"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Local Development Environment automation
&lt;/h3&gt;

&lt;p&gt;With a little help from &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; and &lt;code&gt;make&lt;/code&gt; you can easily automate creation of local development environments for your software development projects. This allows you to automate certain elements of your development workflow and &lt;em&gt;shift left&lt;/em&gt; a lot of your building efforts. While setting up databases and services in local docker containers is possible without &lt;code&gt;make&lt;/code&gt; - &lt;code&gt;make&lt;/code&gt;, makes it (I am not sorry for any of these puns) way way easier. &lt;/p&gt;

&lt;p&gt;Let me show you an example &lt;code&gt;Makefile&lt;/code&gt; I've used for some Rust development, where I needed to spin up both Postgres and Redis in a local environment. You can see the full &lt;code&gt;Makefile&lt;/code&gt; &lt;a href="https://gist.github.com/darko-mesaros/b62f68917c99d6076b8f0bd88f8b9dad" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But let's look at some highlights that I find very useful. For example, here we are defining a macro &lt;code&gt;PG_PASSWORD&lt;/code&gt; using &lt;em&gt;simple assignment&lt;/em&gt;, meaning this expression will be &lt;em&gt;only run once&lt;/em&gt;. This is done by using &lt;code&gt;:=&lt;/code&gt; as the assignment operator, so everytime the &lt;code&gt;$(PG_PASSWORD)&lt;/code&gt; is referenced it wont go in and run the &lt;code&gt;openssl&lt;/code&gt; command, rather it will just get its value.&lt;/p&gt;

&lt;p&gt;We are using this &lt;code&gt;PG_PASSWORD&lt;/code&gt; macro in our code to dynamically define the Postgres password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate a random password (16 characters)
&lt;/span&gt;&lt;span class="nv"&gt;PG_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;shell openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 12 | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we actually execute our application, we check if the &lt;code&gt;.env&lt;/code&gt; file has been created. If it is not, we tell the user to go ahead and run &lt;code&gt;make setup&lt;/code&gt;. But if the file exists, we source it and just &lt;code&gt;cargo run&lt;/code&gt; 🚀&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run with environment variables from .env
&lt;/span&gt;&lt;span class="nl"&gt;run&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; 
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; .env &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Environment file not found. Run 'make setup' first."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Loading environment variables and running application..."&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .env &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are so many more examples where &lt;code&gt;make&lt;/code&gt; can be used. From video game development, to automatic image resizing, to data processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Makefiles 48 years later
&lt;/h2&gt;

&lt;p&gt;Okay, now that you &lt;em&gt;kind of&lt;/em&gt; understand the basics of &lt;code&gt;make&lt;/code&gt;, you may think to yourself: &lt;em&gt;"Darko, this language is ... what? Why is it so convoluted? Is it even worth my time?"&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Well, friend, yes it is! Once you get used to &lt;code&gt;make&lt;/code&gt;, you will never go back. But I fully understand the complexity of getting up and running with &lt;code&gt;make&lt;/code&gt; if you never did so. So, let's adopt &lt;code&gt;make&lt;/code&gt; 48 years later with the help of modern technology. Let me show you how you can use &lt;a href="https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line.html?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;Amazon Q Developer CLI&lt;/a&gt; to generate &lt;code&gt;Makefiles&lt;/code&gt; for your projects. 🥳&lt;/p&gt;

&lt;p&gt;First off, Amazon Q Developer CLI is a command line based &lt;em&gt;Generative AI assistant&lt;/em&gt;. But like really, an assistant! It does not only answer coding questions, it actually does stuff for you. From &lt;em&gt;generating code&lt;/em&gt;, to &lt;em&gt;writing deployment scripts&lt;/em&gt;, to even &lt;em&gt;running commands on your local (and remote) systems&lt;/em&gt;! I really like it! 😍&lt;/p&gt;

&lt;p&gt;To get started with Amazon Q Developer, you can do so for &lt;em&gt;free&lt;/em&gt; by just getting yourself an &lt;a href="https://docs.aws.amazon.com/signin/latest/userguide/sign-in-aws_builder_id.html?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;AWS Builder ID&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;installing Q CLI&lt;/a&gt;. I'll wait ... ⌚ &lt;/p&gt;

&lt;p&gt;Oh, you're back! Excellent! Let me show you how I use this tool to create various &lt;code&gt;Makefiles&lt;/code&gt; for my projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  My link shortener CDK project
&lt;/h3&gt;

&lt;p&gt;What I got here is a rather straightforward &lt;a href="https://aws.amazon.com/cdk/?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;AWS CDK&lt;/a&gt; project that sets up my very own link shortener. This stack features some TypeScript, Rust, and HTML as programming languages. And it deploys AWS Lambda functions, DynamoDB Tables and CloudFront distributions. Oh, and it features multiple stacks.  Making a &lt;code&gt;Makefile&lt;/code&gt; quite a useful thing for managing it.&lt;/p&gt;

&lt;p&gt;Here is the rough structure of my project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── bin
│   └── krtk-rs.ts              # CDK app entry point
├── lambda
│   ├── create_link             # Lambda function for creating short links
│   ├── get_links               # Lambda function for retrieving links
│   └── visit_link              # Lambda function for handling link visits
│   └── process_analytics       # Lambda function for analytics processing 
├── lib
│   ├── certificate-stack.ts    # Stack for SSL certificate
│   └── krtk-rs-stack.ts        # Main infrastructure stack
├── shared                      # Shared Rust code
├── website                     # Frontend assets
│   ├── assets
│   │   └── main.js             # Frontend JavaScript
│   └── index.html              # Main HTML page
└── test
    └── krtk-rs.test.ts         # Tests for the CDK stack (not yet implemented)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within the root of this project I run AWS Q Developer CLI by running &lt;code&gt;q chat&lt;/code&gt;. This starts off the command line chat 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%2Fhogm2e8fx3crys9aicn8.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%2Fhogm2e8fx3crys9aicn8.png" alt="Q Chat Interface" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, I always like to ask a bit about what my current project does, so that I add that structured thought to the context itself (although it already has access to my entire repo).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tell me a bit about what my project does, and how is it built
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I use the following prompt to have it generate me a &lt;code&gt;Makefile&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;Help me create a Makefile that will help me automate certain actions needed in developing this stack. 
Make sure to include deploy commands for individuals as well as all stacks. 
Help me set up local development environments for cargo lambda as well as setting up all the necessary environment variables for them to function.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a moment or so, it gets me the following results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# krtk.rs Makefile
# Automates common development and deployment tasks
&lt;/span&gt;
&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;help install build bootstrap deploy deploy-cert deploy-main local-dev clean test lint env-setup&lt;/span&gt;

&lt;span class="c"&gt;# Default target
&lt;/span&gt;&lt;span class="nl"&gt;help&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"krtk.rs - Serverless URL Shortener"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Usage:"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make install         Install all dependencies"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make build           Build the project"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make bootstrap       Bootstrap AWS CDK environment"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make deploy          Deploy all stacks"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make deploy-cert     Deploy only the certificate stack"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make deploy-main     Deploy only the main stack"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make local-dev       Start local development environment"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make clean           Clean build artifacts"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make test            Run tests"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make lint            Run linters"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  make env-setup       Set up local environment variables"&lt;/span&gt;

&lt;span class="c"&gt;# Installation targets
&lt;/span&gt;&lt;span class="nl"&gt;install&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing dependencies..."&lt;/span&gt;
      npm &lt;span class="nb"&gt;install&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing cargo-lambda..."&lt;/span&gt;
      cargo &lt;span class="nb"&gt;install &lt;/span&gt;cargo-lambda
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Dependencies installed successfully."&lt;/span&gt;

&lt;span class="c"&gt;# Build targets
&lt;/span&gt;&lt;span class="nl"&gt;build&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Building project..."&lt;/span&gt;
      npm run build
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Building Rust Lambda functions..."&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/create_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda build &lt;span class="nt"&gt;--release&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/get_links &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda build &lt;span class="nt"&gt;--release&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/visit_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda build &lt;span class="nt"&gt;--release&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/process_analytics &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda build &lt;span class="nt"&gt;--release&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Build completed successfully."&lt;/span&gt;

&lt;span class="c"&gt;# AWS CDK targets
&lt;/span&gt;&lt;span class="nl"&gt;bootstrap&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bootstrapping AWS CDK environment..."&lt;/span&gt;
      cdk bootstrap
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Bootstrap completed."&lt;/span&gt;

&lt;span class="nl"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deploying all stacks..."&lt;/span&gt;
      cdk deploy &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--require-approval&lt;/span&gt; never
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deployment completed."&lt;/span&gt;

&lt;span class="nl"&gt;deploy-cert&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deploying certificate stack..."&lt;/span&gt;
      cdk deploy CertificateStack &lt;span class="nt"&gt;--require-approval&lt;/span&gt; never
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Certificate stack deployed."&lt;/span&gt;

&lt;span class="nl"&gt;deploy-main&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deploying main application stack..."&lt;/span&gt;
      cdk deploy KrtkRsStack &lt;span class="nt"&gt;--require-approval&lt;/span&gt; never
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Main stack deployed."&lt;/span&gt;

&lt;span class="c"&gt;# Local development
&lt;/span&gt;&lt;span class="nl"&gt;local-dev&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Starting local development environment..."&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting up local DynamoDB..."&lt;/span&gt;
      docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 &lt;span class="nt"&gt;--name&lt;/span&gt; dynamodb-local amazon/dynamodb-local
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Creating local DynamoDB table..."&lt;/span&gt;
      aws dynamodb create-table &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--table-name&lt;/span&gt; local-links &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--attribute-definitions&lt;/span&gt; &lt;span class="nv"&gt;AttributeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;,AttributeType&lt;span class="o"&gt;=&lt;/span&gt;S &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--key-schema&lt;/span&gt; &lt;span class="nv"&gt;AttributeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;,KeyType&lt;span class="o"&gt;=&lt;/span&gt;HASH &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--provisioned-throughput&lt;/span&gt; &lt;span class="nv"&gt;ReadCapacityUnits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5,WriteCapacityUnits&lt;span class="o"&gt;=&lt;/span&gt;5 &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:8000 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Starting local API Gateway..."&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Local development environment is ready."&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Run Lambda functions locally with: cargo lambda watch"&lt;/span&gt;

&lt;span class="c"&gt;# Clean up
&lt;/span&gt;&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Cleaning build artifacts..."&lt;/span&gt;
      &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; cdk.out
      find lambda &lt;span class="nt"&gt;-name&lt;/span&gt; target &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; +
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Stopping local DynamoDB..."&lt;/span&gt;
      docker stop dynamodb-local &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
      docker &lt;span class="nb"&gt;rm &lt;/span&gt;dynamodb-local &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Clean completed."&lt;/span&gt;

&lt;span class="c"&gt;# Testing
&lt;/span&gt;&lt;span class="nl"&gt;test&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running tests..."&lt;/span&gt;
      npm &lt;span class="nb"&gt;test&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/create_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo &lt;span class="nb"&gt;test&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/get_links &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo &lt;span class="nb"&gt;test&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/visit_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo &lt;span class="nb"&gt;test&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/process_analytics &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo &lt;span class="nb"&gt;test&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Tests completed."&lt;/span&gt;

&lt;span class="c"&gt;# Linting
&lt;/span&gt;&lt;span class="nl"&gt;lint&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running linters..."&lt;/span&gt;
      npm run lint
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/create_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo clippy &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; warnings
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/get_links &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo clippy &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; warnings
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/visit_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo clippy &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; warnings
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/process_analytics &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo clippy &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; warnings
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Linting completed."&lt;/span&gt;

&lt;span class="c"&gt;# Environment setup
&lt;/span&gt;&lt;span class="nl"&gt;env-setup&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting up environment variables for local development..."&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export DYNAMODB_TABLE=local-links"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env.local
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export DYNAMODB_ENDPOINT=http://localhost:8000"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .env.local
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export TABLE_NAME=local-links"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export AWS_REGION=us-east-1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .env.local
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export DOMAIN_NAME=localhost"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .env.local
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Environment variables set up in .env.local"&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Run 'source .env.local' to load these variables."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, that is a lot! And check it out, it even decided to run &lt;code&gt;dynamodb-local&lt;/code&gt; in order to emulate my production environment. Storing that information in a &lt;code&gt;.env&lt;/code&gt; file so that it can be used during execution. But something is off... It's has decided &lt;em&gt;not&lt;/em&gt; to pass the environment variable to my Lambda functions via the &lt;code&gt;cargo lambda watch&lt;/code&gt; command. So I ask it nicely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Make sure that the cargo lambda watch also includes a environment variable for my table name as that is required by my function
s. 
Better yet do it by passing the `--env-file` parameter to the cargo lambda watch command, and pass it the path to the `.env` fi
le.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Excellent, now it has changed a part of my &lt;code&gt;Makefile&lt;/code&gt; to also include commands to test my Lambda functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="err"&gt;[...]&lt;/span&gt;

&lt;span class="c"&gt;# Environment setup (must be run before local-dev or watch commands)
&lt;/span&gt;&lt;span class="nl"&gt;env-setup&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting up environment variables for local development..."&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DYNAMODB_TABLE=local-links"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"TABLE_NAME=local-links"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DYNAMODB_ENDPOINT=http://localhost:8000"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .env
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"AWS_REGION=us-east-1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .env
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"DOMAIN_NAME=localhost"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .env
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Environment variables set up in .env file"&lt;/span&gt;

&lt;span class="c"&gt;# Local development
&lt;/span&gt;&lt;span class="nl"&gt;local-dev&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env-setup&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Starting local development environment..."&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Setting up local DynamoDB..."&lt;/span&gt;
      docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 &lt;span class="nt"&gt;--name&lt;/span&gt; dynamodb-local amazon/dynamodb-local &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Creating local DynamoDB table..."&lt;/span&gt;
      aws dynamodb create-table &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--table-name&lt;/span&gt; local-links &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--attribute-definitions&lt;/span&gt; &lt;span class="nv"&gt;AttributeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;,AttributeType&lt;span class="o"&gt;=&lt;/span&gt;S &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--key-schema&lt;/span&gt; &lt;span class="nv"&gt;AttributeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;,KeyType&lt;span class="o"&gt;=&lt;/span&gt;HASH &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--provisioned-throughput&lt;/span&gt; &lt;span class="nv"&gt;ReadCapacityUnits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5,WriteCapacityUnits&lt;span class="o"&gt;=&lt;/span&gt;5 &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:8000 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Local development environment is ready."&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Use 'make watch-&amp;lt;function-name&amp;gt;' to start a local Lambda function."&lt;/span&gt;

&lt;span class="c"&gt;# Lambda watch commands with environment variables from .env file
&lt;/span&gt;&lt;span class="nl"&gt;watch-create-link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env-setup&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Watching create_link lambda..."&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/create_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda watch &lt;span class="nt"&gt;--env-file&lt;/span&gt; ../../.env

&lt;span class="nl"&gt;watch-get-links&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env-setup&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Watching get_links lambda..."&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/get_links &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda watch &lt;span class="nt"&gt;--env-file&lt;/span&gt; ../../.env

&lt;span class="nl"&gt;watch-visit-link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env-setup&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Watching visit_link lambda..."&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/visit_link &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda watch &lt;span class="nt"&gt;--env-file&lt;/span&gt; ../../.env

&lt;span class="nl"&gt;watch-process-analytics&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;env-setup&lt;/span&gt;
      &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Watching process_analytics lambda..."&lt;/span&gt;
      &lt;span class="nb"&gt;cd &lt;/span&gt;lambda/process_analytics &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo lambda watch &lt;span class="nt"&gt;--env-file&lt;/span&gt; ../../.env

&lt;span class="err"&gt;[...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I just answered with a big ol' &lt;code&gt;y&lt;/code&gt; in &lt;code&gt;q chat&lt;/code&gt; and were! Ready to go! 👏 I even get a nice little guide on how to use my brand new &lt;code&gt;Makefile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;I've created a comprehensive Makefile for your krtk.rs project that will help automate development tasks. I've also added a .gitignore file to ensure environment variables and build artifacts aren't committed to your repository.

&lt;span class="gu"&gt;## Makefile Features&lt;/span&gt;

The Makefile includes commands for:
&lt;span class="p"&gt;
1.&lt;/span&gt; Installation and setup:
   • make install - Installs npm dependencies and cargo-lambda
   • make env-setup - Creates a .env file with local development variables
&lt;span class="p"&gt;
2.&lt;/span&gt; Build and deployment:
   • make build - Builds both the CDK project and Rust Lambda functions
   • make bootstrap - Bootstraps your AWS CDK environment
   • make deploy - Deploys all stacks
   • make deploy-cert - Deploys only the certificate stack
   • make deploy-main - Deploys only the main application stack
&lt;span class="p"&gt;
3.&lt;/span&gt; Local development:
   • make local-dev - Sets up a local DynamoDB instance and creates the required table
   • Lambda function development with environment variables:
     • make watch-create-link
     • make watch-get-links
     • make watch-visit-link
     • make watch-process-analytics
&lt;span class="p"&gt;
4.&lt;/span&gt; Testing and maintenance:
   • make test - Runs tests for both CDK and Lambda functions
   • make lint - Runs linters for TypeScript and Rust code
   • make clean - Cleans up build artifacts and stops local services

&lt;span class="gu"&gt;## Environment Variables&lt;/span&gt;

The Makefile creates a .env file with these variables:
• DYNAMODB_TABLE=local-links
• DYNAMODB_ENDPOINT=http://localhost:8000
• AWS_REGION=us-east-1
• DOMAIN_NAME=localhost

These are passed to the Lambda functions using the --env-file parameter when running cargo lambda watch.

&lt;span class="gu"&gt;## Usage&lt;/span&gt;

To get started with local development:

bash
&lt;span class="gh"&gt;# Install dependencies&lt;/span&gt;
make install

&lt;span class="gh"&gt;# Set up local environment and start DynamoDB&lt;/span&gt;
make local-dev

&lt;span class="gh"&gt;# Run a specific Lambda function locally&lt;/span&gt;
make watch-create-link&lt;span class="sb"&gt;


&lt;/span&gt;For deployment:

bash
&lt;span class="gh"&gt;# Deploy all stacks&lt;/span&gt;
make deploy

&lt;span class="gh"&gt;# Or deploy individual stacks&lt;/span&gt;
make deploy-cert
make deploy-main

The help command (make or make help) will show all available commands and their descriptions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, let's see it in action by running a few &lt;code&gt;make&lt;/code&gt; commands! Namely, I want to see how the local development works! &lt;/p&gt;

&lt;p&gt;First: &lt;code&gt;make install&lt;/code&gt; - this just installs all the packages needed to run my stack.&lt;br&gt;
Next: &lt;code&gt;make local-dev&lt;/code&gt; - this configures my local development environment by starting a local version of DynamoDB&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%2Furv8vfgphcdj2m370gos.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%2Furv8vfgphcdj2m370gos.png" alt="screenshot of make-local dev" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, I can execute my &lt;code&gt;create-link&lt;/code&gt; Lambda function locally, by running: &lt;code&gt;make watch-create-link&lt;/code&gt;. This will create a HTTP endpoint where I can interact with my Lambda function like a user would. To invoke it, I can just run the following &lt;code&gt;curl&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://10.0.1.11:9000/lambda-url/create_link &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"url_to_shorten": "https://rup12.net"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Failed to shorten URL 💥 : "Error creating a link - Service Error: ResourceNotFoundException(ResourceNotFoundException { message: Some(\"Requested resource not found\"), meta: ErrorMetadata { code: Some(\"ResourceNotFoundException\"), message: Some(\"Requested resource not found\")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hmm, well that is a future Darko problem, I guess I need to debug those Rusty Lambda functions! 🤔&lt;/p&gt;

&lt;p&gt;Finally, to clean up my development environment, I run: &lt;code&gt;make clean&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Working with static websites
&lt;/h3&gt;

&lt;p&gt;Next up, what I have here is a simple landing page for an open source app I've built. It features a static website running on &lt;a href="https://aws.amazon.com/amplify/?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;AWS Amplify&lt;/a&gt; but is deployed to it using the &lt;a href="https://docs.aws.amazon.com/amplify/latest/userguide/deploy-website-from-s3.html?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;AWS S3 Integration&lt;/a&gt;. So, instead of me going in the AWS Console, uploading the files to S3, going to Amplify and triggering &lt;em&gt;Deploy&lt;/em&gt;. Why not have a &lt;code&gt;Makefile&lt;/code&gt; do all this for me.&lt;/p&gt;

&lt;p&gt;Let's go ask Q:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I need a Makefile for my website here that I upload to a bucket called shuk.rs in my AWS Account. 
I want to use the Makefile to deploy the changes there as well as update the AWS Amplify website using the start-deployment aws CLI command. 
I will need an app-id for this to work. So get that value as well. Use the AWS CLI profile called `personal`. 
Here is the example of the AWS CLI deploy command for amplify: 
aws amplify start-deployment --app-id &amp;lt;app_id&amp;gt; \
--branch-name &amp;lt;branch_name&amp;gt; \
--source-url s3://amzn-s3-demo-website-bucket/prefix \
--source-url-type BUCKET_PREFIX`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I made sure to give it the example of the command I want it to run during the deployment. This ensures it gets it right, especially if this is a rather new feature. And I got this command from the &lt;a href="https://docs.aws.amazon.com/amplify/latest/userguide/update-website-deployed-from-s3.html?trk=dad343da-c131-4cd9-a323-ecf121d818d4&amp;amp;sc_channel=el" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;Check this out, it actually used the AWS CLI locally to find my &lt;code&gt;app-id&lt;/code&gt; for me. What it actually did was first search in &lt;code&gt;us-east-1&lt;/code&gt; and once it could not find it, it tried &lt;code&gt;us-west-2&lt;/code&gt; which worked.&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%2Fwx3roqtc57gwjhscs697.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%2Fwx3roqtc57gwjhscs697.png" alt="Q Chat using AWS CLI to try and find my app-id" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at what it built here!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Makefile for shuk.rs website deployment
# This Makefile handles deployment to both S3 bucket and AWS Amplify
&lt;/span&gt;
&lt;span class="c"&gt;# Configuration
&lt;/span&gt;&lt;span class="nv"&gt;BUCKET_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; shuk.rs
&lt;span class="nv"&gt;REGION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; us-west-2
&lt;span class="nv"&gt;AMPLIFY_APP_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; d32qis9bnvy6r1
&lt;span class="nv"&gt;AMPLIFY_BRANCH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; staging
&lt;span class="nv"&gt;AWS_PROFILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; personal

&lt;span class="c"&gt;# List of files to deploy
&lt;/span&gt;&lt;span class="nv"&gt;WEBSITE_FILES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; index.html install.sh shuk.gif favicon.png

&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;deploy deploy-s3 deploy-amplify clean help&lt;/span&gt;

&lt;span class="c"&gt;# Default target
&lt;/span&gt;&lt;span class="nl"&gt;help&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Available targets:"&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  deploy       - Deploy website to S3 bucket and update Amplify app"&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  deploy-s3    - Deploy website to S3 bucket only"&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  deploy-amplify - Update Amplify app only"&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  clean        - Remove any temporary files"&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  help         - Show this help message"&lt;/span&gt;

&lt;span class="c"&gt;# Deploy to both S3 and Amplify
&lt;/span&gt;&lt;span class="nl"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;deploy-s3 deploy-amplify&lt;/span&gt;

&lt;span class="c"&gt;# Deploy to S3 bucket
&lt;/span&gt;&lt;span class="nl"&gt;deploy-s3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deploying website files to S3 bucket &lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;BUCKET_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;WEBSITE_FILES&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nv"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;$$(&lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                       &lt;span class="k"&gt;*&lt;/span&gt;.html&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"text/html"&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                       &lt;span class="k"&gt;*&lt;/span&gt;.sh&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"text/plain"&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                       &lt;span class="k"&gt;*&lt;/span&gt;.gif&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"image/gif"&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                       &lt;span class="k"&gt;*&lt;/span&gt;.png&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"image/png"&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
                       &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="k"&gt;esac&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Uploading &lt;/span&gt;&lt;span class="nv"&gt;$$&lt;/span&gt;&lt;span class="s2"&gt;file with content-type: &lt;/span&gt;&lt;span class="nv"&gt;$$&lt;/span&gt;&lt;span class="s2"&gt;content_type"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
               aws s3 &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nv"&gt;$$&lt;/span&gt;file s3://&lt;span class="p"&gt;$(&lt;/span&gt;BUCKET_NAME&lt;span class="p"&gt;)&lt;/span&gt;/ &lt;span class="nt"&gt;--content-type&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$$&lt;/span&gt;&lt;span class="s2"&gt;content_type"&lt;/span&gt; &lt;span class="nt"&gt;--profile&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;AWS_PROFILE&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;REGION&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
       &lt;span class="k"&gt;done&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"S3 deployment complete!"&lt;/span&gt;

&lt;span class="c"&gt;# Update Amplify app
&lt;/span&gt;&lt;span class="nl"&gt;deploy-amplify&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Starting deployment for Amplify app &lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;AMPLIFY_APP_ID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; on branch &lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;AMPLIFY_BRANCH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;aws amplify start-deployment &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nt"&gt;--app-id&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;AMPLIFY_APP_ID&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nt"&gt;--branch-name&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;AMPLIFY_BRANCH&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nt"&gt;--source-url&lt;/span&gt; s3://&lt;span class="p"&gt;$(&lt;/span&gt;BUCKET_NAME&lt;span class="p"&gt;)&lt;/span&gt;/ &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nt"&gt;--source-url-type&lt;/span&gt; BUCKET_PREFIX &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nt"&gt;--profile&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;AWS_PROFILE&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
               &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;REGION&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Amplify deployment initiated!"&lt;/span&gt;

&lt;span class="c"&gt;# Clean any temporary files
&lt;/span&gt;&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Cleaning up temporary files..."&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.tmp"&lt;/span&gt; &lt;span class="nt"&gt;-delete&lt;/span&gt;
       &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Clean complete!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, I cannot have the &lt;code&gt;app-id&lt;/code&gt; hardcoded there. So do you remember the little &lt;code&gt;:=&lt;/code&gt; operator I mentioned at the start? YES! It can actually take an expression and turn it into a command! Lovely! Let's ask it to &lt;em&gt;dynamically&lt;/em&gt; get us the &lt;code&gt;app-id&lt;/code&gt; during execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can you make it so that you dynamically update the app-id instead of hardcoding it into the make file? The rest can stay hardcoded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And just like that! We have the correct &lt;code&gt;AMPLIFY_APP_ID&lt;/code&gt;, which will automatically get us our &lt;code&gt;app-id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# Makefile for shuk.rs website deployment
# This Makefile handles deployment to both S3 bucket and AWS Amplify
&lt;/span&gt;
&lt;span class="c"&gt;# Configuration
&lt;/span&gt;&lt;span class="nv"&gt;BUCKET_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; shuk.rs
&lt;span class="nv"&gt;REGION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; us-west-2
&lt;span class="nv"&gt;AMPLIFY_BRANCH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; staging
&lt;span class="nv"&gt;AWS_PROFILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; personal

&lt;span class="c"&gt;# List of files to deploy
&lt;/span&gt;&lt;span class="nv"&gt;WEBSITE_FILES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; index.html install.sh shuk.gif favicon.png

&lt;span class="c"&gt;# Dynamically get the Amplify app-id for shuk.rs
&lt;/span&gt;&lt;span class="nv"&gt;AMPLIFY_APP_ID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;shell aws amplify list-apps &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;REGION&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--profile&lt;/span&gt; &lt;span class="p"&gt;$(&lt;/span&gt;AWS_PROFILE&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"apps[?name=='shuk.rs'].appId"&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;deploy deploy-s3 deploy-amplify clean help check-app-id&lt;/span&gt;
&lt;span class="err"&gt;[...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, I'll make some changes to the &lt;code&gt;index.html&lt;/code&gt; and deploy the changes using &lt;code&gt;make deploy&lt;/code&gt;&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%2Fhwb5ba7hvyclw2lifjfv.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%2Fhwb5ba7hvyclw2lifjfv.png" alt="Deploying a static website using make deploy" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Boom 💥 It's deployed! Thank you &lt;code&gt;make&lt;/code&gt; ❤️&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;Alright friends, I think we have explored plenty about &lt;code&gt;make&lt;/code&gt; and how it can help us in our day-to-day developer lives. We've seen that despite being &lt;em&gt;48 years old&lt;/em&gt;, this tool is still incredibly relevant and useful in our modern tech stack. From its origins solving compilation problems at Bell Labs to streamlining our Terraform deployments and website updates, &lt;code&gt;make&lt;/code&gt; proves that good tools stand the test of time.&lt;/p&gt;

&lt;p&gt;Yes, the syntax can be a bit byzantine at first (those weird macros and pattern rules 🤯), but once you get past that initial learning curve, you'll discover a powerful way to automate repetitive tasks and standardize your workflows. No more mercilessly slamming the up arrow key hoping to find that one command you ran three days ago!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;And&lt;/em&gt; as we've seen with our examples using AWS Q Developer CLI, you don't even need to be a &lt;code&gt;make&lt;/code&gt; expert to start using it. Modern AI tools can help generate sophisticated &lt;code&gt;Makefiles&lt;/code&gt; tailored to your projects, whether it's a complex CDK deployment or a simple static website update.&lt;/p&gt;

&lt;p&gt;So go ahead, create that &lt;code&gt;Makefile&lt;/code&gt; for your project today! Your future self will thank you when you can just type &lt;code&gt;make deploy&lt;/code&gt; instead of remembering that 15-parameter AWS CLI command. After nearly five decades, &lt;code&gt;make&lt;/code&gt; continues to, well, make our lives easier (sorry not sorry for the pun 😆).&lt;/p&gt;

&lt;p&gt;Remember kids, always define your &lt;code&gt;.PHONY&lt;/code&gt; targets! 👏&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>genai</category>
      <category>aws</category>
    </item>
    <item>
      <title>Build On Live | Observability - Show notes</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Thu, 20 Oct 2022 20:19:11 +0000</pubDate>
      <link>https://dev.to/aws/build-on-live-observability-show-notes-b48</link>
      <guid>https://dev.to/aws/build-on-live-observability-show-notes-b48</guid>
      <description>&lt;p&gt;Welcome to our second &lt;strong&gt;Build On Live Event&lt;/strong&gt; which is all about &lt;strong&gt;Observability&lt;/strong&gt;. AWS experts and community members cover topics ranging from tracing, OpenTelemetry, SLOs, eBPFs and more!&lt;/p&gt;

&lt;p&gt;This event was hosted by &lt;a href="https://twitter.com/devopsjacquie" rel="noopener noreferrer"&gt;Jacquie Grindrod&lt;/a&gt; and &lt;a href="https://twitter.com/riferrei" rel="noopener noreferrer"&gt;Ricardo Ferreira&lt;/a&gt; and it was a sight to be seen. With both in-person and remote guests, the industry experts covered a variety of specialty topics within the observability field&lt;/p&gt;

&lt;p&gt;These are the show notes from that event, which was live streamed on the 29th of September 2022. The recording of this event is available on our &lt;a href="https://www.youtube.com/c/BuildOnAWS" rel="noopener noreferrer"&gt;YouTube channel&lt;/a&gt;, but in this article I will be linking each segment notes with its video, so make sure to hit that subscribe button! 👏&lt;/p&gt;




&lt;h2&gt;
  
  
  Individual session notes:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Intro and Welcome&lt;/li&gt;
&lt;li&gt;Go Beyond Observability with AI&lt;/li&gt;
&lt;li&gt;How to Migrate Observability Platforms With OpenSLO&lt;/li&gt;
&lt;li&gt;Intro to eBPF: Explain to Me As if I Was Five&lt;/li&gt;
&lt;li&gt;OpenTelemetry—The Industry Telemetry Standard&lt;/li&gt;
&lt;li&gt;That's a lot of data! how to manage ingestion and storage costs?&lt;/li&gt;
&lt;li&gt;Observability and Distributed Tracing at CNCF&lt;/li&gt;
&lt;li&gt;Creating trace data with OpenTelemetry&lt;/li&gt;
&lt;li&gt;Talking Observability with Liz Fong-Jones&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Intro and Welcome &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/curtEYEvan" rel="noopener noreferrer"&gt;Curtis Evans&lt;/a&gt;, Developer Advocate at AWS&lt;/p&gt;

&lt;p&gt;We kick off the day with your hosts Ricardo, Jacquie and a guest star Curtis. Discussing the basics of Observability and what can we expect throughout the day.&lt;/p&gt;

&lt;p&gt;So, "explain to us like we are 5", Curtis takes an example of a e-Commerce website and what all goes on in an application and how we track each execution and process that happens in each step in your application, that can in the future give us more insights and helps us detect and solve a problem before it even occurs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go Beyond Observability with AI &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/abvijaykumar" rel="noopener noreferrer"&gt;A.B. Vijay Kumar&lt;/a&gt;, IBM Fellow&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/A2OSEDwY-Q4"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Did you know AI can be used to help you understand the stream of events from observability data and alert you when something is bit off? In this session, A.B Vijay Kumar from IBM gives you an overview of how to leverage AI in what the industry calls AIOps (also called Augmented SRE), which can be a powerful component of your observability strategy. He shows a nice demo where AI is used to detecting anomalies and trigger conversations on Slack that people on-call could discuss what the problems are, and what actions the AI recommends taking based on past incidents.&lt;/p&gt;

&lt;p&gt;Also, check out the 1:14 minute mark in the &lt;a href="https://www.youtube.com/watch?v=A2OSEDwY-Q4" rel="noopener noreferrer"&gt;video&lt;/a&gt; something funky happened to the camera 😅&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%2Fbin6uolh5voshjqq9z70.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%2Fbin6uolh5voshjqq9z70.png" alt="Ricardo and Jacquie talking to A.B. remotely" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gartner.com/en/information-technology/glossary/aiops-artificial-intelligence-operations" rel="noopener noreferrer"&gt;What is AIOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-operations-integration/aiops.html" rel="noopener noreferrer"&gt;AI Ops prescriptive guidance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/wellarchitected/latest/analytics-lens/operational-analytics.html" rel="noopener noreferrer"&gt;Well Architected Analytics Lens&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How to Migrate Observability Platforms With OpenSLO &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://www.linkedin.com/in/the-ian-bartholomew/" rel="noopener noreferrer"&gt;Ian Bartholomew&lt;/a&gt;, Site Reliability Engineering Manager at Nobl9&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Rh8zunybRYM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;One of the best ways to measure the availability of services is having SLOs (Service Level Objective) set to them. They help in giving you a more pragmatic way to measure things and calculate how much does it costs having a service unavailable. What you may not know is that you can define them using an agnostic standard called OpenSLO using YAML. In this session, Ian Bartholomew from &lt;a href="https://www.nobl9.com/" rel="noopener noreferrer"&gt;Nobl9&lt;/a&gt; get into the weeds of how to do that, showing step by step the definition, implementation, and migration of defined OpenSLO's from on-premise to the cloud. And he does all of this with a hands-on approach using only the terminal. How cool is that?&lt;/p&gt;

&lt;p&gt;How do you explain/justify Error budgets to Engineering/Upper management? Well, you need to very clearly state that service uptimes will never be a 100%, it's gonna be very close but we also need to understand that all the extra nines is a lot of extra money - exponentially. So this error budget allows for an X amount to be unreliable.&lt;/p&gt;

&lt;p&gt;Quote from &lt;a href="https://twitter.com/mipsytipsy" rel="noopener noreferrer"&gt;Charity Majors&lt;/a&gt;: &lt;em&gt;"Nine nines mean nothing if your customers are unhappy"&lt;/em&gt;&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%2Fv9afyadqu12om267czh3.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%2Fv9afyadqu12om267czh3.png" alt="Ian, Ricardo and Jacquie in the Studio" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://openslo.com" rel="noopener noreferrer"&gt;OpenSLO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.slodlc.com/" rel="noopener noreferrer"&gt;SLO DLC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/incident-management/kpis/error-budget#:~:text=An%20error%20budget%20is%20the,can%20fail%20without%20contractual%20consequences." rel="noopener noreferrer"&gt;What is an error budget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/nobl9/build-on-aws-o11y-demo" rel="noopener noreferrer"&gt;The code Ian has used in the session&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.nobl9.com/signup/" rel="noopener noreferrer"&gt;Free trial for Nobl9&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.meetup.com/sloconf-monthly/events/" rel="noopener noreferrer"&gt;SLOConf Monthly meetup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Intro to eBPF: Explain to Me As if I Was Five &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/antonmry" rel="noopener noreferrer"&gt;Antón Rodríguez&lt;/a&gt;, Principal Software engineer at New Relic&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/vg5BssWmvL0"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Implementing observability these days is a no turning back trip to the world of instrumentation. But instrumenting services can be a lot of work depending on the approach you use. To minimize a bit of this workload, you can use eBPF — a non-intrusive way to instrument sandbox programs in an operating system kernel. In this session, Antón Rodriguez from New Relic explains how he got involved with this technology, how he applies it to his daily job as a software engineer, and also shows a cool demo of eBPF using the CNCF project called Pixie.&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%2F1y04qpfvgvsk0h2fowbl.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%2F1y04qpfvgvsk0h2fowbl.png" alt="Anton showing us the Pixie dashboard" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.galiglobal.com/" rel="noopener noreferrer"&gt;Anton's Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ebpf.io/" rel="noopener noreferrer"&gt;What is eBPF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pixielabs.ai/" rel="noopener noreferrer"&gt;Pixie - CNCF project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.galiglobal.com/blog/2022/20220823-Using-Pixie-with-Strimzi.html" rel="noopener noreferrer"&gt;Using Pixie to monitor a Strimzi kafka cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.confluent.io/events/kafka-summit-london-2022/monitoring-kafka-without-instrumentation-using-ebpf/" rel="noopener noreferrer"&gt;Anton's talk at the Kafka Summit 2022&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  OpenTelemetry—The Industry Telemetry Standard &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/mhausenblas" rel="noopener noreferrer"&gt;Michael Hausenblas&lt;/a&gt;, Open Source - Observability at AWS&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/I6Rtq9D5u7U"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;OpenTelemetry these days is arguably a synonym for observability. This CNCF project that provides an agnostic way for developers to instrument their services to produce telemetry data such as tracing and metrics is catching on. But a project of that magnitude can be often hard to understand. In this session, Michael Hausenblas from AWS gives us an overview of OpenTelemetry, his involvement in this project with CNCF, and how can you get started with this using the right resources. He also clarifies the many sub-projects that exist for OpenTelemetry, which are handy to know as you find your way into this technology.&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%2F7kf4l2egs3kduzr3f29t.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%2F7kf4l2egs3kduzr3f29t.png" alt="Michael, Jacquie and Ricardo" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/reference/specification/protocol/" rel="noopener noreferrer"&gt;OTLP Protocol&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  That's a lot of data! how to manage ingestion and storage costs? &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/TwitchiH" rel="noopener noreferrer"&gt;Richard "RichiH" Hartmann&lt;/a&gt;, Director of Community at Grafana&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/UIqB75PRbuc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;All monitoring initiatives start the same: you collect as much data as you can, you store them infinitely so you can analyze them someday, but one day the bill comes and upper management asks you to decrease infra costs. Suddenly, you shrink your monitoring infra and end up with a shared cluster for all the 100+ services that need some visibility. In this session, Richard Hartmann from Grafana Labs explains why this is an anti-pattern that should not occur every time people panic about infra costs related to monitoring. He shares some best practices about how to optimize ingestion and the storage costs of telemetry data. As he walks us over the different telemetry data, he also explains what are golden signals and how you should implement them.&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%2F03wi0zsrm67eqedau6j7.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%2F03wi0zsrm67eqedau6j7.png" alt="Richard and the hosts on stream" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://grafana.com/blog/" rel="noopener noreferrer"&gt;Grafana Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sre.google/sre-book/table-of-contents/" rel="noopener noreferrer"&gt;SRE eBook by Google&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/richih/talks" rel="noopener noreferrer"&gt;Richard's Talks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Observability and Distributed Tracing at CNCF &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/YuriShkuro" rel="noopener noreferrer"&gt;Yuri Shkuro&lt;/a&gt;, Creator of Jaeger, Co-founder of OpenTelemetry&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/vJskdmyPHOM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Despite of most people think, logs are not the only way to understand the execution path of code. Traces can tell that story too, and when combined with logs, provide even a more interesting story. This is the reason distributed tracing is so mainstream these days. In this session, Yuri Shkuro, from Meta, gives his perspective about the importance of distributed tracing, how he, by accident, bumped into this technology, and how they helped it to grow during his tenure at CNCF. He also explains how projects like OpenTracing, Jaeger, OpenCensus, and Zipkin helped to pave the way to what we know as OpenTelemetry.&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%2F9q7t7ujvcmoi8gpukb9r.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%2F9q7t7ujvcmoi8gpukb9r.png" alt="Yuri, Ricardo and Jacquie on stream" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.jaegertracing.io/" rel="noopener noreferrer"&gt;Jaeger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.shkuro.com/books/2019-mastering-distributed-tracing/" rel="noopener noreferrer"&gt;Mastering Distributed tracing - Book&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.shkuro.com/talks/" rel="noopener noreferrer"&gt;Yuri's talks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yurishkuro" rel="noopener noreferrer"&gt;Yuri's Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@YuriShkuro/temple-six-pillars-of-observability-4ac3e3deb402" rel="noopener noreferrer"&gt;TEMPLE: Six Pillars of Observability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://research.facebook.com/publications/positional-paper-schema-first-application-telemetry/" rel="noopener noreferrer"&gt;Positional Paper: Schema-First Application Telemetry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Creating trace data with OpenTelemetry &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/curtEYEvan" rel="noopener noreferrer"&gt;Curtis Evans&lt;/a&gt;, Developer Advocate at AWS&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/9jA3HDZYiaA"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;There is no better way for developers to learn how to use a specific technology than rolling up their sleeves and writing some code for it to build an example. Curtis Evans from AWS strongly believes that, and he steps up to help us understand OpenTelemetry in a more hands-on way. In this session, he takes his time to instrument a microservice written in Python to produce telemetry data for traces and metrics. He highlights the difference between a piece of code with and without instrumentation, so you can have a sense of how much work is needed.&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%2F2gey4rq00ql2nhmp7nin.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%2F2gey4rq00ql2nhmp7nin.png" alt="Curtis showing some telemetry data on screen" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/instrumentation/" rel="noopener noreferrer"&gt;OpenTelemetry Instrumentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/docs/instrumentation/python/" rel="noopener noreferrer"&gt;OpenTelemetry Python Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/products/management-and-governance/use-cases/monitoring-and-observability/?trk=a4eae550-3d3e-42d1-916d-6737f0b4436c&amp;amp;sc_channel=ps&amp;amp;s_kwcid=AL!4422!3!600238537393!p!!g!!system%20observability&amp;amp;ef_id=CjwKCAjwg5uZBhATEiwAhhRLHqABpCUdBkJwpSVaBAMhbCUzNj6upH5ykomnOlchNYsoa3fQPweF8RoC9zwQAvD_BwE:G:s&amp;amp;s_kwcid=AL!4422!3!600238537393!p!!g!!system%20observability&amp;amp;whats-new-cards.sort-by=item.additionalFields.postDateTime&amp;amp;whats-new-cards.sort-order=desc&amp;amp;blog-posts-cards.sort-by=item.additionalFields.createdDate&amp;amp;blog-posts-cards.sort-order=desc" rel="noopener noreferrer"&gt;AWS Management and Governance page on Observability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://opentelemetry.io/registry/" rel="noopener noreferrer"&gt;OpenTelemetry Registry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Talking Observability with Liz Fong-Jones &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Guest: &lt;a href="https://twitter.com/lizthegrey" rel="noopener noreferrer"&gt;Liz Fong-Jones&lt;/a&gt;, Field CTO at Honeycomb.io&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/2G6fyROWXgI"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Working with observability sometimes looks like building a puzzle with curvy edge pieces. The task at hands is to understand each piece and never lose track of the big picture. The problem is, with observability, knowing how the big picture looks like is not always possible. In this session, Liz Fong-Jones from Honeycomb shares her extensive experience with SRE and observability and shows us how observability looks like and how to pull each technology together to build that bigger picture. With an outstanding end to end example of troubleshooting a problem, fixing it in production, and coming back to development to apply the lessons learned with instrumentation, Liz shares when and how to use observability technologies to improve the system's reliability and customer satisfaction. &lt;/p&gt;

&lt;p&gt;Also, to quote Liz from the day: "Do not be afraid of failure, failure is a learning opportunity. Break you systems as long as you learn from it, so you don't break them the same way twice!"&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%2Fllexy74y8acxlb8wjhh0.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%2Fllexy74y8acxlb8wjhh0.png" alt="Liz running a demo" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some links that were shared:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://glitch.com/~intro-to-o11y-nodejs" rel="noopener noreferrer"&gt;Intro to O11y&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pyroscope.io/" rel="noopener noreferrer"&gt;Pyroscope&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.lizthegrey.com/" rel="noopener noreferrer"&gt;Liz's blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>observability</category>
      <category>aws</category>
      <category>twitch</category>
      <category>notes</category>
    </item>
    <item>
      <title>Build on AWS Weekly - S1 E6 - Local Development Everywhere</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Thu, 25 Aug 2022 15:09:16 +0000</pubDate>
      <link>https://dev.to/darkosubotica/build-on-aws-weekly-s1-e6-local-development-everywhere-29bp</link>
      <guid>https://dev.to/darkosubotica/build-on-aws-weekly-s1-e6-local-development-everywhere-29bp</guid>
      <description>&lt;p&gt;Welcome to episode 6 of Build On Weekly! 🥳 &lt;/p&gt;

&lt;p&gt;Today &lt;a href="https://twitter.com/devopsjacquie"&gt;Jacquie&lt;/a&gt; shows all of us and &lt;a href="https://twitter.com/darkosubotica"&gt;Darko&lt;/a&gt; how she configures her local development environment on her Macbook. On top of that she shows off some tips and tricks on how to automate said configuration for easy migrations between systems! &lt;/p&gt;

&lt;p&gt;We will be posting here, on dev.to, to share &lt;strong&gt;show notes, links, socials, code, and any other things mentioned&lt;/strong&gt; during the live stream with you! 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---eBkiW9n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/166dozw2np73kamhu5np.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---eBkiW9n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/166dozw2np73kamhu5np.png" alt="Jacquie and Darko Episode 6" width="880" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions, feedback or comments - feel free to put them in the comments of this post! 😇&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployed Weekly
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/8TE-VCaPp1E"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Today on Deployed Weekly we kick off with a warm welcome to the 500 new Community Builders we welcomed globally before taking a look at Cloud Glance, a tool that helps you navigate multiple AWS Environments with ease. Next up is the first Amazon CodeWhisperer workshop we’ve encountered while we share some of our thoughts about tools that help you to generate code. We then highlight Amazon Cloudfront’s added HTTP/3 QUIC support. Finally, we shared a link to open roles here at AWS DevRel if you’d like to come work with like us!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links from the discussion:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/developer/community/community-builders/"&gt;AWS Community Builders Program&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloudglance.dev/"&gt;Cloud Glance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/amazon-codewhisperer-workshop"&gt;Amazon Codewhisperer Workshop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2022/08/amazon-cloudfront-supports-http-3-quic/"&gt;AWS Cloudfront HTTP/3 QUIC Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/pulse/open-roles-join-aws-devrel-felipe-lemaitre/"&gt;Come and work with Jacquie and Darko in DevRel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Weekly Builds
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/OrlBvPrHFXk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Today we go on an interactive live tour with Jacquie through her terminal and IDE setup and share tips to make your environment portable between your different mac laptops. Also some cool automation steps she took to make it very easy to migrate between different workstations. &lt;/p&gt;

&lt;p&gt;Some things we discuss: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up scripts&lt;/li&gt;
&lt;li&gt;Package management using Brew and Brewfiles&lt;/li&gt;
&lt;li&gt;Favorite fonts and theme templates &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Links from the discussion&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/gogococo/mac-setup-files"&gt;Jacquie’s Mac Setup Files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@satorusasozaki/automate-mac-os-x-configuration-by-using-brewfile-58a78ce5cc53"&gt;Using Brewfiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rubjo.github.io/victor-mono/"&gt;Jacquie's favorite font&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🐦 Reach out to the hosts and guests:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jacquie: &lt;a href="https://twitter.com/devopsjacquie"&gt;https://twitter.com/devopsjacquie&lt;/a&gt;&lt;br&gt;
Darko: &lt;a href="https://twitter.com/darkosubotica"&gt;https://twitter.com/darkosubotica&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>development</category>
      <category>brewfile</category>
      <category>ide</category>
    </item>
    <item>
      <title>Build on AWS Weekly - S1 E5 - Containers Containers Everywhere</title>
      <dc:creator>Darko Mesaroš ⛅️</dc:creator>
      <pubDate>Thu, 18 Aug 2022 15:28:42 +0000</pubDate>
      <link>https://dev.to/aws/build-on-aws-weekly-s1-e5-containers-containers-everywhere-472i</link>
      <guid>https://dev.to/aws/build-on-aws-weekly-s1-e5-containers-containers-everywhere-472i</guid>
      <description>&lt;p&gt;Welcome to episode 5 of Build On Weekly! 🥳 &lt;/p&gt;

&lt;p&gt;Today &lt;a href="https://twitter.com/devopsjacquie" rel="noopener noreferrer"&gt;Jacquie&lt;/a&gt; and &lt;a href="https://twitter.com/darkosubotica" rel="noopener noreferrer"&gt;Darko&lt;/a&gt;, discuss a few things around Containers and Hybrid environments. That means running your applications On-Premises AND in the cloud. In today's episode watch Darko as he sweats trying to troubleshoot a real time demo. 😅&lt;/p&gt;

&lt;p&gt;We will be posting here, on dev.to, to share &lt;strong&gt;show notes, links, socials, code, and any other things mentioned&lt;/strong&gt; during the live stream with you! 🚀&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%2Fgd9st7872cc2ch2lyf14.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%2Fgd9st7872cc2ch2lyf14.png" alt="Jacquie and Darko - Episode 5" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions, feedback or comments - feel free to put them in the comments of this post! 😇&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployed Weekly
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/YI1zxP9aKqc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Today on deployed weekly we take another peek at Lambda functions and .NET. What are the best strategies when running the two together. We talk about a interesting Open Source tool that helps you prototype and productionize (is that even a word?) ML Pipelines. Another wonderful CLI tool out there, for al the CLI and Tracing fans. A wrap up on the AWS Storage Day that happened the day before and finally an amazing interview/podcast over on Lex Friedman’s channel - with the best programmer in the world John Carmack&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links from the discussion:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimal strategy for running .NET code on Lambda functions by &lt;strong&gt;Steve Bjorg:&lt;/strong&gt; &lt;a href="https://dev.to/lambdasharp/optimal-strategies-for-net-on-aws-lambda-45kg"&gt;https://dev.to/lambdasharp/optimal-strategies-for-net-on-aws-lambda-45kg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sematic&lt;/strong&gt;, an open-source development toolkit for AI/ML: &lt;a href="https://github.com/sematic-ai/sematic" rel="noopener noreferrer"&gt;https://github.com/sematic-ai/sematic&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Do more stuff from the console with &lt;strong&gt;xray-cli!&lt;/strong&gt;: &lt;a href="https://github.com/mhlabs/xray-cli" rel="noopener noreferrer"&gt;https://github.com/mhlabs/xray-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Yesterday - the 10th of August - was &lt;strong&gt;AWS Storage Day!&lt;/strong&gt; 🥳 &lt;a href="https://aws.amazon.com/blogs/aws/welcome-to-aws-storage-day-2022/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/aws/welcome-to-aws-storage-day-2022/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lex Friedman podcast with &lt;strong&gt;John Carmack&lt;/strong&gt;: &lt;a href="https://www.youtube.com/watch?v=I845O57ZSy4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=I845O57ZSy4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Weekly Builds
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/558ycpVpclA"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Today we will be talking about a few things, you all should know about: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Containers and the reason we use them. &lt;/li&gt;
&lt;li&gt;Hybrid environments.&lt;/li&gt;
&lt;li&gt;Darko’s Macbook ECS cluster&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Containers:
&lt;/h3&gt;

&lt;p&gt;Just a quick word this. Containers, or more precisely Containerization is application-level virtualization. The reason for this is so that software can be packaged up in these containers and run in isolated “user spaces” called containers!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;But why?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because we want to be able to package the entire running environment of a piece of software into a single bundle and run it on many different platform. Be that the cloud or in that laptop right in front of you! &lt;em&gt;Magic&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;On today's episode Jacquie and Darko talk about containers, why you should use them, how to orchestrate them and what do they have to do with a Hybrid environment.&lt;/p&gt;

&lt;p&gt;Later in the episode, check out how Darko struggles to add an extrenal "server" to his AWS ECS (Elastic Container Service) &lt;a href="https://macluster.rup12.net/" rel="noopener noreferrer"&gt;cluster&lt;/a&gt;. Plenty of fun times were had while troubleshooting. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links from the discussion:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nathan Peck’s blog post: &lt;a href="https://nathanpeck.com/ingress-to-ecs-anywhere-from-anywhere-using-inlets/" rel="noopener noreferrer"&gt;https://nathanpeck.com/ingress-to-ecs-anywhere-from-anywhere-using-inlets/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Darko’s cluster (if it is still running): &lt;a href="https://macluster.rup12.net/" rel="noopener noreferrer"&gt;https://macluster.rup12.net/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ECS Anywhere: &lt;a href="https://aws.amazon.com/ecs/anywhere/" rel="noopener noreferrer"&gt;https://aws.amazon.com/ecs/anywhere/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🐦 Reach out to the hosts and guests:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Jacquie: &lt;a href="https://twitter.com/devopsjacquie" rel="noopener noreferrer"&gt;https://twitter.com/devopsjacquie&lt;/a&gt;&lt;br&gt;
Darko: &lt;a href="https://twitter.com/darkosubotica" rel="noopener noreferrer"&gt;https://twitter.com/darkosubotica&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ecs</category>
      <category>containers</category>
      <category>hybrid</category>
    </item>
  </channel>
</rss>
