<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Matt Bacchi</title>
        <link>https://bacchi.org/</link>
        <description>Recent content on Matt Bacchi</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Thu, 01 Jan 2026 19:00:00 -0500</lastBuildDate><atom:link href="https://bacchi.org/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Using the VSCode Claude Code Extension with Bedrock and Claude Sonnet 4.5</title>
            <link>https://bacchi.org/posts/vscode-claude-sonnet-4.5-bedrock/</link>
            <pubDate>Thu, 01 Jan 2026 19:00:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/vscode-claude-sonnet-4.5-bedrock/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post Using the VSCode Claude Code Extension with Bedrock and Claude Sonnet 4.5&#34; /&gt;&lt;p&gt;Lots of folks use the Claude IDE, or the Claude Code VSCode extension. Unfortunately, your prompts and completions are used (by default) to train Claude models. &lt;a class=&#34;link&#34; href=&#34;https://code.claude.com/docs/en/data-usage#data-training-policy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[0]&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;AWS Bedrock, on the other hand, doesn&amp;rsquo;t use your prompts and completions to train any AWS models or give them to 3rd parties. &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/bedrock/latest/userguide/data-protection.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[1]&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;For these reasons (privacy, data sovereignty) I&amp;rsquo;m more inclined to use Bedrock as an LLM in my IDE. Today we&amp;rsquo;ll go over how to set up the VSCode Claude Code extension with AWS Bedrock and use the Claude Sonnet 4.5 foundation model.&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&#xA;&lt;/h2&gt;&lt;p&gt;In order to use the Claude Code VSCode extension with Bedrock and the Claude Sonnet 4.5 model, we need to perform these tasks:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Setup AWS IAM permissions to allow Bedrock usage&lt;/li&gt;&#xA;&lt;li&gt;Install and configure Claude Code VSCode extension&lt;/li&gt;&#xA;&lt;li&gt;Integrate AWS credentials, configure extension&lt;/li&gt;&#xA;&lt;li&gt;Test our setup works&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;To do this, we&amp;rsquo;ll use Terraform to create our AWS IAM user and policies (but you could use the AWS console.)&lt;/p&gt;&#xA;&lt;p&gt;Then we&amp;rsquo;ll integrate this all together and verify it works as expected.&lt;/p&gt;&#xA;&lt;h2 id=&#34;unfortunate-missing-features-and-a-bugregression-with-the-claude-code-extension&#34;&gt;Unfortunate Missing Features and a Bug/Regression with the Claude Code Extension&#xA;&lt;/h2&gt;&lt;p&gt;AWS Bedrock enables generating short lived API tokens via their SDK. &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys-generate.html#api-keys-refresh-short-term&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[2]&lt;/a&gt; Claude Code does support two methods for automatic AWS credential refresh, but Bedrock API tokens is not one of them.&lt;/p&gt;&#xA;&lt;p&gt;If it did support this feature it would be the best solution from a security perspective. Tokens would expire in 12 hours and when expired and the extension is used it would automatically refresh them.&lt;/p&gt;&#xA;&lt;p&gt;Instead it only supports AWS SSO (or rather AWS Identity Center) for it&amp;rsquo;s &lt;code&gt;awsAuthRefresh&lt;/code&gt; option, or AWS IAM credentials for its &lt;code&gt;awsCredentialsExport&lt;/code&gt; refresh methods. &lt;a class=&#34;link&#34; href=&#34;https://code.claude.com/docs/en/amazon-bedrock#advanced-credential-configuration&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[3]&lt;/a&gt; This deficiency is a poor decision, or at least an oversight by the Claude Code development team.&lt;/p&gt;&#xA;&lt;p&gt;Unfortunately, a more egregious issue is that they claim the above &lt;code&gt;awsCredentialsExport&lt;/code&gt; refresh method is functional when it is not. Whether it&amp;rsquo;s a regression or bug, or maybe never worked, I couldn&amp;rsquo;t get it working within a couple hours. (Including time spent conversing with the Claude Code VSCode extension using a working AWS Profile and it couldn&amp;rsquo;t suggest a workaround to this problem.) In addition to all these setbacks, using the Claude Code settings file (&lt;code&gt;~/.claude/settings.json&lt;/code&gt;) didn&amp;rsquo;t work either so I have to use the VSCode settings file to set all Claude Code extension configuration options.&lt;/p&gt;&#xA;&lt;p&gt;Since using AWS Identity Center for a personal account is overkill, refreshing Bedrock API tokens in Claude Code is not supported, and the AWS credential export method to automatically refresh my credentials for the Claude Code VSCode extension is not functional, I&amp;rsquo;ll settle for the lowest common denominator and use the AWS Profile in my configuration. I don&amp;rsquo;t love this method because it uses a long lived AWS IAM user credential (access key and secret access key.) But I can&amp;rsquo;t improve security due to the poor state of affairs in the Claude Code VSCode extension.&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-iam-user-and-bedrock-permissions&#34;&gt;Create IAM User and Bedrock Permissions&#xA;&lt;/h2&gt;&lt;p&gt;Create an IAM user and attach IAM policy to the user with this Terraform:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_user&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock_user&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock-user&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_access_key&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;aws_iam_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bedrock_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_policy_document&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;statement&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;effect&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;actions&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock:InvokeModel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock:ListFoundationModels&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock:ListInferenceProfiles&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock:InvokeModelWithResponseStream&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;      #   &amp;#34;bedrock:CallWithBearerToken&amp;#34; # required if using Bedrock API token which we&amp;#39;re not doing here&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;resources&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;statement&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;effect&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Allow&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;actions&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws-marketplace:ViewSubscriptions&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws-marketplace:Subscribe&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;resources&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;condition&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;test&lt;/span&gt;     &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;StringEquals&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;variable&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws:CalledViaLast&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;values&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock.amazonaws.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_iam_user_policy&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bedrock&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;user&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;aws_iam_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bedrock_user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;aws_iam_policy_document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bedrock&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;json&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;setup-aws-profile&#34;&gt;Setup AWS Profile&#xA;&lt;/h2&gt;&lt;p&gt;I typically use &lt;code&gt;aws-vault&lt;/code&gt; to manage my AWS credentials, for enhanced security and to use short lived credentials. But again we&amp;rsquo;re going to have to use the standard AWS method of storing long lived credentials in our &lt;code&gt;~/.aws/credentials&lt;/code&gt; file, and then access that profile from the Claude Code extension.&lt;/p&gt;&#xA;&lt;p&gt;Above in the IAM user creation section, we only created the IAM user and policy. Now you will need to create an Access Key to use as the credential in your profile. Go to the AWS Console and create an access key for this user, follow the instructions to create it for the CLI use case.&lt;/p&gt;&#xA;&lt;img src=&#34;access-key.jpg&#34;&gt;&#xA;&lt;p&gt;After creating it, copy your Access Key and Secret Access Key somewhere for safe keeping (I use a password manager for this purpose.)&lt;/p&gt;&#xA;&lt;p&gt;To setup your profile in the &lt;code&gt;~/.aws/credentials&lt;/code&gt; file, use the command:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws configure --profile YOUR_AWS_PROFILE_NAME&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;It will prompt you to provide the AWS Access Key and Secret Access Key, which will be added to the &lt;code&gt;~/.aws/credentials&lt;/code&gt; file using the profile name you specified in the command (choose wisely!)&lt;/p&gt;&#xA;&lt;h2 id=&#34;enable-bedrock-claude-sonnet-45-and-validate-access&#34;&gt;Enable Bedrock Claude Sonnet 4.5 and Validate Access&#xA;&lt;/h2&gt;&lt;p&gt;After creating the above IAM user and policy, and setting up the profile, we&amp;rsquo;ll login to the AWS console. Choose the AWS region that you normally use, but be aware that these Bedrock foundation models aren&amp;rsquo;t available in every single global AWS region. I used region &lt;code&gt;us-west-2&lt;/code&gt; but &lt;code&gt;us-east-1&lt;/code&gt; and &lt;code&gt;us-east-2&lt;/code&gt; are also supported.&lt;/p&gt;&#xA;&lt;p&gt;Anthropic requires first-time customers to submit use case details before invoking a model once per account or once at the organization&amp;rsquo;s management account. &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[4]&lt;/a&gt; This is a rather antiquated policy in the cloud era, but required nonetheless.&lt;/p&gt;&#xA;&lt;p&gt;Go to the Bedrock section of the AWS console, then to &amp;ldquo;Chat/Text Playground&amp;rdquo; and select Anthropic Claude Sonnet 4.5. You&amp;rsquo;ll be presented with a dialog to fill out and enable the foundation model.&lt;/p&gt;&#xA;&lt;h2 id=&#34;install-and-configure-vscode&#34;&gt;Install and Configure VSCode&#xA;&lt;/h2&gt;&lt;p&gt;Install the VSCode extension:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;code --install-extension anthropic.claude-code&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Identify your Bedrock Claude Sonnet 4.5 inference profile ARN:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws bedrock list-inference-profiles  --region us-west-2 --profile YOUR_AWS_PROFILE_NAME --no-cli-pager &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.inferenceProfileSummaries | .[] | select(.inferenceProfileId | match(&amp;#34;us.anthropic.claude-sonnet-4-5-20250929-v1:0&amp;#34;)) | .inferenceProfileArn&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: This assumes you&amp;rsquo;re in the US, if using another global region use the global Anthropic Claude Sonnet profile name in the above command.&lt;/p&gt;&#xA;&lt;p&gt;Add the following to your VSCode user settings.json file (usually this is &lt;code&gt;~/.config/Code/User/settings.json&lt;/code&gt;):&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;claudeCode.selectedModel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;us.anthropic.claude-sonnet-4-5-20250929-v1:0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;claudeCode.environmentVariables&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_PROFILE&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;YOUR_AWS_PROFILE_NAME&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_REGION&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;YOUR_AWS_REGION_FROM_ABOVE&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;BEDROCK_MODEL_ID&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;INFERENCE_PROFILE_ARN_FROM_ABOVE&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;CLAUDE_CODE_USE_BEDROCK&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;claudeCode.disableLoginPrompt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;did-it-work&#34;&gt;Did it work?&#xA;&lt;/h2&gt;&lt;p&gt;You&amp;rsquo;ll probably have to restart your VSCode session if it was running. Then, open the Claude window and type a question or request and you should see a successful response like below:&lt;/p&gt;&#xA;&lt;img src=&#34;claude.jpg&#34;&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;We did it! I&amp;rsquo;m not super impressed with the missing/broken/overlooked features of the Claude Code VSCode extension related to AWS IAM credentials. But it works fine for the time being and I&amp;rsquo;ll revisit this issue and report back when these issues are resolved and we can all begin using short lived credentials with the extension.&lt;/p&gt;&#xA;&lt;h2 id=&#34;resources&#34;&gt;Resources&#xA;&lt;/h2&gt;&lt;p&gt;I borrowed some information from this incredibly detailed blog post by Vasko Kelkocev. &lt;a class=&#34;link&#34; href=&#34;https://aws.plainenglish.io/configuring-claude-code-extension-with-aws-bedrock-and-how-you-can-avoid-my-mistakes-090dbed5215b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[5]&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;But even though that blog was written in October 2025, it was already out of date by the time I found it. I had to add more IAM permissions to get the extension to work with Bedrock (specifically &lt;code&gt;bedrock:InvokeModelWithResponseStream&lt;/code&gt;), and there were some other issues with the configuration I had to play with. Thanks for the great blog Vasko.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Cover photo by &lt;a href=&#34;https://unsplash.com/@ffstop&#34;&gt;Fotis Fotopoulos&lt;/a&gt; on &lt;a href=&#34;https://unsplash.com/photos/black-computer-keyboard-DuHKoV44prg&#34;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;</description>
        </item><item>
            <title>Firecracker Virtualization Overview</title>
            <link>https://bacchi.org/posts/firecracker-overview/</link>
            <pubDate>Thu, 11 Dec 2025 17:00:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/firecracker-overview/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post Firecracker Virtualization Overview&#34; /&gt;&lt;p&gt;Firecracker is an open source virtualization technology created by Amazon Web Services (AWS) which underpins their AWS Lambda Functions as a Service (FaaS) serverless product.&lt;/p&gt;&#xA;&lt;p&gt;Firecracker was open sourced in 2018 &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/about-aws/whats-new/2018/11/firecracker-lightweight-virtualization-for-serverless-computing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[0]&lt;/a&gt;, making it possible for anyone to use this extremely fast and reliable system for their own projects and use cases.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been researching the ecosystem lately and am impressed at the flexibility architected into the Firecracker code which enables it to be used in many ways. We might have expected them to design it such that it only works in their very tightly controlled environment. But the fact that it&amp;rsquo;s not specialized to just the AWS Lambda use case means that it can be leveraged by anyone from AWS scale to a home lab running a single VM.&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s explore the capabilities of Firecracker and the various methods of using it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;firecracker-high-level-overview&#34;&gt;Firecracker High Level Overview&#xA;&lt;/h2&gt;&lt;p&gt;There are many good quick start documents &lt;a class=&#34;link&#34; href=&#34;https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;1&lt;/a&gt; and blogs describing how to install and start a single Firecracker MicroVM instance. Because of these great resources readily available, I won&amp;rsquo;t describe that here.&lt;/p&gt;&#xA;&lt;p&gt;The basic requirements are:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Firecracker binary&lt;/li&gt;&#xA;&lt;li&gt;kernel&lt;/li&gt;&#xA;&lt;li&gt;rootfs&lt;/li&gt;&#xA;&lt;li&gt;networking configuration (optional)&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;When you start a firecracker VM by executing the &lt;code&gt;firecracker&lt;/code&gt; program, you are running a single VM instance which can be managed through the firecracker process you launched it with. You can send subsequent commands to perform additional management tasks to the firecracker process using the API via a unix socket. When you are done with the VM you can and should stop it &amp;ldquo;gracefully&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;Multiple firecracker processes can be executed at one time, which translates to running multiple VMs. Presumably this is how AWS runs millions of Lambda functions.&lt;/p&gt;&#xA;&lt;h2 id=&#34;configuration&#34;&gt;Configuration&#xA;&lt;/h2&gt;&lt;p&gt;There are a couple ways to configure your VM:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Sending HTTP requests via the API socket &lt;a class=&#34;link&#34; href=&#34;https://github.com/firecracker-microvm/firecracker/blob/main/docs/api_requests/actions.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[2]&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Using the configuration file &lt;a class=&#34;link&#34; href=&#34;https://github.com/firecracker-microvm/firecracker/blob/main/docs/getting-started.md#configuring-the-microvm-without-sending-api-requests&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[3]&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;If you use the configuration file to set the VM guest kernel and rootfs, you can still use the socket to send API requests. These configuration methods seem to conflict, but they appear to me to be part of the design of a highly flexible system.&lt;/p&gt;&#xA;&lt;p&gt;The HTTP API is enhanced by what appears to be an official Go SDK &lt;a class=&#34;link&#34; href=&#34;https://pkg.go.dev/github.com/firecracker-microvm/firecracker-go-sdk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[4]&lt;/a&gt; that you can use to manage your Firecracker VM instances. A likely scenario is that AWS uses this Go SDK to provision and control their Lambda functions via this HTTP API provided by the Firecracker process.&lt;/p&gt;&#xA;&lt;h2 id=&#34;initialization&#34;&gt;Initialization&#xA;&lt;/h2&gt;&lt;p&gt;Firecracker is also flexible in how it can be initialized. Options include:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;command line execution&lt;/li&gt;&#xA;&lt;li&gt;systemd&lt;/li&gt;&#xA;&lt;li&gt;jailer&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The first two options are obviously common to many Linux tools. But the diverse use cases that AWS themselves have for a multi-purpose virtualization technology like Firecracker make it likely that they designed it to be versatile. This adaptable capability extends from the configuration methods to initialization, and likely beyond.&lt;/p&gt;&#xA;&lt;h2 id=&#34;enhanced-isolation-using-jailer&#34;&gt;Enhanced Isolation using Jailer&#xA;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;jailer&lt;/code&gt; tool &lt;a class=&#34;link&#34; href=&#34;https://github.com/firecracker-microvm/firecracker/blob/main/docs/jailer.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[5]&lt;/a&gt; which is specifically designed for firecracker further isolates each firecracker process to its own chroot jail directory. This security mechanism has been used for years in Unix systems and affords a greater sense of security in a multi-tenant environment.&lt;/p&gt;&#xA;&lt;p&gt;We won&amp;rsquo;t go into detail on this for now, and it isn&amp;rsquo;t necessary for your home lab unless you&amp;rsquo;re running untrusted code (i.e. not written by you.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;demonstration&#34;&gt;Demonstration&#xA;&lt;/h2&gt;&lt;p&gt;To quickly show what we&amp;rsquo;ve discussed above, we&amp;rsquo;ll demonstrate with a small bash script that starts a Firecracker micro VM using previously downloaded kernel and rootfs. Here&amp;rsquo;s the script:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/usr/bin/env bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;firecracker&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/bin/firecracker&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;uuid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;/usr/bin/uuidgen&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nohup &lt;span class=&#34;nv&#34;&gt;$firecracker&lt;/span&gt; --api-sock /tmp/&lt;span class=&#34;nv&#34;&gt;$uuid&lt;/span&gt;.socket &lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;created firecracker process running on socket: /tmp/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$uuid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.socket&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl --unix-socket /tmp/&lt;span class=&#34;nv&#34;&gt;$uuid&lt;/span&gt;.socket -i &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -X PUT &lt;span class=&#34;s1&#34;&gt;&amp;#39;http://localhost/boot-source&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -H &lt;span class=&#34;s1&#34;&gt;&amp;#39;Accept: application/json&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -H &lt;span class=&#34;s1&#34;&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;kernel_image_path&amp;#34;: &amp;#34;/tmp/firecracker-test/hello-vmlinux.bin&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;boot_args&amp;#34;: &amp;#34;console=ttyS0 reboot=k panic=1 pci=off&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    }&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl --unix-socket /tmp/&lt;span class=&#34;nv&#34;&gt;$uuid&lt;/span&gt;.socket -i &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -X PUT &lt;span class=&#34;s1&#34;&gt;&amp;#39;http://localhost/drives/rootfs&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -H &lt;span class=&#34;s1&#34;&gt;&amp;#39;Accept: application/json&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -H &lt;span class=&#34;s1&#34;&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;drive_id&amp;#34;: &amp;#34;rootfs&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;path_on_host&amp;#34;: &amp;#34;/tmp/firecracker-test/hello-rootfs.ext4&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;is_root_device&amp;#34;: true,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;is_read_only&amp;#34;: false&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    }&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl --unix-socket /tmp/&lt;span class=&#34;nv&#34;&gt;$uuid&lt;/span&gt;.socket -i &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -X PUT &lt;span class=&#34;s1&#34;&gt;&amp;#39;http://localhost/actions&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -H  &lt;span class=&#34;s1&#34;&gt;&amp;#39;Accept: application/json&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -H  &lt;span class=&#34;s1&#34;&gt;&amp;#39;Content-Type: application/json&amp;#39;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;    -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;action_type&amp;#34;: &amp;#34;InstanceStart&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    }&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Started VM instance.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Running it we get the following output:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;user@temphost:~/data/firecracker-test$ ./startvm.sh &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;created firecracker process running on socket: /tmp/b214c708-e506-455b-a98d-647939a0ef0d.socket&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nohup: appending output to &lt;span class=&#34;s1&#34;&gt;&amp;#39;nohup.out&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;HTTP/1.1 &lt;span class=&#34;m&#34;&gt;204&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Server: Firecracker API&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection: keep-alive&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;HTTP/1.1 &lt;span class=&#34;m&#34;&gt;204&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Server: Firecracker API&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection: keep-alive&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;HTTP/1.1 &lt;span class=&#34;m&#34;&gt;204&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Server: Firecracker API&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection: keep-alive&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Started VM instance.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;user@temphost:~/data/firecracker-test$ tail nohup.out &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; ok &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; * Mounting persistent storage &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;pstore&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; filesystem ...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; ok &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Starting default runlevel&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;    1.088111&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2879b124109, max_idle_ns: &lt;span class=&#34;m&#34;&gt;440795245440&lt;/span&gt; ns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Welcome to Alpine Linux 3.8&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Kernel 4.14.55-84.37.amzn2.x86_64 on an x86_64 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;ttyS0&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;localhost login: &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;You can see that we have a login prompt in the &lt;code&gt;nohup.out&lt;/code&gt; file that indicates the VM is running and ready to accept logins. We didn&amp;rsquo;t setup any SSH keys in this attempt, nor networking, so we&amp;rsquo;re SOL on logging in. But that&amp;rsquo;s OK because we were just trying to show how straightforward this can be.&lt;/p&gt;&#xA;&lt;p&gt;Notice we created a random UUID to use as the firecracker unix socket, which is how you can communicate with it via the HTTP API. After starting the firecracker process, we then make &lt;code&gt;curl&lt;/code&gt; requests to configure the kernel, rootfs, and then initiate the &lt;code&gt;InstanceStart&lt;/code&gt; action.&lt;/p&gt;&#xA;&lt;p&gt;Granted, this is a very rudimentary example. But it shows how easily firecracker can be used if you understand the fundamentals.&lt;/p&gt;&#xA;&lt;h2 id=&#34;firecracker-ecosystem-discrepancies-compared-to-lambda&#34;&gt;Firecracker Ecosystem Discrepancies Compared to Lambda&#xA;&lt;/h2&gt;&lt;p&gt;In multiple AWS re:Invent talks, Lambda architecture has been detailed by AWS employees at a high level. One example is in Julian Wood&amp;rsquo;s 2022 session &lt;a class=&#34;link&#34; href=&#34;https://youtu.be/0_jfH6qijVY?si=GRy8QqQiUwajQKhk&amp;amp;t=636&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;A closer look at AWS Lambda (SVS404-R)&lt;/a&gt;. At 10:36 in the video, he references the Lambda data plane, which consists of a host of interrelated services for synchronous vs. asynchronous Lambda invocations. These services are:&lt;/p&gt;&#xA;&lt;h3 id=&#34;synchronous&#34;&gt;Synchronous&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;Frontend Invoke Service&lt;/li&gt;&#xA;&lt;li&gt;Counting Service&lt;/li&gt;&#xA;&lt;li&gt;Assignment Service&lt;/li&gt;&#xA;&lt;li&gt;Worker Hosts&lt;/li&gt;&#xA;&lt;li&gt;Placement Service&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;asynchronous&#34;&gt;Asynchronous&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;Poller Fleet&lt;/li&gt;&#xA;&lt;li&gt;Queue Manager&lt;/li&gt;&#xA;&lt;li&gt;State Manager&lt;/li&gt;&#xA;&lt;li&gt;Stream Tracker&lt;/li&gt;&#xA;&lt;li&gt;Leasing Service&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;the-cold-truth&#34;&gt;The Cold Truth&#xA;&lt;/h3&gt;&lt;p&gt;These administrative services used to run millions or billions of AWS Lambda invocations are obviously not available for Firecracker. It makes sense that AWS would release their Firecracker product as open source, but they&amp;rsquo;re not likely to ever provide the facade that props Firecracker up in their environment, enabling AWS Lambda to be highly performant and reliable. But this is something I&amp;rsquo;m interested in. I think some of these features that streamline the functionality of Firecracker in the Lambda use case could be built to make it easier to manage for those of us who think this tool is exciting and wish it came with batteries included.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;Over the next few weeks (and months) I&amp;rsquo;ll be playing with this some more. I&amp;rsquo;ll likely be posting as I do this to give a different perspective on firecracker than the standard quick start blogs out there already.&lt;/p&gt;&#xA;&lt;p&gt;Hope you got something out of this today!&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Cover photo by &lt;a href=&#34;https://unsplash.com/@hubblespacetelescope&#34;&gt;NASA Hubble Space Telescope&lt;/a&gt; on &lt;a href=&#34;https://unsplash.com/photos/an-artists-rendering-of-a-distant-object-in-space-H2a2OT8GEkw&#34;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Installing Nvidia Datacenter GPU Manager on Amazon Linux 2023</title>
            <link>https://bacchi.org/posts/al2023-nvidia-dcgm/</link>
            <pubDate>Sat, 01 Feb 2025 08:00:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/al2023-nvidia-dcgm/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post Installing Nvidia Datacenter GPU Manager on Amazon Linux 2023&#34; /&gt;&lt;p&gt;A short post discussing the installation of Nvidia Datacenter GPU Manager on Amazon Linux 2023. I recently had to figure this out using sketchy documentation, so I&amp;rsquo;m hoping this helps some folks out there doing similar head scratching.&#xA;&lt;strong&gt;NOTE&lt;/strong&gt;: This blog post does not include all steps to install Nvidia drivers. I assume you already have driver package(s) required for your application installed.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-the-datacenter-gpu-manager&#34;&gt;What is the Datacenter GPU Manager&#xA;&lt;/h2&gt;&lt;p&gt;Nvidia &lt;a class=&#34;link&#34; href=&#34;https://docs.nvidia.com/data-center-gpu-manager-dcgm/index.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Datacenter GPU Manager&lt;/a&gt; is a suite of tools used for managing and monitoring Nvidia GPUs in the data center.&lt;/p&gt;&#xA;&lt;p&gt;In our environment we use Nvidia Datacenter GPU Manager as a prerequisite for the DCGM Prometheus metrics exporter used to send metrics to Datadog, named &lt;a class=&#34;link&#34; href=&#34;https://github.com/NVIDIA/dcgm-exporter&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;dcgm-exporter&lt;/a&gt;. I won&amp;rsquo;t go into detail on installing &lt;code&gt;dcgm-exporter&lt;/code&gt;, the &lt;a class=&#34;link&#34; href=&#34;https://docs.nvidia.com/data-center-gpu-manager-dcgm/index.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;instructions in the Github README&lt;/a&gt; are fairly straightforward to follow.&lt;/p&gt;&#xA;&lt;h2 id=&#34;amazon-linux-2-end-of-life&#34;&gt;Amazon Linux 2 End Of Life&#xA;&lt;/h2&gt;&lt;p&gt;The Amazon Linux 2 (AL2) &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/amazon-linux-2/faqs/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;EOL date is 6/30/2025&lt;/a&gt; (June 30, 2025). The replacement is Amazon Linux 2023 (AL2023) &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/linux/amazon-linux-2023/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[3]&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;installing-dcgm-on-al2023&#34;&gt;Installing DCGM on AL2023&#xA;&lt;/h2&gt;&lt;p&gt;Installing Nvidia Datacenter GPU Manager on AL2 was documented, but applying that documentation to AL2023 wasn&amp;rsquo;t clear what value to use for the &lt;code&gt;&amp;lt;distro&amp;gt;&lt;/code&gt; &lt;a class=&#34;link&#34; href=&#34;https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#network-repo-installation-for-amazon-linux&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;[4]&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In order to understand what distribution Amazon Linux 2023 most closely relates to, you have to look in the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/linux/al2023/ug/compare-with-al2.html#building-on-fedora&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Amazon Linux 2023 User Guide&lt;/a&gt;. It describes that AL2023 is &amp;ldquo;sourced from multiple versions of Fedora&amp;hellip;including CentOS 9.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;That means when following the Nvidia installation instructions, they suggest enabling the repository with this command:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/&amp;lt;distro&amp;gt;/x86_64/cuda-&amp;lt;distro&amp;gt;.repo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Because AL2023 is derived from Fedora/CentOS 9, the &lt;code&gt;&amp;lt;distro&amp;gt;&lt;/code&gt; parameter is going to be &lt;code&gt;rhel9&lt;/code&gt;. So our command to install the repository instead becomes:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel9/x86_64/cuda-rhel9.repo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Now you can run the install command for the &lt;code&gt;datacenter-gpu-manager&lt;/code&gt; package:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo dnf install -y datacenter-gpu-manager&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;The documentation was not clear which distribution should be used for AL2023. Replace &lt;code&gt;&amp;lt;distro&amp;gt;&lt;/code&gt; with &lt;code&gt;rhel9&lt;/code&gt; in the repo installation command and we&amp;rsquo;re now able to install the &lt;code&gt;datacenter-gpu-manager&lt;/code&gt; package.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Cover photo by &lt;a href=&#34;https://unsplash.com/@christianw&#34;&gt;Christian Wiediger&lt;/a&gt; on &lt;a href=&#34;https://unsplash.com/&#34;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Switching to the Terraform S3 Backend with Native State File Locks</title>
            <link>https://bacchi.org/posts/terraform-s3-backend-native-state-locks/</link>
            <pubDate>Tue, 07 Jan 2025 08:00:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/terraform-s3-backend-native-state-locks/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post Switching to the Terraform S3 Backend with Native State File Locks&#34; /&gt;&lt;p&gt;Terraform is a flexible, cloud agnostic infrastructure as code (IaC) tool. As it constructs infrastructure resources, it builds a ledger used to track resources that have successfully been created as well as additional metadata (such as &lt;code&gt;id&lt;/code&gt;.) Terraform stores this state in a binary formatted file with the extension &lt;code&gt;.tfstate&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-the-terraform-s3-backend&#34;&gt;What is the Terraform S3 Backend&#xA;&lt;/h2&gt;&lt;p&gt;The Terraform state file described above by default is stored in the same directory as the Terraform infrastructure definition files you wrote. But with this state on your local computer it is vulnerable to being lost or overwritten, and it cannot be shared with or managed by other team members. Using a distributed storage mechanism to store this state file is straightforward with Terraform, and they provide many &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/backend#backend-types&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;backend options&lt;/a&gt;. For AWS users, the &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/backend/s3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Terraform S3 Backend&lt;/a&gt; allows storing this state file in AWS S3.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-state-file-locking&#34;&gt;What is State File Locking&#xA;&lt;/h2&gt;&lt;p&gt;So now we know this state file is stored in distributed object storage (AWS S3,) and more than one user can manage resources within it. But to safely manage this state file, we require a locking mechanism (often &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Lock_%28computer_science%29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;called a mutex in computing&lt;/a&gt;) that disallows multiple users from attempting to write to it at once. We would have a mess if we allowed more than one user to write to it at the same time, potentially losing the resources that were created and intended to be stored in this state file.&lt;/p&gt;&#xA;&lt;p&gt;Terraform state locking capability has been available for the &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/backend/s3#state-locking&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;S3 backend&lt;/a&gt; for quite some time. But unfortunately it has required an additional DynamoDB table to be created that tracked the state file locking status.&lt;/p&gt;&#xA;&lt;p&gt;Until now.&lt;/p&gt;&#xA;&lt;p&gt;This DynamoDB table is an extra resource that seemed tangential to the Terraform state backend process and complicated the process of configuring your backend. That requirement has been rendered obsolete with a recent feature that was added to AWS S3, &lt;strong&gt;conditional writes&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;aws-s3-conditional-writes&#34;&gt;AWS S3 Conditional Writes&#xA;&lt;/h2&gt;&lt;p&gt;In August, AWS announced the addition of the &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/about-aws/whats-new/2024/08/amazon-s3-conditional-writes/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;S3 Conditional Writes feature&lt;/a&gt;. This feature of AWS S3 compels S3 clients to check for the existence of an object before writing it, and if it already exists to fail. If the file exists the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-writes.html#conditional-error-response&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;S3 client returns&lt;/a&gt; a &lt;code&gt;412 Precondition Failed&lt;/code&gt; error response.&lt;/p&gt;&#xA;&lt;h2 id=&#34;s3-conditional-write-support-added-in-terraform-v110&#34;&gt;S3 Conditional Write Support Added in Terraform v1.10&#xA;&lt;/h2&gt;&lt;p&gt;Support for S3 Conditional Writes was added to Terraform &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform/releases/tag/v1.10.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;release v1.10&lt;/a&gt;. (If you want to see some great background and architecture detail from the developer Bruno Schaatsbergen about the implementation look &lt;a class=&#34;link&#34; href=&#34;https://github.com/hashicorp/terraform/pull/35661&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.)&lt;/p&gt;&#xA;&lt;p&gt;Thankfully this is completely transparent to the Terraform user (unless it returns an error attempting to lock the state file.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;configuring-the-s3-backend-to-use-native-state-file-locking&#34;&gt;Configuring the S3 Backend to Use Native State File Locking&#xA;&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/backend/s3#state-locking&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Terraform documentation&lt;/a&gt; describes the new configuration parameter &lt;code&gt;use_lockfile&lt;/code&gt; to enable S3 state locking. It also currently describes the old DynamoDB method as still available. (It&amp;rsquo;s common for software to support both an old and new related feature for some time until all users can migrate to the new methodology.)&lt;/p&gt;&#xA;&lt;p&gt;This means you can actually use both locking mechanisms at the same time. But this is both unnecessary overkill, and could lead to confusion and problems. I would recommend that you replace your old DynamoDB locking configuration with S3 state locking immediately. It will be cheaper (without having to pay for an extra DynamoDB table or reads/writes to that table,) and less error prone.&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s how to change your Terraform backend configuration.&lt;/p&gt;&#xA;&lt;h3 id=&#34;terraform-configuration-specifics&#34;&gt;Terraform Configuration Specifics&#xA;&lt;/h3&gt;&lt;p&gt;The old DynamoDB method used a configuration parameter named &lt;code&gt;dynamodb_table&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The new S3 state locking method uses a configuration parameter named &lt;code&gt;use_lockfile&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Both are covered in the current Terraform &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/backend/s3#state-locking&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;documentation&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h4 id=&#34;version-constraints&#34;&gt;Version Constraints&#xA;&lt;/h4&gt;&lt;p&gt;We also recommend that when you switch to the S3 native state locking method, you set the Terraform configuration parameter &lt;code&gt;required_version&lt;/code&gt; to the minimum version that supports S3 native state file locking. If you have users with an earlier version of Terraform, they won&amp;rsquo;t be able to use this feature and will see errors if the &lt;code&gt;use_lockfile&lt;/code&gt; parameter is enabled. Setting the &lt;code&gt;required_version&lt;/code&gt; to v1.10 at a minumum makes your configuration more resilient and doesn&amp;rsquo;t let someone attempt to create or update resources using an older Terraform version. Think of it as a prerequisite.&lt;/p&gt;&#xA;&lt;p&gt;This Terraform version constraints configuration is documented &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/terraform#terraform-required_version&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;, and looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;  required_version&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;~&amp;gt; 1.10&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h4 id=&#34;sample-configuration&#34;&gt;Sample Configuration&#xA;&lt;/h4&gt;&lt;p&gt;With all this background information about the configuration parameters, here&amp;rsquo;s a sample Terraform configuration with both the old and new parameters present:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-hcl&#34; data-lang=&#34;hcl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;provider&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws&amp;#34;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;  region&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;us-west-2&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;terraform&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;backend&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3&amp;#34;&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;    encrypt&lt;/span&gt;        &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;    bucket&lt;/span&gt;         &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tfstate-lock-test-0bhfxn8x1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;    region&lt;/span&gt;         &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;us-west-2&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;    key&lt;/span&gt;            &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;example/terraform-state-lock-test.tfstate&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;    dynamodb_table&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tfstate-lock-test&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;    use_lockfile&lt;/span&gt;   &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;required_providers&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;    aws&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;      source&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;hashicorp/aws&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;      version&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;5.82.2&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    }&lt;span class=&#34;c1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;  # This sets the version constraint to a minimum of 1.10 for native state file locking support&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;  required_version&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;~&amp;gt; 1.10&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;In order to switch away from using the old DynamoDB locking method, remove that &lt;code&gt;dynamodb_table&lt;/code&gt; configuration parameter.&lt;/p&gt;&#xA;&lt;h2 id=&#34;state-file-locking-in-action&#34;&gt;State File Locking in Action&#xA;&lt;/h2&gt;&lt;p&gt;We now know how to configure Terraform S3 native state file locking, but how does it perform and what will we see if you cannot get the mutex to lock the file?&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve tested both methods and will show you the output from each when state file locking fails.&lt;/p&gt;&#xA;&lt;h3 id=&#34;error-from-dynamodb-state-file-locking&#34;&gt;Error from DynamoDB State File Locking&#xA;&lt;/h3&gt;&lt;p&gt;The old DyamoDB state file locking method would return an error such as the below:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ terraform apply plan.out &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Acquiring state lock. This may take a few moments...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;╷&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Error: Error acquiring the state lock&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Error message: operation error DynamoDB: PutItem, https response error StatusCode: 400, RequestID: CP9U4IRC04OBONKIQHM4LUOLLJVV4KQNSO5AEMVJF66Q9ASUAAJG, ConditionalCheckFailedException: The conditional request failed&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Lock Info:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ID:        39f64263-4ad8-a563-faf7-f28f8a042a00&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Path:      tfstate-lock-test-0bhfxn8x1/example/terraform-state-lock-test.tfstate&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Operation: OperationTypeApply&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Who:       user@hostname&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Version:   1.10.3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Created:   2025-01-08 03:38:13.121564614 +0000 UTC&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Info:      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Terraform acquires a state lock to protect the state from being written&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ by multiple users at the same time. Please resolve the issue above and try&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ again. For most commands, you can disable locking with the &lt;span class=&#34;s2&#34;&gt;&amp;#34;-lock=false&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ flag, but this is not recommended.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;error-from-s3-backend-native-state-file-locking&#34;&gt;Error from S3 Backend Native State File Locking&#xA;&lt;/h3&gt;&lt;p&gt;The new S3 backend native state file locking method will return an error that looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ terraform apply plan2.out&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;╷&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Error: Error acquiring the state lock&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Error message: operation error S3: PutObject, https response error StatusCode: 412, RequestID: N0BGGAFN8V1N2WCQ, HostID: 4G32Xus/86u8CehvNbvzv8NoqiyTvsBWGYBXYK6E8Vn0E4+wom+6Jm6WFVUFSaCE7C1TBP5Vauo&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;, api error PreconditionFailed: At least one of the pre-conditions you specified did not hold&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Lock Info:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ID:        837482e8-441e-9ff6-d30b-333ee83d8fc4&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Path:      tfstate-lock-test-0bhfxn8x1/example/terraform-state-lock-test.tfstate&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Operation: OperationTypeApply&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Who:       user@hostname&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Version:   1.10.3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Created:   2025-01-08 03:43:11.691479913 +0000 UTC&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Info:      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Terraform acquires a state lock to protect the state from being written&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ by multiple users at the same time. Please resolve the issue above and try&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ again. For most commands, you can disable locking with the &lt;span class=&#34;s2&#34;&gt;&amp;#34;-lock=false&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ flag, but this is not recommended.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;dealing-with-stale-state-file-locks&#34;&gt;Dealing with Stale State File Locks&#xA;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: After publishing this blog, I was asked whether the &lt;code&gt;terraform force-unlock&lt;/code&gt; command still worked. I tested this and can say it does perform as expected with the old S3 DynamoDB state file locking mechanism. Here&amp;rsquo;s an example session showing this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ terraform apply plan2.out&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;╷&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Error: Error acquiring the state lock&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Error message: operation error S3: PutObject, https response error StatusCode: 412, RequestID: NGQM2VGSTSDWPCZF, HostID: dzPZArnTy31oVeuVLI8Dm61HXnuL6M3R2tlWFe2suztP0zkh4Bwv/eJFBLqVfitAI40I5BvIeds&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;, api error PreconditionFailed: At least one of the pre-conditions you specified did not hold&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Lock Info:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ID:        bde40e3b-2bfb-f577-fea5-44923c9d5275&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Path:      tfstate-lock-test-0bhfxn8x1/example/terraform-state-lock-test.tfstate&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Operation: OperationTypeApply&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Who:       user@hostname&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Version:   1.10.3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Created:   2025-01-08 16:55:35.808464751 +0000 UTC&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   Info:      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ Terraform acquires a state lock to protect the state from being written&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ by multiple users at the same time. Please resolve the issue above and try&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ again. For most commands, you can disable locking with the &lt;span class=&#34;s2&#34;&gt;&amp;#34;-lock=false&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ flag, but this is not recommended.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;╵&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;You can remove the lock, but only do this if you know the lock is stale. To do this, first note the lock ID above, then run the &lt;code&gt;force-unlock command&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ terraform force-unlock bde40e3b-2bfb-f577-fea5-44923c9d5275&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Do you really want to force-unlock?&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Terraform will remove the lock on the remote state.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  This will allow &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; Terraform commands to modify this state, even though it&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  may still be in use. Only &lt;span class=&#34;s1&#34;&gt;&amp;#39;yes&amp;#39;&lt;/span&gt; will be accepted to confirm.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Enter a value: yes&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Terraform state has been successfully unlocked!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;The state has been unlocked, and Terraform commands should now be able to&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;obtain a new lock on the remote state.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;delete-your-old-dynamodb-tables&#34;&gt;Delete Your Old DynamoDB Tables&#xA;&lt;/h2&gt;&lt;p&gt;Now that you&amp;rsquo;ve switched from using the old Terraform DynamoDB locking to the new S3 native state file locking, you can remove the old DynamoDB table used to track these locks!&lt;/p&gt;&#xA;&lt;p&gt;Yay, one less resource to manage and be charged by AWS for.&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xA;&lt;/h2&gt;&lt;p&gt;Hopefully you see the advantage of using the new Terraform S3 backend native state file locking mechanism, and how to configure it for your environment.&lt;/p&gt;&#xA;&lt;p&gt;Happy Terraforming!&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>A Survey of Serverless Sustainability Trends</title>
            <link>https://bacchi.org/posts/survey-serverless-sustainability/</link>
            <pubDate>Sun, 29 Dec 2024 08:00:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/survey-serverless-sustainability/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post A Survey of Serverless Sustainability Trends&#34; /&gt;&lt;p&gt;As we bring 2024 to a close, and after an invigorating week at AWS re:Invent, many will be writing their year in review summaries. I&amp;rsquo;ve decided to dedicate those column inches to the state of serverless sustainability today. The observant among us are quite aware of how the artificial intelligence (AI) craze has wormed it&amp;rsquo;s way into every product, industry and conversation over the past year. It&amp;rsquo;s been making headlines as shuttered power plants like Three Mile Island are &lt;a class=&#34;link&#34; href=&#34;https://www.cnn.com/2024/09/20/energy/three-mile-island-microsoft-ai/index.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;reopened&lt;/a&gt;. And it&amp;rsquo;s on a collision course with the world&amp;rsquo;s &lt;a class=&#34;link&#34; href=&#34;https://www.wired.com/story/true-cost-generative-ai-data-centers-energy/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;climate change goals&lt;/a&gt;. (AWS also &lt;a class=&#34;link&#34; href=&#34;https://www.aboutamazon.com/news/sustainability/amazon-nuclear-small-modular-reactor-net-carbon-zero&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;announced in October&lt;/a&gt; they signed agreements for 3 small modular nuclear reactor projects for their own data centers.)&lt;/p&gt;&#xA;&lt;p&gt;Running servers in data centers is an energy intensive process. Every search for a restaurant or game score requires a response from a server. Running a busy webserver requires the same power as one that gets 5 hits per day. Serverless technologies like AWS Lambda, S3, DynamoDB can be used to reduce that constant power usage when there is no demand.&lt;/p&gt;&#xA;&lt;p&gt;Today we&amp;rsquo;ll discuss the current state of affairs with serverless sustainability, and perhaps a little about sustainable computing in general.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-sustainability&#34;&gt;What is Sustainability&#xA;&lt;/h2&gt;&lt;p&gt;In the context of technology and computing in particular, sustainability equates primarily to power usage and carbon emissions. The computing industry has been on an upward trend in energy use since, well, the beginning of the computer era. During that time, increases in computational capabilities (faster processors) have driven higher demands for electricity. The next (current?) era of computing is going to require rethinking these needs by reducing the power requirements of computers and data centers, recycling hardware, and becoming better climate citizens. (AWS discusses some of their sustainability improvements related to the circular economy in this re:Invent talk &amp;ldquo;Advancing sustainable AWS infrastructure to power AI solutions&amp;rdquo; &lt;a class=&#34;link&#34; href=&#34;https://youtu.be/Fq5Gi-_G6T4?t=303&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.)&lt;/p&gt;&#xA;&lt;p&gt;AWS defines sustainability as one of the 6 pillars of their &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/sustainability.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Serverless Applications Lens for the AWS Well-Architected Framework&lt;/a&gt;. Their Well-Architected Framework &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/wellarchitected/latest/sustainability-pillar/sustainability-pillar.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;documentation covering Sustainability indicates&lt;/a&gt; their focus on environmental sustainability in this pillar. It&amp;rsquo;s important that they make that distinction, and even more telling that they are making a large commitment to improving energy efficiency and carbon emissions in their own operations. This document (and &lt;a class=&#34;link&#34; href=&#34;https://sustainability.aboutamazon.com/carbon-reduction-aws.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;others they&amp;rsquo;ve released [PDF]&lt;/a&gt;) lay out their goals as well as identify how AWS cloud customers can optimize their operations to become more sustainable.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sustainable-workloads&#34;&gt;Sustainable Workloads&#xA;&lt;/h2&gt;&lt;p&gt;As is common when working with AWS, they assert customers approach cloud sustainability by using the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/wellarchitected/latest/sustainability-pillar/the-shared-responsibility-model.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;shared responsibility model&lt;/a&gt;. This is akin to their approach for security in the cloud, so it makes sense that they want users to take our part seriously.&lt;/p&gt;&#xA;&lt;h3 id=&#34;region-selection&#34;&gt;Region Selection&#xA;&lt;/h3&gt;&lt;p&gt;One way to make your application more sustainable is to use the lowest carbon intense AWS region available, taking into account other business requirements such as latency. If you are a small company with only customers in one country or region, you may not be able to take advantage, but if business requirements don&amp;rsquo;t disallow using a more remote location you can use this technique. Obviously some AWS regions are in locations that have a higher percentage of renewable energy entering it&amp;rsquo;s power grid. Deciding to use one of these regions should be based on latency of course too, but carbon intensity must be part of the decision.&lt;/p&gt;&#xA;&lt;p&gt;How, then, do we choose a region for sustainability? A good reference is this AWS Architecture Blog: &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/blogs/architecture/how-to-select-a-region-for-your-workload-based-on-sustainability-goals/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;How to select a Region for your workload based on sustainability goals&lt;/a&gt;. They suggest using the site &lt;a class=&#34;link&#34; href=&#34;electricitymaps.com&#34; &gt;electricitymaps.com&lt;/a&gt; to identify carbon intensity and renewal energy percentage for each regional electricity grid.&lt;/p&gt;&#xA;&lt;p&gt;On the &lt;a class=&#34;link&#34; href=&#34;https://app.electricitymaps.com/map/24h&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;electicitymaps 24 hour climate impact map&lt;/a&gt;, hover over the PJM region (which covers Virginia, home to the &lt;code&gt;us-east-1&lt;/code&gt; AWS region) we see the carbon intensity (as of 12/21/2024) is 409g CO&lt;sup&gt;2&lt;/sup&gt;/kWh, and the renewable energy mix is 8%. If we now look at the California power grid (home to the AWS &lt;code&gt;us-west-1&lt;/code&gt; region), we see 139g CO&lt;sup&gt;2&lt;/sup&gt;/kWh, and the renewable energy mix is 67%.&lt;/p&gt;&#xA;&lt;br&gt;&#xA;&lt;br&gt;&#xA;&lt;img src=&#34;grid.jpg&#34;&gt;&#xA;&lt;h2 id=&#34;over-provisioned-capacity-and-time-shifting&#34;&gt;Over-provisioned Capacity and Time Shifting&#xA;&lt;/h2&gt;&lt;p&gt;Earlier this year I ran across a podcast from the &lt;a class=&#34;link&#34; href=&#34;https://greensoftware.foundation/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Green Software Foundation&lt;/a&gt; called Environment Variables. In one &lt;a class=&#34;link&#34; href=&#34;https://podcasts.castplus.fm/e/vnwkr1kn-greening-serverless&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;episode&lt;/a&gt; the guest Kate Goldenring talked about the sustainability merits of serverless. She pointed out a statistic from the &lt;a class=&#34;link&#34; href=&#34;https://sysdig.com/blog/2023-cloud-native-security-usage-report/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Sysdig 2023 Cloud Native Security and Usage Report&lt;/a&gt; that showed 69% of requested CPU resources go unused. That means as an industry we&amp;rsquo;re over provisioning by more than two thirds (2/3). The goal should be higher hardware utilization according to Kate.&lt;/p&gt;&#xA;&lt;p&gt;This proves what we&amp;rsquo;ve been saying about how running applications on servers (such as EC2) or containers is less efficient than serverless. Provisioning for peak capacity is what makes these &amp;ldquo;always on&amp;rdquo; deployments wasteful because traffic is rarely at it&amp;rsquo;s expected peak usage. Serverless technologies that utilize multi-tenancy are intentionally more sustainable than traditional deployment methods because they enable higher hardware utilization.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s idealistic to assume we can perfectly utilize hardware via multi-tenancy, but one approach Meta has begun using in their internal private cloud functions product called &lt;a class=&#34;link&#34; href=&#34;https://read.engineerscodex.com/p/meta-xfaas-serverless-functions-explained&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;XFaaS&lt;/a&gt; (similar to AWS Lambda) is a technique called &amp;ldquo;time shifting&amp;rdquo;. Instead of running all workloads immediately, they will delay some operations that are not time sensitive. This increases the average utilization of their hardware due to scheduling these delay tolerant functions during off-peak times, ultimately lowering their peaks and raising their troughs. That equates to a higher average utilization.&lt;/p&gt;&#xA;&lt;p&gt;This introduces an alternative approach to managing sustainability, seldom discussed in the serverless realm as far as I&amp;rsquo;ve seen. In many event driven systems events don&amp;rsquo;t require immediate processing, and are delay tolerant by design. This characteristic lends itself well to having the processing delayed until utilization in your system is below a certain threshold (i.e. off hours.) Of course this is only possible for data that isn&amp;rsquo;t expected to be immediately consistent. This type of processing emerged in the mainframe computing era, and was called &amp;ldquo;batch processing&amp;rdquo;. It&amp;rsquo;s still in use today, did you ever wonder why your bank statement can take up to 24 hours to reflect purchases? They&amp;rsquo;re processing payments either overnight or in some batch processing methodology.&lt;/p&gt;&#xA;&lt;h2 id=&#34;time-shifting-on-kubernetes&#34;&gt;Time Shifting on Kubernetes&#xA;&lt;/h2&gt;&lt;p&gt;Although I don&amp;rsquo;t consider Kubernetes to be serverless by definition, I happened across a Kubernetes admission controller recently that accepts delay tolerant workloads. This paradigm is atypical for Kubernetes (which usually processes a request as soon as it&amp;rsquo;s received,) but the pattern hints at the potential future of all workload processing systems.&lt;/p&gt;&#xA;&lt;p&gt;You may have a request sent to your backend system that doesn&amp;rsquo;t require immediate processing, but rather is capable of running whenever is most efficient to do so. The &lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2205.02895&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;research paper describing the Cucumber&lt;/a&gt; and a (2 year old but unmodified) &lt;a class=&#34;link&#34; href=&#34;https://github.com/dos-group/cucumber&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;reference implementation&lt;/a&gt; are available. While this is more geared towards running workloads when excess solar power is being generated, the concept could be extended to many types of situations such as how heavily loaded your servers are.&lt;/p&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xA;&lt;/h2&gt;&lt;p&gt;You&amp;rsquo;ve just read a few of the trends that have been developing in the sustainable serverless computing arena. Hope this has provided some new information for you to go delve into on your own. Thanks and have a great 2025!&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Cover photo by &lt;a href=&#34;https://pixabay.com/users/fabersam-98886&#34;&gt;Samuel Faber&lt;/a&gt; from &lt;a href=&#34;https://pixabay.com/&#34;&gt;Pixabay&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Limitations of AWS EC2 Image Builder Lifecycle Policies</title>
            <link>https://bacchi.org/posts/limitations-ec2-imagebuilder-lifecycle-policies/</link>
            <pubDate>Mon, 12 Aug 2024 08:00:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/limitations-ec2-imagebuilder-lifecycle-policies/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post Limitations of AWS EC2 Image Builder Lifecycle Policies&#34; /&gt;&lt;p&gt;EC2 Image Builder Lifecycle Policies is a fairly new AWS feature that enables automatic cleanup of old EC2 Image Builder pipeline artifacts. If you haven&amp;rsquo;t used EC2 Image Builder, it&amp;rsquo;s quite handy for creating customized AWS Machine Images (AMIs) for your EC2 deployments.&lt;/p&gt;&#xA;&lt;p&gt;This could be a really valuable tool that simplifies the AMI build process. But there are a number of artifacts left behind after your AMI is built that potentially cost money and require manual effort to clean up.&lt;/p&gt;&#xA;&lt;p&gt;Enter EC2 Image Builder Lifecycle Policies. This feature is advertised as a way to automatically tidy these artifacts. Unfortunately it&amp;rsquo;s almost unusable if you build a large number of AMIs constructed from numerous recipes.&lt;/p&gt;&#xA;&lt;p&gt;Below I&amp;rsquo;ll describe a high frequency use case that illustrates the limitations of EC2 Image Builder Lifecycle Policies. You can make your own conclusions about the utility of this tool as it stands today.&lt;/p&gt;&#xA;&lt;h2 id=&#34;standard-use-case&#34;&gt;Standard use case&#xA;&lt;/h2&gt;&lt;p&gt;The process of building AWS EC2 Amazon Machine Images (AMIs) can be rather involved. You start with a base image, add required packages and user data, then build, test, and finally deploy your custom AMI. The deployment step isn&amp;rsquo;t even straightforward, as it potentially requires disk volumes, network interfaces, and additional resources which necessitate experimentation. Even after you&amp;rsquo;ve done all this, managing the state of these AMIs and their related resources still isn&amp;rsquo;t complete. These resources all need to be cleaned up. And because AMIs tend to be created frequently to meet security objectives, the entire process can occur at a high cadence.&lt;/p&gt;&#xA;&lt;h3 id=&#34;why-so-many-amis&#34;&gt;Why so many AMIs?&#xA;&lt;/h3&gt;&lt;p&gt;We all know how frequently CVEs (&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Common_Vulnerabilities_and_Exposures&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Common Vulnerabilities and Exposures&lt;/a&gt;) can be released, and how quickly management expects them to be mitigated. Lower severity security updates come out at an even more unrelenting pace. For production infrastructure at enterprise scale, updates need to be routinely applied and be extremely reliable. This process is simplified by automating it all with an EC2 Image Builder pipeline executed on a regular schedule.&lt;/p&gt;&#xA;&lt;p&gt;But after these AMIs and related resources have been superseded by newer ones they need to be removed. Until now there was no method provided by AWS to perform this action. You needed to develop your own tooling for this purpose.&lt;/p&gt;&#xA;&lt;h2 id=&#34;ec2-image-builder-lifecycle-policies&#34;&gt;EC2 Image Builder Lifecycle Policies&#xA;&lt;/h2&gt;&lt;p&gt;Lifecycle Policies adds a necessary (heretofore missing) feature to EC2 Image Builder. Having AWS remove your unused resources is a great idea. But the execution leaves something to be desired. For the sake of illustration, let&amp;rsquo;s also define what &amp;ldquo;related resources&amp;rdquo; means here.&lt;/p&gt;&#xA;&lt;p&gt;Every AMI built via EC2 Image Builder requires an image recipe and image pipeline be created. An image recipe consists of AWS managed components or custom (user generated) components to perform an AMI build. The pipeline runs your recipes which generate an output image upon success which references the output AMI, infrastructure configuration, distribution settings, and a CloudWatch log stream (which includes pipeline output for debugging purposes.)&lt;/p&gt;&#xA;&lt;p&gt;When you modify the image recipe, a new recipe version is created and the previous versions become obsolete. The now unused recipe and it&amp;rsquo;s related resources (such as the output image as well as the AMI) remains active in AWS indefinitely and won&amp;rsquo;t be removed until you perform that action. (I&amp;rsquo;ve highlighted this specific point for a reason that will become obvious later.)&lt;/p&gt;&#xA;&lt;p&gt;If you thought you merely needed to delete the AMI when you were done with it, you would leave all these related Image Builder resources in your account. (Granted they don&amp;rsquo;t cost a lot, but it makes sense to remove unused resources, if only to avoid hitting quota limits at some point in the future.)&lt;/p&gt;&#xA;&lt;p&gt;While EC2 Image Builder Lifecycle Policies makes this last cleanup bit somewhat more straightforward, it cannot be said it&amp;rsquo;s &amp;ldquo;a one size fits all&amp;rdquo; solution.&lt;/p&gt;&#xA;&lt;h2 id=&#34;limitations-of-the-current-lifecycle-policies-service&#34;&gt;Limitations of the current Lifecycle Policies service&#xA;&lt;/h2&gt;&lt;p&gt;To create a lifecycle policy for AMI image resources, the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/imagebuilder/latest/userguide/create-lifecycle-policies.html#create-lifecycle-policy-ami&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;documentation says&lt;/a&gt; you must &amp;ldquo;apply lifecycle rules to image resources based on the recipe that created them, select up to 50 recipe versions for the policy.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;This is unwieldy because you have to add new recipe versions explicitly each time you create a new image recipe. If you use Infrastructure as Code (IaC) tools to do this (such as Terraform, CloudFormation or CDK), it becomes slightly less manual, but still requires manual effort (or at least in depth awareness of the process.) But even if you add these recipes to your Lifecycle Policy manually, there&amp;rsquo;s a limit of 50 recipe versions in the policy. This isn&amp;rsquo;t as irritating if you only have a dozen recipes in total, the scope of the problem is intensified with scale.&lt;/p&gt;&#xA;&lt;p&gt;Also, I&amp;rsquo;m referring to lifecycle policies for AMI image resources, I don&amp;rsquo;t currently use EC2 Image Builder to create container image resources.&lt;/p&gt;&#xA;&lt;p&gt;The limitations as I see them are:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The maximum number of recipes allowed in the &lt;code&gt;LifecyclePolicyResourceSelection&lt;/code&gt; API &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/imagebuilder/latest/APIReference/API_LifecyclePolicyResourceSelection.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;documentation&lt;/a&gt; which can be used as selection criteria is 50. This 50 recipe limit is quite an arbitrary number, and when a user has a large number of image recipes it is both an extremely small limit, and would become a burden to add all recipes to this rule scope parameter.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve verified this is not adjustable in the AWS Service Quotas self service quota increase dashboard in the AWS Console (or the Service Quotas API).&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;In the EC2 Image Builder Lifecycle Policies AWS Console, when selecting the recipes to apply the Rule Scope, the drop down list only displays a few current recipes. It shows a spinner and indicates it is &amp;ldquo;Loading Recipes&amp;rdquo; (see screenshot) but the additional recipes never show up.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;img src=&#34;rule-scope.png&#34;&gt;&#xA;&lt;h2 id=&#34;recommended-solutions-feature-requests&#34;&gt;Recommended Solutions (Feature Requests)&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;An obvious solution to the first limitation above (the 50 recipe maximum problem) is allowing more than 50 recipes in the selection criteria Rule Scope.&lt;/p&gt;&#xA;&lt;p&gt;Of course, there&amp;rsquo;s a much more user friendly and comprehensive approach. The most ergonomic proposal would be to allow a wildcard or pattern matching syntax. This would allow power users to identify their recipes in the Rule Scope with something that looks like the below json (the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/imagebuilder/latest/APIReference/API_LifecyclePolicyResourceSelectionRecipe.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;API documentation requires&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;/&lt;code&gt;semanticVersion&lt;/code&gt; key value pairs). Otherwise it would mean still having to list every single version you&amp;rsquo;ve created that should be subject to the rule scope.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ubuntu-recipe&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;semanticVersion&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;My rationale for these suggestions are as follows: If AWS only took the approach of allowing more than 50 recipes in the selection criteria Rule Scope, users would still have to add every single recipe version to the Rule Scope. Every single recipe version would have to be inserted in the &lt;code&gt;LifecyclePolicyResourceSelection&lt;/code&gt; mentioned above. Allowing for a wildcard is much more approachable, as users would only need to add the recipe name and a wildcard to the selection criteria Rule Scope once, and never have to think about it again.&lt;/p&gt;&#xA;&lt;p&gt;This single feature would make EC2 Image Builder Lifecycle Policies much more useful and less of a burden for users who actively manage recipes and need a tool to clean these resources up (without resorting to writing something from scratch.)&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;To resolve the AWS Console Rule Scope drop down problem, it seems like the first 6 results are returned in the request, but the pagination isn&amp;rsquo;t working to return more than those 6 results. In fact, if you open your browser developer console, you can see that 6 results are returned from the &lt;code&gt;ListImageRecipes&lt;/code&gt; request, but no more ever appear to be returned.&lt;/p&gt;&#xA;&lt;p&gt;Thankfully the AWS CLI command &lt;code&gt;aws imagebuilder update-lifecycle-policy&lt;/code&gt; (and obviously the API) allows you to provide a list of recipes, but the AWS Console is typically the first exposure that users have to how a feature works. Fixing this issue would be helpful to users newly exposed to Lifecycle Policies.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;While EC2 Image Builder Lifecycle Policies has the potential to be a great service, it is currently hampered by the user experience (UX.) Adding functionality to make adding recipes to policies easier would be a major improvement for early adopters and power users.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>S3 Bucket Takeover Neutralization</title>
            <link>https://bacchi.org/posts/s3-bucket-takeover-neutralization/</link>
            <pubDate>Tue, 30 Jan 2024 07:00:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/s3-bucket-takeover-neutralization/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post S3 Bucket Takeover Neutralization&#34; /&gt;&lt;p&gt;There&amp;rsquo;s been a recent &lt;a class=&#34;link&#34; href=&#34;https://checkmarx.com/blog/hijacking-s3-buckets-new-attack-technique-exploited-in-the-wild-by-supply-chain-attackers/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;uptick in the number of S3 buckets&lt;/a&gt; that have become &amp;ldquo;hijacked&amp;rdquo; or &amp;ldquo;taken over&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;How can an attacker take over your S3 bucket? What can you do to prevent this on your buckets?&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;ll answer these questions and provide details on how you can neutralize the threat of S3 bucket takeovers.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-hijacking&#34;&gt;What is Hijacking?&#xA;&lt;/h2&gt;&lt;p&gt;How can your S3 bucket get hijacked?&lt;/p&gt;&#xA;&lt;p&gt;It should be noted that the term &amp;ldquo;hijacked&amp;rdquo; is a misnomer. S3 buckets which have ended up in this state were managed poorly by the owner. The original owner had to choose to give up ownership of the S3 bucket, prior to it being claimed by a bad actor. If you have an active AWS S3 bucket in your account, this cannot occur unless you relinquish control. These are categorized as &lt;a class=&#34;link&#34; href=&#34;https://www.crowdstrike.com/cybersecurity-101/cyberattacks/supply-chain-attacks/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;software supply chain attacks&lt;/a&gt;, where the attacker hijacks open source software or software updates, eventually compromising target computers.&lt;/p&gt;&#xA;&lt;p&gt;AWS uses a &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;global namespace&lt;/a&gt; for S3 buckets. If a bucket name &amp;ldquo;mattbacchi&amp;rdquo; is available and I requisition it, no one else in the world can use that bucket name. A global namespace has some downsides, namely that everyone competes for the same bucket names, and a single bucket name cannot be owned by more than one AWS account.&lt;/p&gt;&#xA;&lt;p&gt;This surge in exploit/hijack/takeover incidents ultimately has this global namespace to blame. If you owned an S3 bucket but then deleted it, someone else could subsequently recreate it in their account (after a short period of time.)&lt;/p&gt;&#xA;&lt;p&gt;If the deleted bucket was public and contained trusted files (such as npm packages), someone with sinister intentions could recreate the bucket and masquerade as you. If they named their tainted files the same as your trusted files, users might download the malicious content assuming it was your original content. This is how the above poisoned &amp;ldquo;bignum&amp;rdquo; &lt;a class=&#34;link&#34; href=&#34;https://checkmarx.com/blog/hijacking-s3-buckets-new-attack-technique-exploited-in-the-wild-by-supply-chain-attackers/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;npm package exploit&lt;/a&gt; worked. The S3 bucket owned by someone the &amp;ldquo;bignum&amp;rdquo; software developer trusted was abandoned, subsequently an attacker recreated it with malicious content.&lt;/p&gt;&#xA;&lt;p&gt;These attacks cannot occur if S3 buckets are managed with better data lifecycle hygiene.&lt;/p&gt;&#xA;&lt;h2 id=&#34;preventing-s3-bucket-takeover&#34;&gt;Preventing S3 Bucket Takeover&#xA;&lt;/h2&gt;&lt;p&gt;In order to neutralize this threat, I recommend never deleting your S3 buckets.&lt;/p&gt;&#xA;&lt;p&gt;As described above, the only S3 buckets vulnerable to this attack vector are those that have been deleted and are no longer active. The logical defense is to never relinquish your S3 buckets, instead you maintain the bucket and name forever.&lt;/p&gt;&#xA;&lt;p&gt;Won&amp;rsquo;t this get expensive, you may ask? AWS &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/s3/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;bills customers for S3&lt;/a&gt; based on storage. If you aren&amp;rsquo;t storing any data in the bucket, it will never generate a charge. In this way we retain an S3 bucket name so that it doesn&amp;rsquo;t fall into the wrong hands.&lt;/p&gt;&#xA;&lt;p&gt;Of course, this may not be necessary for all S3 buckets you own. I recommend using this technique for any buckets that are public and have been used in production software applications. The &amp;ldquo;bignum&amp;rdquo; npm package bucket above is a prime example, retaining that bucket would have prevented the attack.&lt;/p&gt;&#xA;&lt;h2 id=&#34;decommissioning-process&#34;&gt;Decommissioning Process&#xA;&lt;/h2&gt;&lt;p&gt;Developing an official process to manage this in your organization is important.&lt;/p&gt;&#xA;&lt;p&gt;If you intend to retain your S3 buckets in order to prevent takeover, you must first develop documentation and communicate this policy. Also consider how you will implement identifiers or signposts indicating the bucket must be retained to administrators who may not be familiar with the process. I&amp;rsquo;ve personally used documentation, an AWS tagging scheme, and a couple other methods to prevent the bucket from being accidentally relinquished.&lt;/p&gt;&#xA;&lt;p&gt;One method of making this obvious to infrastructure engineers (i.e. devops or platform engineers) is to create a zero byte file in the bucket that identifies it as persistent. I have suggested the file be named &lt;code&gt;DO_NOT_DELETE_S3_BUCKET_PERSISTENT&lt;/code&gt; as a fairly large signpost for people to prevent them from deleting it. A sample command to do this via the AWS CLI is something like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;touch DO_NOT_DELETE_S3_BUCKET_PERSISTENT&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; aws s3 cp DO_NOT_DELETE_S3_BUCKET_PERSISTENT s3://BUCKETNAME/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Another method is to create an AWS tag on the bucket such as &lt;code&gt;persistent=true&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Finally, if you want to use a more durable mechanism, add an S3 bucket policy that denies the action &lt;code&gt;s3:DeleteBucket&lt;/code&gt; as well as &lt;code&gt;s3:PutObject&lt;/code&gt;. This will prevent removing the bucket unless the user is an administrator, at which point they can remove the &lt;code&gt;s3:DeleteBucket&lt;/code&gt; permission from the bucket policy. But they must manually perform this update, and hopefully that extra step makes them realize it shouldn&amp;rsquo;t be deleted.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;Today we&amp;rsquo;ve discussed the cause of S3 bucket hijacking and some methods of preventing it. Hopefully this motivates you to perform some analysis of your S3 buckets and apply these suggestions in your environment.&lt;/p&gt;&#xA;&lt;p&gt;Thanks for reading and have a great day!&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Event Driven Processing of ip-ranges.json</title>
            <link>https://bacchi.org/posts/eda-ip-ranges-json/</link>
            <pubDate>Sun, 28 Jan 2024 08:00:00 -0600</pubDate>
            <guid>https://bacchi.org/posts/eda-ip-ranges-json/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post Event Driven Processing of ip-ranges.json&#34; /&gt;&lt;p&gt;Imagine you have a security group that needs to allow all IP addresses of AWS EC2 instances. Or imagine you have to allow IP addresses of Github Actions runners so that only your CI workers connect to your VPC. Both of those IP address ranges change regularly, and need to be updated (usually by hand.)&lt;/p&gt;&#xA;&lt;p&gt;If we want to automate these security group updates, how could you figure out when these IP address ranges have changed? AWS has an SNS notification sent every time their &lt;code&gt;ip-ranges.json&lt;/code&gt; list changes. The SNS notification can be used to initiate an automated procedure to update our security group.&lt;/p&gt;&#xA;&lt;p&gt;What we&amp;rsquo;re describing is an &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/event-driven-architecture/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;event driven architecture&lt;/a&gt;. In event driven architectures, an event producer causes an event to be created. A downstream event consumer handles the event and may trigger further events.&lt;/p&gt;&#xA;&lt;p&gt;In this 2 part blog post series, we&amp;rsquo;ll cover event driven architectures. In the first part of the example used to illustrate the mechanics, we&amp;rsquo;ll build the IP address range processing component. This piece of the puzzle processes the AWS &lt;code&gt;ip-ranges.json&lt;/code&gt; file and inserts it into a DynamoDB table. The second blog in this series will insert the IP ranges into AWS security groups.&lt;/p&gt;&#xA;&lt;p&gt;After the next blog post, you&amp;rsquo;ll be able to manage IP address ranges in your environment using Event Driven Architecture.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-event-driven-architecture&#34;&gt;What is Event Driven Architecture?&#xA;&lt;/h2&gt;&lt;p&gt;The Wikipedia page for &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Event-driven_architecture&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;event driven architecture&lt;/a&gt; (or EDA) describes it as &amp;ldquo;a software architecture paradigm concerning the production and detection of events&amp;rdquo;. This is in contrast to software which is focused on its own state, and doesn&amp;rsquo;t concern itself with external state changes. Event driven architectures are often made up of loosely coupled components that act independantly on events that they&amp;rsquo;re concerned with.&lt;/p&gt;&#xA;&lt;h3 id=&#34;why-use-eda-for-data-processing&#34;&gt;Why use EDA for data processing?&#xA;&lt;/h3&gt;&lt;p&gt;Data processing is often well suited to the EDA model because it&amp;rsquo;s rarely necessary to syncronously perform a data processing task. If a user purchases something in a shopping cart, certainly the interatction with the bank or credit card needs to be syncronous and immediate. But if the website catalogs all purchases in a &amp;ldquo;top ten products&amp;rdquo; list from all user purchases, that processing can be done asyncrynously at a later, and possibly less busy time of the day. It&amp;rsquo;s common for data engineering teams to perform extract, transform, load (or ETL) jobs that process data off hours, to avoid contention for compute resources. This can all be done with an  event driven model, where the list of purchased items in our above example would be sent to an event bus (such as AWS EventBridge or Apache Kafka.) Consumers of that type of event would then act on the event depending on their function.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sns-notification-for-ip-rangesjson&#34;&gt;SNS notification for ip-ranges.json&#xA;&lt;/h2&gt;&lt;p&gt;As mentioned above, anyone can subscribe to SNS notifications for the &lt;code&gt;ip-ranges.json&lt;/code&gt; list. When a change occurs to that list the SNS notification is sent out. It acts as the event producer in this case, causing anyone who is subscribed to the notification list to receive the event.&lt;/p&gt;&#xA;&lt;p&gt;In our example today, we&amp;rsquo;ll setup an AWS Lambda function to process these events stemming from the SNS notification. Our function will be the event consumer in this scenario.&lt;/p&gt;&#xA;&lt;h2 id=&#34;data-organization-of-the-ip-rangesjson-file&#34;&gt;Data organization of the ip-ranges.json file&#xA;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;ip-ranges.json&lt;/code&gt; file &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html#aws-ip-syntax&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;syntax&lt;/a&gt; consists of a creation date (to indicate last update time) and a list of IPv4 and IPv6 address ranges. These look like the following sample:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;ip_prefix&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;52.4.0.0/14&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;region&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;us-east-1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;service&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;EC2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;network_border_group&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;us-east-1&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;We want to maintain all of this information, and in fact enhance it with the date stamp (or &lt;code&gt;synctoken&lt;/code&gt;) which is included in the &lt;code&gt;ip-ranges.json&lt;/code&gt; file as mentioned above.&lt;/p&gt;&#xA;&lt;h2 id=&#34;dynamodb-single-table-design&#34;&gt;DynamoDB Single Table Design&#xA;&lt;/h2&gt;&lt;p&gt;We&amp;rsquo;ll be inserting all of these IP address ranges into a DynamoDB table for future access and processing (triggered via events.) DynamoDB is great for serverless applications because it allows a large number of stateless connections via HTTP. Using a single DynamoDB table, we&amp;rsquo;ll store all of this data in a way that can be easily queried by creating composite keys that pre-join the data fields and make lookups extremely fast. This concept is discussed quite extensively, but Alex Debrie (an AWS Data Hero) has a &lt;a class=&#34;link&#34; href=&#34;https://www.alexdebrie.com/posts/dynamodb-single-table/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;blog post&lt;/a&gt; that covers these ideas quite well.&lt;/p&gt;&#xA;&lt;p&gt;Since we want to enable queries that return IP prefixes based on AWS region and service. In order to do that, we&amp;rsquo;ll format the data with both a primary key (PK) and sort key (SK), as well as a synctoken that is completely separate from the IP prefixes. This synctoken will enable us to remove all IP prefixes that have the synctoken because we&amp;rsquo;ll be creating a &lt;a class=&#34;link&#34; href=&#34;https://www.trek10.com/blog/the-ten-rules-for-data-modeling-with-dynamodb&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;global secondary index&lt;/a&gt; using the synctoken to allow fast queries of the items containing a particular synctoken. We can add non-normalized data to the same DynamoDB table because it isn&amp;rsquo;t an SQL database, it&amp;rsquo;s more like a key-value or wide-column store database, generally referred to as NoSQL.&lt;/p&gt;&#xA;&lt;p&gt;Here is what our primary and secondary key layout will look like:&lt;/p&gt;&#xA;&lt;img src=&#34;primary-key.png&#34;&gt;&#xA;&lt;h2 id=&#34;lambda-function-overview&#34;&gt;Lambda Function Overview&#xA;&lt;/h2&gt;&lt;p&gt;We&amp;rsquo;ll use a Lambda function that gets triggered by &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html#subscribe-notifications&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;an SNS notification&lt;/a&gt; whenever the IP ranges JSON changes. This SNS subscription, Lambda Function, DynamoDB table and all the AWS infrastructure is configured using AWS Cloud Development Kit (CDK.) The Lambda Function itself does one thing. It downloads the JSON, cycles through every item, and adds it to the DynamoDB table.&lt;/p&gt;&#xA;&lt;h2 id=&#34;aws-cdk-configuration&#34;&gt;AWS CDK configuration&#xA;&lt;/h2&gt;&lt;p&gt;The configuration used to create the Lambda Function and other infrastructure is in the Github repository &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/eda-ip-ranges/tree/main&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;. Instructions on how to deploy the infrastructure are also in that repository.&lt;/p&gt;&#xA;&lt;p&gt;Once deployed the Lambda Function will do nothing until the next time the SNS notification invokes it when the JSON file has changed. Below you can see a screenshot of recent invocations of the function in my environment.&lt;/p&gt;&#xA;&lt;img src=&#34;cloudwatch-metrics-lambda-1.png&#34;&gt;&#xA;&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping Up&#xA;&lt;/h2&gt;&lt;p&gt;In this first part of the blog series, you saw how we used Event Driven Architecture to respond to an event and perform some data processing. In the next section we&amp;rsquo;ll handle using these IP address ranges to update security groups allowing traffic for certain AWS services.&lt;/p&gt;&#xA;&lt;p&gt;Thanks for reading and have a great day!&lt;/p&gt;&#xA;&lt;h2 id=&#34;resources&#34;&gt;Resources&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;AWS &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/blogs/security/how-to-automatically-update-your-security-groups-for-amazon-cloudfront-and-aws-waf-by-using-aws-lambda/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;blog&#xA;post&lt;/a&gt;&#xA;on &amp;ldquo;How to Automatically Update Your Security Groups for Amazon CloudFront and&#xA;AWS WAF by Using AWS Lambda&amp;rdquo;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Cover photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@thephotographytimes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Dushyant Kumar&lt;/a&gt; on&#xA;&lt;a class=&#34;link&#34; href=&#34;https://unsplash.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>New and Improved Job Searching Resources in 2024</title>
            <link>https://bacchi.org/posts/job-searching-resources-2024/</link>
            <pubDate>Thu, 11 Jan 2024 08:00:00 -0600</pubDate>
            <guid>https://bacchi.org/posts/job-searching-resources-2024/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post New and Improved Job Searching Resources in 2024&#34; /&gt;&lt;p&gt;A couple years ago I shared a&#xA;&lt;a class=&#34;link&#34; href=&#34;https://bacchi.org/posts/tech-job-search-2021/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;post&lt;/a&gt; that detailed various&#xA;tech industry job search resources. There are a number of more modern sites&#xA;available today that have remote tech roles and the ability to filter the&#xA;results more effectively than places like LinkedIn.&lt;/p&gt;&#xA;&lt;h2 id=&#34;ventureloop&#34;&gt;Ventureloop&#xA;&lt;/h2&gt;&lt;p&gt;Ventureloop is a job site that lists primarily venture capital startups who are&#xA;looking for candidates. If you&amp;rsquo;re interested in startups (and some of these can&#xA;be very large and established companies such as DataDog to name just one) take a&#xA;look at their search site&#xA;&lt;a class=&#34;link&#34; href=&#34;https://www.ventureloop.com/ventureloop/job_search.php&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;otta&#34;&gt;Otta&#xA;&lt;/h2&gt;&lt;p&gt;Otta requires you to sign up and fill out a questionaire of what you&amp;rsquo;re looking&#xA;for in a company and role. For instance the size of the company, the&#xA;technologies they use and whether you&amp;rsquo;re looking for a remote position are all&#xA;things you can add to an allow or deny list. Then they filter roles and present&#xA;them to you so that you can have roles that match what you&amp;rsquo;re looking for.&lt;/p&gt;&#xA;&lt;p&gt;The company descriptions are detailed (and written by the Otta staff not just&#xA;the company PR materials) and they have an indicator of how quickly they get&#xA;back to candidates, as well as how much growth they&amp;rsquo;re expecting in the next&#xA;year. All helpful information to have about a prospective new company.&lt;/p&gt;&#xA;&lt;p&gt;Sign up &lt;a class=&#34;link&#34; href=&#34;https://app.otta.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;climatebase&#34;&gt;Climatebase&#xA;&lt;/h2&gt;&lt;p&gt;If you&amp;rsquo;re interested in tech jobs (or any roles) in the climate tech industry,&#xA;here&amp;rsquo;s your chance to do something for the environment.&lt;/p&gt;&#xA;&lt;p&gt;Check it out &lt;a class=&#34;link&#34; href=&#34;https://climatebase.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;stillhiring-today&#34;&gt;StillHiring Today&#xA;&lt;/h2&gt;&lt;p&gt;With the subtitle of &amp;ldquo;&lt;strong&gt;WHO THE FRIGGIN’ FRIG IS HIRING RN!?&lt;/strong&gt;&amp;rdquo;, and using a&#xA;giant airtable sheet listing actively hiring companies, StillHiring Today is a&#xA;unique offering. They have a lot of entries but you have to weed through the&#xA;table manually, and they don&amp;rsquo;t list positions just the company name and what&#xA;types of open roles(by job function) they have. It&amp;rsquo;s still helpful to find&#xA;companies that you are interested in working for, and know that they&amp;rsquo;re actively&#xA;hiring.&lt;/p&gt;&#xA;&lt;p&gt;Check out the &lt;a class=&#34;link&#34; href=&#34;https://stillhiring.today/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;list&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Cover photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@we_are_rising&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;lucas Favre&lt;/a&gt; on&#xA;&lt;a class=&#34;link&#34; href=&#34;https://unsplash.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Bundling Go Lambda Functions with the AWS CDK</title>
            <link>https://bacchi.org/posts/cdk-bundling-golang-functions/</link>
            <pubDate>Thu, 21 Dec 2023 18:22:00 -0500</pubDate>
            <guid>https://bacchi.org/posts/cdk-bundling-golang-functions/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post Bundling Go Lambda Functions with the AWS CDK&#34; /&gt;&lt;p&gt;Recently the Lambda Go runtime has changed from using the Go 1.x managed runtime&#xA;to using the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-golang.html#golang-al1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;provided&#xA;runtimes&lt;/a&gt;&#xA;which have been historically used for custom runtimes (i.e. Rust.) The former&#xA;&lt;code&gt;go1.x&lt;/code&gt; runtime is being deprecated on January 8, 2024 (quite soon) and the new&#xA;runtimes &lt;code&gt;provided.al2023&lt;/code&gt; or &lt;code&gt;provided.al2&lt;/code&gt; are expected to be used.&lt;/p&gt;&#xA;&lt;p&gt;With the introduction of these new runtimes, all of our Go binaries must &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/golang-handler.html#golang-handler-naming&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;now be&#xA;called&lt;/a&gt;&#xA;&lt;code&gt;bootstrap&lt;/code&gt; and be located at the root of the zip file used to deploy the&#xA;function.&lt;/p&gt;&#xA;&lt;p&gt;If we have two functions built by separate function code, in the &lt;code&gt;go1.x&lt;/code&gt; runtime&#xA;the naming convention would allow us to name them differently (i.e. &lt;code&gt;create&lt;/code&gt; vs.&#xA;&lt;code&gt;list&lt;/code&gt;). Now we must name both function handlers &lt;code&gt;bootstrap&lt;/code&gt;, potentially&#xA;causing confusion during the bundling process.&lt;/p&gt;&#xA;&lt;p&gt;In today&amp;rsquo;s blog post, we&amp;rsquo;ll describe how to bundle two different Go functions&#xA;with the same name in a single CDK stack.&lt;/p&gt;&#xA;&lt;h2 id=&#34;aws-cdk-deployment-using-typescript&#34;&gt;AWS CDK Deployment Using Typescript&#xA;&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;ll be using Typescript as the language for the AWS CDK deployment. It might be&#xA;strange to mix languages for CDK deployment (Typescript) and the Lambda function&#xA;(Go), but CDK uses Typescript as its main language and most examples are written&#xA;in that. The reason for using Go in this example is because many deployments&#xA;need to use compiled languages for task duration and performance (not&#xA;necessarily to improve cold start time.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;source-organization&#34;&gt;Source Organization&#xA;&lt;/h2&gt;&lt;p&gt;As described earlier, in the past we could have kept the names of the Go&#xA;function source files in the same directory and compiled them separately to&#xA;different file names. Now that the handler file name has to be the same&#xA;(&lt;code&gt;bootstrap&lt;/code&gt;), they can&amp;rsquo;t be output to the same directory any longer.&lt;/p&gt;&#xA;&lt;p&gt;The layout of the files now looks like the following, with each function in its&#xA;own subdirectory in the &lt;code&gt;lib/functions&lt;/code&gt; directory:&lt;/p&gt;&#xA;&lt;img src=&#34;golang-function-layout.png&#34;&gt;&#xA;&lt;h2 id=&#34;bundling-go-functions&#34;&gt;Bundling Go Functions&#xA;&lt;/h2&gt;&lt;p&gt;Now that we have the function code in separate directories, we can bundle them&#xA;using the Alpha CDK construct for a &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-lambda-go-alpha-readme.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Go&#xA;Function&lt;/a&gt;,&#xA;shown below.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-typescript&#34; data-lang=&#34;typescript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;BasicGoLambdaStack&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;extends&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Stack&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;constructor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;scope&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;Construct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;props?&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;StackProps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;super&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;scope&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;props&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;TableV2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Table&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;partitionKey&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;AttributeType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;STRING&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nx&#34;&gt;removalPolicy&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;RemovalPolicy.DESTROY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;createFunction&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;GoFunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;CreateFunction&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;lib/functions/create&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;DYNAMODB_TABLE&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tableName&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;logRetention&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;RetentionDays.ONE_WEEK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;listFunction&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;GoFunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;ListFunction&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;entry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;lib/functions/list&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;DYNAMODB_TABLE&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;tableName&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nx&#34;&gt;logRetention&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;RetentionDays.ONE_WEEK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The above configuration is obviously fairly straightforward. But before I found&#xA;the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-lambda-go-alpha-readme.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;aws-lambda-go-alpha&lt;/a&gt;&#xA;module, I attempted (mostly unsuccessfully) to use the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;aws-lambda-function&#xA;Function&#xA;construct&lt;/a&gt;&#xA;which required using the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Code.fromAsset&lt;/a&gt;&#xA;method with the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.ILocalBundling.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ILocalBundling&#xA;interface&lt;/a&gt;.&#xA;This was extremely uncooperative, I found &lt;a class=&#34;link&#34; href=&#34;https://github.com/aws-samples/cdk-lambda-bundling/blob/main/lib/cdk-bundling-lambda-stack.ts&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;multiple&#xA;blogs&lt;/a&gt;&#xA;and suggestions on how to configure this, and in the end I did get it working,&#xA;but the solution I came up with was ugly and actually packaged the Go source&#xA;file in the zip file with the bootstrap handler. Not cool.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s great that the CDK now supports Go Lambda functions as a full blown&#xA;construct. While &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.NodejsFunction.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;NodeJS&#xA;functions&lt;/a&gt;&#xA;have been supported for much longer it makes sense to have Go supported the same&#xA;way, because the aggravation I endured packaging these Go handlers with the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;standard Lambda Function&#xA;construct&lt;/a&gt;&#xA;was a serious pain in the ass.&lt;/p&gt;&#xA;&lt;h2 id=&#34;verifying-the-output&#34;&gt;Verifying the Output&#xA;&lt;/h2&gt;&lt;p&gt;Now that we have these defined, we can package the artifacts using &lt;code&gt;cdk synth&lt;/code&gt;&#xA;and verify that the &lt;code&gt;bootstrap&lt;/code&gt; binary was created for both functions.&lt;/p&gt;&#xA;&lt;p&gt;We can see here that the first messages output from the &lt;code&gt;cdk synth&lt;/code&gt; command are&#xA;the two functions being bundled:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ cdk synth&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Bundling asset BasicGoLambdaStack/CreateFunction/Code/Stage...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Bundling asset BasicGoLambdaStack/ListFunction/Code/Stage...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Resources:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;And when we look in the &lt;code&gt;cdk.out&lt;/code&gt; directory which is where our intermediate CDK&#xA;files are placed during packaging, we see that the two Lambda Function output&#xA;directories itemized in the stack asset JSON file (called&#xA;&lt;code&gt;BasicGoLambdaStack.assets.json&lt;/code&gt;) have binaries in them (ignore the third .js&#xA;asset, that&amp;rsquo;s for the cloudwatch logs):&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ tree cdk.out/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cdk.out/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── asset.4e26bf2d0a26f2097fb2b261f22bb51e3f6b4b52635777b1e54edbd8e2d58c35&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── index.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── asset.b0bae29696f98febe5e6a655c4f61466ad71ebfa0071b46a15e917a1d307333c&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── bootstrap&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── asset.f153e459ffb70033083e7507aaa06c00f4b13a792fad71433c11b5f050078e74&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── bootstrap&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── BasicGoLambdaStack.assets.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── BasicGoLambdaStack.template.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── cdk.out&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── manifest.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── tree.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; directories, &lt;span class=&#34;m&#34;&gt;8&lt;/span&gt; files&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;After running &lt;code&gt;cdk synth&lt;/code&gt; to verify things, we can deploy with &lt;code&gt;cdk deploy&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;success&#34;&gt;Success&#xA;&lt;/h2&gt;&lt;p&gt;Now we can execute the functions and see them working as expected:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ curl -X POST -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; https://someurl.execute-api.us-west-2.amazonaws.com/todos --data &lt;span class=&#34;s1&#34;&gt;&amp;#39;{ &amp;#34;title&amp;#34;: &amp;#34;stuff&amp;#34;, &amp;#34;details&amp;#34;: &amp;#34;really some stuff&amp;#34;}&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;80cf566a-937b-4aef-98ef-48b84ee75c01&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;title&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;stuff&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;details&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;really some stuff&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ curl -X GET https://someurl.execute-api.us-west-2.amazonaws.com/todos&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;80cf566a-937b-4aef-98ef-48b84ee75c01&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;title&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;stuff&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;details&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;really some stuff&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xA;&lt;/h2&gt;&lt;p&gt;The new requirements for using the provided runtimes for Go Lambda Functions&#xA;poses some minor challenges (especially if you have to migrate already running&#xA;Go 1.x Lambda Functions) but thankfully the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cdk/api/v2/docs/aws-lambda-go-alpha-readme.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;aws-lambda-go-alpha&lt;/a&gt;&#xA;module makes it much more straightforward than bundling these manually.&lt;/p&gt;&#xA;&lt;p&gt;I hope you&amp;rsquo;ve gotten a good understanding of how to bundle Go Lambda functions&#xA;by reading this. I know I learned a lot, and this will come in handy as I use Go&#xA;for Lambdas going forward.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;Cover photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@jessefotograaf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Jesse De Meulenaere&lt;/a&gt; on &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>A Gentle Introduction to AWS Lambda</title>
            <link>https://bacchi.org/posts/gentle-intro-lambda/</link>
            <pubDate>Tue, 01 Feb 2022 08:00:00 -0600</pubDate>
            <guid>https://bacchi.org/posts/gentle-intro-lambda/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post A Gentle Introduction to AWS Lambda&#34; /&gt;&lt;p&gt;You&amp;rsquo;ve probably heard of AWS Lambda and serverless by now. But what is Lambda&#xA;all about? The short definition of AWS Lambda is a &amp;ldquo;Functions as a Service&amp;rdquo;&#xA;(FaaS) technology. The longer and more complicated answer is that Lambda is a&#xA;lightweight runtime that requires no infrastructure to be defined by the&#xA;developer.&#xA;FaaS allows developers to build software features quickly with less emphasis on&#xA;the question of &lt;em&gt;where&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt; they run. This allows for more focus on the&#xA;business logic that users interact with. Functions as a Service is the most&#xA;recent innovation in the long line of virtualization technologies. Compute&#xA;virtualization started with physical servers, then moved to virtual machines&#xA;(VMs), which grew into Infrastructure as a Service (IaaS). Platforms as a&#xA;Service came next with companies like Heroku allowing developers to deploy&#xA;without caring about infrastructure specifics. Now we&amp;rsquo;re arriving at FaaS, which&#xA;promises to abstract all these details away.&#xA;&lt;a class=&#34;link&#34; href=&#34;https://dashbird.io/blog/origin-of-serverless/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Here&lt;/a&gt; are a&#xA;&lt;a class=&#34;link&#34; href=&#34;https://joshfechter.com/iaas-paas-saas/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;couple&lt;/a&gt; good descriptions of these&#xA;origins and where we are as an industry today.&lt;/p&gt;&#xA;&lt;h2 id=&#34;lambda-vs-serverless-terminology&#34;&gt;Lambda vs. Serverless Terminology&#xA;&lt;/h2&gt;&lt;p&gt;The terms serverless and AWS Lambda are often used interchangeably, but they&#xA;aren&amp;rsquo;t exactly the same thing. Serverless refers to a collection of tools that&#xA;require no infrastructure configurations from the developer, including&#xA;databases, queues, functions and gateways as a service. AWS Lambda is only the&#xA;FaaS component in this list. That means there are many more products such as API&#xA;gateways, message queueing systems, notification tools, and serverless databases&#xA;that fill out the serverless landscape. In this blog post we&amp;rsquo;ll only work with a&#xA;couple of these, namely AWS Lambda and AWS API Gateway for our demonstration.&lt;/p&gt;&#xA;&lt;h2 id=&#34;faas-platforms&#34;&gt;FaaS Platforms&#xA;&lt;/h2&gt;&lt;p&gt;There are many &lt;a class=&#34;link&#34; href=&#34;https://fauna.com/blog/comparison-faas-providers&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;FaaS&#xA;providers&lt;/a&gt; in the industry.&#xA;From the big players like Google, IBM, and AWS to the smaller ones like the open&#xA;source OpenWhisk and OpenFaaS, they all provide similar functionality&#xA;(generally) with different developer experiences.&lt;/p&gt;&#xA;&lt;p&gt;There are also Edge computing FaaS providers, which instead of executing the&#xA;code in one central data center, run the code in a data center nearest the user,&#xA;known as the &amp;ldquo;Edge&amp;rdquo;. The players in this area of serverless technology are&#xA;companies like Cloudflare, Lambda@Edge (AWS), and Fastly.&lt;/p&gt;&#xA;&lt;h2 id=&#34;aws-lambda-in-plain-english&#34;&gt;AWS Lambda in Plain English&#xA;&lt;/h2&gt;&lt;p&gt;After reading the above definition of serverless, Functions as a Service, and&#xA;AWS Lambda, your understanding might still be cloudy (no pun intended). I&amp;rsquo;ll&#xA;attempt to explain it in more simple terms.&lt;/p&gt;&#xA;&lt;p&gt;The description on the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/welcome.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;AWS documentation&#xA;website&lt;/a&gt; says &amp;ldquo;Lambda&#xA;is a compute service that lets you run code without provisioning or managing&#xA;servers.&amp;rdquo; The essence of Lambda is that AWS built all the scaffolding to allow&#xA;you and I to send them a single piece of code, which they will run for us.&lt;/p&gt;&#xA;&lt;p&gt;We don&amp;rsquo;t need to build servers or container images in order to run this single&#xA;piece of code. All we have to think about is writing code, and then a small SAM&#xA;template file which defines the requirements of the deployment, and finally&#xA;shipping it.&lt;/p&gt;&#xA;&lt;h3 id=&#34;is-it-really-a-single-function&#34;&gt;Is it Really a Single Function?&#xA;&lt;/h3&gt;&lt;p&gt;In order to wrap your brain around this idea of functions as a service, think of&#xA;a single method or function in a small program. The function is called by&#xA;another function, and may return a result.&lt;/p&gt;&#xA;&lt;p&gt;Below you see a simple Python program in which there is a parent function&#xA;(&lt;code&gt;main()&lt;/code&gt;) calling a child function (&lt;code&gt;childfunction()&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;childfunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inputstring&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inputstring&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;world&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;hi&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;childfunction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;value: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The output of this program looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ python hello.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;value: world&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;At it&amp;rsquo;s simplest form, AWS Lambda can be thought of as a single child function&#xA;being called by a parent function. AWS owns the parent function, which executes&#xA;your function (the child function) in it&amp;rsquo;s own virtual environment.&lt;/p&gt;&#xA;&lt;p&gt;Your objective during the rest of this blog post is to write, deploy and execute&#xA;a single Lambda function.&lt;/p&gt;&#xA;&lt;h2 id=&#34;lets-write-one-bite-sized-function&#34;&gt;Let&amp;rsquo;s Write One Bite Sized Function&#xA;&lt;/h2&gt;&lt;p&gt;For this example, we&amp;rsquo;ll write a small function that does nothing particularly&#xA;important, but demonstrates the mechanics of running a function in AWS Lambda.&#xA;You are probably familiar with shell environment variables. In your terminal you&#xA;can print out the environment variables defined in your session, or even create&#xA;new environment variables.&lt;/p&gt;&#xA;&lt;p&gt;The below terminal command prints out an environment variable showing the user name&#xA;that you are logged in as:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mbacchi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h3 id=&#34;what-will-the-function-do&#34;&gt;What Will the Function Do?&#xA;&lt;/h3&gt;&lt;p&gt;The function we&amp;rsquo;ll deploy will print out the default &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;runtime environment&#xA;variables&lt;/a&gt;&#xA;in the AWS Lambda execution environment.&lt;/p&gt;&#xA;&lt;p&gt;Similar to the terminal session above, our Lambda function can access the&#xA;default environment variables such as &lt;code&gt;AWS_LAMBDA_FUNCTION_NAME&lt;/code&gt;,&#xA;&lt;code&gt;AWS_LAMBDA_LOG_GROUP_NAME&lt;/code&gt;, or &lt;code&gt;TZ&lt;/code&gt;. But how do we see the output of &lt;code&gt;print&lt;/code&gt;&#xA;statements in a Lambda? Anything that gets printed to STDOUT &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/python-logging.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;will be logged to&#xA;CloudWatch&#xA;Logs&lt;/a&gt; using&#xA;the log group name of the function.&lt;/p&gt;&#xA;&lt;h2 id=&#34;how-does-lambda-work&#34;&gt;How Does Lambda Work?&#xA;&lt;/h2&gt;&lt;p&gt;The concepts that you&amp;rsquo;ll need to understand are described in the AWS &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Lambda&#xA;documentation&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Here are some of the most important details you&amp;rsquo;ll need to write your Lambda&#xA;functions:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Invocation:&lt;/strong&gt; The function is&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;invoked&lt;/a&gt;&#xA;by one of the triggers that AWS provides. It can also be triggered by cron like&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;scheduling&#xA;events&lt;/a&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Entrypoint:&lt;/strong&gt; Your Lambda function needs to implement a&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/python-handler.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;handler&lt;/a&gt;&#xA;which is the method (or function) that gets called by AWS when triggered.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Environment:&lt;/strong&gt; The handler is passed an &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/python-handler.html#python-handler-how&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;event object and context&#xA;object&lt;/a&gt;&#xA;from AWS that provides your function both data to be processed and context&#xA;(information) about how it was called and other clues that you can use in your&#xA;code.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Response:&lt;/strong&gt; In certain cases you will want to syncronously &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/python-handler.html#python-handler-return&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;return a&#xA;value&lt;/a&gt;&#xA;from your function, but that is optional. If you are writing an API backend&#xA;you will return a value through API Gateway. If instead you are performing&#xA;some scheduled data processing you may not return a value.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;background-on-associated-serverless-components&#34;&gt;Background on Associated Serverless Components&#xA;&lt;/h2&gt;&lt;p&gt;We mentioned earlier how serverless isn&amp;rsquo;t just AWS Lambda, and in this project&#xA;we&amp;rsquo;ll use API Gateway and CloudWatch Logs, but only to enable us to show how our&#xA;Lambda function executes.&lt;/p&gt;&#xA;&lt;p&gt;AWS &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;API&#xA;Gateway&lt;/a&gt;&#xA;is, as the name suggests, an API gateway product. But it also allows for more&#xA;than just API calls. For example it enables generic HTTP/HTTPS traffic, REST&#xA;APIs and Websocket APIs. You can host a standard web server with API Gateway and&#xA;Lambda, you aren&amp;rsquo;t limited to just APIs with API Gateway.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;CloudWatch&#xA;Logs&lt;/a&gt;&#xA;is a logging product from AWS that allows all other AWS products to log their&#xA;activity to a central location. In our example we&amp;rsquo;ll be looking at the output of&#xA;our Lambda function to see the environment variables available in the Lambda&#xA;itself during runtime.&lt;/p&gt;&#xA;&lt;p&gt;We&amp;rsquo;re not going to cover these in any more detail because they&amp;rsquo;re not the main&#xA;focus of this post.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sample-lambda-function&#34;&gt;Sample Lambda Function&#xA;&lt;/h2&gt;&lt;p&gt;For this example deployment, we&amp;rsquo;ll use &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;a GitHub repository that has our AWS&#xA;Lambda function&lt;/a&gt; defined. The Lambda&#xA;function in this repo was written with the intention of being used for&#xA;demonstration purposes, and as a simple function that can be deployed when&#xA;testing out CI/CD or the many serverless deployment tools available today (such&#xA;as &lt;a class=&#34;link&#34; href=&#34;https://github.com/serverless/serverless&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Serverless Framework&lt;/a&gt;, &lt;a class=&#34;link&#34; href=&#34;https://github.com/aws/aws-cdk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Cloud&#xA;Development Kit (CDK)&lt;/a&gt; etc.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;deploying-a-lambda-function-with-aws-sam&#34;&gt;Deploying a Lambda Function with AWS SAM&#xA;&lt;/h2&gt;&lt;p&gt;AWS SAM is the &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/serverless/sam/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Serverless Application&#xA;Model&lt;/a&gt;, which allows you to &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;write a&#xA;template&lt;/a&gt;&#xA;describing the Lambda function, and any related resources you need to run your&#xA;Lambda. The SAM template uses the YAML markup language and is based on AWS&#xA;Cloudformation. After reading the template, SAM performs the deployment for you,&#xA;and you can watch Cloudformation events to identify what the outcome was.&lt;/p&gt;&#xA;&lt;p&gt;We are going to use the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars/blob/master/template.yaml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;template&lt;/a&gt;&#xA;in the above repository to deploy the function. I won&amp;rsquo;t go into detail breaking&#xA;down all of the items in the template for now. That information can be found in&#xA;the documentation above or in other blogs. But I do want to highlight the two&#xA;resources used here, the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars/blob/main/template.yaml#L14&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;LambdaEnvVarsFunction&lt;/a&gt;&#xA;which is of the type &lt;code&gt;AWS::Serverless::Function&lt;/code&gt; and the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars/blob/main/template.yaml#L26&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;LambdaLogGroup&lt;/a&gt;,&#xA;which is the definition of our &lt;code&gt;AWS::Logs::LogGroup&lt;/code&gt; CloudWatch log group, where&#xA;our Lambda output will be collected.&lt;/p&gt;&#xA;&lt;h2 id=&#34;install-sam-cli&#34;&gt;Install SAM CLI&#xA;&lt;/h2&gt;&lt;p&gt;You&amp;rsquo;ll need to install a few components before running SAM. I would recommend&#xA;running this in a Python virtual environment (venv), and I will provide basic&#xA;steps here to set that up.&lt;/p&gt;&#xA;&lt;p&gt;From your terminal run these commands (this is on a Linux system):&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Step 1: Make sure you have Python 3.8 (you may have to install this first, on&#xA;Fedora Linux the command would be &lt;code&gt;sudo dnf install python3.8&lt;/code&gt;)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ which python3.8&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/usr/bin/python3.8&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Step 2: Create a Python 3.8 virtual environment&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ python3.8 -m venv venv38&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ ls venv38&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bin  include  lib  lib64  pyvenv.cfg&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Step 3: Activate the virtual environment&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ . venv38/bin/activate&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ which python&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/FAKE_PATH/lambda-env-vars7/venv38/bin/python&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ which pip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/FAKE_PATH/lambda-env-vars7/venv38/bin/pip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Step 4: Install SAM CLI &lt;strong&gt;NOTE: This installs Docker in the Python virtual environment&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ pip install aws-sam-cli&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting aws-sam-cli&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Using cached aws_sam_cli-1.37.0-py3-none-any.whl &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;5.0 MB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting &lt;span class=&#34;nv&#34;&gt;boto3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;1.*,&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1.18.32&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Using cached boto3-1.20.46-py3-none-any.whl &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;131&lt;/span&gt; kB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Now you can move on to the next step, where we run the Lambda function locally.&lt;/p&gt;&#xA;&lt;h2 id=&#34;running-your-lambda-function-with-sam-local&#34;&gt;Running Your Lambda Function with SAM Local&#xA;&lt;/h2&gt;&lt;p&gt;Before we deploy to AWS itself, we want to test our code by invoking the Lambda&#xA;function locally. What is this magic you ask? SAM provides a utility&#xA;command called &lt;code&gt;sam local invoke&lt;/code&gt; which allows your function to run locally in a&#xA;Docker container to test that it runs as expected before deploying to AWS.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; We assume you haven&amp;rsquo;t left the terminal session in step 4 above. If&#xA;you have, activate your Python virtual environment as in step 3 above.&lt;/p&gt;&#xA;&lt;p&gt;Run &lt;code&gt;sam local invoke&lt;/code&gt; as &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars#testing-using-sam-local&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;described in the Git&#xA;repository&lt;/a&gt;&#xA;(this uses &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars/blob/main/events/event.json&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;test&#xA;events&lt;/a&gt;&#xA;supplied with Lambda function in the repository)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sam &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; invoke LambdaEnvVarsFunction --event events/event.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Invoking app.lambda_handler &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;python3.8&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Skip pulling image and use &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; one: public.ecr.aws/sam/emulation-python3.8:rapid-1.37.0-x86_64.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Mounting /home/mbacchi/data/repos/mbacchi/lambda-env-vars7/.aws-sam/build/LambdaEnvVarsFunction as /var/task:ro,delegated inside runtime container&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;START RequestId: f97086cf-e8b6-4d9f-b2bc-b627ca5961e6 Version: &lt;span class=&#34;nv&#34;&gt;$LATEST&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Hello there this is the body: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;_HANDLER&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;app.lambda_handler&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_REGION&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;us-east-1&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_EXECUTION_ENV&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_Lambda_python3.8&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_LAMBDA_FUNCTION_NAME&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;LambdaEnvVarsFunction&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_LAMBDA_FUNCTION_MEMORY_SIZE&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;128&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_LAMBDA_FUNCTION_VERSION&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;$LATEST&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_LAMBDA_LOG_GROUP_NAME&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;aws/lambda/LambdaEnvVarsFunction&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_LAMBDA_LOG_STREAM_NAME&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;$LATEST&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;LANG&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;en_US.UTF-8&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;TZ&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;:/etc/localtime&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;LAMBDA_TASK_ROOT&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;/var/task&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;LAMBDA_RUNTIME_DIR&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;/var/runtime&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;PATH&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;LD_LIBRARY_PATH&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;PYTHONPATH&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;/var/runtime&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;AWS_LAMBDA_RUNTIME_API&amp;#39;&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;127.0.0.1:9001&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;END RequestId: f97086cf-e8b6-4d9f-b2bc-b627ca5961e6&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;REPORT RequestId: f97086cf-e8b6-4d9f-b2bc-b627ca5961e6&#x9;Init Duration: 0.11 ms&#x9;Duration: 100.72 ms&#x9;Billed Duration: &lt;span class=&#34;m&#34;&gt;101&lt;/span&gt; ms&#x9;Memory Size: &lt;span class=&#34;m&#34;&gt;128&lt;/span&gt; MB&#x9;Max Memory Used: &lt;span class=&#34;m&#34;&gt;128&lt;/span&gt; MB&#x9;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;statusCode&amp;#34;&lt;/span&gt;: 200, &lt;span class=&#34;s2&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;_HANDLER\&amp;#34;: \&amp;#34;app.lambda_handler\&amp;#34;, \&amp;#34;AWS_REGION\&amp;#34;: \&amp;#34;us-east-1\&amp;#34;, \&amp;#34;AWS_EXECUTION_ENV\&amp;#34;: \&amp;#34;AWS_Lambda_python3.8\&amp;#34;, \&amp;#34;AWS_LAMBDA_FUNCTION_NAME\&amp;#34;: \&amp;#34;LambdaEnvVarsFunction\&amp;#34;, \&amp;#34;AWS_LAMBDA_FUNCTION_MEMORY_SIZE\&amp;#34;: \&amp;#34;128\&amp;#34;, \&amp;#34;AWS_LAMBDA_FUNCTION_VERSION\&amp;#34;: \&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$LATEST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&amp;#34;, \&amp;#34;AWS_LAMBDA_LOG_GROUP_NAME\&amp;#34;: \&amp;#34;aws/lambda/LambdaEnvVarsFunction\&amp;#34;, \&amp;#34;AWS_LAMBDA_LOG_STREAM_NAME\&amp;#34;: \&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$LATEST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\&amp;#34;, \&amp;#34;LANG\&amp;#34;: \&amp;#34;en_US.UTF-8\&amp;#34;, \&amp;#34;TZ\&amp;#34;: \&amp;#34;:/etc/localtime\&amp;#34;, \&amp;#34;LAMBDA_TASK_ROOT\&amp;#34;: \&amp;#34;/var/task\&amp;#34;, \&amp;#34;LAMBDA_RUNTIME_DIR\&amp;#34;: \&amp;#34;/var/runtime\&amp;#34;, \&amp;#34;PATH\&amp;#34;: \&amp;#34;/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin\&amp;#34;, \&amp;#34;LD_LIBRARY_PATH\&amp;#34;: \&amp;#34;/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib\&amp;#34;, \&amp;#34;PYTHONPATH\&amp;#34;: \&amp;#34;/var/runtime\&amp;#34;, \&amp;#34;AWS_LAMBDA_RUNTIME_API\&amp;#34;: \&amp;#34;127.0.0.1:9001\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;deploy-to-aws&#34;&gt;Deploy to AWS&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Before deploying you need to setup your &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;AWS&#xA;credentials&lt;/a&gt; properly.&lt;/p&gt;&#xA;&lt;p&gt;In order to deploy the Lambda function, we&amp;rsquo;ll follow the steps in the &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars#deploying-to-aws&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;lambda-env-vars&lt;/a&gt; repository:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Step 1: Run &lt;code&gt;sam build&lt;/code&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sam build&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Building codeuri: /home/mbacchi/data/repos/mbacchi/lambda-env-vars7/env_vars runtime: python3.8 metadata: &lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt; architecture: x86_64 functions: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;LambdaEnvVarsFunction&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Running PythonPipBuilder:ResolveDependencies&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Running PythonPipBuilder:CopySource&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Build Succeeded&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Built Artifacts  : .aws-sam/build&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Built Template   : .aws-sam/build/template.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Commands you can use &lt;span class=&#34;nv&#34;&gt;next&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;=========================&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;*&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Invoke Function: sam &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; invoke&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;*&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Test Function in the Cloud: sam sync --stack-name &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;stack-name&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt; --watch&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;*&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Deploy: sam deploy --guided&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Step 2: Run &lt;code&gt;sam package&lt;/code&gt; (this creates an S3 bucket, which must be removed later)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sam package --output-template-file packaged.yaml --resolve-s3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Creating the required resources...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Successfully created!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-61z4v277mwy0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    A different default S3 bucket can be &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; in samconfig.toml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Or by specifying --s3-bucket explicitly.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Uploading to eb6c7534d67a5b044653e48f2802a548  &lt;span class=&#34;m&#34;&gt;452695&lt;/span&gt; / &lt;span class=&#34;m&#34;&gt;452695&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;100.00%&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Successfully packaged artifacts and wrote output template to file packaged.yaml.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Execute the following &lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt; to deploy the packaged template&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sam deploy --template-file /home/mbacchi/data/repos/mbacchi/lambda-env-vars7/packaged.yaml --stack-name &amp;lt;YOUR STACK NAME&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Step 3: Run &lt;code&gt;sam deploy&lt;/code&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;65&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;66&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;67&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;68&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;69&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;70&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;71&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;72&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;73&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;74&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;75&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;76&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;77&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;78&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;79&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;80&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;81&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;82&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;83&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;84&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;85&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;86&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;87&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;88&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;89&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;90&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;91&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sam deploy --template-file packaged.yaml --region us-east-2 --capabilities CAPABILITY_IAM --stack-name lambda-env-vars --resolve-s3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-61z4v277mwy0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    A different default S3 bucket can be &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; in samconfig.toml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Or by specifying --s3-bucket explicitly.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Deploying with following &lt;span class=&#34;nv&#34;&gt;values&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;===============================&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Stack name                   : lambda-env-vars&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Region                       : us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Confirm changeset            : False&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Disable rollback             : False&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-61z4v277mwy0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Capabilities                 : &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;CAPABILITY_IAM&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Parameter overrides          : &lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Signing Profiles             : &lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Initiating &lt;span class=&#34;nv&#34;&gt;deployment&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;=====================&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Uploading to 77524ed205c6d82d5487433831c24c0f.template  &lt;span class=&#34;m&#34;&gt;1635&lt;/span&gt; / &lt;span class=&#34;m&#34;&gt;1635&lt;/span&gt;  &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;100.00%&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Waiting &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; changeset to be created..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CloudFormation stack changeset&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Operation                                                  LogicalResourceId                                          ResourceType                                               Replacement                                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Add                                                      LambdaEnvVarsFunctionLambdaEnvVarsPermissionProd           AWS::Lambda::Permission                                    N/A                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Add                                                      LambdaEnvVarsFunctionRole                                  AWS::IAM::Role                                             N/A                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Add                                                      LambdaEnvVarsFunction                                      AWS::Lambda::Function                                      N/A                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Add                                                      LambdaLogGroup                                             AWS::Logs::LogGroup                                        N/A                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Add                                                      ServerlessRestApiDeploymentcaa6ada684                      AWS::ApiGateway::Deployment                                N/A                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Add                                                      ServerlessRestApiProdStage                                 AWS::ApiGateway::Stage                                     N/A                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Add                                                      ServerlessRestApi                                          AWS::ApiGateway::RestApi                                   N/A                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Changeset created successfully. arn:aws:cloudformation:us-east-2:592431548397:changeSet/samcli-deploy1643607514/85a31faf-1358-47ff-9eeb-4428020bb482&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2022-01-30 22:38:46 - Waiting &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; stack create/update to &lt;span class=&#34;nb&#34;&gt;complete&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CloudFormation events from stack operations&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ResourceStatus                                             ResourceType                                               LogicalResourceId                                          ResourceStatusReason                                     &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::IAM::Role                                             LambdaEnvVarsFunctionRole                                  -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::IAM::Role                                             LambdaEnvVarsFunctionRole                                  Resource creation Initiated                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::IAM::Role                                             LambdaEnvVarsFunctionRole                                  -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::Lambda::Function                                      LambdaEnvVarsFunction                                      -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::Lambda::Function                                      LambdaEnvVarsFunction                                      Resource creation Initiated                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::Lambda::Function                                      LambdaEnvVarsFunction                                      -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::Logs::LogGroup                                        LambdaLogGroup                                             -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::ApiGateway::RestApi                                   ServerlessRestApi                                          -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::ApiGateway::RestApi                                   ServerlessRestApi                                          Resource creation Initiated                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::ApiGateway::RestApi                                   ServerlessRestApi                                          -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::Logs::LogGroup                                        LambdaLogGroup                                             Resource creation Initiated                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::ApiGateway::Deployment                                ServerlessRestApiDeploymentcaa6ada684                      -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::Lambda::Permission                                    LambdaEnvVarsFunctionLambdaEnvVarsPermissionProd           Resource creation Initiated                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::Lambda::Permission                                    LambdaEnvVarsFunctionLambdaEnvVarsPermissionProd           -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::Logs::LogGroup                                        LambdaLogGroup                                             -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::ApiGateway::Deployment                                ServerlessRestApiDeploymentcaa6ada684                      Resource creation Initiated                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::ApiGateway::Deployment                                ServerlessRestApiDeploymentcaa6ada684                      -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::ApiGateway::Stage                                     ServerlessRestApiProdStage                                 -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_IN_PROGRESS                                         AWS::ApiGateway::Stage                                     ServerlessRestApiProdStage                                 Resource creation Initiated                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::ApiGateway::Stage                                     ServerlessRestApiProdStage                                 -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::Lambda::Permission                                    LambdaEnvVarsFunctionLambdaEnvVarsPermissionProd           -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CREATE_COMPLETE                                            AWS::CloudFormation::Stack                                 lambda-env-vars                                            -                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CloudFormation outputs from deployed stack&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Outputs                                                                                                                                                                                                                                   &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Key                 LambdaEnvVarsApi                                                                                                                                                                                                      &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Description         API Gateway endpoint URL &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; Prod stage &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; Lambda Env Vars &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;                                                                                                                                                  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Value               https://e4cusxvy7f.execute-api.us-east-2.amazonaws.com/Prod/env_vars/                                                                                                                                                 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Key                 LambdaLogGroup                                                                                                                                                                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Description         Cloudwatch Log Group ARN                                                                                                                                                                                              &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Value               /aws/lambda/lambda-env-vars-LambdaEnvVarsFunction-6r0qwkWGeZSp                                                                                                                                                        &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Key                 LambdaEnvVarsFunctionIamRole                                                                                                                                                                                          &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Description         Implicit IAM Role created &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; Lambda Env Vars &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;                                                                                                                                                                &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Value               arn:aws:iam::592431548397:role/lambda-env-vars-LambdaEnvVarsFunctionRole-L05B77IT7WK0                                                                                                                                 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Key                 LambdaEnvVarsFunction                                                                                                                                                                                                 &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Description         Lambda Env Vars Function ARN                                                                                                                                                                                          &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Value               arn:aws:lambda:us-east-2:592431548397:function:lambda-env-vars-LambdaEnvVarsFunction-6r0qwkWGeZSp                                                                                                                     &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Successfully created/updated stack - lambda-env-vars in us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;The &lt;code&gt;sam deploy&lt;/code&gt; command has deployed the Lambda function to AWS and returned&#xA;the API Gateway endpoint which we can use to invoke the Lambda with an API call.&#xA;We need the API Gateway URL from the above output, look for the&#xA;&lt;code&gt;LambdaEnvVarsApi&lt;/code&gt; key. In our example above, this is:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;https://e4cusxvy7f.execute-api.us-east-2.amazonaws.com/Prod/env_vars/&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;get-request-to-invoke-the-lambda-function&#34;&gt;GET Request to Invoke the Lambda Function&#xA;&lt;/h2&gt;&lt;p&gt;Now that we have the API Gateway URL (also known as the endpoint,) we can use a&#xA;tool like curl to perform an HTTP GET request against the endpoint. Because we&#xA;defined the &lt;code&gt;Events&lt;/code&gt;&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars/blob/main/template.yaml#L20-L25&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;stanza&lt;/a&gt;&#xA;with a &lt;code&gt;Type&lt;/code&gt; of &lt;code&gt;Api&lt;/code&gt;, and &lt;code&gt;Method&lt;/code&gt; &lt;code&gt;get&lt;/code&gt;, SAM has deployed an API Gateway&#xA;resource to trigger our Function. (More detailed discussion on this implicit API&#xA;Gateway resource&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;).&lt;/p&gt;&#xA;&lt;p&gt;We will use the command &lt;code&gt;curl&lt;/code&gt; to perform a &lt;code&gt;GET&lt;/code&gt; request as below:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ curl -X GET https://e4cusxvy7f.execute-api.us-east-2.amazonaws.com/Prod/env_vars/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;_HANDLER&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;app.lambda_handler&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_REGION&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;us-east-2&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_EXECUTION_ENV&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_Lambda_python3.8&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_LAMBDA_FUNCTION_NAME&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;lambda-env-vars-LambdaEnvVarsFunction-6r0qwkWGeZSp&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_LAMBDA_FUNCTION_MEMORY_SIZE&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;128&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_LAMBDA_FUNCTION_VERSION&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$LATEST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_LAMBDA_LOG_GROUP_NAME&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;/aws/lambda/lambda-env-vars-LambdaEnvVarsFunction-6r0qwkWGeZSp&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_LAMBDA_LOG_STREAM_NAME&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;2022/01/31/[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$LATEST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;]c2b9b9c953154c8daa7c9b2c0637b70e&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;LANG&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;en_US.UTF-8&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;TZ&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;:UTC&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;LAMBDA_TASK_ROOT&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/task&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;LAMBDA_RUNTIME_DIR&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/runtime&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;PATH&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;LD_LIBRARY_PATH&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;PYTHONPATH&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/runtime&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;AWS_LAMBDA_RUNTIME_API&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1:9001&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;On line 2, we can see the response JSON, which is what the Lambda function&#xA;returned to us via the API Gateway. And we see all the environment variables&#xA;that we had expected, just as in the &lt;code&gt;sam local invoke&lt;/code&gt; command earlier.&lt;/p&gt;&#xA;&lt;p&gt;But how can we observe the output of the &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-env-vars/blob/main/env_vars/app.py#L50&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;print statement at line&#xA;50&lt;/a&gt;?&lt;/p&gt;&#xA;&lt;p&gt;To do that we look at the CloudWatch log output. Browse to your AWS console, and&#xA;search for the Cloudwatch log group name that was in the &lt;code&gt;Outputs&lt;/code&gt; section of&#xA;the &lt;code&gt;sam deploy&lt;/code&gt; command output.&lt;/p&gt;&#xA;&lt;p&gt;In our case the LambdaLogGroup name was:&#xA;&lt;code&gt;/aws/lambda/lambda-env-vars-LambdaEnvVarsFunction-6r0qwkWGeZSp&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;When I browse there in CloudWatch, I see the &amp;ldquo;Hello there&amp;rdquo; line in the output,&#xA;which was sent to CloudWatch because we performed a &lt;code&gt;print&lt;/code&gt; to standard output&#xA;within the Lambda function code:&lt;/p&gt;&#xA;&lt;img src=&#34;cloudwatch-log-output.png&#34;&gt;&#xA;&lt;h2 id=&#34;what-just-occurred-whats-next&#34;&gt;What Just Occurred? What&amp;rsquo;s Next?&#xA;&lt;/h2&gt;&lt;p&gt;Congratulations, you just deployed and invoked your first Lambda function.&lt;/p&gt;&#xA;&lt;p&gt;Take some time to examine the output of the function in CloudWatch Logs, as well&#xA;as what was returned during your &lt;code&gt;curl&lt;/code&gt; command.&lt;/p&gt;&#xA;&lt;p&gt;Challenge 1: If you&amp;rsquo;ve heard of the &lt;a class=&#34;link&#34; href=&#34;https://www.postman.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Postman&lt;/a&gt; tool,&#xA;you can also call the API endpoint from there. Give it a shot.&lt;/p&gt;&#xA;&lt;p&gt;Challenge 2: You can display the HTTP headers when calling the API endpoint. How&#xA;would you see the headers with the &lt;code&gt;curl&lt;/code&gt; command? How would you see them with&#xA;Postman?&lt;/p&gt;&#xA;&lt;p&gt;Challenge 3: Read more about Lambda functions, SAM, Serverless Framework, CDK.&#xA;Build your own Lambda and deploy it. Let me know how it goes on Twitter&#xA;&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/fshwsprr&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;@fshwsprr&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;clean-up-aws-resources&#34;&gt;Clean Up AWS Resources&#xA;&lt;/h2&gt;&lt;p&gt;When you are done playing around with this Lambda function, run these commands to remove your resources:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;code&gt;aws cloudformation delete-stack --stack-name lambda-env-vars --region us-east-2&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;aws s3 rb s3://aws-sam-cli-managed-default-samclisourcebucket-61z4v277mwy0 --force&lt;/code&gt; &lt;strong&gt;NOTE:&lt;/strong&gt; This requires you to look at the output of your &lt;code&gt;sam package&lt;/code&gt; or &lt;code&gt;sam deploy&lt;/code&gt; command above to get the name of the S3 bucket to remove!&lt;/li&gt;&#xA;&lt;li&gt;Finally, you can deactivate your python virtual environment with the command: &lt;code&gt;deactivate&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;summary&#34;&gt;Summary&#xA;&lt;/h2&gt;&lt;p&gt;If you&amp;rsquo;ve read this far, the important takeaways about AWS Lambda in my opinion, are:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The concept that Lambda functions are only one part of the cloud serverless&#xA;landscape.&lt;/li&gt;&#xA;&lt;li&gt;Understanding invocation options and how your single function gets called by&#xA;AWS.&lt;/li&gt;&#xA;&lt;li&gt;The fact that you can locally invoke the function in SAM Local before you&#xA;deploy to AWS.&lt;/li&gt;&#xA;&lt;li&gt;Anything you print inside your function will be written to CloudWatch Logs&#xA;(assuming you created a Log Group for your Lambda.)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Thanks for reading! Enjoy your serverless and Lambda journey!&lt;/p&gt;&#xA;&lt;p&gt;Cover photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@chuklanov&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Avel Chuklanov&lt;/a&gt; on &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/s/photos/learn&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>How to Avoid CIDR Conflicts in AWS Sagemaker Notebooks</title>
            <link>https://bacchi.org/posts/sagemaker-cidr-conflict/</link>
            <pubDate>Wed, 12 Jan 2022 08:00:00 -0600</pubDate>
            <guid>https://bacchi.org/posts/sagemaker-cidr-conflict/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post How to Avoid CIDR Conflicts in AWS Sagemaker Notebooks&#34; /&gt;&lt;p&gt;Networking can sometimes be quite complicated. Despite the oft repeated joke&#xA;that &amp;ldquo;It&amp;rsquo;s always DNS&amp;rdquo;, sometimes your problem is even more difficult to&#xA;diagnose than DNS.&lt;/p&gt;&#xA;&lt;p&gt;According to Wikipedia, Classless Inter-Domain Routing (or&#xA;&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;CIDR&lt;/a&gt;) &amp;ldquo;is the&#xA;method for allocating IP addresses and for IP routing&amp;rdquo; on the internet and on&#xA;private networks. If there are conflicts in two networks&amp;rsquo; CIDR ranges, it can&#xA;cause headaches that make DNS problems look like childs play.&lt;/p&gt;&#xA;&lt;p&gt;This is a story about how I unknowingly created a CIDR conflict, and I hope it&#xA;will be useful to help you avoid CIDR conflicts in Sagemaker Notebooks in the&#xA;future.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-is-aws-sagemaker&#34;&gt;What is AWS Sagemaker&#xA;&lt;/h2&gt;&lt;p&gt;AWS Sagemaker is a popular Machine Learning platform that provides preconfigured&#xA;environments which allow you to begin training ML models quickly.&lt;/p&gt;&#xA;&lt;p&gt;Sagemaker Notebooks provide the platform to build and train your models. Under&#xA;the covers an AWS Sagemaker Notebook is an EC2 instance running a Jupyter&#xA;notebook packaged with numerous libraries and algorithms. This prevents users&#xA;from having to configure their own compute, storage and libraries themselves.&lt;/p&gt;&#xA;&lt;p&gt;A benefit of Sagemaker Notebooks is that you can run generic Python commands&#xA;alongside your more complex ML code within the Jupyter notebooks. For example,&#xA;while testing out some connectivity issues recently I was able to use the&#xA;ubiquitous Python Requests library to perform an HTTP GET request within the&#xA;Sagemaker Notebook to verify I was able to communicate with a webserver I&#xA;launched in another AWS account.&lt;/p&gt;&#xA;&lt;h2 id=&#34;creating-a-vpc&#34;&gt;Creating a VPC&#xA;&lt;/h2&gt;&lt;p&gt;When I create new projects or resources in AWS accounts, I find it useful to&#xA;create a new VPC just for the resources in that specific project. This provides&#xA;network isolation, security and connectivity to the specific components needed&#xA;for the project. During VPC creation you need to provide a CIDR range that the&#xA;VPC will use.&lt;/p&gt;&#xA;&lt;p&gt;CIDR ranges must be built using the private address spaces that &lt;a class=&#34;link&#34; href=&#34;https://datatracker.ietf.org/doc/html/rfc1918#section-3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;IETF RFC&#xA;1918&lt;/a&gt; dictates. This&#xA;means that you choose the CIDR range, but it must be in the &lt;code&gt;192.168.0.0&lt;/code&gt; range&#xA;for 256 Class C networks, or &lt;code&gt;172.16.0.0&lt;/code&gt; for 16 Class B networks, or &lt;code&gt;10.0.0.0&lt;/code&gt;&#xA;for a Class A network.&lt;/p&gt;&#xA;&lt;p&gt;The day I was working on these Sagemaker resources, I randomly chose the range&#xA;&lt;code&gt;172.17.0.0&lt;/code&gt; for this VPC, and this fateful decision would come to haunt me.&lt;/p&gt;&#xA;&lt;h2 id=&#34;sagemaker-notebooks&#34;&gt;Sagemaker Notebooks&#xA;&lt;/h2&gt;&lt;p&gt;As described briefly above, Sagemaker Notebooks run on an AWS EC2 instance, and&#xA;provide preconfigured tools for ML use cases. Part of that tooling is a&#xA;wonderful open source product called &lt;a class=&#34;link&#34; href=&#34;http://jupyter.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Jupyter Notebook&lt;/a&gt;,&#xA;which is a web based Python experimentation environment. Jupyter Notebooks run&#xA;inside Docker on the Sagemaker Notebook EC2 instance.&lt;/p&gt;&#xA;&lt;p&gt;When you configure Docker on an EC2 instance or any workstation/laptop/Linux&#xA;machine, it sets up virtual networking of its own to provide network&#xA;connectivity to the Docker containers. This local virtual networking sets up a&#xA;bridge network interface that allows communication between the Docker network&#xA;and the local machine as well as the internet if allowed. The &lt;a class=&#34;link&#34; href=&#34;https://docs.docker.com/network/bridge/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;default Docker&#xA;bridge&lt;/a&gt; network uses the range&#xA;&lt;code&gt;172.17.0.0&lt;/code&gt; for the &lt;code&gt;docker0&lt;/code&gt; network interface.&lt;/p&gt;&#xA;&lt;h2 id=&#34;cidr-range-conflict-causes-connectivity-problem&#34;&gt;CIDR Range Conflict Causes Connectivity Problem&#xA;&lt;/h2&gt;&lt;p&gt;Now that the background is set, you can see why a connectivity problem was&#xA;destined to occur on the Sagemaker Notebook instance. Since the VPC CIDR range&#xA;utilized &lt;code&gt;172.17.0.0&lt;/code&gt;, that meant all EC2 instances or network interfaces&#xA;created in that VPC would be provided with an IP address within the &lt;code&gt;172.17.0.0&lt;/code&gt;&#xA;range.&lt;/p&gt;&#xA;&lt;p&gt;Because the Jupyter Notebook running in Docker on the Sagemaker Notebook EC2&#xA;instance used the Docker bridge network &lt;code&gt;172.17.0.0&lt;/code&gt; and listened for all&#xA;traffic being sent to that destination, it superceded the traffic sent to the&#xA;outside world. Any network packets sent to the default route (&lt;code&gt;0.0.0.0&lt;/code&gt;) via the&#xA;default gateway (&lt;code&gt;172.17.112.1&lt;/code&gt;) were actually intercepted by the same Docker&#xA;bridge network, and not sent outside the bridge network.&lt;/p&gt;&#xA;&lt;p&gt;This is shown via the &lt;code&gt;route -n&lt;/code&gt; command on the Sagemaker Notebook EC2 instance terminal:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-console&#34; data-lang=&#34;console&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;sh-4.2$ route -n&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;Kernel IP routing table&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;Destination     Gateway         Genmask         Flags Metric Ref    Use Iface&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;0.0.0.0         172.17.112.1    0.0.0.0         UG    10002  0        0 eth2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;169.254.0.0     0.0.0.0         255.255.255.0   U     0      0        0 veth_def_agent&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;169.254.169.254 0.0.0.0         255.255.255.255 UH    0      0        0 eth0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;172.17.112.0    0.0.0.0         255.255.240.0   U     0      0        0 eth2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9bb29e923d05&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;go&#34;&gt;192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 bridge0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;was-this-unexpected&#34;&gt;Was This Unexpected?&#xA;&lt;/h2&gt;&lt;p&gt;What could have been done to avoid this you ask?&lt;/p&gt;&#xA;&lt;p&gt;As I mentioned earlier, the &lt;a class=&#34;link&#34; href=&#34;https://docs.docker.com/network/bridge/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;default Docker&#xA;bridge&lt;/a&gt; network uses the range&#xA;&lt;code&gt;172.17.0.0&lt;/code&gt; for the &lt;code&gt;docker0&lt;/code&gt; network interface. It&amp;rsquo;s fine that AWS simply used&#xA;that default without modifying it, but that implementation detail should have&#xA;been documented in the Sagemaker Notebook documentation.&lt;/p&gt;&#xA;&lt;p&gt;Ideally my suggested resolution is different. If the AWS end user (aka customer)&#xA;tries creating a Sagemaker Notebook in a VPC that has a CIDR range the same as&#xA;the default Docker bridge range (&lt;code&gt;172.17.0.0&lt;/code&gt;), they should change the Docker&#xA;bridge network range to something else to avoid a conflict.&lt;/p&gt;&#xA;&lt;h2 id=&#34;wrap-up&#34;&gt;Wrap Up&#xA;&lt;/h2&gt;&lt;p&gt;Ultimately the responsibility was on me to create the VPC and the Sagemaker&#xA;Notebook and make sure they worked correctly. But this was made infinitely more&#xA;difficult by AWS making choices themselves. Because AWS Sagemaker did not&#xA;document the Docker bridge network range they used, and did not programatically&#xA;configure an alternate Docker bridge network range if the customer selected the&#xA;same CIDR range for their VPC as the default Docker bridge network, I was left&#xA;troubleshooting a nasty problem.&lt;/p&gt;&#xA;&lt;p&gt;Please be aware this is still an open issue. (I say that in a figurative way not&#xA;literal. There is no AWS Support ticket open, and they have not committed to&#xA;fixing this in any way.)&lt;/p&gt;&#xA;&lt;p&gt;If you want to avoid CIDR conflicts on Sagemaker Notebooks in your AWS VPC,&#xA;make sure you use a CIDR range other than &lt;code&gt;172.17.0.0&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@fabioha?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;fabio&lt;/a&gt; on &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/s/photos/robot?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Master your Tech Job Search in 2021</title>
            <link>https://bacchi.org/posts/tech-job-search-2021/</link>
            <pubDate>Sun, 06 Jun 2021 08:00:00 -0600</pubDate>
            <guid>https://bacchi.org/posts/tech-job-search-2021/</guid>
            <description>&lt;p&gt;Over the last few years I&amp;rsquo;ve provided information on how to approach a job&#xA;search to friends and coworkers. I typically send an email with this&#xA;information, but I think it&amp;rsquo;s useful to a broader audience, so I&amp;rsquo;ll provide it&#xA;here in a blog post.&lt;/p&gt;&#xA;&lt;p&gt;This is certainly not meant to be an exhaustive discussion of every aspect of&#xA;job searching. There are many other resources out there on the internet that&#xA;have great recommendations. What I&amp;rsquo;ve written here just happens to be&#xA;information I thought was useful and not well covered as far as I&amp;rsquo;ve seen.&lt;/p&gt;&#xA;&lt;p&gt;Read on to learn how to make your job search more effective.&lt;/p&gt;&#xA;&lt;h2 id=&#34;get-organized&#34;&gt;Get organized&#xA;&lt;/h2&gt;&lt;p&gt;Organizing your job search can be immensely beneificial. I&amp;rsquo;ve found &lt;a class=&#34;link&#34; href=&#34;https://anonymoushash.vmbrasseur.com/2017/04/05/organise-your-job-hunt-with-trello/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;this&#xA;method&lt;/a&gt;&#xA;by VM Brasseur to be a good pattern. Using a kanban board like Trello is&#xA;imperative to keep track of every role you&amp;rsquo;re considering. I&amp;rsquo;ve done this in the&#xA;past and it helps to tabs on the status of each role you&amp;rsquo;ve applied to. I&amp;rsquo;ve&#xA;even kept notes on mutual interests that I discussed with interviewers so that I&#xA;could remember in case we talked again.&lt;/p&gt;&#xA;&lt;h2 id=&#34;where-to-look-for-remote-roles&#34;&gt;Where to look for remote roles&#xA;&lt;/h2&gt;&lt;p&gt;Since I&amp;rsquo;ve worked remotely (or as part of a distributed workforce) for 12+&#xA;years, I primarily look for roles that allow for remote work. Prior to the&#xA;pandemic, finding companies that were remote friendly could be challenging. This&#xA;has changed somewhat, but the new challenge is identifying which companies are&#xA;willing to continue allowing remote work after life is back to normal. To that&#xA;end, here are some sites I&amp;rsquo;ve used to search for roles that are more&#xA;remote friendly:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://duckduckgo.com/?q=site%3Aycombinator.com&amp;#43;who&amp;#43;is&amp;#43;hiring&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Hacker News monthly &amp;ldquo;Who is Hiring&amp;rdquo; thread&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://whoishiring.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;whoishiring.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://remoteok.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;remoteok.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://weworkremotely.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;weworkremotely.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://remotive.io&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;remotive.io&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://jobs.underpin.company/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;underpin.company&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://indeed.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;indeed.com&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re looking to work with a company that doesn&amp;rsquo;t profit off the ills of&#xA;society, such as ad tech or surveillance capitalism, there are a few sites&#xA;that list companies who do good in the world.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://techjobsforgood.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Tech jobs for good&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://peoplefirstjobs.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;People first jobs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.google.com/spreadsheets/d/1dFVoF6f9VU5pjaGhyyvQaBN0n6ae-iLCtlvsO1N2jhA/edit#gid=0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Ethical Tech Jobs Boards list&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;If you are interested in the startup world, you can find positions via their&#xA;venture capital (VC) funding companies:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://jobs.kaporcapital.com/?l=1425&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Kapor Capital&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://jobs.backstagecapital.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Backstage Capital&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.ventureloop.com/ventureloop/home.php&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Ventureloop&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Finally, there are lists of remote companies all over the place — a cursory&#xA;search would probably surface even more:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/lukasz-madon/awesome-remote-job/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Awesome Remote Job&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://about.gitlab.com/company/culture/all-remote/jobs/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Gitlab list of remote companies&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/remoteintech/remote-jobs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Remote-friendly companies&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;looking-for-roles-in-twitter-posts&#34;&gt;Looking for roles in Twitter posts&#xA;&lt;/h2&gt;&lt;p&gt;The above resources are all sites where you can actively search their list of&#xA;roles. I&amp;rsquo;ve found another productive method is to tap your extended network,&#xA;specifically people you follow on social media. I have experience searching on&#xA;Twitter, and have gotten many interesting leads.&lt;/p&gt;&#xA;&lt;p&gt;You can perform an actual Twitter search, but I prefer passively watching my&#xA;feed for Tweets mentioning that someone has roles available. These Tweets are&#xA;advertising open roles, so if the job description interests you, contact them&#xA;via DM (or whatever contact method they describe) to inquire about the role or&#xA;begin the application process. Even if the specific role isn&amp;rsquo;t something you are&#xA;excited about, follow the person and they may post more roles in the future or&#xA;retweet jobs from people in their network.&lt;/p&gt;&#xA;&lt;p&gt;Another method is keeping an eye out for someone who Tweets asking for leads.&#xA;You&amp;rsquo;ll often see responses from amazing and helpful people that are direct links&#xA;to job descriptions. Look through these replies to see if there are any roles&#xA;that interest you, and apply accordingly. I have even seen roles posted to Tweet&#xA;threads like these days later.&lt;/p&gt;&#xA;&lt;p&gt;One example of Twitter activity like this could be seen in the 2020 Mozilla&#xA;layoff, which affected 250 Mozillians. People who wanted to help started using&#xA;the &lt;a class=&#34;link&#34; href=&#34;https://twitter.com/search?q=%23MozillaLifeboat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;#MozillaLifeboat&lt;/a&gt; hash&#xA;tag, which had hundreds of tweets per day during that time. Obviously if you can&#xA;help someone else this way, please do, but it can also be a source of roles that&#xA;you might not be aware of if you&amp;rsquo;re doing a job search yourself.&lt;/p&gt;&#xA;&lt;h2 id=&#34;research-to-find-top-companies&#34;&gt;Research to find top companies&#xA;&lt;/h2&gt;&lt;p&gt;There are mediocre companies in every industry, but there are also exceptional&#xA;companies. If you already know the best companies in your industry, then start&#xA;looking for roles on their websites. If you feel like you cannot meet their&#xA;requirements, apply anyway and see if you may be underestimating your abilities.&#xA;I&amp;rsquo;m also a fan of finding a really great job description that you don&amp;rsquo;t yet&#xA;qualify for and using that to set goals for yourself for 6 months or a year from&#xA;now. Work on building those skills you are missing and apply to that role or a&#xA;similar one when you level up and meet your goals.&lt;/p&gt;&#xA;&lt;p&gt;If you don&amp;rsquo;t know great workplaces, use your network to find out which ones are&#xA;held in high regard by people you respect. Then start searching those websites&#xA;for roles that intrigue you.&lt;/p&gt;&#xA;&lt;h2 id=&#34;apply-to-roles-just-a-little-bit-above-your-experience-level&#34;&gt;Apply to roles just a little bit above your experience level&#xA;&lt;/h2&gt;&lt;p&gt;I recommend that you apply for roles that have requirements that are slightly&#xA;beyond your experience. Not having a few technologies that a job description&#xA;lists is not a disqualifier. This should be viewed as a challenge instead. There&#xA;are three reasons for this.&lt;/p&gt;&#xA;&lt;p&gt;First, it is important to always be growing and investing in your skills. There&#xA;is no better way to do this than learning a technology you haven&amp;rsquo;t used before&#xA;on the job. Not meeting every bullet point is okay. Be honest during interviews,&#xA;stating that you haven&amp;rsquo;t yet been exposed to the particular tool or technology&#xA;before and would love to have the opportunity. You can also play with it on your&#xA;own time to learn some of the basics. Then during the interview, you can say&#xA;something like &amp;ldquo;I&amp;rsquo;ve used it for personal projects but haven&amp;rsquo;t supported it in a&#xA;production environment.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;Second, it is best in my experience to avoid working in a role doing the exact&#xA;same things you have done before. While this may feel more comfortable, I find&#xA;these jobs to quickly become boring. Look for a position that has new&#xA;technologies that will be interesting to learn. This enables you to add new&#xA;things to your resume. You want to grow into the position; having skills for&#xA;every line item listed in the description often ensures you will not love the&#xA;job in the long term.&lt;/p&gt;&#xA;&lt;p&gt;Third, when managers write job descriptions, they often list the skills that&#xA;describe their &amp;ldquo;dream&amp;rdquo; candidate. The employee who may have just left the&#xA;company and created a vacancy may not have ticked all those boxes. There are&#xA;often few people who meet every requirement, but HR or management wants to list&#xA;every possible skill that might be needed now or desired for a future project.&#xA;Think of the job listing as aspirational, both for yourself and the hiring&#xA;company. Aspire to work in a role that is just above your current capabilities.&lt;/p&gt;&#xA;&lt;h2 id=&#34;locate-free-mentors-or-coaching-on-twitter&#34;&gt;Locate free mentors or coaching on Twitter&#xA;&lt;/h2&gt;&lt;p&gt;I have come across very generous people on Twitter who have made offers of free&#xA;career advice, career coaching, or mentoring. For example, one person&#xA;occasionally offers 30 minute meetings where you can pick her brain about any of&#xA;these topics. I&amp;rsquo;ve seen Tweets asking mentors willing to volunteer their time to&#xA;respond to her Tweet, and the thread grew to dozens of people offering their&#xA;time to anyone who needs advice. This is a really special quality that we often&#xA;forget about when thinking about social media, but it is one of the most&#xA;selfless things I&amp;rsquo;ve seen on Twitter and can provide a great opportunity for&#xA;newer job seekers to talk to seasoned veterans.&lt;/p&gt;&#xA;&lt;p&gt;I myself have used these mentors to both build my network and get advice on my&#xA;resume, job search, and more. I won&amp;rsquo;t share the names of these people because&#xA;they haven&amp;rsquo;t given me permission to do so, but to find similar offers, you can&#xA;search Twitter for the words &amp;lsquo;mentor&amp;rsquo; and &amp;lsquo;coaching&amp;rsquo; related to the words &amp;lsquo;job&#xA;searching,&amp;rsquo; &amp;lsquo;applying,&amp;rsquo; &amp;lsquo;resume,&amp;rsquo; &amp;rsquo;negotiating,&amp;rsquo; and &amp;lsquo;switching.&amp;rsquo; You could also&#xA;search on the technologies or programming languages you use or desire to use in&#xA;a new role, and you will likely find someone willing to mentor you.&lt;/p&gt;&#xA;&lt;p&gt;That all being said, don&amp;rsquo;t pay for this — at least not early in your career or&#xA;your search. If you are further along in your career you could employ a career&#xA;coach, but I don&amp;rsquo;t think it&amp;rsquo;s necessary for your first job.&lt;/p&gt;&#xA;&lt;h2 id=&#34;use-your-network&#34;&gt;Use your network&#xA;&lt;/h2&gt;&lt;p&gt;Your social media network (let&amp;rsquo;s just say Twitter and LinkedIn for now) is a&#xA;great way to find roles, mentors, encouragement, and camaraderie. As mentioned&#xA;above, you can search for roles this way, but you can also ask your &amp;lsquo;whisper&#xA;network&amp;rsquo; about whether a team or a manager or a company is likely to be a good&#xA;fit for you. Your social media connections might make introductions for you or&#xA;even offer to setup meetings with someone you need to know to be considered for&#xA;a position. It&amp;rsquo;s a good idea to be on the lookout for ways you can leverage your&#xA;network like this.&lt;/p&gt;&#xA;&lt;p&gt;But (and this is where we put the social in social media) you should also be&#xA;offering to do this for anyone you run across that you might be able to help. If&#xA;you&amp;rsquo;ve benefitted from this type of relationship, please be willing to give back&#xA;(or pay it forward, whichever floats your boat.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;resume-building-and-writing&#34;&gt;Resume building and writing&#xA;&lt;/h2&gt;&lt;p&gt;I won&amp;rsquo;t go into how to write your resume because there are many blogs and&#xA;websites that already cover this. Take a look at my resume&#xA;&lt;a class=&#34;link&#34; href=&#34;https://bacchi.org/resume&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt; as an example if you like.&lt;/p&gt;&#xA;&lt;p&gt;I will say quickly that you should work hard to create your own resume building&#xA;experiences. One way to do this is to get involved with open source projects or&#xA;any professional project to learn how they operate at an organizational level&#xA;and build skills that you can add to your resume.&lt;/p&gt;&#xA;&lt;p&gt;Employers look for these team experiences, not just a laundry list of&#xA;programming languages and frameworks.&lt;/p&gt;&#xA;&lt;h2 id=&#34;try-to-do-more-than-just-applying-to-roles-on-company-websites&#34;&gt;Try to do more than just applying to roles on company websites&#xA;&lt;/h2&gt;&lt;p&gt;Related to the networking topic above, you&amp;rsquo;ll be more effective if you take a&#xA;more active approach to the application process. Some coaches recommend reaching&#xA;out to any contacts you have before you apply to find out information about the&#xA;hiring manager, team culture, or other nuggets of information that can help you&#xA;achieve your goal. If you don&amp;rsquo;t know anyone working at a company you are&#xA;applying to, coaches suggest researching the company and making a new connection&#xA;by even cold emailing. The goal of this approach is to find a champion that can&#xA;help surface your application to the top of the pile of applicants.&lt;/p&gt;&#xA;&lt;p&gt;Other ways to stand out are to work on open source projects and show your value.&#xA;Or I&amp;rsquo;ve heard of people &lt;a class=&#34;link&#34; href=&#34;https://thoughtcatalog.com/ryan-holiday/2018/03/heres-the-technique-that-ambitious-people-use-to-get-what-they-want/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;doing other work in advance to prove how&#xA;interested&lt;/a&gt;&#xA;they are in the company and the position they&amp;rsquo;re applying for. The most extreme&#xA;case of this I&amp;rsquo;ve heard about was someone showing off their skills and&#xA;suggesting that the company hire them for a role that didn&amp;rsquo;t even exist yet.&lt;/p&gt;&#xA;&lt;p&gt;This isn&amp;rsquo;t easy and isn&amp;rsquo;t a guarantee, but having a contact help you is&#xA;certainly going to be more effective than just applying by itself.&lt;/p&gt;&#xA;&lt;h2 id=&#34;interviewing&#34;&gt;Interviewing&#xA;&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;m not going to discuss interviewing in depth at all, but one great suggestion&#xA;I&amp;rsquo;ve seen is to find a mock interviewer to practice. Interviewing successfully&#xA;(or even without those jitters) is a skill that can be improved.&lt;/p&gt;&#xA;&lt;p&gt;Find someone you trust, &lt;a class=&#34;link&#34; href=&#34;https://techinterviewhandbook.org/mock-interviews&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;or an&#xA;organization&lt;/a&gt; that is willing&#xA;to act as the interviewer and schedule a mock interview. Approach it as if it&#xA;were a real interview process. This will make you more confident in real&#xA;interviews.&lt;/p&gt;&#xA;&lt;h2 id=&#34;pay-scale-and-salary-negotiation-resources&#34;&gt;Pay scale and salary negotiation resources&#xA;&lt;/h2&gt;&lt;p&gt;Before you go into your first interview, you should know the target salary you&#xA;are looking for. As&#xA;&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/Latesha_Byrd/status/1316016200673980418?s=20&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;@Latesha_Byrd&lt;/a&gt;&#xA;and @techgirl1908 say, &amp;ldquo;know your worth&amp;rdquo;!&lt;/p&gt;&#xA;&lt;p&gt;This is an amazing resource to help you figure out how people in your position&#xA;are paid, whether remote or in a specific region:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.levels.fyi/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://www.levels.fyi/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;When negotiating your salary, these blog posts are golden (even though a couple&#xA;are vintage):&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.kalzumeus.com/2012/01/23/salary-negotiation/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://www.kalzumeus.com/2012/01/23/salary-negotiation/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://haseebq.com/my-ten-rules-for-negotiating-a-job-offer/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://haseebq.com/my-ten-rules-for-negotiating-a-job-offer/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.lastweekinaws.com/podcast/screaming-in-the-cloud/how-software-developers-can-negotiate-better-salaries-with-josh-doody/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://www.lastweekinaws.com/podcast/screaming-in-the-cloud/how-software-developers-can-negotiate-better-salaries-with-josh-doody/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;hiring-for-certain-remote-jobs-may-not-be-possible-in-every-state&#34;&gt;Hiring for certain remote jobs may not be possible in every state&#xA;&lt;/h2&gt;&lt;p&gt;Finally, some companies do not hire for remote positions in certain states.&#xA;There are two reasons for this (that I&amp;rsquo;m aware of).&lt;/p&gt;&#xA;&lt;p&gt;First, employers don&amp;rsquo;t always have a presence in every state. Therefore they&#xA;often use Professional Employer Organizations (PEOs) that are HR platforms that&#xA;provide employee services in states where they don&amp;rsquo;t have an office. This is&#xA;common practice for remote friendly companies. Still, sometimes they list the&#xA;state you live in as a state they don&amp;rsquo;t hire in. While that&amp;rsquo;s hard to accept,&#xA;especially if you like the job description, it&amp;rsquo;s the way things work these days.&#xA;Not every company hires in every state.&lt;/p&gt;&#xA;&lt;p&gt;Second, and this is the more underhanded(or shall we say, disappointing) reason,&#xA;is because they don&amp;rsquo;t want to share the pay scale for the position. &lt;a class=&#34;link&#34; href=&#34;https://news.ycombinator.com/item?id=27233073&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Colorado&#xA;recently passed&lt;/a&gt; a law that went&#xA;into effect in January 2021 that required pay transparency. This law said that&#xA;job postings available to Colorado residents needed to share a salary range. In&#xA;order to avoid sharing salary ranges, some companies are now disqualifying&#xA;Colorado residents from these roles so that they don&amp;rsquo;t run afoul of this law.&lt;/p&gt;&#xA;&lt;p&gt;While I don&amp;rsquo;t like this response, its entirely within their right to take this&#xA;action at the present time. C&amp;rsquo;est la vie.&lt;/p&gt;&#xA;&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&#xA;&lt;/h2&gt;&lt;p&gt;I hope you were able to get some valuable information from this post. I found a&#xA;recent &lt;a class=&#34;link&#34; href=&#34;https://twitter.com/SahilBloom/status/1399375061111382022?s=20&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;tweet&lt;/a&gt;&#xA;from Sahil Bloom (&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/SahilBloom&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;@SahilBloom&lt;/a&gt;) as I was&#xA;writing this, and it reinforced a lot of what I have been saying for a couple&#xA;years. Funny how things occur simultaneously like that.&lt;/p&gt;&#xA;&lt;p&gt;Find me on Twitter (&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/fshwsprr&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;@fshwsprr&lt;/a&gt;) to respond if you&#xA;have something to say; I&amp;rsquo;d love to hear from you.&lt;/p&gt;&#xA;&lt;p&gt;Take care!&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>#awswishlist Series: More granular service IPs in AWS ip-ranges.json list</title>
            <link>https://bacchi.org/posts/awswhishlist-ip-ranges-json/</link>
            <pubDate>Sat, 23 Jan 2021 08:00:00 -0600</pubDate>
            <guid>https://bacchi.org/posts/awswhishlist-ip-ranges-json/</guid>
            <description>&lt;p&gt;This will be the first in a series of posts describing Tweets I&amp;rsquo;ve sent with the&#xA;hashtag #awswishlist. Tweets to this #awswishlist hashtag come from anyone who&#xA;uses AWS and is frustrated with the AWS user experience in some way. These&#xA;Tweets are often responded to by AWS Support staff on Twitter, indicating&#xA;they&amp;rsquo;ll be passing the feedback on to the team responsible for the AWS service.&#xA;But in my tenure using AWS, I&amp;rsquo;ve only personally seen one wishlist item get&#xA;resolved within a reasonable time frame.&lt;/p&gt;&#xA;&lt;p&gt;This blog series will demonstrate why these #awswishlist items are so&#xA;disappointing, and the contortions that users are required to perform in order&#xA;to work around these UX deficiencies.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-straw-that-broke-the-devops-back&#34;&gt;The straw that broke the DevOps back&#xA;&lt;/h2&gt;&lt;p&gt;So I was working on a project to allow traffic through our CDN for SNS&#xA;notifications. (I know what you&amp;rsquo;re thinking. Saying &amp;ldquo;SNS notifications&amp;rdquo; is&#xA;redundant. But if I just said &amp;ldquo;SNS&amp;rdquo; the subject isn&amp;rsquo;t clear enough.) It would be&#xA;great if I could just create a list of CIDRs for the SNS IP ranges. Wait a&#xA;minute&amp;hellip;it appears there&amp;rsquo;s no way to filter just that service from the full&#xA;list of 3000 or more CIDRs.&lt;/p&gt;&#xA;&lt;p&gt;With this realization I shot out the following Tweet:&lt;/p&gt;&#xA;&lt;img src=&#34;tweet-awswishlist-ip-ranges-json.png&#34;&gt;&#xA;&lt;p&gt;And this is the response from AWS Support:&lt;/p&gt;&#xA;&lt;img src=&#34;aws-support-tweet.png&#34;&gt;&#xA;&lt;h2 id=&#34;what-is-ip-rangesjson&#34;&gt;What is ip-ranges.json?&#xA;&lt;/h2&gt;&lt;p&gt;The AWS &lt;a class=&#34;link&#34; href=&#34;https://ip-ranges.amazonaws.com/ip-ranges.json&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ip-ranges.json&lt;/a&gt; file is&#xA;a huge list of CIDR ranges that are used by AWS services. As far as I know, it&#xA;lists every AWS IP address so that users can do things like adding these IPs to&#xA;their firewall allow rule sets. This is just one use case, but the list is&#xA;provided for users to validate that an IP address is owned by AWS.&lt;/p&gt;&#xA;&lt;p&gt;Thankfully AWS provides details for the CIDR ranges such as AWS Region (i.e.&#xA;&lt;code&gt;us-east-1&lt;/code&gt;), and the AWS service that these ranges are used for. But the&#xA;services covered in this list is only a very small subset of all AWS services.&#xA;This is limiting because users cannot filter every service that may send traffic&#xA;from the AWS network to the user&amp;rsquo;s network. For example AWS Simple Notification&#xA;Service (SNS) sends requests from AWS&amp;rsquo;s network to the user&amp;rsquo;s network. Yet this&#xA;service is not listed in the &lt;code&gt;ip-ranges.json&lt;/code&gt; list, so you would have to allow&#xA;every AWS IP address, not a subset containing only the SNS CIDRs which would be&#xA;much more reasonable.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html#aws-ip-syntax&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;AWS documentation for this ip-ranges.json&#xA;syntax&lt;/a&gt;&#xA;shows that the user can only perform filtering on the services below, because&#xA;they are the only services that are broken out separately.&lt;/p&gt;&#xA;&lt;img src=&#34;ip-ranges-json-services.png&#34;&gt;&#xA;&lt;p&gt;This is a major problem.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-so-few-services&#34;&gt;Why so few services?&#xA;&lt;/h2&gt;&lt;p&gt;The &amp;ldquo;Valid Values&amp;rdquo; list contains 17 service specific items, and the overall&#xA;&lt;code&gt;AMAZON&lt;/code&gt; value is a superset that contains every AWS CIDR (including those in&#xA;the service specific subsets).&lt;/p&gt;&#xA;&lt;p&gt;AWS now has over 300 services, obviously not every service has outgoing traffic&#xA;to a user&amp;rsquo;s network, but that&amp;rsquo;s beside the point. If they separate out some&#xA;services that have outgoing traffic, they should do the same for every service&#xA;with outgoing traffic.&lt;/p&gt;&#xA;&lt;p&gt;Also, some of their most important services such as SNS (which by the way, is&#xA;one of AWS&amp;rsquo;s first services created, &lt;a class=&#34;link&#34; href=&#34;https://www.awsgeek.com/AWS-History/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;in Apr&#xA;2010&lt;/a&gt;) are not on this list. This should&#xA;be corrected immediately so that users can add these SNS CIDRs to their firewall&#xA;allow lists (I&amp;rsquo;m not asking for a friend, I&amp;rsquo;m the customer in this case who&amp;rsquo;s&#xA;really interested in doing this).&lt;/p&gt;&#xA;&lt;h2 id=&#34;mind-the-gap&#34;&gt;Mind the gap&#xA;&lt;/h2&gt;&lt;p&gt;While its great that AWS Support responds to these Tweets now (there was a time&#xA;when they did not, and you didn&amp;rsquo;t know if your lone voice in the wilderness was&#xA;reaching anyone,) it seems that these deficiencies are everywhere, meaning in&#xA;every AWS service. I know there are UX problems, AWS Support knows there are UX&#xA;problems, Werner Vogels knows there are UX problems, and Jeff Bezos better know&#xA;there are UX problems. It&amp;rsquo;s a tall order to get everything right. But AWS keeps&#xA;saying they have relentless focus on the customer. Fix these rough edges before&#xA;more services are released.&lt;/p&gt;&#xA;&lt;p&gt;Why I&amp;rsquo;m annoyed here is that they started breaking out service subsets in&#xA;&lt;code&gt;ip-ranges.json&lt;/code&gt;, but they didn&amp;rsquo;t take it to its natural conclusion, which would&#xA;have been including every (outgoing) service as a valid filter value. It isn&amp;rsquo;t&#xA;relentless focus on the customer if the user has to build a list of all 3000&#xA;some odd CIDRs from the list in order to allow just the SNS traffic, when it&#xA;should only require hundreds or even dozens in such an allow list.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>AWS Amplify Custom Domain Management</title>
            <link>https://bacchi.org/posts/aws-amplify-domain/</link>
            <pubDate>Sun, 24 May 2020 07:34:36 -0600</pubDate>
            <guid>https://bacchi.org/posts/aws-amplify-domain/</guid>
            <description>&lt;img src=&#34;https://bacchi.org/&#34; alt=&#34;Featured image of post AWS Amplify Custom Domain Management&#34; /&gt;&lt;p&gt;Recently I moved my personal blog from GitHub Pages to AWS Amplify. While it was&#xA;fairly easy to setup the Amplify project and CI/CD pieces, the DNS configuration&#xA;for &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/amplify/latest/userguide/custom-domains.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Custom&#xA;Domains&lt;/a&gt;&#xA;was less straightforward. The following observations are what I found to be less&#xA;than ideal while using Amplify for the first time.&lt;/p&gt;&#xA;&lt;h2 id=&#34;aws-amplify-dns-instructions&#34;&gt;AWS Amplify DNS instructions&#xA;&lt;/h2&gt;&lt;p&gt;One problem that I found with AWS Amplify, which was surprising for someone who&#xA;is familiar with Route53 and DNS, is that the suggested instructions on the&#xA;Amplify Domain Management page are somewhat cryptic. Amplify is a fairly new AWS&#xA;service, so I&amp;rsquo;ll give them some lattitude, but this UI/UX needs to be improved.&lt;/p&gt;&#xA;&lt;img src=&#34;amplify-dns.png&#34;&gt;&#xA;&lt;p&gt;These were the problems that I think are the most blatant, and how they can be improved.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The ownership verification CNAME should clearly indicate what the host name is&#xA;and what the record is. In the above image, it just shows the host name on&#xA;the left side of the CNAME record type, and the record value on the right&#xA;side. It was slightly confusing to me, and for someone who is unfamiliar with&#xA;DNS and AWS Route53 it is likely even more difficult to follow.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The ANAME information is confusing if you&amp;rsquo;re using AWS Route53, though it&#xA;does say in very small grey type that this also means ALIAS record. Isn&amp;rsquo;t&#xA;this commonly known simply as an A record? I&amp;rsquo;m no DNS expert but I expect AWS to use&#xA;common terminology when possible. They do discuss terminology in the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/amplify/latest/userguide/custom-domain-troubleshoot-guide.html#understanding-dns-terminology-and-concepts.title&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Amplify&#xA;documentation&lt;/a&gt;&#xA;but it should be clearly described in the actual instructions where you&amp;rsquo;re&#xA;telling people how to set this up. Documentation should be secondary, as many&#xA;people don&amp;rsquo;t read AWS documentation and it is not often easy to locate AWS&#xA;docs.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The DNS record information (shown in the above image) is hidden in the&#xA;Actions drop down here.&lt;/p&gt;&#xA; &lt;img src=&#34;amplifyviewdnsrecords.png&#34;&gt;&#xA;&lt;p&gt;This should be much more visible. Possibly a big red button saying &amp;ldquo;Setup Your&#xA;DNS HERE&amp;rdquo;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;The CloudFront distribution domain name in the above image is helpful, but it&#xA;should also include the CloudFront distribution zone ID. I had to pretend to&#xA;add this CNAME record in the Route53 console before I could figure out what&#xA;zone this CloudFront distribution was part of. This is necessary if you&amp;rsquo;re&#xA;using something like Terraform to proivsion these CNAME or ANAME records.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;When a user has a Route53 zone in another AWS organizational account, it&#xA;should be possible to use that zone, rather than creating ACM certs and zone&#xA;records in the AWS organization account which houses the Amplify website.&#xA;This might be possible with IAM cross account roles or something else but I&#xA;haven&amp;rsquo;t found documentation to indicate that as of yet.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;So there are quite a few concerning UI/UX issues that need to be addressed to&#xA;make Amplify more welcoming to the average bear.&lt;/p&gt;&#xA;&lt;h2 id=&#34;integration-with-other-aws-organization-accounts&#34;&gt;Integration with other AWS organization accounts&#xA;&lt;/h2&gt;&lt;p&gt;My blog using Amplify is in a separate AWS account than my AWS Route53 and AWS&#xA;Certificate Manager resources, which might be a common pattern for many&#xA;organizations. In effect, because the Amplify application is not in the same&#xA;account as the Route53 and ACM resources for the domain, this becomes the&#xA;equivalent of configuring a custom domain managed by &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/amplify/latest/userguide/to-add-a-custom-domain-managed-by-a-third-party-dns-provider.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;a third-party DNS&#xA;provider&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I understand that AWS cannot automatically grant its own services access to&#xA;another AWS account in the same AWS organization to enable these two services to&#xA;work together. But there should be the capability to use IAM permissions or&#xA;roles to grant another account access to the DNS services that Amplify seems to&#xA;manage under the covers.&lt;/p&gt;&#xA;&lt;h2 id=&#34;amplify-provisions-other-aws-resources-which-are-not-visible&#34;&gt;Amplify provisions other AWS resources which are not visible&#xA;&lt;/h2&gt;&lt;p&gt;The above observation segues into the next concern, why are Ampify created&#xA;resources such as Route53 zones and records, CloudFront distributions and ACM&#xA;certificates hidden when using this service? When Amplify creates your application&#xA;using a custom domain, it creates ACM certificates, DNS records, and a&#xA;CloudFront distribution that are all (as far as I can tell) invisible in the&#xA;console.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m familiar with the pattern that when I use the AWS console to create an EC2&#xA;instance for example, it creates security groups and possibly VPC resources for&#xA;me. Anyone who has created an EC2 instance using Infrastructure as Code (IaC)&#xA;tooling knows there are multiple things that AWS does under the covers in the&#xA;console for this operation. The difference here though, is that those resources&#xA;are visible and accounted for in the console.&lt;/p&gt;&#xA;&lt;p&gt;Oddly, if I create an Amplify app using the console, additional resources that&#xA;get created on my behalf are not visible in the console. Now I can possibly&#xA;understand that these are hidden because they might be non-billable resources,&#xA;and the costs are rolled up into one single Amplify cost line item (although&#xA;that is not reflected or described in the &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/amplify/console/pricing/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;pricing&#xA;page&lt;/a&gt;.) But these resources&#xA;should still be shown to me so that I can view them for example to see the&#xA;Route53 zone ID if I was using it for my own custom domain CNAME record.&lt;/p&gt;&#xA;&lt;p&gt;Again, this may be because the Amplify team doesn&amp;rsquo;t want you to attempt to&#xA;manipulate or configure these resources, but it seems to me an antipattern to&#xA;generate resources that are not visible, while some of the information from&#xA;those resources is necessary to use the service properly. I&amp;rsquo;d much rather that&#xA;these were visible, but there was a disclaimer that they were associated with an&#xA;Amplify app and not billed as normal Route53, ACM or CloudFront resources that&#xA;the user initiated and created themselves.&lt;/p&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;Overall I&amp;rsquo;m happy with the complexity that the service is able to abstract for&#xA;its users. But there are rough edges and I&amp;rsquo;d ask for AWS to look into working on&#xA;addressing these concerns. It does appear that in order to make this a very&#xA;approachable service for some, it has traded off some configurability. That may&#xA;mean the Amplify service is really only operable in a subset of use cases.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Discourse API Testing</title>
            <link>https://bacchi.org/posts/discourse-api-testing/</link>
            <pubDate>Sun, 26 Apr 2020 23:07:16 -0600</pubDate>
            <guid>https://bacchi.org/posts/discourse-api-testing/</guid>
            <description>&lt;p&gt;Discourse is used for a number of purposes, but their forum software is quite&#xA;popular. I&amp;rsquo;ve been looking at how to us the &lt;a class=&#34;link&#34; href=&#34;https://docs.discourse.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Discourse&#xA;API&lt;/a&gt; to automate creating posts. This blog post&#xA;describes how to setup a local Discourse instance and perform API calls against&#xA;it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;setup-discourse-container&#34;&gt;Setup Discourse Container&#xA;&lt;/h2&gt;&lt;p&gt;This step is fairly straightforward thanks to &lt;a class=&#34;link&#34; href=&#34;https://github.com/bitnami/bitnami-docker-discourse&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Bitnami&amp;rsquo;s Discourse Docker&#xA;container&lt;/a&gt; which launches&#xA;and configures all the components in a Docker Compose environment.&lt;/p&gt;&#xA;&lt;p&gt;At first I just tried to launch it with &lt;code&gt;docker compose up -d&lt;/code&gt; and while it&#xA;appeared to start and run successfully I couldn&amp;rsquo;t see anything in my browser. I&#xA;then read that you have to set the &lt;code&gt;DISCOURSE_HOSTNAME&lt;/code&gt; to the IP address you&#xA;want to run Discourse on. If you&amp;rsquo;re running on localhost, set it to &lt;code&gt;127.0.0.1&lt;/code&gt;.&#xA;This &lt;a class=&#34;link&#34; href=&#34;https://github.com/bitnami/bitnami-docker-discourse/issues/100&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;issue&lt;/a&gt;&#xA;cleared it up for me.&lt;/p&gt;&#xA;&lt;p&gt;So after editing the &lt;code&gt;docker-compose.yml&lt;/code&gt; file, it now looks like this, and is&#xA;ready to start Discourse:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git diff docker-compose.yml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;diff --git a/docker-compose.yml b/docker-compose.yml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;index 1acf76d..51bc761 &lt;span class=&#34;m&#34;&gt;100644&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;--- a/docker-compose.yml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+++ b/docker-compose.yml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;@@ -30,7 +30,7 @@ services:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       - &lt;span class=&#34;nv&#34;&gt;DISCOURSE_POSTGRESQL_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;bitnami_application&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       - &lt;span class=&#34;nv&#34;&gt;DISCOURSE_POSTGRESQL_USERNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;bn_discourse&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       - &lt;span class=&#34;nv&#34;&gt;DISCOURSE_POSTGRESQL_PASSWORD&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;bitnami1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-      - &lt;span class=&#34;nv&#34;&gt;DISCOURSE_HOSTNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;www.example.com&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+      - &lt;span class=&#34;nv&#34;&gt;DISCOURSE_HOSTNAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;127.0.0.1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   sidekiq:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     image: &lt;span class=&#34;s1&#34;&gt;&amp;#39;bitnami/discourse:2&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     depends_on:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Now run docker-compose, with the command:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker-compose up -d&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Wait a minute for the application to come up and continue on to the next section. If you want to query the containers to verify they are all up, you&amp;rsquo;ll see 4 of them, similar to:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker ps -a&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS                     PORTS                  NAMES&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;b4e5a2298efe        bitnami/discourse:2                                   &lt;span class=&#34;s2&#34;&gt;&amp;#34;/app-entrypoint.sh …&amp;#34;&lt;/span&gt;   &lt;span class=&#34;m&#34;&gt;25&lt;/span&gt; hours ago        Up &lt;span class=&#34;m&#34;&gt;12&lt;/span&gt; hours                3000/tcp               bitnami-docker-discourse_sidekiq_1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cbe2a7800486        bitnami/discourse:2                                   &lt;span class=&#34;s2&#34;&gt;&amp;#34;/app-entrypoint.sh …&amp;#34;&lt;/span&gt;   &lt;span class=&#34;m&#34;&gt;25&lt;/span&gt; hours ago        Up &lt;span class=&#34;m&#34;&gt;12&lt;/span&gt; hours                0.0.0.0:80-&amp;gt;3000/tcp   bitnami-docker-discourse_discourse_1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;c84794c82b3b        bitnami/postgresql:11                                 &lt;span class=&#34;s2&#34;&gt;&amp;#34;/opt/bitnami/script…&amp;#34;&lt;/span&gt;   &lt;span class=&#34;m&#34;&gt;29&lt;/span&gt; hours ago        Up &lt;span class=&#34;m&#34;&gt;12&lt;/span&gt; hours                5432/tcp               bitnami-docker-discourse_postgresql_1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2c00b3c124a2        bitnami/redis:5.0                                     &lt;span class=&#34;s2&#34;&gt;&amp;#34;/opt/bitnami/script…&amp;#34;&lt;/span&gt;   &lt;span class=&#34;m&#34;&gt;29&lt;/span&gt; hours ago        Up &lt;span class=&#34;m&#34;&gt;12&lt;/span&gt; hours                6379/tcp               bitnami-docker-discourse_redis_1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;create-a-discourse-user&#34;&gt;Create a Discourse User&#xA;&lt;/h2&gt;&lt;p&gt;For this test, I don&amp;rsquo;t need to setup SMTP email because I&amp;rsquo;m really only trying&#xA;out the Discourse API locally. Unfortunately Discourse relies on SMTP to&#xA;send emails for every user registration, even the first user signup process. For our purposes, we don&amp;rsquo;t need email&#xA;capability, we only need a user to login and create an API token.&lt;/p&gt;&#xA;&lt;p&gt;This can be accomplished using the following steps.&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Connect to the discourse container:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@host bitnami-docker-discourse&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ docker &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; -it bitnami-docker-discourse_discourse_1 /bin/shell&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Using the steps for &amp;ldquo;Need to log in without receiving a registration email?&amp;rdquo; in the &lt;a class=&#34;link&#34; href=&#34;https://meta.discourse.org/t/troubleshooting-email-on-a-new-discourse-install/16326/2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;email troubleshooting&lt;/a&gt; documentation as a guide, we&amp;rsquo;ll run &lt;code&gt;rake&lt;/code&gt; to create an admin account:&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;root@cbe2a7800486:/opt/bitnami/discourse# &lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/opt/bitnami/discourse&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;root@cbe2a7800486:/opt/bitnami/discourse# &lt;span class=&#34;nv&#34;&gt;RAILS_ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;production bundle &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; rake admin:create&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Email:  myuser@example.com&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Password:  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Repeat password:  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Ensuring account is active!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Account created successfully with username myuser&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Do you want to grant Admin privileges to this account? &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Y/n&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;  y&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Your account now has Admin privileges!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;Login to the Discourse GUI using the user/password you created above&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;create-api-key&#34;&gt;Create API Key&#xA;&lt;/h2&gt;&lt;p&gt;Next we&amp;rsquo;ll create the API key that we&amp;rsquo;re going to use to create posts. Follow these steps:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Go to the Admin page (hamburger menu in upper right)&lt;/li&gt;&#xA;&lt;li&gt;Click on the API tab at the top&lt;/li&gt;&#xA;&lt;li&gt;Select &amp;ldquo;New API Key&amp;rdquo;&lt;/li&gt;&#xA;&lt;li&gt;Plug in your username, the description, and the user level of &amp;ldquo;Single User&amp;rdquo;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Write down the key because you&amp;rsquo;ll never see it in full again if you forget it. (But of course you can create a new one and delete this one very easily.)&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-new-category&#34;&gt;Create New Category&#xA;&lt;/h2&gt;&lt;p&gt;You can create a new category via the GUI, but to do this via the API use a command similar to:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -X POST &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://127.0.0.1/categories.json&amp;#34;&lt;/span&gt; -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json;&amp;#34;&lt;/span&gt; -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Api-Key: 1234512345&amp;#34;&lt;/span&gt; -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Api-Username: myuser&amp;#34;&lt;/span&gt; --data &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;name&amp;#34;: &amp;#34;New Category&amp;#34;, &amp;#34;color&amp;#34;: &amp;#34;b3e0ff&amp;#34;, &amp;#34;text_color&amp;#34;: &amp;#34;000000&amp;#34;}&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;category&amp;#34;&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:6,&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;New Category&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;color&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;b3e0ff&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;text_color&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;000000&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;slug&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;new-category&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The new category ID (as shown in the response,) is &lt;code&gt;6&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-a-post-in-the-new-category&#34;&gt;Create a Post in the New Category&#xA;&lt;/h2&gt;&lt;p&gt;To finally perform the post creation using the API, do something like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -X POST &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://127.0.0.1/posts.json&amp;#34;&lt;/span&gt; -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json;&amp;#34;&lt;/span&gt; -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Api-Key: 1234512345&amp;#34;&lt;/span&gt; -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Api-Username: myuser&amp;#34;&lt;/span&gt; --data &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;title&amp;#34;: &amp;#34;This is a new post in the newest category!&amp;#34;, &amp;#34;category&amp;#34;: 6, &amp;#34;raw&amp;#34;: &amp;#34;This is the body for the new post&amp;#34;}&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;:24,&lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;:null,&lt;span class=&#34;s2&#34;&gt;&amp;#34;username&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;myuser&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;avatar_template&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;/letter_avatar_proxy/v4/letter/m/9de0a6/{size}.png&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;2020-04-27T03:12:10.295Z&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;cooked&amp;#34;&lt;/span&gt;:&lt;span class=&#34;s2&#34;&gt;&amp;#34;\u003cp\u003eThis is the body for the new post&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;And now you&amp;rsquo;ve created a new post using the API. Mission accomplished! (For real, not like with W.)&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Using AWS Lambda@Edge on Cloudfront</title>
            <link>https://bacchi.org/posts/lambda-edge-cloudfront/</link>
            <pubDate>Tue, 28 Jan 2020 23:07:16 -0600</pubDate>
            <guid>https://bacchi.org/posts/lambda-edge-cloudfront/</guid>
            <description>&lt;p&gt;I&amp;rsquo;ve been attempting to learn more about Lambda@Edge and how to use functions at&#xA;the AWS edge locations, so I wrote up this demo. It isn&amp;rsquo;t performing a very&#xA;realistic operation, but it did allow me to understand the Lambda@Edge and&#xA;Cloudfront cache relationship (aka &amp;ldquo;event model&amp;rdquo;) and how to intercept CDN cache&#xA;requests and modify responses in a Lambda function.&lt;/p&gt;&#xA;&lt;h2 id=&#34;demo-repository&#34;&gt;Demo Repository&#xA;&lt;/h2&gt;&lt;p&gt;The repository is at &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-edge-cloudfront-terraform&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://github.com/mbacchi/lambda-edge-cloudfront-terraform&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;All the instructions for deploying the Terraform and uploading the html/js files&#xA;to the S3 bucket are in the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-edge-cloudfront-terraform/blob/master/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;README.md&lt;/a&gt;.&#xA;Follow those instructions to deploy using Terraform.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Deploying can take 5 minutes in order to replicate the CloudFront&#xA;distribution to all AWS edge locations.&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&#xA;&lt;/h2&gt;&lt;p&gt;The below steps are possible only after deploying all the AWS resources via&#xA;Terraform and placing the html/js files in the S3 bucket.&lt;/p&gt;&#xA;&lt;p&gt;The basic flow of the actions in this demo are:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;The CloudFront distribution sits in front of an S3 bucket which hosts the&#xA;&lt;code&gt;index.html&lt;/code&gt; page&lt;/li&gt;&#xA;&lt;li&gt;When the Submit butten is pressed, the &lt;code&gt;index.html&lt;/code&gt; page passes the&#xA;querystring to the CloudFront distribution&lt;/li&gt;&#xA;&lt;li&gt;The &lt;code&gt;viewer_request.py&lt;/code&gt; Lambda function associated with the CloudFront&#xA;distribution intercepts the request before the cache performs the lookup. In&#xA;the function we perform a 302 redirect to the 2nd html page &lt;code&gt;other.html&lt;/code&gt;,&#xA;with the same query string as passed by the &lt;code&gt;index.html&lt;/code&gt; page.&lt;/li&gt;&#xA;&lt;li&gt;As the response is sent to the viewer, the &lt;code&gt;origin_response.py&lt;/code&gt; Lambda&#xA;function adds the &lt;code&gt;content-security-policy&lt;/code&gt; that allows the &lt;code&gt;other.py&lt;/code&gt; page&#xA;to execute scripts in the CloudFront distribution domain, and allows&#xA;github.com to be used to connect via an API call (also known as the connect&#xA;source), all on the fly by adding HTTP headers to the response.&lt;/li&gt;&#xA;&lt;li&gt;When loaded on the viewer&amp;rsquo;s web browser, the &lt;code&gt;other.html&lt;/code&gt; page makes the API&#xA;call in &lt;code&gt;script.js&lt;/code&gt; with the query string, and the async await function loads&#xA;the response into the DOM when the API query returns.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;lambdaedge-basics&#34;&gt;Lambda@Edge Basics&#xA;&lt;/h2&gt;&lt;p&gt;The below diagram (from &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;the AWS&#xA;documentation&lt;/a&gt;)&#xA;explains how the request from and response to the viewer can be modified before&#xA;or after the cache.&lt;/p&gt;&#xA;&lt;img src=&#34;cloudfront-events-that-trigger-lambda-functions.png&#34;&gt;&#xA;&lt;p&gt;In our example we will use the viewer request and origin response points of this&#xA;diagram to execute our Lambda functions and modify the request/response.&lt;/p&gt;&#xA;&lt;h2 id=&#34;request-and-response&#34;&gt;Request and Response&#xA;&lt;/h2&gt;&lt;p&gt;The &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-edge-cloudfront-terraform/blob/master/lambda/viewer_request.py&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;viewer_request.py Lambda&#xA;function&lt;/a&gt;&#xA;first looks at the request and identifies if the referrer URI includes the string&#xA;&lt;code&gt;index.html&lt;/code&gt;. If so it redirects to the CloudFront distribution domain name,&#xA;appending the query string passed to the page.&lt;/p&gt;&#xA;&lt;p&gt;As that redirect is handled it goes to the cache (and possibly to the origin) to&#xA;get the 2nd html page, and in the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-edge-cloudfront-terraform/blob/master/lambda/origin_response.py&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;origin_response.py&lt;/a&gt;&#xA;the Content Security Policy (i.e. CSP) is dynamically configured to allow the&#xA;CloudFront distribution domain name to execute scripts(&lt;code&gt;script-src&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;Finally when the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-edge-cloudfront-terraform/blob/master/other.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;other.html&lt;/a&gt;&#xA;page loads, it calls the Javascript async function to query the GitHub API with&#xA;the querystring username provided to &lt;code&gt;index.html&lt;/code&gt;, and fills in the DOM with the&#xA;response json.&lt;/p&gt;&#xA;&lt;h2 id=&#34;logging-and-troubleshooting&#34;&gt;Logging and troubleshooting&#xA;&lt;/h2&gt;&lt;p&gt;The output of the Lambda@Edge function (we have multiple print statements) is&#xA;directed to AWS Cloudwatch just like any Lambda function. This allows us to take&#xA;a look at the output and either debug or use for general information. This is&#xA;going to be in the region that is closest to your user making the request, so in&#xA;my case I am in Colorado, and the edge location apparently is &lt;code&gt;us-west-2&lt;/code&gt;&#xA;(Oregon).&lt;/p&gt;&#xA;&lt;p&gt;You can also use the Chrome (or Brave) developer console to show errors when&#xA;making requests. Hit &lt;code&gt;Ctrl-Shift-I&lt;/code&gt; or use the browser menu to open the&#xA;Developer Tools and watch while you load the page.&lt;/p&gt;&#xA;&lt;p&gt;This is all described in the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/lambda-edge-cloudfront-terraform/blob/master/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;README.md&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;additional-resources&#34;&gt;Additional Resources&#xA;&lt;/h2&gt;&lt;p&gt;More help about CloudFront, Lambda@Edge and AWS can be found at these links:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Using AWS Lambda with CloudFront&#xA;Lambda@Edge&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Customizing Content at the Edge with&#xA;Lambda@Edge&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-how-it-works-tutorial.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Tutorial: Creating a Simple Lambda@Edge&#xA;Function&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;CloudFront Events That Can Trigger a Lambda&#xA;Function&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&#xA;&lt;/h2&gt;&lt;p&gt;This was an interesting project to work on. CloudFront and Lambda@Edge appear&#xA;quite useful now that I&amp;rsquo;ve learned the basics. Hope you got something out of&#xA;this demo too.&lt;/p&gt;&#xA;&lt;p&gt;Enjoy!&lt;/p&gt;&#xA;&lt;h2 id=&#34;addendum&#34;&gt;Addendum&#xA;&lt;/h2&gt;&lt;p&gt;In the original version of this post, I indicated that these deployments could&#xA;take anywhere from 20-30 minutes. I&amp;rsquo;ve corrected this information because that&#xA;has now changed.&lt;/p&gt;&#xA;&lt;p&gt;The AWS CloudFront team has recently shared &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/blogs/networking-and-content-delivery/slashing-cloudfront-change-propagation-times-in-2020-recent-changes-and-looking-forward/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;updated information about their&#xA;deployment&#xA;times&lt;/a&gt;.&#xA;They have improved these deployments from 20-30 minutes to typically around 5&#xA;minutes.&lt;/p&gt;&#xA;&lt;p&gt;This is a major improvement and makes it much easier to use.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Running Brave in a Docker Container</title>
            <link>https://bacchi.org/posts/brave-in-docker/</link>
            <pubDate>Wed, 11 Sep 2019 08:24:14 -0600</pubDate>
            <guid>https://bacchi.org/posts/brave-in-docker/</guid>
            <description>&lt;p&gt;Security minded users often run Docker to create an additional sandbox around an&#xA;untrusted application running on their system. Web Browsers are among the most&#xA;untrusted applications we run today. Here&amp;rsquo;s how to setup the Brave Browser to&#xA;run in Docker.&lt;/p&gt;&#xA;&lt;p&gt;To paraphrase T.S. Eliot, &amp;lsquo;good coders borrow and great coders steal.&amp;rsquo; So I&amp;rsquo;ll&#xA;be borrowing from Jess Frazelle&amp;rsquo;s work on running Chromium in&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/jessfraz/dockerfiles/blob/master/chromium/Dockerfile&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Docker&lt;/a&gt;&#xA;and using her&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/jessfraz/dotfiles/blob/master/etc/docker/seccomp/chrome.json&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;seccomp&lt;/a&gt;&#xA;profile. This specifically provides the list of system calls that Chromium or in&#xA;our case Brave can run in the Docker container.&lt;/p&gt;&#xA;&lt;h2 id=&#34;install-and-configure-docker&#34;&gt;Install and Configure Docker&#xA;&lt;/h2&gt;&lt;p&gt;You will first need to install Docker on your machine and make sure the daemon&#xA;is running. To verify your system is configured to run Docker, try running the&#xA;&lt;code&gt;hello-world&lt;/code&gt; image:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@host ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ docker run hello-world&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Unable to find image &lt;span class=&#34;s1&#34;&gt;&amp;#39;hello-world:latest&amp;#39;&lt;/span&gt; locally&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;latest: Pulling from library/hello-world&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1b930d010525: Pull &lt;span class=&#34;nb&#34;&gt;complete&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;If it doesn&amp;rsquo;t run there are&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.docker.com/install/linux/docker-ce/ubuntu/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;many&lt;/a&gt;&#xA;&lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/configure-docker-daemon&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;guides&lt;/a&gt;&#xA;to configuring Docker available.&lt;/p&gt;&#xA;&lt;h2 id=&#34;brave-in-docker&#34;&gt;Brave in Docker&#xA;&lt;/h2&gt;&lt;p&gt;In order to run Brave in Docker clone the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/brave-docker&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;brave-github&lt;/a&gt; GitHub repository.&lt;/p&gt;&#xA;&lt;p&gt;The Dockerfile in this repository uses a basic Fedora image to install Brave&#xA;from the &lt;a class=&#34;link&#34; href=&#34;https://brave-browser.readthedocs.io/en/latest/installing-brave.html#linux&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;release channel RPM&#xA;repository&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Follow these steps to setup additional prereqs:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Change into the brave-docker directory after cloning: &lt;code&gt;cd brave-docker&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Next, you&amp;rsquo;ll need to download the seccomp profile from &lt;a class=&#34;link&#34; href=&#34;https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;: &lt;code&gt;wget https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json -O chrome.json&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Add xhost permissions for your user using &lt;a class=&#34;link&#34; href=&#34;https://github.com/jessfraz/dockerfiles/issues/65#issuecomment-304463458&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;the command&lt;/a&gt; (It&amp;rsquo;s probably good to come up with a more restrictive method than opening up xhost to all clients.): &lt;code&gt;xhost +&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;building-the-docker-image&#34;&gt;Building the Docker image&#xA;&lt;/h2&gt;&lt;p&gt;To build the image, run:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@host brave-docker&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ docker build . -t brave-release-fedora&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;You can use any tag you like, just replace the &lt;code&gt;-t&lt;/code&gt; argument above.&lt;/p&gt;&#xA;&lt;p&gt;To list your image after building, run the command:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@host brave-docker&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ docker images&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;REPOSITORY             TAG                 IMAGE ID            CREATED              SIZE&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brave-release-fedora   latest              729a66f5a7cf        About a minute ago   1.08GB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;running-the-container&#34;&gt;Running the container&#xA;&lt;/h2&gt;&lt;p&gt;To run Brave in the image you built, use the &lt;code&gt;docker run&lt;/code&gt; command:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@host brave-docker&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ docker run -it --net host --cpuset-cpus &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; --memory 512mb &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v &lt;span class=&#34;nv&#34;&gt;$HOME&lt;/span&gt;/Downloads:/home/brave/Downloads:z -v /tmp/.X11-unix:/tmp/.X11-unix &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;--security-opt &lt;span class=&#34;nv&#34;&gt;seccomp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;./chrome.json -e &lt;span class=&#34;nv&#34;&gt;DISPLAY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;unix&lt;span class=&#34;nv&#34;&gt;$DISPLAY&lt;/span&gt; --device /dev/dri &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;-v /dev/shm:/dev/shm --device /dev/snd brave-release-fedora&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;It will default to using UID/GID 1000 for the &lt;code&gt;brave&lt;/code&gt; user in the container.&#xA;This will allow you to mount your &lt;code&gt;~/Download&lt;/code&gt; directory as a volume in the&#xA;container, in order to download files as you would using a browser normally in&#xA;your environment. If you need to change the UID/GID, pass the flag &lt;code&gt;--build-arg UID_GID=YOUR_UID&lt;/code&gt; to the &lt;code&gt;docker build&lt;/code&gt; command in the previous section.&lt;/p&gt;&#xA;&lt;p&gt;Have fun!&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Setting up an EC2 Instance as an Inlets Exit Node</title>
            <link>https://bacchi.org/posts/inlets-aws-ec2/</link>
            <pubDate>Wed, 21 Aug 2019 08:41:54 -0600</pubDate>
            <guid>https://bacchi.org/posts/inlets-aws-ec2/</guid>
            <description>&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/alexellis/inlets&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Inlets&lt;/a&gt; is a fairly new project that&#xA;allows you to setup reverse proxy, websocket tunnels, or other endpoints to the&#xA;public internet, it is similar to &lt;a class=&#34;link&#34; href=&#34;https://ngrok.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ngrok&lt;/a&gt;. The &lt;a class=&#34;link&#34; href=&#34;https://youtu.be/jrAqqe8N3q4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;video&#xA;overview from Alex Ellis&lt;/a&gt; shows how simple it&#xA;makes setting up the environment.&lt;/p&gt;&#xA;&lt;p&gt;Also, there are scripts in the Inlets repository to provision DigitalOcean&#xA;droplets. Let&amp;rsquo;s setup an AWS EC2 instance, though AWS is more expensive than DO,&#xA;it&amp;rsquo;s obviously a popular platform. The steps below are &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/vpc/latest/userguide/vpc-subnets-commands-example.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;required to setup an AWS&#xA;VPC and related&#xA;networking&lt;/a&gt;&#xA;before launching our instance.&lt;/p&gt;&#xA;&lt;p&gt;In this blog post we&amp;rsquo;ll set up an exit node using the AWS CLI, then make it&#xA;simpler with Terraform.&lt;/p&gt;&#xA;&lt;h2 id=&#34;using-the-aws-cli&#34;&gt;Using the AWS CLI&#xA;&lt;/h2&gt;&lt;p&gt;Here is an example of the commands that would need to be run from the AWS CLI if&#xA;you wanted to use that method for starting up the EC2 instance. (&lt;em&gt;Note&lt;/em&gt;: Do not&#xA;copy all these commands directly, many of them reference objects in my AWS&#xA;account such as VPC IDs, SG IDs etc. and which were removed after this blog post&#xA;was written.)&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 create-vpc --cidr-block 10.0.0.0/16 --region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 create-security-group --group-name &lt;span class=&#34;s2&#34;&gt;&amp;#34;temp-inlets-sg&amp;#34;&lt;/span&gt; --vpc-id vpc-0492e18d8bda513ab --description &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Inlets security group&amp;#34;&lt;/span&gt; --region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 authorize-security-group-ingress --group-id sg-08754da824fc991bc --protocol tcp --port &lt;span class=&#34;m&#34;&gt;22&lt;/span&gt; --cidr &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;161.97.199.201/32 --region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 authorize-security-group-ingress --group-id sg-08754da824fc991bc --protocol tcp --port &lt;span class=&#34;m&#34;&gt;8090&lt;/span&gt; --cidr &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;161.97.199.201/32 --region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 create-key-pair --key-name inlets-test-keypair --region us-east-2 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq -r &lt;span class=&#34;s2&#34;&gt;&amp;#34;.KeyMaterial&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;&amp;gt; inlets-keypair.pem&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 create-subnet --vpc-id vpc-0492e18d8bda513ab --availability-zone us-east-2a --cidr-block 10.0.5.0/20 &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;--region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 create-internet-gateway --region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 attach-internet-gateway --vpc-id vpc-0492e18d8bda513ab --internet-gateway-id igw-07411b46a0ce5ae46 &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;--region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 create-route-table --vpc-id vpc-0492e18d8bda513ab --region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 create-route --route-table-id rtb-0423d1a8bf3f1a226 --destination-cidr-block 0.0.0.0/0 --gateway-id &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;igw-07411b46a0ce5ae46 --region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 associate-route-table  --subnet-id subnet-00de3c90045c569db --route-table-id rtb-0423d1a8bf3f1a226 &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;--region us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aws ec2 run-instances --image-id ami-0eaecb2e7d28d5f33 --count &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; --instance-type t3a.micro --security-group-ids &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;sg-08754da824fc991bc --key-name inlets-test-keypair --region us-east-2 --tag-specifications &lt;span class=&#34;se&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ResourceType=instance,Tags=[{Key=&amp;#34;Purpose&amp;#34;,Value=&amp;#34;TESTING&amp;#34;}]&amp;#39;&lt;/span&gt; --associate-public-ip-address&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s a lot of typing to setup an AWS instance before deploying the inlets&#xA;project. Lets see if we can do this with less effort using Terraform.&lt;/p&gt;&#xA;&lt;h2 id=&#34;terraform&#34;&gt;Terraform&#xA;&lt;/h2&gt;&lt;p&gt;The terraform equivalent to setup an EC2 instance with all the plumbing is quite&#xA;a bit more concise. You can view the Terraform I wrote in &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/inlets-aws-terraform&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;this&#xA;repository&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: We don&amp;rsquo;t create an AWS keypair in Terraform, I consider that bad form.&#xA;In order to avoid any security concerns we expect that you use a keypair&#xA;previously generated or uploaded to your AWS account. You can use the &lt;code&gt;aws ec2 create-key-pair&lt;/code&gt; command &lt;a class=&#34;link&#34; href=&#34;#using-the-aws-cli&#34; &gt;above&lt;/a&gt; as an example if you want&#xA;to use the CLI.&lt;/p&gt;&#xA;&lt;h3 id=&#34;prerequisites&#34;&gt;Prerequisites&#xA;&lt;/h3&gt;&lt;ul&gt;&#xA;&lt;li&gt;Terraform&lt;/li&gt;&#xA;&lt;li&gt;An AWS account&lt;/li&gt;&#xA;&lt;li&gt;An AWS Keypair&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;prepare-to-run-terraform&#34;&gt;Prepare to run terraform&#xA;&lt;/h3&gt;&lt;p&gt;These steps include:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Install terraform&lt;/li&gt;&#xA;&lt;li&gt;Clone the &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/inlets-aws-terraform&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;inlets-aws-terraform&#xA;repository&lt;/a&gt; (i.e. &lt;code&gt;git clone https://github.com/mbacchi/inlets-aws-terraform&lt;/code&gt;)&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;cd inlets-aws-terraform&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Run &lt;code&gt;terraform init&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Export environment variables for your AWS_PROFILE and AWS_REGION. This looks&#xA;something like: &lt;code&gt;export AWS_PROFILE=PROFILE_NAME &amp;amp;&amp;amp; export AWS_REGION=us-east-2&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Don&amp;rsquo;t forget to change the &lt;code&gt;PROFILE_NAME&lt;/code&gt; in the export command above!&lt;/li&gt;&#xA;&lt;li&gt;Change the &lt;code&gt;key_name&lt;/code&gt; on &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/inlets-aws-terraform/blob/master/main.tf#L64&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;line&#xA;64&lt;/a&gt;&#xA;of &lt;code&gt;main.tf&lt;/code&gt; to the name of your own keypair!&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;create-the-terraform-plan&#34;&gt;Create the terraform plan&#xA;&lt;/h3&gt;&lt;p&gt;Create the token and run the &lt;code&gt;terraform plan&lt;/code&gt; command with the single command line:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;token&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;head -c &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; /dev/urandom &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sha256sum &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; cut -d&lt;span class=&#34;s2&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; -f1&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; terraform plan -out&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;terraform_plan.&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date +%F.%H.%M.%S&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;.out  -var &lt;span class=&#34;s2&#34;&gt;&amp;#34;token=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$token&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This will output a file to be used in the next step, named something like: &lt;code&gt;terraform_plan.2019-08-20.23.04.54.out&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You might not have &lt;code&gt;sha256sum&lt;/code&gt; on your system, it can be replaced&#xA;with &lt;code&gt;shasum&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h3 id=&#34;apply-the-terraform-plan&#34;&gt;Apply the terraform plan&#xA;&lt;/h3&gt;&lt;p&gt;Apply the plan that you created in the previous step after reviewing the plan output.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;terraform apply terraform_plan.2019-08-20.23.04.54.out&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Apply complete! Resources: &lt;span class=&#34;m&#34;&gt;25&lt;/span&gt; added, &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; changed, &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; destroyed.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Outputs:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;inlets_token&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 2395590c8b333cb2cb9f54ac152aac03e0365c1c69ce20348a3124b84c98ec62&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;public_ip_address&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 3.19.218.92&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The terraform output that you see in the last few lines provides the Inlets&#xA;token required by the client to authenticate with the server, and the public IP&#xA;address of the EC2 instance. Use this info in the below steps.&lt;/p&gt;&#xA;&lt;h2 id=&#34;connecting-to-inlets&#34;&gt;Connecting to Inlets&#xA;&lt;/h2&gt;&lt;p&gt;Now that you have deployed the AWS infrastructure using Terraform, we will run&#xA;an application locally and serve it on the public internet from the Inlets exit&#xA;node.&lt;/p&gt;&#xA;&lt;p&gt;This is documented in the &lt;a class=&#34;link&#34; href=&#34;https://github.com/alexellis/inlets#install-the-cli&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Inlets&#xA;README&lt;/a&gt;, but basically on&#xA;your client machine you need an application such as a webserver running. For&#xA;example my jekyll blog:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; blog&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make serve &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;JEKYLL_ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;development jekyll serve&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Configuration file: _config.yml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            Source: .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       Destination: _site&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Incremental build: disabled. Enable with --incremental&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Generating... &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt; in 1.149 seconds.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Auto-regeneration: enabled &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;myblog&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Server address: http://127.0.0.1:4000&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Server running... press ctrl-c to stop.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;In another terminal session I can start the Inlets client:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;TOKEN&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2395590c8b333cb2cb9f54ac152aac03e0365c1c69ce20348a3124b84c98ec62&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;REMOTE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;3.19.218.92:8090&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;inlets client  --remote&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$REMOTE&lt;/span&gt; --upstream&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://127.0.0.1:4000 --token &lt;span class=&#34;nv&#34;&gt;$TOKEN&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;In a web browser, I can open the url &lt;code&gt;3.19.218.92:8090&lt;/code&gt; and see my&#xA;application that was running locally only.&lt;/p&gt;&#xA;&lt;h2 id=&#34;remove-the-terraformed-infrastructure&#34;&gt;Remove the Terraformed infrastructure&#xA;&lt;/h2&gt;&lt;p&gt;When you want to remove this infrastructure, run &lt;code&gt;terraform destroy&lt;/code&gt; from the&#xA;cloned &lt;code&gt;inlets-aws-terraform&lt;/code&gt; directory where you ran &lt;code&gt;terraform apply&lt;/code&gt; etc.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Why Did Official Python Docker Images Disappear for an Afternoon?</title>
            <link>https://bacchi.org/posts/official-python-docker-images/</link>
            <pubDate>Mon, 29 Jul 2019 09:19:13 -0600</pubDate>
            <guid>https://bacchi.org/posts/official-python-docker-images/</guid>
            <description>&lt;p&gt;We have all become accustomed to services on the internet being reliable and&#xA;available approximately 100% of the time. Many services obviously have outages,&#xA;recently GitHub, Cloudflare, Twitter, Facebook have all had widespread service&#xA;disruptions. Some apps affect downstream processes and services that rely on&#xA;them. This is a story about how I found the official Python images on Docker Hub&#xA;were missing for the &lt;code&gt;linux/amd64&lt;/code&gt; architecture for an entire&#xA;afternoon(potentially longer).&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-stage-is-set&#34;&gt;The Stage is Set&#xA;&lt;/h2&gt;&lt;p&gt;Unfortunately, the &lt;a class=&#34;link&#34; href=&#34;https://hub.docker.com/_/python&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;official Python Docker Hub&lt;/a&gt;&#xA;images don&amp;rsquo;t explicitly indicate which architecture they support. You would&#xA;expect images for popular distributions such as Debian Buster would be available&#xA;for both amd64 and ARM architectures.&lt;/p&gt;&#xA;&lt;p&gt;On Saturday, July 13 I was working on some Dockerfiles that I use to test my&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/python-git-secrets&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Python library&lt;/a&gt;, and I couldn&amp;rsquo;t&#xA;download the Buster image I had used in the past. The error I encountered was:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;no matching manifest &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; linux/amd64 in the manifest list entries&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This &lt;a class=&#34;link&#34; href=&#34;https://success.docker.com/article/error-pulling-image-no-matching-manifest&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;support&#xA;page&lt;/a&gt;&#xA;indicated I could list all images for my architecture using a command similar&#xA;to:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DOCKER_CLI_EXPERIMENTAL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;enabled docker manifest inspect -v python:3.8-rc-buster &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.[].Descriptor.platform&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;amd64&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;arm&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;v6&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The only architecure returned for this image at the time was ARM. I worked&#xA;around this problem by &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/dockerfiles/tree/master/python3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;using the Alpine Linux&#xA;image&lt;/a&gt; instead&#xA;because I needed to get this testing completed. But that limitation struck me as&#xA;strange. It kept gnawing at me, I couldn&amp;rsquo;t shake the feeling I must have been&#xA;using incorrect command. A couple weeks later I decided to write a blog post&#xA;about my experience. Funny enough as I was writing the very blog post you&amp;rsquo;re&#xA;reading now, I found that the Buster images were in fact available once again.&lt;/p&gt;&#xA;&lt;h2 id=&#34;act-two&#34;&gt;Act Two&#xA;&lt;/h2&gt;&lt;p&gt;Today the results returned from Docker Hub include amd64, ARM and others:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DOCKER_CLI_EXPERIMENTAL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;enabled docker manifest inspect -v python:3.8-rc-buster &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; jq &lt;span class=&#34;s1&#34;&gt;&amp;#39;.[].Descriptor.platform&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;amd64&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;arm&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;v5&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;arm&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;v7&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;arm64&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;variant&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;v8&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;386&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;ppc64le&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;architecture&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;s390x&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;os&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;linux&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This is expected. But not what I found 2 weeks ago.&lt;/p&gt;&#xA;&lt;p&gt;There was no outage reported on the &lt;a class=&#34;link&#34; href=&#34;https://status.docker.com/pages/history/533c6539221ae15e3f000031&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Docker Hub status&#xA;page&lt;/a&gt; for that&#xA;day. It stands to reason then that the Python official Docker images were&#xA;somehow not built properly for amd64 and other platforms during this window of&#xA;time.&lt;/p&gt;&#xA;&lt;p&gt;I would love to know how this occurred. I guess this reinforces how the folks&#xA;who say &lt;a class=&#34;link&#34; href=&#34;https://www.hanselman.com/blog/EverythingsBrokenAndNobodysUpset.aspx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;everything is&#xA;broken&lt;/a&gt;&#xA;really have a point. At least I wasn&amp;rsquo;t using this in an automated process as&#xA;part of a CI pipeline or something. Although I also see that type of transient&#xA;service outage in my day job an just hit the &lt;code&gt;Restart Job&lt;/code&gt; button in Jenkins.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Returning HTTP Errors from API Gateway in AWS Lambda Functions using Python and Serverless Framework</title>
            <link>https://bacchi.org/posts/aws-lambda-api-gateway-python-errors/</link>
            <pubDate>Tue, 21 May 2019 09:22:07 -0600</pubDate>
            <guid>https://bacchi.org/posts/aws-lambda-api-gateway-python-errors/</guid>
            <description>&lt;p&gt;There are many examples available for how to return an error from an AWS Lambda&#xA;function through API Gateway to a client in Node.js, but relatively few for how&#xA;to do so using the Python runtime. Here we will try to give some basic info&#xA;using Python with a POST action.&lt;/p&gt;&#xA;&lt;h2 id=&#34;prereqs&#34;&gt;Prereqs&#xA;&lt;/h2&gt;&lt;p&gt;This assumes you already have an AWS account, have configured your AWS access&#xA;credentials or profile and set the AWS_REGION environment variable to your&#xA;region of choice. Otherwise it will use the &lt;code&gt;us-west-2&lt;/code&gt; region by default.&lt;/p&gt;&#xA;&lt;p&gt;You will also need the &lt;a class=&#34;link&#34; href=&#34;serverless.com&#34; &gt;Serverless Framework&lt;/a&gt; to be installed.&lt;/p&gt;&#xA;&lt;h2 id=&#34;lambda-proxy-integration&#34;&gt;Lambda-Proxy Integration&#xA;&lt;/h2&gt;&lt;p&gt;In this blog post we are going to cover the &lt;a class=&#34;link&#34; href=&#34;https://serverless.com/framework/docs/providers/aws/events/apigateway/#lambda-proxy-integration&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Lambda-Proxy integration&#xA;method&lt;/a&gt;&#xA;versus the &lt;a class=&#34;link&#34; href=&#34;https://serverless.com/framework/docs/providers/aws/events/apigateway/#lambda-integration&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Lambda&#xA;method&lt;/a&gt;.&#xA;This is the simplest and from what I&amp;rsquo;ve found least documented because it just&#xA;seems obvious to AWS technical writers, Serverless framework developers and blog&#xA;authors. Most examples are written in Node.js because of that because that&amp;rsquo;s&#xA;what both AWS and Serverless framework documents discuss. Our example hopes to&#xA;make it a little more clear.&lt;/p&gt;&#xA;&lt;h2 id=&#34;create-serverless-project&#34;&gt;Create Serverless project&#xA;&lt;/h2&gt;&lt;p&gt;Let&amp;rsquo;s start by creating a new Serverless framework project. We will be using the&#xA;&lt;code&gt;aws-python3&lt;/code&gt; template for this, which populates a basic &lt;code&gt;serverless.yml&lt;/code&gt;&#xA;configuration file and a basic handler function. To do so we use the &lt;code&gt;serverless create&lt;/code&gt; command (abbreviated as &lt;code&gt;sls create&lt;/code&gt; for brevity) to generate the skeleton to&#xA;our project.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux serverless&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ sls create --template aws-python3 --path test-lambda-exception-handling&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Generating boilerplate...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Generating boilerplate in &lt;span class=&#34;s2&#34;&gt;&amp;#34;/serverless/test-lambda-exception-handling&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; _______                             __&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   _   .-----.----.--.--.-----.----&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  .-----.-----.-----.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;___&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  -__&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   _&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  -__&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   _&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  -__&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__ --&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__ --&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;____   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;_____&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;se&#34;&gt;\_&lt;/span&gt;__/&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;_____&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;__&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;_____&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;_____&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;_____&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;             The Serverless Application Framework&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;       &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;                           serverless.com, v1.38.0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; -------&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Successfully generated boilerplate &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; template: &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws-python3&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Once we have this template in place, you can modify the files yourself, or copy&#xA;the below into your project. It is also available in &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/python-lambda-exception-handling&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;my GitHub&#xA;repository&lt;/a&gt; if you&amp;rsquo;d&#xA;rather look at that.&lt;/p&gt;&#xA;&lt;p&gt;The handler function and YAML are:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;json&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;throw_error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;loads&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# this can be seen in CloudWatch Logs&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;statusCode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;400&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;s2&#34;&gt;&amp;#34;context.aws_request_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;aws_request_id&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# for fun show the Lambda requestID&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Bad Request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;isBase64Encoded&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;test-lambda-exception-handling&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;provider&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;aws&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;python3.7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;region&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;${AWS_REGION, &amp;#39;us-east-2&amp;#39;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;dev&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;functions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;throw_error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;handler.throw_error&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;events&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;throw&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;method&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;post&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;what-this-does&#34;&gt;What this does&#xA;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;serverless.yml&lt;/code&gt; file defines the FaaS or Cloud provider where you are going&#xA;to run the function, as well as the function itself. This is a very basic single&#xA;function for the purposes of this demo. The documentation is&#xA;&lt;a class=&#34;link&#34; href=&#34;https://serverless.com/framework/docs/providers/aws/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;. As you can see we&#xA;are running in AWS Lambda, and using the function named &lt;code&gt;throw_error&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The handler can be named anything, but must be referenced in the &lt;code&gt;.yml&lt;/code&gt; file.&#xA;We&amp;rsquo;re using the name that the Serverless template provided for us. In a Lambda&#xA;runtime environment, you&amp;rsquo;re passed an event object and a context object. You are&#xA;provided event details including any data passed to the function via the POST&#xA;request. The context object has information about the execution environment,&#xA;invocation and other things, &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;described&#xA;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Our handler simply loads the event data, and then prints it so that it can be&#xA;viewed in Cloudwatch Logs. This isn&amp;rsquo;t returned to the calling client. Because&#xA;we&amp;rsquo;re using API Gateway, the response must conform to a &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;specific&#xA;format&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In our function we simply return a &lt;code&gt;400 Bad Request&lt;/code&gt; response immediately after&#xA;decoding the data passed in.&lt;/p&gt;&#xA;&lt;h2 id=&#34;deploying-the-project&#34;&gt;Deploying the project&#xA;&lt;/h2&gt;&lt;p&gt;If we&amp;rsquo;re cautios we can look at what will be deployed by first running the &lt;code&gt;sls package&lt;/code&gt; command. Then we can look in the &lt;code&gt;.zip&lt;/code&gt; file that it will upload to AWS&#xA;Lambda.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux test-lambda-exception-handling&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ sls package&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Packaging service...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Excluding development dependencies...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux test-lambda-exception-handling&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ ls -a&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.  ..  .gitignore  handler.py  .serverless  serverless.yml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux test-lambda-exception-handling&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ ls .serverless/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cloudformation-template-create-stack.json  cloudformation-template-update-stack.json  serverless-state.json  test-lambda-exception-handling.zip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux test-lambda-exception-handling&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ zipinfo -l .serverless/test-lambda-exception-handling.zip &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Archive:  .serverless/test-lambda-exception-handling.zip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Zip file size: &lt;span class=&#34;m&#34;&gt;407&lt;/span&gt; bytes, number of entries: &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw-rw-r--  4.5 unx      &lt;span class=&#34;m&#34;&gt;451&lt;/span&gt; bl      &lt;span class=&#34;m&#34;&gt;273&lt;/span&gt; defN 80-Jan-01 00:00 handler.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; file, &lt;span class=&#34;m&#34;&gt;451&lt;/span&gt; bytes uncompressed, &lt;span class=&#34;m&#34;&gt;273&lt;/span&gt; bytes compressed:  39.5%&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;To deploy we use the &lt;code&gt;sls deploy&lt;/code&gt; command.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux test-lambda-exception-handling&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ sls deploy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Packaging service...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Excluding development dependencies...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Creating Stack...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Checking Stack create progress...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.....&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Stack create finished...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Uploading CloudFormation file to S3...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Uploading artifacts...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Uploading service test-lambda-exception-handling.zip file to S3 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;407&lt;/span&gt; B&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Validating template...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Updating Stack...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Checking Stack update progress...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.................................&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serverless: Stack update finished...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Service Information&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;service: test-lambda-exception-handling&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;stage: dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;region: us-east-2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;stack: test-lambda-exception-handling-dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;resources: &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;api keys:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  None&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;endpoints:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  POST - https://7vt4w7lb4l.execute-api.us-east-2.amazonaws.com/dev/throw&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;functions:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  throw_error: test-lambda-exception-handling-dev-throw_error&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;layers:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  None&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This returns the URL for POST actions, which we will use in our next step.&lt;/p&gt;&#xA;&lt;h2 id=&#34;invoking-the-function&#34;&gt;Invoking the Function&#xA;&lt;/h2&gt;&lt;p&gt;Now we can simply run a POST against our new function URL and see how it will&#xA;respond.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux test-lambda-exception-handling&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ curl -i -X POST https://7vt4w7lb4l.execute-api.us-east-2.amazonaws.com/dev/throw --data &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;blah&amp;#34;: &amp;#34;blah1&amp;#34;}&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;HTTP/2 &lt;span class=&#34;m&#34;&gt;400&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;content-type: application/json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;content-length: &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;date: Wed, &lt;span class=&#34;m&#34;&gt;22&lt;/span&gt; May &lt;span class=&#34;m&#34;&gt;2019&lt;/span&gt; 01:34:50 GMT&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;x-amzn-requestid: ca8164e7-7c31-11e9-b114-d91ebd2032b3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;context.aws_request_id: 87f10bcd-7c85-46d5-bcd7-493aca45e1f0&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;x-amz-apigw-id: &lt;span class=&#34;nv&#34;&gt;aD8RIG3MCYcFk2w&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;x-amzn-trace-id: &lt;span class=&#34;nv&#34;&gt;Root&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1-5ce4a73a-af05ec85fe34062d036b396f&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;Sampled&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;x-cache: Error from cloudfront&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;via: 1.1 c4fb40b7909e4dd897bba2e297b284e7.cloudfront.net &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;CloudFront&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;x-amz-cf-id: Sovagss83OsF-hv8b7QHcf9GkmV2r1A_XEF8KzI18GMrhWzGvfaGSQ&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Bad Request&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@linux test-lambda-exception-handling&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ &#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This shows that we receive the &lt;code&gt;Bad Request&lt;/code&gt; response, with HTTP status code 400&#xA;as expected.&lt;/p&gt;&#xA;&lt;p&gt;In a future post I&amp;rsquo;ll describe how to return errors in Python with the &lt;a class=&#34;link&#34; href=&#34;https://serverless.com/framework/docs/providers/aws/events/apigateway/#lambda-integration&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Lambda&#xA;integration&lt;/a&gt;&#xA;method.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Using Git hook templates to avoid committing secrets to public repositories</title>
            <link>https://bacchi.org/posts/git-hook-templates/</link>
            <pubDate>Fri, 11 May 2018 12:39:43 -0600</pubDate>
            <guid>https://bacchi.org/posts/git-hook-templates/</guid>
            <description>&lt;p&gt;Git doesn&amp;rsquo;t have the concept of a per user global hook. It would be nice if you could create hooks in your home directory that could be executed in all repositories that you work with. Instead, it does allow you to write hooks that reside in a user specific template directory to then be copied into any repositories that you clone or create from scratch.&lt;/p&gt;&#xA;&lt;p&gt;After following this guide to configure template hooks, when you clone or create a new repository using the &lt;code&gt;git init&lt;/code&gt; command, your hooks will be copied into your new repositories.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-would-i-want-hooks-in-every-new-repository&#34;&gt;Why would I want hooks in every new repository?&#xA;&lt;/h2&gt;&lt;p&gt;There could be many reasons why you want to setup a hook in every new repository. My current use case has to do with preventing AWS credentials from accidentally being committed to any of my GitHub repositories. This prevents you from having someone get into your AWS account and potentially racking up a large bill you would be responsible for. Automatically scanning your commit for any patterns that look like AWS secrets will prevent this costly mistake.&lt;/p&gt;&#xA;&lt;h2 id=&#34;template-configuration&#34;&gt;Template configuration&#xA;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;git init&lt;/code&gt; &lt;a class=&#34;link&#34; href=&#34;https://git-scm.com/docs/git-init#_template_directory&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;man page&lt;/a&gt; talks about the Template Directory which gives us the ability to copy hooks into new repositories. It must first be configured using the &lt;code&gt;git config&lt;/code&gt; command, specfying the &lt;a class=&#34;link&#34; href=&#34;https://git-scm.com/docs/git-config#git-config-inittemplateDir&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;&lt;code&gt;init.templatedir&lt;/code&gt;&lt;/a&gt; which is the directory where you will store your hooks. You will run a command such as:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git config --global init.templatedir &lt;span class=&#34;s1&#34;&gt;&amp;#39;~/.git_template&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This config directive is added to the &lt;code&gt;[init]&lt;/code&gt; section in your &lt;code&gt;.gitconfig&lt;/code&gt; file, which looks like the following:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;init&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;nv&#34;&gt;templatedir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; ~/.git_template&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;create-the-hook&#34;&gt;Create the hook&#xA;&lt;/h2&gt;&lt;p&gt;Now we can create our hook and place it in the template hooks directory (which is actually templatedir/hooks). This hook employs &lt;code&gt;git-secrets&lt;/code&gt; to prevent me from accidentally committing my AWS credentials to GitHub:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# A git hook to run git-secrets (locally &amp;#39;installed&amp;#39;) against a repository.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# This should be extended to do much more verification and error handling,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# but is presented as a demonstration.&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# This assumes you&amp;#39;ve already setup git-secrets patterns (i.e. &amp;#34;git-secrets --register-aws&amp;#34;).&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Verify that the git-secrets file is in our path&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;secretspath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;which git-secrets&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; -z &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;secretspath&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; ! -x &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;secretspath&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;git-secrets not found!&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;RESPONSE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;git-secrets --scan -r .&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;RC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$?&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$RC&lt;/span&gt; -eq &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return code 1 from git-secrets indicates scan found a verboten string&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ERROR: [pre-commit hook] Aborting commit because git-secrets found a prohibited pattern in this repository&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Please remove the file with the pattern in the output above from this repository!&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# no secrets found in repo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Looking in that directory we see the new hook, but we need to make it executable so I will run the command &lt;code&gt;chmod 744&lt;/code&gt; on the file:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host hooks&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ chmod &lt;span class=&#34;m&#34;&gt;744&lt;/span&gt; ~/.git_template/hooks/pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host hooks&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ ls -l ~/.git_template/hooks&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;total &lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rwxrw-r--. &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; user1 user1 &lt;span class=&#34;m&#34;&gt;931&lt;/span&gt; May &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; 20:34 pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;prepare-a-file-containing-a-pattern-that-will-fail-the-git-secrets-scan&#34;&gt;Prepare a file containing a pattern that will fail the git-secrets scan&#xA;&lt;/h2&gt;&lt;p&gt;At this point we will create a new directory to test our hook. Start by creating a directory to work in:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host repos&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ mkdir template-dir-demo &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; template-dir-demo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Then create a file with a string that looks like an AWS secret(hint, the AWS secret access key is a 40 character string containing lower, upper and digit characters):&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host template-dir-demo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ ipython&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Python 3.6.4 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;default, Mar &lt;span class=&#34;m&#34;&gt;13&lt;/span&gt; 2018, 18:18:20&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Type &lt;span class=&#34;s1&#34;&gt;&amp;#39;copyright&amp;#39;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;credits&amp;#39;&lt;/span&gt; or &lt;span class=&#34;s1&#34;&gt;&amp;#39;license&amp;#39;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; more information&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;IPython 6.2.1 -- An enhanced Interactive Python. Type &lt;span class=&#34;s1&#34;&gt;&amp;#39;?&amp;#39;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; help.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;In &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;1&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: import random&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;In &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;2&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: from string import ascii_uppercase, ascii_lowercase, digits&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;In &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;chars&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; ascii_uppercase + ascii_lowercase + digits&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;In &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;4&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;.join&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;random.choice&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;chars&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; _ in range&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;40&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;In &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;5&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: key&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Out&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;5&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;s1&#34;&gt;&amp;#39;dbMi8e8YYNnTUnlTEEyyYbK3KfQExuaRXF8roC9d&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host template-dir-demo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;aws_secret_access_key = dbMi8e8YYNnTUnlTEEyyYbK3KfQExuaRXF8roC9d&amp;#39;&lt;/span&gt; &amp;gt; blah1.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host template-dir-demo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat blah1.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;aws_secret_access_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; dbMi8e8YYNnTUnlTEEyyYbK3KfQExuaRXF8roC9d&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Now we will run &lt;code&gt;git init .&lt;/code&gt; to initialize a git repository in the current directory, and we see that the pre-commit hook is copied from the template directory:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host template-dir-demo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git init .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Initialized empty Git repository in /home/user1/repos/template-dir-demo/.git/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host template-dir-demo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ ls -altr .git/hooks/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;total &lt;span class=&#34;m&#34;&gt;12&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rwxrwxr-x. &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; user1 user1  &lt;span class=&#34;m&#34;&gt;931&lt;/span&gt; May &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; 20:39 pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;h2 id=&#34;perform-a-commit&#34;&gt;Perform a commit&#xA;&lt;/h2&gt;&lt;p&gt;Finally, lets stage and commit the file and see if the pre-commit hook allows the file to be staged and committed:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host template-dir-demo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git add blah1.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@host template-dir-demo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git commit -m &lt;span class=&#34;s2&#34;&gt;&amp;#34;blah1 file with a secret&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./blah1.txt:1:aws_secret_access_key &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; dbMi8e8YYNnTUnlTEEyyYbK3KfQExuaRXF8roC9d&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;ERROR&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Matched one or more prohibited patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Possible mitigations:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Mark &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; positives as allowed using: git config --add secrets.allowed ...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Mark &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; positives as allowed by adding regular expressions to .gitallowed at repository&lt;span class=&#34;s1&#34;&gt;&amp;#39;s root directory&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;- List your configured patterns: git config --get-all secrets.patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;- List your configured allowed patterns: git config --get-all secrets.allowed&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;- List your configured allowed patterns in .gitallowed at repository&amp;#39;&lt;/span&gt;s root directory&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Use --no-verify &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; this is a one-time &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; positive&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ERROR: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;pre-commit hook&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Aborting commit because git-secrets found a prohibited pattern in this repository&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please remove the file with the pattern in the output above from this repository!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;As you can see using a Git template for hooks will help us automatically setup hooks to use in any new repository whether it is cloned or created with the &lt;code&gt;git init&lt;/code&gt; command.&lt;/p&gt;&#xA;&lt;p&gt;I hope this was helpful to you.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>AWS CodeCommit SSH Key ID</title>
            <link>https://bacchi.org/posts/aws-codecommit-ssh-key-id/</link>
            <pubDate>Mon, 22 Jan 2018 14:28:31 -0600</pubDate>
            <guid>https://bacchi.org/posts/aws-codecommit-ssh-key-id/</guid>
            <description>&lt;p&gt;Working on AWS CodeCommit today, I setup SSH access to the repository. During&#xA;the initial configuration I provided the SSH public key in the AWS Console, but&#xA;then couldn&amp;rsquo;t connect to my repository. In the brief instructions on the IAM&#xA;Console page they tell you how to update your &lt;code&gt;~/.ssh/config&lt;/code&gt; file, but the&#xA;example doesn&amp;rsquo;t explicitly say what the IdentityFile is supposed to be set to.&#xA;In the more detailed instructions they do specify the IdentityFile should&#xA;reference your &lt;i&gt;&lt;b&gt;private key&lt;/b&gt;&lt;/i&gt;, not your public key.&lt;/p&gt;&#xA;&lt;p&gt;For others who are confused about this, and my future self, &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-ssh-unixes.html?icmpid=docs_acc_console_connect#setting-up-ssh-unixes-keys&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&amp;rsquo;s the AWS&#xA;documentation&lt;/a&gt;&#xA;for how to configure SSH Key ID for CodeCommit.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>3rd Party Github Credential Scanning</title>
            <link>https://bacchi.org/posts/github-scanning-3rd-parties/</link>
            <pubDate>Sat, 20 Jan 2018 14:34:36 -0600</pubDate>
            <guid>https://bacchi.org/posts/github-scanning-3rd-parties/</guid>
            <description>&lt;p&gt;While writing &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/python-git-secrets&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;a Python library&lt;/a&gt;&#xA;that performs scanning of Git repositories similar to AWS Labs&#39;&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/awslabs/git-secrets&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;git-secrets&lt;/a&gt;, I was surprised by some&#xA;3rd party scanning services randomly scanning my repository for AWS credentials.&#xA;I had included deactivated AWS credentials in my repository so that I could test&#xA;my library. My plan was to replace these credentials with a randomly generated&#xA;string later on but at first I was satisfied to commit the actual (but not&#xA;active) credentials to Github themselves.&lt;/p&gt;&#xA;&lt;p&gt;A couple weeks after I created the repository on Github, I got an email from a&#xA;random address named &amp;lsquo;githubbot&amp;rsquo;. In the email they indicated that they had&#xA;found a credential in my repository. As a reward for notifying me of this&#xA;potentially costly situation, the email indicated I could send them bitcoin, and&#xA;they included the wallet address. Below is the email itself:&lt;/p&gt;&#xA;&lt;img src=&#34;githubbot.png&#34;&gt;&#xA;&lt;p&gt;Later that day, in order to remove the credential file used in testing, I pushed&#xA;a commit that moved the credential strings in the test driver itself. Within an&#xA;hour I got an email from another unrelated service GitGuardian, indicating I&#xA;exposed an API key in my repository. Who knew so many good samaritan services&#xA;existed to help people out. Here&amp;rsquo;s this email:&lt;/p&gt;&#xA;&lt;img src=&#34;gitguardian.png&#34;&gt;&#xA;&lt;p&gt;What I realized from this encounter is that there are all kinds of unknown&#xA;actors in the Github universe. Some will be benevolent like these, but there&#xA;very well could be black hat types who are scanning every public repository for&#xA;ways to get ahold of your AWS or other keys and will take advantage of them.&lt;/p&gt;&#xA;&lt;p&gt;Watch what you do with your keys!!!! If you want some pointers on how to prevent&#xA;releasing credentials accidentally to Github, take a look at my recent [blog&#xA;post on preventing secret leaks]({{ site.baseurl }}{% post_url&#xA;2017-12-22-3-ways-prevent-secret-leaks-github %}).&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Writing to the AWS Lambda SAM Local container /tmp filesystem</title>
            <link>https://bacchi.org/posts/sam-local-readwrite-filesystem/</link>
            <pubDate>Sun, 07 Jan 2018 14:55:57 -0600</pubDate>
            <guid>https://bacchi.org/posts/sam-local-readwrite-filesystem/</guid>
            <description>&lt;p&gt;While using &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/lambda/latest/dg/test-sam-local.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;AWS Lambda SAM&#xA;Local&lt;/a&gt; to test&#xA;Lambda functions locally, I encountered an error writing to the current&#xA;directory where the function was running in the container (/var/task/). I&amp;rsquo;m not&#xA;claiming a best practice of writing to the filesystem while running a Lambda&#xA;function, but that&amp;rsquo;s part of my learning process for the moment, and I will&#xA;investigate other workflows shortly. But what I was able to get working&#xA;successfuly was writing to the /tmp filesystem instead of the current working&#xA;directory.&lt;/p&gt;&#xA;&lt;p&gt;Here is the example code where it writes to the current directory with an the&#xA;result that we encounter the error that the directory is read only:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@nuc2 sample-sam-local-write&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat samlocalwrite.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;import os&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;import sys&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def handler&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;event, context&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    print&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Starting samlocalwrite lambda handler function&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    print&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Directory provided from event was: {}&amp;#34;&lt;/span&gt;.format&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;event&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;directory&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;remote_repo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; event&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;directory&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;#local_repo = os.path.join(os.path.sep, &amp;#34;tmp&amp;#34;, os.path.basename(event[&amp;#39;directory&amp;#39;]))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;local_repo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; os.path.basename&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;event&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;directory&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; not os.path.exists&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;local_repo&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        os.makedirs&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;local_repo&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    with open&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;local_repo + &lt;span class=&#34;s2&#34;&gt;&amp;#34;blah.txt&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s1&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; as f:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        f.write&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;blah\n&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;And the output of the &lt;code&gt;sam local invoke&lt;/code&gt; command:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@nuc2 sample-sam-local-write&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ sam &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; invoke &lt;span class=&#34;s2&#34;&gt;&amp;#34;SamLocalWriteFunction&amp;#34;&lt;/span&gt; -e event.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:50:24 Successfully parsed template.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:50:24 Connected to Docker 1.35&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:50:24 Fetching lambci/lambda:python3.6 image &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; python3.6 runtime...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python3.6: Pulling from lambci/lambda&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;f338a32fa56c: Pull &lt;span class=&#34;nb&#34;&gt;complete&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4926b20b634f: Pull &lt;span class=&#34;nb&#34;&gt;complete&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;298eae5902d7: Pull &lt;span class=&#34;nb&#34;&gt;complete&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;e58d162628c7: Pull &lt;span class=&#34;nb&#34;&gt;complete&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;e02bc73f2e71: Pull &lt;span class=&#34;nb&#34;&gt;complete&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Digest: sha256:0682e157b34e18cf182b2aaffb501971c7a0c08c785f337629122b7de34e3945&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Status: Downloaded newer image &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; lambci/lambda:python3.6&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:51:25 Invoking samlocalwrite.handler &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;python3.6&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:51:25 Decompressing /home/mbacchi/data/repos/mbacchi/sample-sam-local-write/samlocalwrite.zip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:51:46 WARNING: No AWS credentials found. Missing credentials may lead to slow startup &lt;span class=&#34;nb&#34;&gt;times&lt;/span&gt; as detailed in https://github.com/awslabs/aws-sam-local/issues/134&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:51:46 Mounting /tmp/aws-sam-local-1515358285999917851 as /var/task:ro inside runtime container&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;START RequestId: 9371dabf-9678-4fc4-83d8-5d8c8cf8c9fa Version: &lt;span class=&#34;nv&#34;&gt;$LATEST&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Starting samlocalwrite lambda handler &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Directory provided from event was: whatever&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Errno 30&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Read-only file system: &lt;span class=&#34;s1&#34;&gt;&amp;#39;whatever&amp;#39;&lt;/span&gt;: OSError&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Traceback &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;most recent call last&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  File &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/task/samlocalwrite.py&amp;#34;&lt;/span&gt;, line 18, in handler&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    os.makedirs&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;local_repo&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  File &lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/lang/lib/python3.6/os.py&amp;#34;&lt;/span&gt;, line 220, in makedirs&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    mkdir&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;name, mode&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OSError: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Errno 30&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Read-only file system: &lt;span class=&#34;s1&#34;&gt;&amp;#39;whatever&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;END RequestId: 9371dabf-9678-4fc4-83d8-5d8c8cf8c9fa&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;REPORT RequestId: 9371dabf-9678-4fc4-83d8-5d8c8cf8c9fa Duration: &lt;span class=&#34;m&#34;&gt;161&lt;/span&gt; ms Billed Duration: &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; ms Memory Size: &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; MB Max Memory Used: &lt;span class=&#34;m&#34;&gt;18&lt;/span&gt; MB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;errorMessage&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;[Errno 30] Read-only file system: &amp;#39;whatever&amp;#39;&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;errorType&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;OSError&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;stackTrace&amp;#34;&lt;/span&gt;: &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/task/samlocalwrite.py&amp;#34;&lt;/span&gt;, 18, &lt;span class=&#34;s2&#34;&gt;&amp;#34;handler&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;os.makedirs(local_repo)&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;, &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/var/lang/lib/python3.6/os.py&amp;#34;&lt;/span&gt;, 220, &lt;span class=&#34;s2&#34;&gt;&amp;#34;makedirs&amp;#34;&lt;/span&gt;, &lt;span class=&#34;s2&#34;&gt;&amp;#34;mkdir(name, mode)&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;If we make a slight modification to write to the &lt;code&gt;/tmp&lt;/code&gt; filesystem:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@nuc2 sample-sam-local-write&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ diff samlocalwrite.py samlocalwrite-new.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;14,15c14,15&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;     &lt;span class=&#34;c1&#34;&gt;#local_repo = os.path.join(os.path.sep, &amp;#34;tmp&amp;#34;, os.path.basename(event[&amp;#39;directory&amp;#39;]))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;lt;     &lt;span class=&#34;nv&#34;&gt;local_repo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; os.path.basename&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;event&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;directory&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt;     &lt;span class=&#34;nv&#34;&gt;local_repo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; os.path.join&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;os.path.sep, &lt;span class=&#34;s2&#34;&gt;&amp;#34;tmp&amp;#34;&lt;/span&gt;, os.path.basename&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;event&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;directory&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;gt;     &lt;span class=&#34;c1&#34;&gt;#local_repo = os.path.basename(event[&amp;#39;directory&amp;#39;])&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;We get a successful run:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@nuc2 sample-sam-local-write&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ sam &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; invoke &lt;span class=&#34;s2&#34;&gt;&amp;#34;SamLocalWriteFunction&amp;#34;&lt;/span&gt; -e event.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:55:54 Successfully parsed template.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:55:54 Connected to Docker 1.35&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:55:54 Fetching lambci/lambda:python3.6 image &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; python3.6 runtime...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python3.6: Pulling from lambci/lambda&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Digest: sha256:0682e157b34e18cf182b2aaffb501971c7a0c08c785f337629122b7de34e3945&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Status: Image is up to date &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; lambci/lambda:python3.6&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:55:54 Invoking samlocalwrite.handler &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;python3.6&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:55:54 Decompressing /home/mbacchi/data/repos/mbacchi/sample-sam-local-write/samlocalwrite.zip&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:56:15 WARNING: No AWS credentials found. Missing credentials may lead to slow startup &lt;span class=&#34;nb&#34;&gt;times&lt;/span&gt; as detailed in https://github.com/awslabs/aws-sam-local/issues/134&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2018/01/07 15:56:15 Mounting /tmp/aws-sam-local-1515358554848977835 as /var/task:ro inside runtime container&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;START RequestId: 0af0a302-49db-4ca2-a0fa-db31acb0182a Version: &lt;span class=&#34;nv&#34;&gt;$LATEST&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Starting samlocalwrite lambda handler &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Directory provided from event was: whatever&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;END RequestId: 0af0a302-49db-4ca2-a0fa-db31acb0182a&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;REPORT RequestId: 0af0a302-49db-4ca2-a0fa-db31acb0182a Duration: &lt;span class=&#34;m&#34;&gt;160&lt;/span&gt; ms Billed Duration: &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; ms Memory Size: &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; MB Max Memory Used: &lt;span class=&#34;m&#34;&gt;18&lt;/span&gt; MB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Again, this may not be the perfect solution but it is a way to write to the&#xA;image filesystem if necessary in your Lambda function.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>3 Ways to Prevent .pypirc Credentials or Other Secrets from Leaking onto Github</title>
            <link>https://bacchi.org/posts/3-ways-prevent-secret-leaks-github/</link>
            <pubDate>Fri, 22 Dec 2017 15:02:42 -0600</pubDate>
            <guid>https://bacchi.org/posts/3-ways-prevent-secret-leaks-github/</guid>
            <description>&lt;p&gt;Even if you&amp;rsquo;re not involved in the Python community, you might have heard about&#xA;&lt;a class=&#34;link&#34; href=&#34;http://python-security.readthedocs.io/pypi-vuln/index-2017-11-08-pypirc_exposure_on_github.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;this security&#xA;incident&lt;/a&gt;&#xA;a while back. This is a not uncommon scenario where developers who may not be&#xA;Github or distribution tooling (or security) experts make a mistake and breed&#xA;mistrust in their project as well as the distribution medium itself.&lt;/p&gt;&#xA;&lt;p&gt;But setting up your environment to prevent these accidental credential disclosures&#xA;is easy to do, and will enhance your security posture.&lt;/p&gt;&#xA;&lt;p&gt;Here are a few ways to prevent these exposures with git and other tools.&lt;/p&gt;&#xA;&lt;h2 id=&#34;add-the-pypirc-file-to-the-gitignore-list&#34;&gt;Add the .pypirc file to the .gitignore list&#xA;&lt;/h2&gt;&lt;p&gt;This is the most straightforward, and will force git to ignore the &lt;code&gt;.pypirc&lt;/code&gt; when&#xA;you&amp;rsquo;re adding/committing changes to the repository.&lt;/p&gt;&#xA;&lt;p&gt;I typically use my global &lt;code&gt;.gitignore&lt;/code&gt; file, but you can also add it to the&#xA;repository specific &lt;code&gt;.gitignore&lt;/code&gt; file. Here&amp;rsquo;s how to do both.&lt;/p&gt;&#xA;&lt;p&gt;Create a &lt;code&gt;~/.gitignore&lt;/code&gt; and make this your personal git core.excludesfile:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git config --global core.excludesfile&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~/.gitignore&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git config -l --global &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep core.excludesfile&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;core.excludesfile&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~/.gitignore&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.pypirc&amp;#34;&lt;/span&gt;&amp;gt;&amp;gt; ~/.gitignore&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat ~/.gitignore&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.idea&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.pypirc&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Now you can test whether this will work using the &lt;code&gt;git check-ignore&lt;/code&gt; command:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git check-ignore -v .pypirc&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/home/mbacchi/.gitignore:4:.pypirc&#x9;.pypirc&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$?&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;If you want to add it to the project repository instead, simply perform the&#xA;same operation on the &lt;code&gt;.gitignore&lt;/code&gt; file in the repository. But be aware that&#xA;unless you also commit the &lt;code&gt;.gitignore&lt;/code&gt; file into the repository this ignore&#xA;will lost upon removing and recreating this repository.&lt;/p&gt;&#xA;&lt;h2 id=&#34;add-a-git-pre-commit-hook-to-your-git-repository-that-will-analyze-the-staged-files-for-pypirc&#34;&gt;Add a git pre-commit hook to your git repository that will analyze the staged files for .pypirc&#xA;&lt;/h2&gt;&lt;p&gt;In order to use a git pre-commit hook, first add the file &lt;code&gt;pre-commit&lt;/code&gt; to the&#xA;.git/hooks directory in your repository:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat .git/hooks/pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#!/bin/sh&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# A git hook to check whether .pypirc files exist in the staged files list&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PYPIRC&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;git status -s&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep .pypirc&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PYPIRC&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; *&lt;span class=&#34;s2&#34;&gt;&amp;#34;.pypirc&amp;#34;&lt;/span&gt;* &lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# .pypirc is included in the staged files&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ERROR: [pre-commit hook] Aborting commit because you have the file .pypirc staged to be committed.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Remove it from the repository using \&amp;#34;git rm --cached .pypirc\&amp;#34;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;You should also move your .pypirc file to your home directory with the command \&amp;#34;mv .pypirc ~\&amp;#34;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# not found&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Make sure it is executable, if it can&amp;rsquo;t execute it won&amp;rsquo;t function correctly&#xA;in the git workflow:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ chmod &lt;span class=&#34;m&#34;&gt;744&lt;/span&gt; .git/hooks/pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ ls -l .git/hooks/pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rwxr--r--. &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; mbacchi mbacchi &lt;span class=&#34;m&#34;&gt;533&lt;/span&gt; Dec &lt;span class=&#34;m&#34;&gt;22&lt;/span&gt; 15:17 .git/hooks/pre-commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This will do a &lt;code&gt;git status&lt;/code&gt; and grep the output for the &lt;code&gt;.pypirc&lt;/code&gt; file, if found&#xA;it will return 1, which tells &lt;code&gt;git commit&lt;/code&gt; to abort.&lt;/p&gt;&#xA;&lt;p&gt;Now, test that it works as expected:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git add .pypirc&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git status&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;On branch master&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;No commits yet&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Changes to be committed:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;use &lt;span class=&#34;s2&#34;&gt;&amp;#34;git rm --cached &amp;lt;file&amp;gt;...&amp;#34;&lt;/span&gt; to unstage&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;new file:   .pypirc&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Untracked files:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;use &lt;span class=&#34;s2&#34;&gt;&amp;#34;git add &amp;lt;file&amp;gt;...&amp;#34;&lt;/span&gt; to include in what will be committed&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;LICENSE.txt&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;README.rst&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;blah/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;kerplunk/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;setup.cfg&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;setup.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git commit&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ERROR: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;pre-commit hook&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Aborting commit because you have the file .pypirc staged to be committed.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Remove it from the repository using &lt;span class=&#34;s2&#34;&gt;&amp;#34;git rm --cached .pypirc&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;You should also move your .pypirc file to your home directory with the &lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;mv .pypirc ~&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$?&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;NOTE: This does only work on the repository level, it can&amp;rsquo;t be added to your&#xA;personal git configuration to be used for all repos you work in.&lt;/p&gt;&#xA;&lt;h2 id=&#34;use-git-secrets-to-perform-analysis-of-your-current-staged-files-as-well-as-the-repositorys-commit-history-for-secret-keys&#34;&gt;Use git-secrets to perform analysis of your current staged files, as well as the repository&amp;rsquo;s commit history for secret keys&#xA;&lt;/h2&gt;&lt;p&gt;Not specific to &lt;code&gt;.pypirc&lt;/code&gt; credentials, we have also heard&#xA;&lt;a class=&#34;link&#34; href=&#34;https://www.theregister.co.uk/2017/11/14/dxc_github_aws_keys_leaked/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;stories&lt;/a&gt;&#xA;of people accidentally leaking AWS or other private keys (think SSH id_rsa&#xA;vs. id_rsa.pub files for example) on Github. Not excited about doing this&#xA;yourself? Me either. So here&amp;rsquo;s one way I&amp;rsquo;ve been analyzing both my current&#xA;git repository commits, as well as my git history.&lt;/p&gt;&#xA;&lt;p&gt;Using the AWS Labs developed&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/awslabs/git-secrets&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;git-secrets&lt;/a&gt; we can setup our&#xA;global git config to prevent strings that look like AWS Access Key ID or AWS&#xA;Secret Access Key strings to be committed to git repositories and Github.&lt;/p&gt;&#xA;&lt;p&gt;Clone and install the &lt;code&gt;git-secrets&lt;/code&gt; bash script in your personal bin tree:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname repos&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git clone git@github.com:awslabs/git-secrets.git&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Cloning into &lt;span class=&#34;s1&#34;&gt;&amp;#39;git-secrets&amp;#39;&lt;/span&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;remote: Counting objects: 250, &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;remote: Compressing objects: 100% &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;7/7&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;, &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;remote: Total &lt;span class=&#34;m&#34;&gt;250&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;delta 2&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;, reused &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;delta 0&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;, pack-reused &lt;span class=&#34;m&#34;&gt;243&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Receiving objects: 100% &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;250/250&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;, 80.42 KiB &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 1.36 MiB/s, &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Resolving deltas: 100% &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;141/141&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;, &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname repos&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ &lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; git-secrets/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname git-secrets&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cp git-secrets ~/bin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname git-secrets&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ &lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ../test-pypi/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git-secrets --help&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;usage: git secrets --scan &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;-r&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;--recursive&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--cached&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--no-index&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--untracked&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&amp;lt;files&amp;gt;...&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   or: git secrets --scan-history&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   or: git secrets --install &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;-f&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;--force&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&amp;lt;target-directory&amp;gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   or: git secrets --list &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--global&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   or: git secrets --add &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;-a&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;--allowed&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;-l&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;--literal&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--global&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &amp;lt;pattern&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   or: git secrets --add-provider &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--global&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &amp;lt;command&amp;gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;arguments...&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   or: git secrets --register-aws &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--global&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   or: git secrets --aws-provider &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&amp;lt;credentials-file&amp;gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --scan                Scans &amp;lt;files&amp;gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; prohibited patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --scan-history        Scans repo &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; prohibited patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --install             Installs git hooks &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; Git repository or Git template directory&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --list                Lists secret patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --add                 Adds a prohibited or allowed pattern, ensuring to de-dupe with existing patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --add-provider        Adds a secret provider that when called outputs secret patterns on new lines&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --aws-provider        Secret provider that outputs credentials found in an ini file&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --register-aws        Adds common AWS patterns to the git config and scans &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; ~/.aws/credentials&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -r, --recursive       --scan scans directories recursively&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --cached              --scan scans searches blobs registered in the index file&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --no-index            --scan searches files in the current directory that is not managed by Git&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --untracked           In addition to searching in the tracked files in the working tree, --scan also in untracked files&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -f, --force           --install overwrites hooks &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; the hook already exists&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -l, --literal         --add and --add-allowed patterns are escaped so that they are literal&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -a, --allowed         --add adds an allowed pattern instead of a prohibited pattern&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    --global              Uses the --global git config&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;We&amp;rsquo;re going to register the AWS secret patterns in the test-pypi repository:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git-secrets --register-aws&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git config -l &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep secrets&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;secrets.providers&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;git secrets --aws-provider&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;secrets.patterns&lt;span class=&#34;o&#34;&gt;=[&lt;/span&gt;A-Z0-9&lt;span class=&#34;o&#34;&gt;]{&lt;/span&gt;20&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;secrets.patterns&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;|&amp;#39;)?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)(&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;)?\s*(:|=&amp;gt;|=)\s*(&amp;#34;|&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;?&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;A-Za-z0-9/&lt;span class=&#34;se&#34;&gt;\+&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=]{&lt;/span&gt;40&lt;span class=&#34;o&#34;&gt;}(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;|&amp;#39;)?&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;secrets.patterns=(&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;)?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?(&amp;#34;|&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;?&lt;span class=&#34;se&#34;&gt;\s&lt;/span&gt;*&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;:&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=)&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\s&lt;/span&gt;*&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;|&amp;#39;)?[0-9]{4}\-?[0-9]{4}\-?[0-9]{4}(&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;?&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;secrets.allowed&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;AKIAIOSFODNN7EXAMPLE&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;secrets.allowed&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Now using an AWS credential file that I made invalid immediately after&#xA;creating(seriously, this won&amp;rsquo;t work if you try using it), I will scan the&#xA;repository for secrets:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat aws-credentials&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;default&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;aws_access_key_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;AKIAISITMFSJISKWFAJX&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;aws_secret_access_key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;AqIjAxOLf0KPdlLnv5azQOERkTtWo87RvlMSb3Az&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@hostname test-pypi&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git-secrets --scan -r .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./aws-credentials:2:aws_access_key_id&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;AKIAISITMFSJISKWFAJX&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./aws-credentials:3:aws_secret_access_key&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;AqIjAxOLf0KPdlLnv5azQOERkTtWo87RvlMSb3Az&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;ERROR&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Matched one or more prohibited patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Possible mitigations:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Mark &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; positives as allowed using: git config --add secrets.allowed ...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Mark &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; positives as allowed by adding regular expressions to .gitallowed at repository&lt;span class=&#34;s1&#34;&gt;&amp;#39;s root directory&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;- List your configured patterns: git config --get-all secrets.patterns&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;- List your configured allowed patterns: git config --get-all secrets.allowed&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;- List your configured allowed patterns in .gitallowed at repository&amp;#39;&lt;/span&gt;s root directory&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- Use --no-verify &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; this is a one-time &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt; positive&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This could be setup for other patterns of course but AWS is the most&#xA;straightforward and frequently committed to Github repositories. You can also&#xA;scan the commit history for previously committed secrets.&lt;/p&gt;&#xA;&lt;p&gt;Using the steps above, you could create a pre-commit hook for your git&#xA;repository to prevent secrets from being committed to git.&lt;/p&gt;&#xA;&lt;p&gt;Hope these suggestions make their way into your personal or team&amp;rsquo;s workflow to&#xA;make you more secure!&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Using dnsmasq on Asuswrt-merlin to ignore MAC addresses</title>
            <link>https://bacchi.org/posts/merlin-dnsmasq-ignore/</link>
            <pubDate>Wed, 13 Dec 2017 15:06:30 -0600</pubDate>
            <guid>https://bacchi.org/posts/merlin-dnsmasq-ignore/</guid>
            <description>&lt;p&gt;Here&amp;rsquo;s another &amp;lsquo;for posterity&amp;rsquo; type post.&lt;/p&gt;&#xA;&lt;p&gt;I forgot I had configured my WiFi router to ignore certain MAC addresses and&#xA;when I tried to put that machine on the Network today I had a rude awakening.&#xA;Using the asuswrt-merlin firmware on my RT-AC66U router, I had configured things&#xA;to allow 2 machines to be served DHCP from another PC so that I could run&#xA;Cobbler on that machine and boot/kickstart these two hosts just by hitting the&#xA;power button. But when I disconnected this Cobbler server at the beginning of my&#xA;renovation, I forgot the MAC addresses were being ignored by the router.&lt;/p&gt;&#xA;&lt;p&gt;In order to enable these MAC addresses on the WiFi router I first tried&#xA;to comment the lines out, but then instead moved the config file to root&amp;rsquo;s home&#xA;dir. Also I had to reboot the router:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;admin@RT-AC66U:/tmp/home/root# mv /jffs/configs/dnsmasq.conf.add .&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;admin@RT-AC66U:/tmp/home/root# ls&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dnsmasq.conf.add&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;admin@RT-AC66U:/tmp/home/root# more dnsmasq.conf.add&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 12/13/2017 comment these out while other dhcp server isn&amp;#39;t available&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#dhcp-host=ec:a8:6b:f4:ce:01,ignore&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#dhcp-host=ec:a8:6b:f5:a4:ed,ignore&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;admin@RT-AC66U:/tmp/home/root# ls -ltr /jffs/configs/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;admin@RT-AC66U:/tmp/home/root# reboot&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;</description>
        </item><item>
            <title>Ajax/jQuery on AWS Lambda</title>
            <link>https://bacchi.org/posts/aws-lambda-ajax-jquery/</link>
            <pubDate>Sun, 03 Dec 2017 15:10:12 -0600</pubDate>
            <guid>https://bacchi.org/posts/aws-lambda-ajax-jquery/</guid>
            <description>&lt;p&gt;I&amp;rsquo;ve been trying to learn more about AWS Lambda, at the same time learning some&#xA;web development. For a newcomer to web application development, there is the&#xA;question of whether you work on leveling up with traditional server based apps&#xA;or &amp;ldquo;serverless&amp;rdquo;, aka FaaS, aka Lambda. I wanted to try converting a simple Flask&#xA;app to Lambda, this is how I did it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-project-should-i-work-on&#34;&gt;What project should I work on?&#xA;&lt;/h2&gt;&lt;p&gt;Borrowing inspiration from Katelyn Lemay&amp;rsquo;s&#xA;&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/klemay/status/937041036647550977&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;tweet&lt;/a&gt; I started with a&#xA;straightforward application challenge from freeCodeCamp which displays quotes&#xA;when the user clicks a button. I figured this would exercise the muscles&#xA;required to do some client side scripting to experiment with how that worked on&#xA;Lambda. I also wanted to use Python vs. straight Javascript for the backend. I&#xA;found out that there are some interesting differences between running a Flask&#xA;application on a webserver vs. running it as a function on Lambda.&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s the basic application I created (again, the idea and some css borrowed&#xA;from &lt;a class=&#34;link&#34; href=&#34;https://twitter.com/klemay/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;@klemay&lt;/a&gt;):&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/flask-quotes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://github.com/mbacchi/flask-quotes&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;m using &lt;a class=&#34;link&#34; href=&#34;https://github.com/Miserlou/Zappa&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Zappa&lt;/a&gt; to deploy the Python app to&#xA;AWS Lambda. Zappa makes it easy to upload an app without having to do a lot of&#xA;preparation on AWS and packaging the bits manually. This is probably not useful&#xA;to everyone but I wanted to avoid the overhead of running Lambda in order to get&#xA;the app functioning before I learned it in detail, and Zappa helped with that.&lt;/p&gt;&#xA;&lt;h2 id=&#34;whats-so-interesting-about-that&#34;&gt;What&amp;rsquo;s so interesting about that?&#xA;&lt;/h2&gt;&lt;p&gt;This rudimentary application introduces two things to me. First I haven&amp;rsquo;t done&#xA;Ajax/jQuery in a Python application before. That&amp;rsquo;s not exciting to many folks&#xA;but when the concept is new to you its hard to work out the mechanics of the&#xA;process. Second I knew the term &lt;a class=&#34;link&#34; href=&#34;https://www.w3schools.com/js/js_htmldom.asp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Document Object&#xA;Model&lt;/a&gt; but didn&amp;rsquo;t know how to&#xA;manipulate it nor how to initiate the Ajax call.&lt;/p&gt;&#xA;&lt;p&gt;jQuery is intimidating too, but approachable if you start with the fundamentals.&#xA;Now I know $.getJSON() means roughly the same thing as $.ajax() (give or take,&#xA;its shorthand for the &lt;a class=&#34;link&#34; href=&#34;http://api.jquery.com/jquery.getjson/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ajax&lt;/a&gt; call.) But&#xA;wow is it confusing, for example what are the mechanics of not providing the&#xA;optional second parameter&#xA;(&lt;a class=&#34;link&#34; href=&#34;http://api.jquery.com/jquery.getjson/#jQuery-getJSON-url-data-success&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;data&lt;/a&gt;),&#xA;yet allowing the third optional handler (success) to work? I use that &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/flask-quotes/blob/master/static/js/quote.js#L4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;local-webserver-vs-lambda&#34;&gt;Local webserver vs. Lambda&#xA;&lt;/h2&gt;&lt;p&gt;So after getting this to work using a local Flask server, how do we transition&#xA;to serving it from AWS? I initially tried to just upload the same app with Zappa&#xA;to Lambda, but while the inital load of the page worked, any time I clicked the&#xA;&amp;ldquo;New Quote&amp;rdquo; button nothing happened. This had me furiously searching google for whether or&#xA;not I needed a full REST API to work on AWS Lambda or some other changes. I did&#xA;find out I probably needed to enable CORS on the API Gateway.&lt;/p&gt;&#xA;&lt;p&gt;There were other potential answers for why it wasn&amp;rsquo;t working that I found out&#xA;about. Did I need to use&#xA;&lt;a class=&#34;link&#34; href=&#34;http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/browser-invoke-lambda-function-example.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;lambda.invoke&lt;/a&gt;&#xA;or some similar mechanism to call the &lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/flask-quotes/blob/master/static/js/quote.js&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;new_quote&lt;/a&gt; function via the onClick action in the browser? Did I need to setup a full &lt;a class=&#34;link&#34; href=&#34;https://github.com/awslabs/aws-serverless-workshops/tree/master/WebApplication/4_RESTfulAPIs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;REST API with Cognito&lt;/a&gt;, or some other &lt;a class=&#34;link&#34; href=&#34;https://stackoverflow.com/a/32058145/4332397&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;API Gateway&lt;/a&gt; configuration that I was missing?&lt;/p&gt;&#xA;&lt;p&gt;In the end I realized I was calling the new_quote function using a relative&#xA;path, but I needed to call the full URL to the API Gateway that I already knew&#xA;from performing &amp;ldquo;zappa deploy dev&amp;rdquo; earlier, so when I ran &amp;ldquo;zappa update&amp;rdquo; it used&#xA;the same gateway. That change looked like:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname flask-quotes&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ git diff 3d9eccd static/js/quote.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;diff --git a/static/js/quote.js b/static/js/quote.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;index aa51353..5df7a88 &lt;span class=&#34;m&#34;&gt;100644&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;--- a/static/js/quote.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+++ b/static/js/quote.js&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;@@ -1,6 +1,6 @@&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; newQuote&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;document&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;.ready&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-        $.getJSON&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/new_quote&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+        $.getJSON&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;https://qlyaou0kc3.execute-api.us-east-1.amazonaws.com/dev/new_quote&amp;#39;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;             &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;data&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                 &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;#quote-text&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;.text&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;data&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;             &lt;span class=&#34;o&#34;&gt;})&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname flask-quotes&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;For reference the Zappa settings for the project were:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname flask-quotes&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat zappa_settings.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;dev&amp;#34;&lt;/span&gt;: &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;app_function&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;app.app&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_region&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;us-east-1&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;profile_name&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;default&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;project_name&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;flask-quotes&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;runtime&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;python3.6&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;s3_bucket&amp;#34;&lt;/span&gt;: &lt;span class=&#34;s2&#34;&gt;&amp;#34;zappa-p1kcu59iy&amp;#34;&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cors&amp;#34;&lt;/span&gt;: &lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Overall this was a fun challenge and although I banged my head on a few things I&#xA;learned a ton about Lambda, Javascript, Ajax, jQuery, client side scripting and&#xA;Zappa.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Using Zappa as an AWS Lambda Python Framework</title>
            <link>https://bacchi.org/posts/aws-lambda-zappa/</link>
            <pubDate>Fri, 01 Dec 2017 15:15:15 -0600</pubDate>
            <guid>https://bacchi.org/posts/aws-lambda-zappa/</guid>
            <description>&lt;p&gt;I spent a little time with &lt;a class=&#34;link&#34; href=&#34;https://github.com/Miserlou/Zappa&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Zappa&lt;/a&gt; today&#xA;which is an AWS Lambda (aka &amp;ldquo;serverless&amp;rdquo;) framework for Python. Its not hard to&#xA;create a very basic Flask application, then invoke Zappa to perform the many&#xA;manual steps of creating a Lambda function, resulting in a URL where your&#xA;application is running.&lt;/p&gt;&#xA;&lt;p&gt;First, I verified I was using Python 3.6, then I created a Python Virtual&#xA;environment and installed Zappa and then Flask.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ python3 --version&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Python 3.6.2&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ mkvenv&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ . venv/bin/activate&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ pip install zappa&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting zappa&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Using cached zappa-0.45.1-py3-none-any.whl&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting cfn_flip&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0.2.5 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;from troposphere&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1.9.0-&amp;gt;zappa&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Using cached cfn_flip-0.2.5.tar.gz&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Installing collected packages: PyYAML, six, python-dateutil, docutils, jmespath, botocore, s3transfer,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;boto3, click, placebo, kappa, durationpy, wheel, wsgi-request-logger, toml, urllib3, chardet, certifi,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;idna, requests, argcomplete, Unidecode, python-slugify, future, lambda-packages, tqdm, hjson, Werkzeug,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;base58, cfn-flip, troposphere, zappa&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; PyYAML ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; placebo ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; kappa ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; durationpy ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; wsgi-request-logger ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; toml ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; future ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; lambda-packages ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; hjson ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; cfn-flip ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py install &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; troposphere ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Successfully installed PyYAML-3.12 Unidecode-0.4.21 Werkzeug-0.12 argcomplete-1.9.2 base58-0.2.4 boto3-1.4.8&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;botocore-1.8.6 certifi-2017.11.5 cfn-flip-0.2.5 chardet-3.0.4 click-6.7 docutils-0.14 durationpy-0.5&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;future-0.16.0 hjson-3.0.1 idna-2.6 jmespath-0.9.3 kappa-0.6.0 lambda-packages-0.19.0 placebo-0.8.1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;python-dateutil-2.6.1 python-slugify-1.2.4 requests-2.18.4 s3transfer-0.1.12 six-1.11.0 toml-0.9.3&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tqdm-4.19.1 troposphere-2.1.1 urllib3-1.22 wheel-0.30.0 wsgi-request-logger-0.4.6 zappa-0.45.1&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ pip install Flask&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting Flask&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Using cached Flask-0.12.2-py2.py3-none-any.whl&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Requirement already satisfied: click&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2.0 in ./venv/lib/python3.6/site-packages &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;from Flask&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting itsdangerous&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0.21 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;from Flask&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Using cached itsdangerous-0.24.tar.gz&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting Jinja2&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2.4 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;from Flask&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Downloading Jinja2-2.10-py2.py3-none-any.whl &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;126kB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    100% &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 133kB 2.6MB/s&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Requirement already satisfied: Werkzeug&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0.7 in ./venv/lib/python3.6/site-packages &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;from Flask&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Collecting MarkupSafe&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0.23 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;from Jinja2&amp;gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;2.4-&amp;gt;Flask&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Using cached MarkupSafe-1.0.tar.gz&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Building wheels &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; collected packages: itsdangerous, MarkupSafe&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py bdist_wheel &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; itsdangerous ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Stored in directory: /home/user1/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Running setup.py bdist_wheel &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; MarkupSafe ... &lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Stored in directory: /home/user1/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Successfully built itsdangerous MarkupSafe&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Flask&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Successfully installed Flask-0.12.2 Jinja2-2.10 MarkupSafe-1.0 itsdangerous-0.24&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;I created a very simple Hello World app in Flask(borrowed from the Flask&#xA;quickstart &lt;a class=&#34;link&#34; href=&#34;http://flask.pocoo.org/docs/0.12/quickstart/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;here&lt;/a&gt;):&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat app.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;from flask import Flask&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;app&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; Flask&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;__name__&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;@app.route&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;def hello_world&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Hello, Lambda users!&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;With the Flask &amp;ldquo;application&amp;rdquo; in my current directory, I was able to run &amp;ldquo;zappa&#xA;init&amp;rdquo; to get everything built. It asks some questions:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;60&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;61&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;62&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;63&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;64&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ zappa init&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;███████╗ █████╗ ██████╗ ██████╗  █████╗&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;╚══███╔╝██╔══██╗██╔══██╗██╔══██╗██╔══██╗&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  ███╔╝ ███████║██████╔╝██████╔╝███████║&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ███╔╝  ██╔══██║██╔═══╝ ██╔═══╝ ██╔══██║&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;███████╗██║  ██║██║     ██║     ██║  ██║&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝     ╚═╝  ╚═╝&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Welcome to Zappa!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Zappa is a system &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; running server-less Python web applications on AWS Lambda and AWS API Gateway.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;This &lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;init&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt; will &lt;span class=&#34;nb&#34;&gt;help&lt;/span&gt; you create and configure your new Zappa deployment.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Let&lt;span class=&#34;s1&#34;&gt;&amp;#39;s get started!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;Your Zappa configuration can support multiple production stages, like &amp;#39;&lt;/span&gt;dev&lt;span class=&#34;s1&#34;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;staging&lt;span class=&#34;s1&#34;&gt;&amp;#39;, and &amp;#39;&lt;/span&gt;production&lt;span class=&#34;s1&#34;&gt;&amp;#39;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;What do you want to call this environment (default &amp;#39;&lt;/span&gt;dev&lt;span class=&#34;s1&#34;&gt;&amp;#39;):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;AWS Lambda and API Gateway are only available in certain regions. Let&amp;#39;&lt;/span&gt;s check to make sure you have a profile&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; up in one that will work.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Okay, using profile default!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Your Zappa deployments will need to be uploaded to a private S3 bucket.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If you don&lt;span class=&#34;s1&#34;&gt;&amp;#39;t have a bucket yet, we&amp;#39;&lt;/span&gt;ll create one &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; you too.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt; you want call your bucket? &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;default &lt;span class=&#34;s1&#34;&gt;&amp;#39;zappa-fysh7qlsu&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;It looks like this is a Flask application.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What&lt;span class=&#34;s1&#34;&gt;&amp;#39;s the modular path to your app&amp;#39;&lt;/span&gt;s &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;?&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;This will likely be something like &lt;span class=&#34;s1&#34;&gt;&amp;#39;your_module.app&amp;#39;&lt;/span&gt;.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;We discovered: app.app&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Where is your app&lt;span class=&#34;s1&#34;&gt;&amp;#39;s function? (default &amp;#39;&lt;/span&gt;app.app&lt;span class=&#34;s1&#34;&gt;&amp;#39;):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;You can optionally deploy to all available regions in order to provide fast global service.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;If you are using Zappa for the first time, you probably don&amp;#39;&lt;/span&gt;t want to &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt; this!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Would you like to deploy this application globally? &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;default &lt;span class=&#34;s1&#34;&gt;&amp;#39;n&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;y/n/&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;p&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;rimary&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: n&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Okay, here&lt;span class=&#34;s1&#34;&gt;&amp;#39;s your zappa_settings.json:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;{&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    &amp;#34;dev&amp;#34;: {&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;app_function&amp;#34;: &amp;#34;app.app&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;aws_region&amp;#34;: &amp;#34;us-east-1&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;profile_name&amp;#34;: &amp;#34;default&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;project_name&amp;#34;: &amp;#34;hello&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;runtime&amp;#34;: &amp;#34;python3.6&amp;#34;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        &amp;#34;s3_bucket&amp;#34;: &amp;#34;zappa-fysh7qlsu&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    }&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;}&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;Does this look okay? (default &amp;#39;&lt;/span&gt;y&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;y/n&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: y&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Done! Now you can deploy your Zappa application by executing:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;$ zappa deploy dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;After that, you can update your application code with:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;$ zappa update dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;To learn more, check out our project page on GitHub here: https://github.com/Miserlou/Zappa&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;and stop by our Slack channel here: https://slack.zappa.io&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Enjoy!,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ~ Team Zappa!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Simple, right? After that I deployed the application:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ zappa deploy dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Calling deploy &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; stage dev..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Creating hello-dev-ZappaLambdaExecutionRole IAM Role..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Creating zappa-permissions policy on hello-dev-ZappaLambdaExecutionRole IAM Role.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Downloading and installing dependencies..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; - &lt;span class=&#34;nv&#34;&gt;sqlite&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;python36: Using precompiled lambda package&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Packaging project as zip.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Uploading hello-dev-1512173647.zip &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;5.7MiB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;100%&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;██████████████████████████████████████████████████████████████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 6.02M/6.02M &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;00:01&amp;lt;00:00, 3.63MB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Scheduling..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Scheduled hello-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; minutes&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Uploading hello-dev-template-1512173657.json &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;1.6KiB&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;100%&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;██████████████████████████████████████████████████████████████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 1.59K/1.59K &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;00:00&amp;lt;00:00, 10.7KB/s&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Waiting &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; stack hello-dev to create &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;this can take a bit&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;100%&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;████████████████████████████████████████████████████████████████████████████████████████████████&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 4/4 &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;00:15&amp;lt;00:00,  5.89s/res&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Deploying API Gateway..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Deployment complete!: https://te5p0mowh3.execute-api.us-east-1.amazonaws.com/dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;After uploading, you can use curl to connect:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ curl https://te5p0mowh3.execute-api.us-east-1.amazonaws.com/dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Hello, Lambda users!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;And here&amp;rsquo;s the AWS console showing the invocation count of the lambda function:&lt;/p&gt;&#xA;&lt;img src=&#34;hello-dev.png&#34;&gt;&#xA;&lt;p&gt;To remove the test Lambda I created, use &amp;ldquo;zappa undeploy&amp;rdquo;:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;venv&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user1@hostname hello&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ zappa undeploy dev&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Calling undeploy &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; stage dev..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Are you sure you want to undeploy? &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;y/n&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; y&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Deleting API Gateway..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Waiting &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; stack hello-dev to be deleted..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Unscheduling..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Unscheduled hello-dev-zappa-keep-warm-handler.keep_warm_callback.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Deleting Lambda &lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;..&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Done!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;</description>
        </item><item>
            <title>Docker error IPv4 forwarding is disabled</title>
            <link>https://bacchi.org/posts/docker-ipv4-forwarding-disabled/</link>
            <pubDate>Fri, 29 Sep 2017 15:29:29 -0600</pubDate>
            <guid>https://bacchi.org/posts/docker-ipv4-forwarding-disabled/</guid>
            <description>&lt;p&gt;Another common error is that the docker daemon cannot connect to the outside&#xA;world to download anything during build time. This can be corrected in a number&#xA;of ways, but I have done it thusly.&#xA;The error is commonly encountered as you are trying to build a docker image, the&#xA;warning &lt;strong&gt;&amp;quot;[Warning] IPv4 forwarding is disabled. Networking will not work.&amp;quot;&lt;/strong&gt;&#xA;tells you that you need to enable IPv4 forwarding.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Step &lt;span class=&#34;m&#34;&gt;10&lt;/span&gt; : RUN &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; -x &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; pip install -U pip setuptools &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; pip install -r /tmp/requirements/dev.txt ...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ---&amp;gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Warning&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; IPv4 forwarding is disabled. Networking will not work.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; ---&amp;gt; Running in b4b9fb134518&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ pip install -U pip setuptools&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Retrying &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Retry&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;4, &lt;span class=&#34;nv&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;None, &lt;span class=&#34;nv&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;None, &lt;span class=&#34;nv&#34;&gt;redirect&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;None&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt; after connection&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;broken by NewConnectionError&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;Failed to establish a new connection: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Errno -2&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Name or service not known,&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: /simple/pip/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;First setup the docker daemon config file to have a DNS server or two available&#xA;to make requests of:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat /etc/docker/daemon.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;dns&amp;#34;&lt;/span&gt;: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;10.1.1.254&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;8.8.8.8&amp;#34;&lt;/span&gt;,&lt;span class=&#34;s2&#34;&gt;&amp;#34;10.115.1.220&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;live-restore&amp;#34;&lt;/span&gt;: &lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;You can see above that I have multiple local(intranet vpn) nameservers as well&#xA;as the Google DNS server 8.8.8.8. This would require a docker daemon restart&#xA;to be enabled(systemctl restart docker), but we will wait for the next step to&#xA;be completed before performing that daemon restart.&lt;/p&gt;&#xA;&lt;p&gt;Now we must enable forwarding between interfaces in the kernel. This will&#xA;be done using the sysctl parameter net.ipv4.ip_forward. It can be set once from&#xA;the command line but upon system restart will not be retained, so I set it in&#xA;the docker sysctl file:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat  /usr/lib/sysctl.d/99-docker.conf&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;fs.may_detach_mounts&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;net.ipv4.ip_forward&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This will then set the net.ipv4.ip_forward variable to true every time the docker&#xA;daemon is started or restarted.&lt;/p&gt;&#xA;&lt;p&gt;Now we can perform that restart and make sure both of these changes are enabled.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ sudo systemctl restart docker&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;</description>
        </item><item>
            <title>Docker socket group permissions</title>
            <link>https://bacchi.org/posts/docker-socket-group-permission/</link>
            <pubDate>Thu, 28 Sep 2017 15:32:12 -0600</pubDate>
            <guid>https://bacchi.org/posts/docker-socket-group-permission/</guid>
            <description>&lt;p&gt;I always forget this when trying to run docker as a non-root user, so documenting&#xA;it for posterity.&lt;/p&gt;&#xA;&lt;p&gt;If you get an error connecting to the docker daemon as a standard user, such as:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ docker ps&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Cannot connect to the Docker daemon. Is the docker daemon running on this host?&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;And you&amp;rsquo;re sure your docker daemon is actually up:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ sudo systemctl status docker&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;● docker.service - Docker Application Container Engine&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   Loaded: loaded &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;/usr/lib/systemd/system/docker.service&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; disabled&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; vendor preset: disabled&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   Active: active &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;running&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; since Thu 2017-09-28 17:08:49 EDT&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; 8min ago&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     Docs: http://docs.docker.com&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Main PID: &lt;span class=&#34;m&#34;&gt;3375&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;dockerd-current&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   CGroup: /system.slice/docker.service&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           ├─3375 /usr/bin/dockerd-current --add-runtime docker-runc&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/libexec/docker/docker-runc-current --defaul...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           └─3380 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock -...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:48 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.265161468-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Graph ...onds&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:48 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.265978330-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;warning &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;mou...ound&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:48 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.266206907-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Loadin...art.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:48 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: ......time&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.473174045-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;...true&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:48 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.840829045-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Defaul...ress&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:49 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.998079496-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Loadin...one.&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:49 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.998264761-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Daemon...tion&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08:49 centos7 dockerd-current&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;3375&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;: &lt;span class=&#34;nv&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2017-09-28T17:08:48.998296244-04:00&amp;#34;&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info &lt;span class=&#34;nv&#34;&gt;msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Docker....12.6&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;Sep 28 17:08:49 centos7 systemd[1]: Started Docker Application Container Engine.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;Sep 28 17:08:49 centos7 dockerd-current[3375]: time=&amp;#34;&lt;/span&gt;2017-09-28T17:08:49.028663143-04:00&lt;span class=&#34;s2&#34;&gt;&amp;#34; level=info msg=&amp;#34;&lt;/span&gt;API li...sock&lt;span class=&#34;s2&#34;&gt;&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;Hint: Some lines were ellipsized, use -l to show in full.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;The solution I&amp;rsquo;ve found most straightforward (but rather apathetic on the security&#xA;front) is to change the permissions of the docker.sock file, but your&#xA;userid must be in the dockerroot group:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ grep docker /etc/group&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dockerroot:x:990:mbacchi&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$  ls -ltr /var/run/docker.sock&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;srw-rw----. &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; root root &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; Sep &lt;span class=&#34;m&#34;&gt;28&lt;/span&gt; 17:08 /var/run/docker.sock&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$  sudo chown root:dockerroot /var/run/docker.sock&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mbacchi@centos7 ~&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ docker ps&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;</description>
        </item><item>
            <title>Empty greenhouse.io job posts</title>
            <link>https://bacchi.org/posts/greenhouse-iframe/</link>
            <pubDate>Thu, 24 Aug 2017 15:34:16 -0600</pubDate>
            <guid>https://bacchi.org/posts/greenhouse-iframe/</guid>
            <description>&lt;p&gt;I was interested in a job description a company posted via Twitter, but I&#xA;couldn&amp;rsquo;t view the text and didn&amp;rsquo;t understand why. This wasn&amp;rsquo;t the first time&#xA;this happened so decided to dig into the problem and determine if it was an&#xA;issue with my environment or the website.&#xA;My initial assumption was there was some problem with the company&amp;rsquo;s website. But&#xA;they must test that these postings are visible occasionally right? Looking at&#xA;the page source there was no job description content, but rather this URL:&lt;/p&gt;&#xA;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://app.greenhouse.io/embed/job_board/js?for=fastly&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://app.greenhouse.io/embed/job_board/js?for=fastly&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Well this was a little unexpected but not totally surprising. They use a service&#xA;to host all their job openings and then embed it in an iframe on their site.&#xA;Could the iframe be a problem? I did a google search and found no hits&#xA;whatsoever. How could I be the first person to encounter this? I&amp;rsquo;m not an&#xA;experienced web developer but have been teaching myself some Python Pyramid&#xA;stuff lately. Lets see what the developer console says about the page.  It&#xA;indicated the error:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET https://app.greenhouse.io/embed/job_board/js?for&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;fastly net::ERR_BLOCKED_BY_CLIENT&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;This told me that the server wasn&amp;rsquo;t the problem but instead my client was&#xA;blocking the content. What now? Oh, ya, I have extensions such as Fair Adblocker&#xA;and Privacy Badger installed to prevent sites from tracking me. I looked to see&#xA;if those were blocking any greenhouse.io sites and sure enough, there were 4&#xA;URLs being blocked:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;app.greenhouse.io&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;boards.greenhouse.io&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;boards-use1-cdn.greenhouse.io&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;boards-api.greenhouse.io&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Once I disabled full blocking on those sites, and only enabled blocking of&#xA;cookies, I was able to view the iframe with the job description.&lt;/p&gt;&#xA;&lt;p&gt;Hope this helps somebody (maybe even me) sometime in the future.&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Using Docker to create an ad hoc Yum repository</title>
            <link>https://bacchi.org/posts/docker-yumrepo/</link>
            <pubDate>Fri, 27 Jan 2017 15:37:47 -0600</pubDate>
            <guid>https://bacchi.org/posts/docker-yumrepo/</guid>
            <description>&lt;p&gt;Docker can be used to quickly create and serve many services, one such example&#xA;is serving RPMs via Yum in an ad hoc manner.  Have you ever wanted to create a Yum&#xA;repository consisting of some RPMs very quickly to be used for testing&#xA;purposes?  I did this week.  I could have created the repo and installed a web&#xA;server on any machine.  But what if we had the RPMs and the Yum repository&#xA;both dynamically hosted on the servers where the Chef cookbooks were being&#xA;executed?  That was my goal for the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/docker-yumrepo&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;docker-yumrepo&lt;/a&gt; project, enabling&#xA;the creation of an ad hoc Yum repository.&lt;/p&gt;&#xA;&lt;p&gt;This tool has prerequisites that createrepo_c and docker to be installed prior.&#xA;You will place the RPMs you want in the repo in the src directory(after running&#xA;&amp;lsquo;make src&amp;rsquo;), then it will build and runs a docker image.  This will serve the&#xA;repository on port 80 (so make sure you don&amp;rsquo;t have another webserver on&#xA;port 80.)  Voila, you now have a yum repository accessible on the URL:&lt;/p&gt;&#xA;&lt;p&gt;http://localhost/docker-yumrepo&lt;/p&gt;&#xA;&lt;p&gt;To use this you can install a Yum repo config file such as:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;user@centos docker-yumrepo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;$ cat /etc/yum.repos.d/docker-yumrepo.repo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;docker-yumrepo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;docker-yumrepo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;baseurl&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://localhost/docker-yumrepo&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;enabled&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;gpgcheck&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Instructions are also available in the&#xA;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mbacchi/docker-yumrepo/blob/master/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;README&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Enjoy!&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Vagrant NFS synced_folders</title>
            <link>https://bacchi.org/posts/vagrant-nfs-synced-folders/</link>
            <pubDate>Sun, 15 Jan 2017 15:40:23 -0600</pubDate>
            <guid>https://bacchi.org/posts/vagrant-nfs-synced-folders/</guid>
            <description>&lt;p&gt;After upgrading to Fedora 25 yesterday, Vagrant 1.8.5 in the updates repo was&#xA;unusable with VirtualBox for 2 reasons:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;The newest centos/7 box didn&amp;rsquo;t use vbox guest additions for shared folders, forcing the use of NFS&lt;/li&gt;&#xA;&lt;li&gt;Vagrant issue &lt;a class=&#34;link&#34; href=&#34;https://github.com/mitchellh/vagrant/issues/8138&#34;  title=&#34;Issue 8138&#34;&#xA;     target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;8138&lt;/a&gt; which is not fixed in the newest RPM from Vagrant means I had to install from source.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;This required two workarounds in my Vagrantfile:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;The setting config.vm.synced_folder requires the &amp;rsquo;type: &amp;quot;nfs&amp;quot;&amp;rsquo; parameter.&lt;/li&gt;&#xA;&lt;li&gt;The config.vm.provision section required the &amp;lsquo;chef.synced_folder_type = &amp;quot;nfs&amp;quot;&amp;rsquo; parameter.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;This looks like the following now:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;network&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;private_network&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;10.10.10.12&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;synced_folder&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;django3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/django3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;nfs&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;berkshelf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;enabled&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kp&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;provision&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:chef_solo&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;synced_folder_type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;nfs&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cookbooks_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cookbooks&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chef&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;roles_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;roles&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;</description>
        </item></channel>
</rss>
