build last two commits

This commit is contained in:
2026-03-24 10:11:20 -07:00
parent ff9eb09838
commit 21e3dca187
278 changed files with 3912 additions and 3366 deletions

View File

@ -15,7 +15,7 @@
<meta property="og:site_name" content="hello hello">
<meta property="og:image" content="/img/azure-locations.jpg">
<meta property="og:image:alt" content="A Linux terminal. There is a fun rainbow flag in ascii art at the top, and then the user has called a command asking Azure for a list of resources applicable to a specific resource type">
<meta property="og:image:alt" content="A Linux terminal. There is a fun rainbow flag in ascii art at the top, and then the user has called a command asking Azure for a list of locations applicable to a specific resource type. The output is lengthy.">
<meta name="generator" content="Eleventy v3.1.2">
@ -623,6 +623,8 @@ a:active {
a.ha,
span.ha-placeholder {
color: var(--color-pink);
font-size: .8em;
vertical-align: .1em;
}
span.ha-placeholder {
opacity: .55;
@ -1425,7 +1427,7 @@ export { HeadingAnchors }</script>
</div>
<img src="/img/azure-locations.jpg" alt="A Linux terminal. There is a fun rainbow flag in ascii art at the top, and then the user has called a command asking Azure for a list of resources applicable to a specific resource type" loading="lazy" decoding="async" width="1000" height="827">
<img src="/img/azure-locations.jpg" alt="A Linux terminal. There is a fun rainbow flag in ascii art at the top, and then the user has called a command asking Azure for a list of locations applicable to a specific resource type. The output is lengthy." loading="lazy" decoding="async" width="1000" height="827">
<h2 id="context">context</h2>
@ -1474,7 +1476,7 @@ export { HeadingAnchors }</script>
<li>All referenced resource types</li>
<li>All referenced modules</li>
</ol>
<h3 id="grep">grep</h3>
<h3 id="grep"><code>grep</code></h3>
<p>Resources and modules both have patterns in how they are declared. Thankfully, they're pretty simple regexes. <code>grep</code> will spit out lines in a file that match a given regex.</p>
<pre class="language-sh"><code class="language-sh"><span class="token comment"># this gets us strings like</span>
<span class="token comment"># resource resourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = {</span>
@ -1483,7 +1485,7 @@ export { HeadingAnchors }</script>
<span class="token comment"># this gets us strings like</span>
<span class="token comment"># module vm '../../modules/vm/main.bicep' = {</span>
<span class="token function">grep</span> <span class="token parameter variable">-E</span> <span class="token string">"^module "</span> <span class="token string">"<span class="token variable">$file</span>"</span></code></pre>
<h3 id="cut">cut</h3>
<h3 id="cut"><code>cut</code></h3>
<p>From there, let's use <code>cut</code> to strip off the parts we don't want.</p>
<pre class="language-sh"><code class="language-sh"><span class="token comment"># this gets us strings like</span>
<span class="token comment"># Microsoft.Resources/resourceGroups</span>
@ -1496,14 +1498,14 @@ export { HeadingAnchors }</script>
<span class="token function">grep</span> <span class="token parameter variable">-E</span> <span class="token string">"^module "</span> <span class="token string">"<span class="token variable">$file</span>"</span> <span class="token punctuation">\</span>
<span class="token operator">|</span> <span class="token function">cut</span> <span class="token parameter variable">-d</span> <span class="token string">"'"</span> <span class="token parameter variable">-f</span> <span class="token number">2</span> -</code></pre>
<p>These calls are a little opaque. <code>-d</code> sets a <strong>delimiter</strong> (what to split on). <code>-f</code> picks a <strong>field</strong> to return, numbered from 1.</p>
<h3 id="mapfile">mapfile</h3>
<h3 id="mapfile"><code>mapfile</code></h3>
<p>We'll save these values to variables. <code>mapfile</code> reads a file, putting each line into a new array element. <code>-t</code> <strong>trims</strong> newline characters. The <code>&lt;</code>s do some redirection, and yes, the space between them <em>matters</em>.</p>
<pre class="language-sh"><code class="language-sh"><span class="token builtin class-name">mapfile</span> <span class="token parameter variable">-t</span> resources <span class="token operator">&lt;</span> <span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token function">grep</span> <span class="token parameter variable">-E</span> <span class="token string">"^resource "</span> <span class="token string">"<span class="token variable">$file</span>"</span> <span class="token punctuation">\</span>
<span class="token operator">|</span> <span class="token function">cut</span> <span class="token parameter variable">-d</span> <span class="token string">"'"</span> <span class="token parameter variable">-f</span> <span class="token number">2</span> - <span class="token punctuation">\</span>
<span class="token operator">|</span> <span class="token function">cut</span> <span class="token parameter variable">-d</span> <span class="token string">"@"</span> <span class="token parameter variable">-f</span> <span class="token number">1</span> -<span class="token punctuation">)</span>
<span class="token builtin class-name">mapfile</span> <span class="token parameter variable">-t</span> modules <span class="token operator">&lt;</span> <span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token function">grep</span> <span class="token parameter variable">-E</span> <span class="token string">"^module "</span> <span class="token string">"<span class="token variable">$file</span>"</span> <span class="token punctuation">\</span>
<span class="token operator">|</span> <span class="token function">cut</span> <span class="token parameter variable">-d</span> <span class="token string">"'"</span> <span class="token parameter variable">-f</span> <span class="token number">2</span> -<span class="token punctuation">)</span></code></pre>
<h3 id="dirname-and-more">dirname (&amp; more)</h3>
<h3 id="dirname-and-more"><code>dirname</code> (&amp; more)</h3>
<p>We can't just stop there. We need to search each module in turn. Using <code>dirname</code>, we can get the directory of the file we're searching, then append the relative module path.</p>
<pre class="language-sh"><code class="language-sh"><span class="token function-name function">get_resources</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment"># ... grep, cut, etc ...</span>
@ -1518,7 +1520,7 @@ export { HeadingAnchors }</script>
<p>A lot just happened there besides <code>dirname</code>. <code>{modules[@]}</code> is all the array elements (as opposed to just <code>$modules</code>, which evaluates to the first element). <code>${#modules[@]}</code>, on the other hand - note the pound sign - is the number of elements in the array.</p>
<p>Additionally, <code>mapfile</code> usually writes from index 0 onwards. But with the <code>-O</code> argument, we can specify an <strong>origin</strong>. By setting the starting point to the length of the array, we append to the array rather than writing over existing data.</p>
<p>Finally, we got some recursion going! <code>get_resources</code> calls <code>get_resources</code> for every module found.</p>
<h3 id="the-get-resources-function">the get_resources function</h3>
<h3 id="the-get-resources-function">the <code>get_resources</code> function</h3>
<p>So far, our code looks like this:</p>
<pre class="language-sh"><code class="language-sh"><span class="token function-name function">get_resources</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token builtin class-name">mapfile</span> <span class="token parameter variable">-t</span> resources <span class="token operator">&lt;</span> <span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token function">grep</span> <span class="token parameter variable">-E</span> <span class="token string">"^resource "</span> <span class="token string">"<span class="token variable">$file</span>"</span> <span class="token punctuation">\</span>
@ -1540,11 +1542,11 @@ export { HeadingAnchors }</script>
<h2 id="finding-locations">finding locations</h2>
<p>Now we need to use these resource types to get available locations. First, actually call our function from above. We'll assume we're in a directory with a top-level <code>main.bicep</code> file.</p>
<pre class="language-sh"><code class="language-sh"><span class="token builtin class-name">mapfile</span> <span class="token parameter variable">-t</span> resources <span class="token operator">&lt;</span> <span class="token operator">&lt;</span><span class="token punctuation">(</span>get_resources <span class="token string">"main.bicep"</span><span class="token punctuation">)</span></code></pre>
<h3 id="sort">sort</h3>
<h3 id="sort"><code>sort</code></h3>
<p>Does sorting matter? Not really, but <code>sort</code> has a useful feature, <code>-u</code>, which returns <strong>u</strong>nique items (aka, it deduplicates). Looking up the same resource type twice slows us down.</p>
<pre class="language-sh"><code class="language-sh"><span class="token builtin class-name">mapfile</span> <span class="token parameter variable">-t</span> resources <span class="token operator">&lt;</span> <span class="token operator">&lt;</span><span class="token punctuation">(</span>get_resources <span class="token string">"main.bicep"</span> <span class="token operator">|</span> <span class="token function">sort</span> -u<span class="token punctuation">)</span></code></pre>
<p><code>sort</code> is one reason it helps to have newlines as delimiters - it expects that.</p>
<h3 id="az">az</h3>
<h3 id="az"><code>az</code></h3>
<p>We'll use <code>az</code> to list <em>all</em> the locations - just to give ourselves a starting point. You could also use the locations for the first resource type.</p>
<pre class="language-sh"><code class="language-sh"><span class="token builtin class-name">mapfile</span> <span class="token parameter variable">-t</span> locations <span class="token operator">&lt;</span> <span class="token operator">&lt;</span><span class="token punctuation">(</span>az account list-locations <span class="token parameter variable">--query</span> <span class="token string">"[].displayName"</span> <span class="token punctuation">\</span>
<span class="token parameter variable">--out</span> tsv<span class="token punctuation">)</span></code></pre>
@ -1553,7 +1555,7 @@ export { HeadingAnchors }</script>
<span class="token parameter variable">--query</span> <span class="token string">"resourceTypes[?resourceType=='<span class="token variable">$resourceType</span>'].locations | [0]"</span> <span class="token punctuation">\</span>
<span class="token parameter variable">--out</span> tsv<span class="token punctuation">)</span></code></pre>
<p><code>--out tsv</code> means we will get a list with no decoration whatsoever - it's vital for programmatic handling of <code>az</code> command output.</p>
<h3 id="cut-again">cut (again)</h3>
<h3 id="cut-again"><code>cut</code> (again)</h3>
<p>We'll need to get those <code>$namespace</code> and <code>$resourceType</code> variables. <code>cut</code> comes back in handy:</p>
<pre class="language-sh"><code class="language-sh"><span class="token comment"># remember, $resource is something like Microsoft.Resources/resourceGroups</span>
@ -1564,7 +1566,7 @@ export { HeadingAnchors }</script>
<span class="token comment"># this gets us strings like</span>
<span class="token comment"># resourceGroups</span>
<span class="token assign-left variable">resourceType</span><span class="token operator">=</span><span class="token variable"><span class="token variable">$(</span><span class="token builtin class-name">echo</span> <span class="token string">"<span class="token variable">$resource</span>"</span> <span class="token operator">|</span> <span class="token function">cut</span> <span class="token parameter variable">-d</span> <span class="token string">"/"</span> <span class="token parameter variable">-f</span> <span class="token number">2</span> -<span class="token variable">)</span></span></code></pre>
<h3 id="comm">comm</h3>
<h3 id="comm"><code>comm</code></h3>
<p>Okay, we can get locations. How do we handle finding their intersection?</p>
<p><code>comm</code> to the rescue. It finds <strong>common</strong> lines between two <em>sorted</em> files. Its default output is three columns - lines only in file 1, lines only in file 2, and lines common to both. We can suppress the first two columns with <code>-12</code>.</p>
<p><code>comm</code> expects files, so we'll reuse our redirection <code>&lt;(someCommand)</code> from earlier.</p>
@ -1578,7 +1580,7 @@ export { HeadingAnchors }</script>
<span class="token keyword">then</span>
<span class="token comment"># handle</span>
<span class="token keyword">fi</span></code></pre>
<h3 id="tee">tee</h3>
<h3 id="tee"><code>tee</code></h3>
<p>We'll print the locations to the shell. We can even use <code>tee</code> to print them to a file for good measure:</p>
<pre class="language-sh"><code class="language-sh"><span class="token keyword">for</span> <span class="token for-or-select variable">location</span> <span class="token keyword">in</span> <span class="token string">"<span class="token variable">${locations<span class="token punctuation">[</span>@<span class="token punctuation">]</span>}</span>"</span><span class="token punctuation">;</span> <span class="token keyword">do</span> <span class="token builtin class-name">echo</span> <span class="token string">"<span class="token variable">$location</span>"</span><span class="token punctuation">;</span> <span class="token keyword">done</span> <span class="token operator">|</span> <span class="token function">tee</span> locations.txt</code></pre>
<h3 id="the-location-code">the location code</h3>
@ -1697,11 +1699,11 @@ export { HeadingAnchors }</script>
<ol id="postlist">
<li class="post">
<a class="postlink" href="/backend-accessibility/">
<a class="postlink" href="/moving-images/">
<img src="/img/camelCase-print.jpg" alt="A carved stamp next to its print. The print reads &#39;#camelCase&#39; in a slightly formal-looking italic font." loading="lazy" decoding="async" width="1000" height="750">
<img src="/img/cormorant.jpg" alt="Image unrelated to post. A cormorant, a type of black waterfowl, poses with wings spread on a buoy in Puget Sound. Off to the left, another bird floats." loading="lazy" decoding="async" width="1000" height="666">
<h2 data-ha-exclude="" id="backend-accessibility">backend accessibility</h2>
<h2 data-ha-exclude="" id="moving-images">moving images</h2>
<ul class="postlist-tags">
<li>software</li>
@ -1711,26 +1713,14 @@ export { HeadingAnchors }</script>
</li>
<li class="post">
<a class="postlink" href="/my-favorite-git-flag/">
<a class="postlink" href="/brookes-notebook/">
<img src="/img/shelf-mushrooms.jpg" alt="Picture unrelated to post. Creamy beige shelf mushrooms on a mossy tree trunk." loading="lazy" decoding="async" width="1000" height="666">
<img src="/img/brooke-notebook.jpg" alt="A six panel collage showing the covers, endpapers, and some of the pages of a notebook." loading="lazy" decoding="async" width="1000" height="1500">
<h2 data-ha-exclude="" id="my-favorite-git-flag">my favorite git flag</h2>
<h2 data-ha-exclude="" id="brookes-notebook">brooke&#39;s notebook</h2>
<ul class="postlist-tags">
<li>software</li>
</ul>
</a>
</li>
<li class="post">
<a class="postlink" href="/recommendations-and-favorites/">
<img src="/img/metal-curl.jpg" alt="Photo unrelated to content of post. A metal sculpture rises up and curls into itself, with similar sculptures around it. Looking through the very center of the curve, an any-gender bathroom sign is visible." loading="lazy" decoding="async" width="1000" height="666">
<h2 data-ha-exclude="" id="recommendations-and-favorites">recommendations &amp; favorites</h2>
<ul class="postlist-tags">
<li>book</li>
<li>highlight</li>
@ -1738,6 +1728,22 @@ export { HeadingAnchors }</script>
</a>
</li>
<li class="post">
<a class="postlink" href="/designing-a-bag/">
<img src="/img/shoelace-bag.jpg" alt="a 3-image collage showcasing a leather crossbody bag. the leather body is brown and fairly simple. up the narrow sides, rope is laced through grommets in a style resembling a shoe lacing. the rope forms the handle and loops seamlessly through the other side of the bag, joining in one point in a figure-8 follow-through knot. At the bottom corners, there are small diagonal lines of stitching to give the bag a small lip around the base and ensure small objects don&#39;t slide out." loading="lazy" decoding="async" width="1000" height="1777">
<h2 data-ha-exclude="" id="designing-a-bag">designing a bag</h2>
<ul class="postlist-tags">
<li>leather</li>
<li>software</li>
</ul>
</a>
</li>
</ol>
</section>
@ -1769,6 +1775,6 @@ export { HeadingAnchors }</script>
</footer>
<!-- This page `/azure-locations-and-file-crawling/` was built on 2026-03-24T16:54:11.082Z -->
<!-- This page `/azure-locations-and-file-crawling/` was built on 2026-03-24T17:11:02.656Z -->
</body>
</html>