<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://stackql.io/blog/tutorials</id>
    <title>StackQL Blog - Tutorials</title>
    <updated>2026-09-17T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://stackql.io/blog/tutorials"/>
    <subtitle>Practical walkthroughs for cloud operations, security and automation using SQL</subtitle>
    <icon>https://stackql.io/favicon.ico</icon>
    <rights>Copyright © 2026 StackQL Studios</rights>
    <entry>
        <title type="html"><![CDATA[Declarative cloud stacks in SQL: an intro to stackql-deploy]]></title>
        <id>https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy</id>
        <link href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy"/>
        <updated>2026-09-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tutorial 2 in this series showed the query-before-mutation pattern by hand. Query live state, apply a policy gate, mutate what's out of policy, verify convergence. Every step was a SQL statement typed into a shell. The pattern held, but the shape was low-level. One resource at a time. One session at a time. No structure for repeating it across environments or holding it right over time.]]></summary>
        <content type="html"><![CDATA[<p>Tutorial 2 in this series showed the query-before-mutation pattern by hand. Query live state, apply a policy gate, mutate what's out of policy, verify convergence. Every step was a SQL statement typed into a shell. The pattern held, but the shape was low-level. One resource at a time. One session at a time. No structure for repeating it across environments or holding it right over time.</p>
<p><code>stackql-deploy</code> takes that pattern and turns it into a framework. Define your resources once as SQL-anchored files, declare them in a manifest, and let the framework run the exists check, the create-or-update, the state check, and the exports as a single build. Same underlying pattern, now something a team can operate at scale.</p>
<p>This tutorial walks through the tool end to end. What it is, how a project is shaped, how a single resource is defined, and how the whole thing runs against a real Google Cloud project.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-stackql-deploy-is">What stackql-deploy is<a href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy#what-stackql-deploy-is" class="hash-link" aria-label="Direct link to What stackql-deploy is" title="Direct link to What stackql-deploy is" translate="no">​</a></h2>
<p><code>stackql-deploy</code> is a model-driven deployment framework built on top of stackql. You describe cloud resources as SQL query files (each with a few named blocks called anchors), collect them in a manifest, and run a single command to converge your cloud state to what the manifest declares. It's inspired by dbt in shape: a project directory, models as files, environments as configurations, and a small CLI that operates on the whole thing.</p>
<p>Three properties are worth naming up front.</p>
<p><strong>Declarative.</strong> You describe what you want to exist. The tool figures out whether to create, update, or leave alone based on live queries against the cloud API, not a cached state file.</p>
<p><strong>Idempotent by design.</strong> Every resource has an exists check and an optional state check. The tool skips resources that already match, updates what has drifted, and creates what is missing. Running build twice in a row produces the same converged state, but only the first run actually mutates anything.</p>
<p><strong>Provider-agnostic through the stackql query layer.</strong> Because everything under the hood is stackql SQL against real cloud APIs, the same tool can deploy AWS, GCP, Azure, Snowflake, Databricks, or any other provider stackql supports. One framework, one query grammar, many clouds.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-a-project-is-shaped">How a project is shaped<a href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy#how-a-project-is-shaped" class="hash-link" aria-label="Direct link to How a project is shaped" title="Direct link to How a project is shaped" translate="no">​</a></h2>
<p>A stackql-deploy project is a directory with a manifest at the root and one <code>.iql</code> file per resource. Scaffolding a new project uses the <code>init</code> command:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql-deploy init example-stack --provider google</span><br></div></code></pre></div></div>
<p>This creates a directory shaped like this:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">example-stack/</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">├── stackql_manifest.yml</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">└── resources/</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    └── example_vpc.iql</span><br></div></code></pre></div></div>
<p>The manifest declares the providers, the global variables, and the resources the stack contains. Here is a minimal one for a single VPC network in GCP:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token key atrule" style="color:rgb(255, 203, 139)">version</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"example-stack"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> description for "example</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">stack"</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">providers</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> google</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">globals</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:rgb(255, 203, 139)">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> project</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"{{ MY_PROJECT_NAME }}"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:rgb(255, 203, 139)">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> region</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> australia</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">southeast1</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">resources</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:rgb(255, 203, 139)">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> example_vpc</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">props</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:rgb(255, 203, 139)">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> vpc_name</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"{{ stack_name }}-{{ stack_env }}-vpc"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">exports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> vpc_name</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> vpc_link</span><br></div></code></pre></div></div>
<p>The globals block holds values that apply across every resource. The template syntax reads environment variables or values passed at build time. The resources block lists each thing to deploy, with per-resource properties that get substituted into the SQL below.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-a-resource-is-defined">How a resource is defined<a href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy#how-a-resource-is-defined" class="hash-link" aria-label="Direct link to How a resource is defined" title="Direct link to How a resource is defined" translate="no">​</a></h2>
<p>Each <code>.iql</code> file holds one resource. Inside the file, named blocks (anchors) declare the different query shapes the framework runs at different points in the lifecycle:</p>
<p><img decoding="async" loading="lazy" alt="The six anchor blocks in a stackql-deploy resource file: exists, create, statecheck, exports, delete" src="https://stackql.io/assets/images/stackql-deploy-anchors-1418ef9b16c122978fc497c20bc61577.png" width="1614" height="1274" class="img_ev3q"></p>
<p>Read the anchors in order. <code>exists</code> is a live query that answers whether the resource is already there. <code>create</code> is the mutation to run if it isn't. <code>statecheck</code> runs after create to confirm the resource actually reached the desired configuration, with retries and delays for slow-to-propagate cloud APIs. <code>exports</code> captures values to reuse in other resources within the same stack. <code>delete</code> is the reverse mutation for teardown.</p>
<p>A note on the INSERT syntax. The columns split between path parameters (<code>project</code> stays plain since it maps to the URL path) and body fields (<code>data__name</code>, <code>data__autoCreateSubnetworks</code>, <code>data__routingConfig</code> get the <code>data__</code> prefix). This is method-specific rather than universal across providers, and you can confirm the exact contract for any resource with:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">DESCRIBE</span><span class="token plain"> METHOD google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">compute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">networks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">insert</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>This is the same query-before-mutation loop Tutorial 2 walked through by hand, formalized into a resource-file structure. The framework runs it for every resource in the manifest, in dependency order, with proper handling for the states each resource can be in.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="running-a-dry-run-build">Running a dry-run build<a href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy#running-a-dry-run-build" class="hash-link" aria-label="Direct link to Running a dry-run build" title="Direct link to Running a dry-run build" translate="no">​</a></h2>
<p>Install <code>stackql-deploy</code> via cargo:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">cargo install stackql-deploy</span><br></div></code></pre></div></div>
<p>Then, from the parent directory of your stack, run build in dry-run mode with a stack name, an environment name, and your project ID:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql-deploy build example-stack dev --dry-run -e MY_PROJECT_NAME=your-project-id</span><br></div></code></pre></div></div>
<p>The framework loads the manifest, resolves the globals with your environment variables, then walks each resource in order. In dry-run mode, it renders every query it would execute against the cloud API and reports what it would do, without actually mutating anything. All the template variables are resolved: <code>{{ project }}</code> becomes your project ID, <code>{{ vpc_name }}</code> becomes <code>example-stack-dev-vpc</code>, and the routingConfig JSON is inlined into the INSERT.</p>
<p>Dry-run is the first thing to reach for. It gives you the full execution plan without touching your cloud, which makes it the natural pattern for pull-request checks and pre-deploy previews.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="running-for-real">Running for real<a href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy#running-for-real" class="hash-link" aria-label="Direct link to Running for real" title="Direct link to Running for real" translate="no">​</a></h2>
<p>Once the dry-run output looks right, drop the flag to execute:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql-deploy build example-stack dev -e MY_PROJECT_NAME=your-project-id</span><br></div></code></pre></div></div>
<p>The framework runs the same sequence, but this time the exists check hits the cloud API, and if the resource is missing, the create INSERT is sent for real. <code>statecheck</code> retries until GCP reports the resource has converged to the desired configuration, then exports capture the live values:</p>
<p><img decoding="async" loading="lazy" alt="stackql-deploy build output showing exists check, create, state check, and exports completing successfully against Google Cloud in 3.61 seconds" src="https://stackql.io/assets/images/stackql-deploy-real-build-d903d806e332bc5597747ef9191ed096.png" width="1430" height="504" class="img_ev3q"></p>
<p>Read that output top to bottom. <code>exists</code> returned no match, so <code>create</code> ran. Right after create, the framework re-ran the exists check and confirmed the VPC was there. <code>statecheck</code> ran once and passed. <code>exports</code> captured <code>vpc_name</code> and <code>vpc_link</code>. Total time: under 4 seconds for a single-resource stack. The same pattern scales to a stack with dozens of resources across multiple providers.</p>
<p>For test-only runs (checks without mutations, useful in CI):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql-deploy test example-stack dev -e MY_PROJECT_NAME=your-project-id</span><br></div></code></pre></div></div>
<p>And to reverse the whole stack:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql-deploy teardown example-stack dev -e MY_PROJECT_NAME=your-project-id</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-this-enables">What this enables<a href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy#what-this-enables" class="hash-link" aria-label="Direct link to What this enables" title="Direct link to What this enables" translate="no">​</a></h2>
<p>The obvious use is provisioning: describe a stack once, deploy it across dev, sit, and prod environments by changing one flag. But the deeper value is what the anchor structure enables.</p>
<p>Because every resource has an exists check and a state check, running build against an already-deployed stack is a policy convergence run. If someone changed a firewall rule out of band, the next build detects the drift via <code>statecheck</code> and re-applies the correct configuration. Nothing else on the stack gets touched. That's continuous convergence without needing a separate drift-detection tool.</p>
<p>Because everything is SQL and the query grammar is the same across every provider, extending a stack from GCP-only to multi-cloud is a matter of adding new <code>.iql</code> files and provider entries in the manifest. No new tool to learn, no separate DSL, no provider-specific templating conventions.</p>
<p>And because the framework is CI-friendly (<code>test</code> for validation without mutation, dry-run for previews, exit codes for pass/fail), it slots into whatever pipeline you already use to ship infrastructure changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-this-fits-in-the-series">Where this fits in the series<a href="https://stackql.io/blog/tutorials/declarative-cloud-stacks-stackql-deploy#where-this-fits-in-the-series" class="hash-link" aria-label="Direct link to Where this fits in the series" title="Direct link to Where this fits in the series" translate="no">​</a></h2>
<p>Tutorial 1 introduced stackql for querying live cloud state across multiple clouds with SQL. Tutorial 2 showed how the same query engine lets agents read live state before mutating anything, one query at a time. The Actions guide put the audit pattern in CI. This tutorial shows the framework that operationalizes the whole pattern: not one query at a time, but a manifest-driven declaration of an entire cloud stack, with idempotence, environment scoping, and continuous convergence built in.</p>
<p>If the pattern makes sense to you, star the <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class="">stackql repository</a> so more developers find it. Full documentation, more manifest examples, and provider-specific guides are at stackql-deploy.io.</p>
<p>Next in this series: authoring your own multi-cloud stack from scratch, using stackql-deploy against AWS and GCP together.</p>]]></content>
        <author>
            <name>Nirmal Chhodvadiya</name>
            <uri>https://www.linkedin.com/in/nirmalchhodvadiya/</uri>
        </author>
        <category label="stackql-deploy" term="stackql-deploy"/>
        <category label="gcp" term="gcp"/>
        <category label="iac" term="iac"/>
        <category label="sql" term="sql"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Add continuous cloud audit to your CI/CD in ten minutes]]></title>
        <id>https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions</id>
        <link href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions"/>
        <updated>2026-09-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Cloud security reviews are usually quarterly. Configuration drift happens daily. Between review cycles, buckets get created, firewall rules get loosened, service accounts get reused, and a bucket that was locked down last quarter might not be locked down today. Nothing about the review cadence catches any of it.]]></summary>
        <content type="html"><![CDATA[<p>Cloud security reviews are usually quarterly. Configuration drift happens daily. Between review cycles, buckets get created, firewall rules get loosened, service accounts get reused, and a bucket that was locked down last quarter might not be locked down today. Nothing about the review cadence catches any of it.</p>
<p>Tutorial 1 in this series walked through auditing three clouds with <code>stackql</code> from your terminal. Tutorial 2 showed how the same query engine lets an agent read live state before mutating anything. This guide takes the same audit pattern and puts it in your CI, so the check runs every day, or on every pull request, or every hour, without anyone remembering to run it.</p>
<p>The tool is <a href="https://github.com/stackql/stackql-audit-action" target="_blank" rel="noopener noreferrer" class="">stackql-audit-action</a>, a GitHub Action that runs an opinionated set of security checks against your cloud accounts and renders findings inline on the workflow run page. Setup is copy-paste. First results in under two minutes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-it-checks">What it checks<a href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions#what-it-checks" class="hash-link" aria-label="Direct link to What it checks" title="Direct link to What it checks" translate="no">​</a></h2>
<p>The action ships with seven built-in checks for GCP:</p>
<ul>
<li class="">SSH (22/tcp) open to the internet — HIGH</li>
<li class="">RDP (3389/tcp) open to the internet — HIGH</li>
<li class="">Cloud SQL instances reachable on a public IP — HIGH</li>
<li class="">Compute instances with public IPs — MEDIUM</li>
<li class="">Compute instances using the default service account — MEDIUM</li>
<li class="">Storage buckets without uniform bucket-level access — MEDIUM</li>
<li class="">Default VPC network exists — MEDIUM</li>
</ul>
<p>Similar built-in check sets exist for AWS and Azure. A provider only runs if its credentials are supplied, so you can start with GCP and add the others by dropping in their secrets. This walkthrough covers GCP end to end.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setup">Setup<a href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions#setup" class="hash-link" aria-label="Direct link to Setup" title="Direct link to Setup" translate="no">​</a></h2>
<p>You need three things:</p>
<ul>
<li class="">A GitHub repository</li>
<li class="">A GCP project you're authorized to audit</li>
<li class="">A Google Cloud service account JSON key with read access to Compute, Cloud SQL, Storage, and IAM</li>
</ul>
<p>Store the service account key as a GitHub secret. In your repository, go to <strong>Settings → Secrets and variables → Actions → New repository secret</strong>. Name the secret <code>GCP_SA_JSON</code> and paste the full JSON key as the value.</p>
<p>Never commit credentials to the repo. Never share a key JSON on Slack or email. Rotate the key if you ever paste one somewhere by accident.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="add-the-workflow">Add the workflow<a href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions#add-the-workflow" class="hash-link" aria-label="Direct link to Add the workflow" title="Direct link to Add the workflow" translate="no">​</a></h2>
<p>Create <code>.github/workflows/cloud-audit.yml</code> with this content:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token key atrule" style="color:rgb(255, 203, 139)">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> GCP Audit</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">workflow_dispatch</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">inputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule" style="color:rgb(255, 203, 139)">project-id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> GCP project ID to audit</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">required</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule" style="color:rgb(255, 203, 139)">fail-on-severity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Severity threshold to fail on (CRITICAL/HIGH/MEDIUM/LOW/NONE)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">required</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">false</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HIGH</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">jobs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">audit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">runs-on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">latest</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:rgb(255, 203, 139)">uses</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> stackql/stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">audit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">action@v0.1</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">with</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">          </span><span class="token key atrule" style="color:rgb(255, 203, 139)">project-id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> inputs.project</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">id </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">          </span><span class="token key atrule" style="color:rgb(255, 203, 139)">gcp-credentials</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> secrets.GCP_SA_JSON </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">          </span><span class="token key atrule" style="color:rgb(255, 203, 139)">fail-on-severity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> inputs.fail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">severity </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Two things worth noting. The action is pinned to <code>@v0.1</code> for reproducibility. If you use <code>@main</code>, tomorrow's audit runs against tomorrow's version, which can change without warning. Pin to a real tag or a commit SHA. The <code>fail-on-severity</code> input controls when the workflow fails. For a first run, set it to <code>NONE</code> so the workflow completes even if findings surface. Once you've reviewed the output and confirmed the checks match your expectations, raise it to <code>HIGH</code> or <code>MEDIUM</code> as an enforcement gate.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="run-the-audit">Run the audit<a href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions#run-the-audit" class="hash-link" aria-label="Direct link to Run the audit" title="Direct link to Run the audit" translate="no">​</a></h2>
<p>Commit and push. Then in your repository, go to <strong>Actions → GCP Audit → Run workflow</strong>. Fill in the project ID and start the run. First run takes about 20-30 seconds.</p>
<p>When the run completes, click into it and scroll down. The audit summary renders inline as a markdown table on the workflow run page:</p>
<p><img decoding="async" loading="lazy" alt="StackQL GCP audit summary rendered inline on the GitHub Actions workflow run page" src="https://stackql.io/assets/images/stackql-audit-action-summary-bf9418f1264c443bcd0f4b13e744d6c2.png" width="1800" height="805" class="img_ev3q"></p>
<p>Every check reports its status. Green checkmarks mean the check ran and found nothing. Yellow (MEDIUM) or red (HIGH) markers mean findings surfaced, with the affected resource names listed in a table and a short remediation note underneath.</p>
<p>In this test run, the audit surfaced nine medium-severity findings across three categories: one Compute instance using the default service account, one Compute instance with a public IP, and seven buckets without uniform bucket-level access. The other four checks ran and returned no findings. That distinction matters. A check running cleanly is signal too.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="making-it-continuous">Making it continuous<a href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions#making-it-continuous" class="hash-link" aria-label="Direct link to Making it continuous" title="Direct link to Making it continuous" translate="no">​</a></h2>
<p>Manual triggers are for testing. For continuous audit, change the trigger to run on a schedule or on pull requests:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token key atrule" style="color:rgb(255, 203, 139)">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">schedule</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token key atrule" style="color:rgb(255, 203, 139)">cron</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'0 9 * * *'</span><span class="token plain">   </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># every day at 09:00 UTC</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">pull_request</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">branches</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">workflow_dispatch</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">      </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># keep manual trigger as a fallback</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">inputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule" style="color:rgb(255, 203, 139)">project-id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> GCP project ID to audit</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token key atrule" style="color:rgb(255, 203, 139)">required</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token boolean important" style="color:rgb(255, 88, 116)">true</span><br></div></code></pre></div></div>
<p>The scheduled run catches drift that happens outside your PR flow. The pull-request run catches policy violations before they merge. Together they cover both the intentional and the accidental changes that can widen your attack surface between security reviews.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="extending-it-with-your-own-checks">Extending it with your own checks<a href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions#extending-it-with-your-own-checks" class="hash-link" aria-label="Direct link to Extending it with your own checks" title="Direct link to Extending it with your own checks" translate="no">​</a></h2>
<p>The seven built-in checks are a starting point, not the full set your organization cares about. The action lets you point at your own directory of check definitions, one YAML file per check:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token key atrule" style="color:rgb(255, 203, 139)">id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> my</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">org</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">firewall</span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain">check</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Allow only known source ranges</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">severity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> HIGH</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Catch firewall rules with sourceRanges outside our corp CIDRs.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">remediation</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> Restrict to known CIDRs or migrate to IAP.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">query</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">|</span><span class="token scalar string" style="color:rgb(173, 219, 103)"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">  SELECT name, network, sourceRanges</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">  FROM google.compute.firewalls</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">  WHERE project = '${PROJECT_ID}'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">    AND direction = 'INGRESS'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">columns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> network</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> sourceRanges</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><br></div></code></pre></div></div>
<p>A query returning zero rows means no findings. Any rows returned become finding rows. Every check is a small YAML file, so extending the audit to cover your organization's specific policies is one file per rule. See the <code>queries/</code> directory in the action repository for the built-in checks as reference implementations.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-this-fits">Where this fits<a href="https://stackql.io/blog/tutorials/continuous-cloud-audit-github-actions#where-this-fits" class="hash-link" aria-label="Direct link to Where this fits" title="Direct link to Where this fits" translate="no">​</a></h2>
<p>Tutorial 1 in this series introduced the audit pattern manually: SELECT across three clouds, spot the risky resources, know what to fix. Tutorial 2 introduced query-before-mutation: read live state before an agent acts, apply a policy gate, converge safely. This guide connects the two. The audit runs continuously in CI. When something drifts, the query-before-mutation pattern is how an agent or an operator brings it back into policy.</p>
<p>If the pattern makes sense to you, star the <a href="https://github.com/stackql/stackql-audit-action" target="_blank" rel="noopener noreferrer" class="">stackql-audit-action repository</a> so more developers can find it. And if you have suggestions for checks that belong in the built-in set, the <code>queries/</code> directory takes pull requests.</p>
<p>Next in this series: authoring your own check library with <code>stackql-audit-action</code>, and running the same pattern against AWS and Azure alongside GCP.</p>]]></content>
        <author>
            <name>Nirmal Chhodvadiya</name>
            <uri>https://www.linkedin.com/in/nirmalchhodvadiya/</uri>
        </author>
        <category label="github-actions" term="github-actions"/>
        <category label="gcp" term="gcp"/>
        <category label="security" term="security"/>
        <category label="ci-cd" term="ci-cd"/>
        <category label="audit" term="audit"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Query before you mutate: how agents should touch your infrastructure]]></title>
        <id>https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure</id>
        <link href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure"/>
        <updated>2026-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The problem with plan, review, apply]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-problem-with-plan-review-apply">The problem with plan, review, apply<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#the-problem-with-plan-review-apply" class="hash-link" aria-label="Direct link to The problem with plan, review, apply" title="Direct link to The problem with plan, review, apply" translate="no">​</a></h2>
<p>Infrastructure-as-code was designed around human-speed changes: write a plan, review it, apply it, and use state snapshots to know what was managed before. That works best when writers are few and changes are infrequent.</p>
<p>Agents change those assumptions. They run continuously and multiple actors can touch the same resources at the same time. Drift is no longer exceptional. It is unavoidable and relentless.</p>
<p>Canonical IaC tools like Terraform still matter because they represent intent. What's weakened is their ability to reflect current reality. Agents rarely own the whole picture. They usually operate in narrow scopes, working on a slice of infrastructure that other agents, other tools, or humans are also touching. In that world, an agent will regularly encounter infrastructure that was mutated out of band, outside whatever IaC system nominally manages it.</p>
<p>Query-before-mutation handles this case. Read live cloud state, compare it with policy, apply a bounded policy gate, mutate only what is out of policy, then verify. Each run starts from reality rather than a cached view.</p>
<p>The demo takes about ten minutes and uses Google Cloud Storage bucket encryption, but the pattern is provider-agnostic.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="query-before-mutation">Query before mutation<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#query-before-mutation" class="hash-link" aria-label="Direct link to Query before mutation" title="Direct link to Query before mutation" translate="no">​</a></h2>
<p>Correctness comes from querying live state before acting. Safety comes from something separate: policy gates that bound what a single run is allowed to do. Location locks, resource caps, budget ceilings, allowlists. Two patterns, two jobs. Agentic query-before-mutation complements centralised IaC approaches leveraging snapshots of state. Policy gates replace the review meeting.</p>
<p>The combined loop is correct by default because it reads reality, and safe by default because it cannot do more than the gate allows. Agents can run it continuously. Humans can run it manually. The output converges either way.</p>
<p><code>stackql</code> implements this pattern. Any resource on any supported cloud can be read with SQL and mutated with SQL where the provider exposes mutation methods. Kubernetes solved reconciliation inside the cluster, but nothing reconciles across your cloud. That gap is where this pattern belongs. The demo uses Google Cloud Storage because the mutation surface is clean, but the shape is the same for AWS S3, Vault secrets, GitHub org settings, or anything else an agent needs to reason about.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setup">Setup<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#setup" class="hash-link" aria-label="Direct link to Setup" title="Direct link to Setup" translate="no">​</a></h2>
<p>You need three things:</p>
<ul>
<li class="">Docker (to run <code>stackql</code> without installing anything else)</li>
<li class="">A Google Cloud project with credentials that can read buckets and update encryption config, plus an existing Cloud KMS key you want to enforce</li>
<li class="">About ten minutes</li>
</ul>
<p>Clone the tutorial folder from the <code>stackql</code> repo:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">git clone https://github.com/stackql/stackql.git</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">cd stackql/docs/tutorials/query-before-mutation-01</span><br></div></code></pre></div></div>
<p>Copy the sample environment file and add your service account credentials:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">cp .env.sample .env</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"># Then edit .env to set:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"># GOOGLE_CREDENTIALS=&lt;service-account-json-on-one-line&gt;</span><br></div></code></pre></div></div>
<p>Bring up an interactive <code>stackql</code> shell:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">docker compose run --rm --entrypoint bash stackql</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"># then inside the container:</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql shell</span><br></div></code></pre></div></div>
<p>Pull the Google provider from the registry. This only needs to happen once per shell session:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">REGISTRY PULL google v26</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token number" style="color:rgb(247, 140, 108)">07.00432</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>You're ready.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="query-the-live-state">Query the live state<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#query-the-live-state" class="hash-link" aria-label="Direct link to Query the live state" title="Direct link to Query the live state" translate="no">​</a></h2>
<p>Ask the GCS API which buckets exist and what encryption is currently applied to each.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> encryption </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">storage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">buckets </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> project </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'your-project-id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Expected output on a project with a mix of encryption configurations:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">| name                       | location | encryption                                    |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| demo-app-bucket1           | US       | null                                          |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| demo-app-bucket2           | US       | null                                          |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| stackql-demo-src-bucket    | US       | null                                          |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| stackql-encrypted-bucket-1 | US       | {"defaultKmsKeyName":"projects/.../keys/..."} |</span><br></div></code></pre></div></div>
<p>Three buckets show encryption as null, meaning Google-managed encryption keys (GMEK), the default. One already uses a customer-managed key. Under a policy that requires customer-managed keys, three buckets are out of policy.</p>
<p>A state snapshot can tell you what Terraform previously configured. This query tells you what GCS reports now, regardless of who created or changed the bucket. If ten agents and two humans are all touching this project at various points during the day, the query still returns the current truth every time you run it. That's the property the pattern is built on.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="apply-a-policy-gate">Apply a policy gate<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#apply-a-policy-gate" class="hash-link" aria-label="Direct link to Apply a policy gate" title="Direct link to Apply a policy gate" translate="no">​</a></h2>
<p>Three buckets don't match policy. Before mutating, the agent needs to prove it's allowed to. That's what the policy gate does.</p>
<p>A gate is anything that bounds what a single run of the agent can do. Scope by project or location, cap the number of resources changed, or enforce an explicit allowlist. The shape depends on how much freedom the agent has and how much you're willing to lose in one bad run.</p>
<p>For this demo, two gates cover most of the risk. The first is a location lock. The agent should only ever act on buckets in the location it was configured for. This is a WHERE clause on every query and mutation:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> location </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'US'</span><br></div></code></pre></div></div>
<p>Trivial when the project's buckets are in one location. In production, agents move between locations based on task, and touching a bucket in the wrong region can mean acting on resources in an environment the agent has no business in. One clause, but it's the difference between a bounded action and an unbounded one.</p>
<p>The second gate is a count cap. Before running a mutation across multiple buckets, ask the API how many the mutation would touch:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">COUNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(127, 219, 202)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">storage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">buckets </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> project </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'your-project-id'</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> location </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'US'</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> encryption </span><span class="token operator" style="color:rgb(127, 219, 202)">IS</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>If the query returns 20 buckets and the agent's policy expects to be operating in a project with 3 to 5 non-compliant buckets, something has changed. Maybe an account merger, maybe a script created buckets out of band, maybe the credentials point to the wrong project entirely. The agent shouldn't proceed. It should log the discrepancy and wait for a human to look.</p>
<p>Gates like these aren't clever. They're routine, boring, and easy to skip. They're also the reason a query-before-mutation loop can run without a human review meeting attached to every apply. The gate carries the weight the meeting used to.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="mutate-to-converge">Mutate to converge<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#mutate-to-converge" class="hash-link" aria-label="Direct link to Mutate to converge" title="Direct link to Mutate to converge" translate="no">​</a></h2>
<p>The gates passed. For each bucket without a customer-managed key, apply the policy:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">UPDATE</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">storage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">buckets </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">SET</span><span class="token plain"> data__encryption </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{"defaultKmsKeyName":"projects/your-project-id/locations/us/keyRings/your-ring/cryptoKeys/your-key"}'</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> bucket </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'demo-app-bucket1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Two things worth noting. The <code>data__encryption</code> prefix is how <code>stackql</code> passes fields into the request body, distinguishing them from URL parameters. The <code>WHERE</code> clause uses <code>bucket</code> rather than <code>name</code>, because <code>bucket</code> is the identifier the underlying patch method requires.</p>
<p>Expected output:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">The operation was despatched successfully</span><br></div></code></pre></div></div>
<p>In an agent loop, this runs as a bounded iteration over the non-compliant buckets returned by the earlier query, applying the same UPDATE to each one.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="verify-convergence">Verify convergence<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#verify-convergence" class="hash-link" aria-label="Direct link to Verify convergence" title="Direct link to Verify convergence" translate="no">​</a></h2>
<p>A successful mutation is not enough. Query the bucket again to verify:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> encryption </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">storage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">buckets </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> bucket </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'demo-app-bucket1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Expected output:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">| name             | encryption                                                                    |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| demo-app-bucket1 | {"defaultKmsKeyName":"projects/your-project-id/locations/us/keyRings/..."}    |</span><br></div></code></pre></div></div>
<p>The bucket converged from GMEK to the required customer-managed key.</p>
<p>Run the loop again and something interesting happens: the mutation is a no-op. The SELECT finds no drift, the count check passes trivially, no UPDATE fires. That's idempotence by design. The agent can run every minute, every hour, every day, and it does the same right thing whether the target is already compliant or has just drifted. No state snapshot needed to remember what it did last time. Every run starts from live reality.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-same-pattern-from-an-agent">The same pattern from an agent<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#the-same-pattern-from-an-agent" class="hash-link" aria-label="Direct link to The same pattern from an agent" title="Direct link to The same pattern from an agent" translate="no">​</a></h2>
<p>Everything above is you typing SQL into a shell. The same pattern maps directly to an agent through <code>stackql</code>'s MCP server, listed in the Claude directory at <a href="https://claude.ai/directory/ant.dir.gh.stackql.stackql" target="_blank" rel="noopener noreferrer" class="">claude.ai/directory/ant.dir.gh.stackql.stackql</a>.</p>
<p>Install it, add your GCP credentials, and ask Claude in plain English:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">List all GCS buckets in the project stackql-demo, and for each </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">show whether encryption is a customer-managed key or the </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Google-managed default.</span><br></div></code></pre></div></div>
<p><img decoding="async" loading="lazy" alt="Claude Desktop response showing stackql MCP query result with bucket encryption table" src="https://stackql.io/assets/images/query-before-you-mutate-claude-mcp-d13b8fbb6cc97642de918cbbf11d1823.png" width="1640" height="1041" class="img_ev3q"></p>
<p>Claude uses the <code>stackql</code> MCP server to run the same underlying SELECT you saw earlier, then formats the result into a readable table. The query, gate, mutate, and verify loop runs the same way an agent runs it, just as reasoning steps in a conversation instead of shell commands.</p>
<p>Notice what the agent adds that the raw shell output doesn't: it separates CMEK buckets from Google-managed default ones, calls out which KMS key each CMEK bucket uses, and flags a caveat you didn't ask about (the difference between bucket-default encryption and per-object encryption). That's the value of running the pattern through an agent rather than a script. Same query, same result, plus the reasoning layer on top.</p>
<p>The shell walkthrough above was for you to see the pattern happen line by line. The MCP integration is how the pattern runs end to end in an actual agent's workflow.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-this-goes-next">Where this goes next<a href="https://stackql.io/blog/tutorials/query-before-you-mutate-agents-infrastructure#where-this-goes-next" class="hash-link" aria-label="Direct link to Where this goes next" title="Direct link to Where this goes next" translate="no">​</a></h2>
<p>Query before mutation is one instance of a broader pattern. Six patterns, really, that hold together as a working model for how agents should operate on infrastructure. Query before mutation is one. Idempotent assertions, bi-temporal views, agents as event sources, universal interfaces, and policy gates are the other five. Together they replace the assumptions the plan-review-apply model was built on.</p>
<p>The full argument is in Jeff Aven's talk from AI Engineer Melbourne, "Treating Infrastructure as Data: Building an AI-Native Control Plane." If the pattern in this tutorial made sense to you, the talk is the map for what else fits with it.</p>
<p>If this tutorial was useful, star the <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class="">stackql repo</a>. Every star helps other developers and agents find the pattern, and helps the project climb the MCP registry where more agents can discover it.</p>
<p>Next in this series: idempotent assertions with <code>stackql-deploy</code>. Same shape, different pattern, applied to declarative infrastructure that runs continuously without breaking on repeat.</p>]]></content>
        <author>
            <name>Nirmal Chhodvadiya</name>
            <uri>https://www.linkedin.com/in/nirmalchhodvadiya/</uri>
        </author>
        <category label="agentic" term="agentic"/>
        <category label="mcp" term="mcp"/>
        <category label="gcp" term="gcp"/>
        <category label="security" term="security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Auditing three clouds without writing three scripts]]></title>
        <id>https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts</id>
        <link href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts"/>
        <updated>2026-08-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A hands-on walkthrough of the StackQL multi-cloud bucket audit. One Docker command, one SQL query, and you get a normalised table of AWS, GCP, and Azure storage buckets with encryption class, public flag, and HTTPS enforcement side by side.]]></summary>
        <content type="html"><![CDATA[<p>If you've audited buckets in more than one cloud, you already know what this is like. Three consoles. Three CLIs. Three auth patterns. And a bit of glue code to pull the outputs together every time someone asks a question that spans all three.</p>
<p>The question is usually simple. "Which buckets are public across all our clouds?" You end up running three separate scripts, then reconciling three different output shapes just to give one answer.</p>
<p>This tutorial doesn't make that faster. It replaces it. One query, one view, all three clouds.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-stackql-is-in-three-sentences">What StackQL is, in three sentences<a href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts#what-stackql-is-in-three-sentences" class="hash-link" aria-label="Direct link to What StackQL is, in three sentences" title="Direct link to What StackQL is, in three sentences" translate="no">​</a></h2>
<p>StackQL is SQL for cloud APIs. You write a normal SQL query, and it makes the API calls to AWS, GCP, Azure, or dozens of other providers to get the answer back as rows and columns.</p>
<p>The important part for this tutorial: it queries the live provider APIs on every run. There's no local database, no cache, no sync job to schedule. What you see is the current state of your cloud, right now.</p>
<p>It exists because someone got tired of writing the same audit logic three times.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-youll-need">What you'll need<a href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts#what-youll-need" class="hash-link" aria-label="Direct link to What you'll need" title="Direct link to What you'll need" translate="no">​</a></h2>
<p>You'll need Docker installed and read-only credentials for whichever clouds you want to audit. All three are optional. If you leave a cloud's credentials blank, it gets skipped.</p>
<p>For AWS, GCP, and Azure, the audit needs a service account or role that can list storage buckets and read their configuration. The audit-action repo has the exact permissions per provider <a href="https://github.com/stackql/stackql-audit-action/blob/main/docs/required-auth.md" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="run-the-audit">Run the audit<a href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts#run-the-audit" class="hash-link" aria-label="Direct link to Run the audit" title="Direct link to Run the audit" translate="no">​</a></h2>
<p>The tutorial folder has three files: a docker-compose file, an <code>.env.audit.example</code> template, and a README. Grab the folder from <a href="https://github.com/stackql/stackql/tree/main/docs/tutorials/preview-bucket-01" target="_blank" rel="noopener noreferrer" class=""><code>docs/tutorials/preview-bucket-01/</code></a> in the <code>stackql/stackql</code> repo.</p>
<p><strong>1. Copy the env template</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">cp ./audit/.env.audit.example ./audit/.env.audit</span><br></div></code></pre></div></div>
<p>Then open <code>.env.audit</code> and fill in credentials for whichever clouds you want. The variables are named for what they are: <code>AWS_ACCESS_KEY_ID</code>, <code>AWS_SECRET_ACCESS_KEY</code>, <code>AWS_REGION</code>, <code>AZURE_TENANT_ID</code>, <code>AZURE_CLIENT_ID</code>, <code>AZURE_CLIENT_SECRET</code>, <code>GOOGLE_CREDENTIALS</code> (the service account JSON, on one line), and <code>GOOGLE_ORG_ID</code>.</p>
<p>If you're only auditing one or two clouds, leave the others blank.</p>
<p><strong>2. Pull the StackQL Docker image</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">docker compose -f docker-compose.bucket.audit.yaml pull</span><br></div></code></pre></div></div>
<p>The tutorial pins to <code>stackql/stackql:v0.10.601</code>. The audit uses views under <code>stackql_preview.*</code> which are still evolving, so pinning matters for reproducibility.</p>
<p><strong>3. Run the audit</strong></p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">docker compose -f docker-compose.bucket.audit.yaml run --rm stackql</span><br></div></code></pre></div></div>
<p>On a modest account this takes about 30 seconds. Output goes straight to your terminal as a table.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-the-output-tells-you">What the output tells you<a href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts#what-the-output-tells-you" class="hash-link" aria-label="Direct link to What the output tells you" title="Direct link to What the output tells you" translate="no">​</a></h2>
<p>When the audit finishes, you get a single table printed to your terminal. Something like this (bucket names are placeholders):</p>
<p><img decoding="async" loading="lazy" alt="Terminal screenshot showing StackQL audit output as a table with columns for provider, bucket name, encryption class, public flag, and HTTPS enforcement. Rows include AWS, GCP, and Azure buckets with a mix of provider-managed and customer-managed encryption, and one public bucket flagged per AWS and GCP." src="https://stackql.io/assets/images/stackql-multi-cloud-bucket-audit-output-3f4bf600f6b808b07f2bd12197978a86.png" width="1510" height="678" class="img_ev3q"></p>
<p><em>Example output from the audit. Bucket configuration across three cloud providers in one normalised table.</em></p>
<p>The point isn't the specific findings. It's the shape.</p>
<p>Three different resource types (S3 buckets, GCS buckets, and Azure Storage Accounts) normalised into one table with the same columns. Encryption class, public flag, HTTPS enforcement. Side by side, for every cloud you provided credentials for.</p>
<p>A few patterns to notice in the table:</p>
<ul>
<li class=""><strong>Public buckets across providers.</strong> Filter by <code>public = true</code> and you have the answer to your security team's question, in every cloud, in one place.</li>
<li class=""><strong>Encryption side by side.</strong> The <code>encryption_class</code> column shows which buckets use provider-managed keys versus customer-managed. Different providers have different naming conventions internally; StackQL normalises them to the same two categories.</li>
<li class=""><strong>HTTPS enforcement in one column.</strong> Whether it's S3 bucket policies, GCS uniform access, or Azure secure transfer, same column, same values, no translation needed.</li>
</ul>
<p>This is what SQL for cloud APIs actually delivers. Not just SQL as a query language, but a uniform data model across providers, so you can ask one question and get one answer.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="performance-and-scope">Performance and scope<a href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts#performance-and-scope" class="hash-link" aria-label="Direct link to Performance and scope" title="Direct link to Performance and scope" translate="no">​</a></h2>
<p>StackQL runs each provider's query in parallel using the credentials you provided. There's no local database being populated and no background sync; every run hits the live APIs and returns what's there right now.</p>
<p>On the test account this took about 30 seconds. The query is scoped to one AWS region and one GCP organization, which keeps the API footprint bounded and reflects the current preview default. Streaming output and broader audits (across regions, deeper across resource types) are in flight from the StackQL team.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-this-covers-today">What this covers today<a href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts#what-this-covers-today" class="hash-link" aria-label="Direct link to What this covers today" title="Direct link to What this covers today" translate="no">​</a></h2>
<p>Today, this audit covers storage buckets across AWS, GCP, and Azure. One region at a time for AWS, one organization at a time for GCP. Entitlements, IAM, and other resource types are on the roadmap as separate audits under <code>stackql_preview.*</code> and will get their own tutorials as they land.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-go-next">Where to go next<a href="https://stackql.io/blog/tutorials/auditing-three-clouds-without-writing-three-scripts#where-to-go-next" class="hash-link" aria-label="Direct link to Where to go next" title="Direct link to Where to go next" translate="no">​</a></h2>
<p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><code>github.com/stackql/stackql</code></a> is the flagship repo. If this tutorial was worth reading, give it a star. It's genuinely the thing that tells the team to build more tutorials like this one, and it helps other engineers with the same three-console problem find the project.</p>
<p>A few natural next steps from here:</p>
<ul>
<li class=""><strong>Run it against your own accounts.</strong> The audit works exactly the same way against real credentials. You can start with one cloud and add the others by adding their env vars.</li>
<li class=""><strong>Move it into CI.</strong> The <a href="https://github.com/stackql/stackql-audit-action" target="_blank" rel="noopener noreferrer" class=""><code>stackql-audit-action</code></a> repo has ready-to-use GitHub Actions workflows for all-clouds, single-cloud, deep-audit, and OIDC-authenticated variants. Drop one into your repo, add secrets, and you have a scheduled cross-cloud audit running on every push.</li>
<li class=""><strong>Ask questions.</strong> The <a href="https://join.slack.com/t/stackqlcommunity/shared_invite/zt-46ndqydvn-X8ip8b9xgkT__IOTFbMlVg" target="_blank" rel="noopener noreferrer" class="">StackQL community Slack</a> is the fastest way. GitHub issues on the flagship repo also work.</li>
</ul>
<p>More audits are on the way, including entitlements, deeper checks, and larger estates. If there's a specific one you'd find useful, opening an issue is the fastest way to get it on the roadmap.</p>]]></content>
        <author>
            <name>Nirmal Chhodvadiya</name>
            <uri>https://www.linkedin.com/in/nirmalchhodvadiya/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="multi-cloud" term="multi-cloud"/>
        <category label="audit" term="audit"/>
        <category label="security" term="security"/>
        <category label="aws" term="aws"/>
        <category label="gcp" term="gcp"/>
        <category label="azure" term="azure"/>
        <category label="docker" term="docker"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[From finding to fix: cloud auto-remediation with AI and StackQL]]></title>
        <id>https://stackql.io/blog/tutorials/ai-remediation-pull-requests</id>
        <link href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests"/>
        <updated>2026-06-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[An audit tells you what is wrong. This is the other half - a GitHub Actions loop that opens one pull request per finding, checks live state before it mutates, and applies on merge. OIDC only, no agents in the estate, GitHub as the audit trail.]]></summary>
        <content type="html"><![CDATA[<p>A cloud audit tells you what is wrong. The work starts when you have to fix it. Most tooling stops at the findings list and hands a spreadsheet to an engineer, and the findings sit there until someone has a quiet afternoon.</p>
<p>This post walks through the other half: a remediation loop that turns each finding into a reviewable pull request, verifies live state before it changes anything, and applies the fix on merge. It runs entirely in GitHub Actions, authenticates with OIDC, and uses StackQL to talk to cloud control planes. The repo is public at <a href="https://github.com/stackql-labs/stackql-ai-remediation" target="_blank" rel="noopener noreferrer" class="">stackql-labs/stackql-ai-remediation</a>, and the example throughout is FinOps waste (unattached disks, idle IPs, zero-VM projects), though the shape is the same for posture and security checks.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-loop">The loop<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#the-loop" class="hash-link" aria-label="Direct link to The loop" title="Direct link to The loop" translate="no">​</a></h2>
<p>The pipeline is deliberately small:</p>
<ol>
<li class="">A scheduled or dispatched audit runs against the cloud control plane and writes findings as structured data.</li>
<li class="">For each finding, the loop opens one pull request carrying the exact proposed change.</li>
<li class="">A preflight status check queries live reality before anything can merge.</li>
<li class="">On merge, the change is applied through the vendor CLI.</li>
<li class="">A post-apply check confirms the resource is actually gone.</li>
</ol>
<p>What is deliberately absent matters as much as what is present. No agents running in the estate. No long-lived cloud keys. No log pipeline, no inventory sync, no external scanner appliance. The data path is GitHub Actions to StackQL to the cloud control-plane APIs, and the audit trail is the pull request history.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-finding-is-just-data">A finding is just data<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#a-finding-is-just-data" class="hash-link" aria-label="Direct link to A finding is just data" title="Direct link to A finding is just data" translate="no">​</a></h2>
<p>The audit emits each finding as JSON, and that JSON is the contract the rest of the loop reads. A single FinOps finding looks like this:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"run_id"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"27901134862"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"provider"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"aws"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"check_id"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"aws-finops-unattached-volume"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"check_name"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"Unattached EBS volumes"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"severity"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"LOW"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"category"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"waste"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"region"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"ap-southeast-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"suggested_remediation"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"type"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"delete"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"tool"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"stackql"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"preflight_query"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"SELECT VolumeId FROM aws.ec2.volumes WHERE region = 'ap-southeast-2' AND VolumeId = 'vol-0a1b2c3d4e5f' AND State = 'available'"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"sql_query"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"DELETE FROM aws.ec2.volumes WHERE region = 'ap-southeast-2' AND VolumeId = 'vol-0a1b2c3d4e5f'"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"description"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"Delete the unattached EBS volume (snapshot first if its data may be needed)."</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"fields"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"volumeId"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"vol-0a1b2c3d4e5f"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"size"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"20"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"status"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"available"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"estimated_monthly_usd"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1.92</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>The finding already carries its own remediation: a preflight query and the SQL that would fix it, both fully substituted with concrete values. The rest of the loop is mechanical from here.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="one-pull-request-per-finding">One pull request per finding<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#one-pull-request-per-finding" class="hash-link" aria-label="Direct link to One pull request per finding" title="Direct link to One pull request per finding" translate="no">​</a></h2>
<p><code>generate_proposals.py</code> reads the findings and writes one directory per finding:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">remediations/proposed/&lt;run-id&gt;/&lt;n&gt;-&lt;check-id&gt;-&lt;resource-id&gt;/</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  finding.json      # verbatim copy of the finding</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  preflight.sql     # the live-state check, pass = &gt;=1 row</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  remediation.sql   # the canonical fix (applied via CLI on merge)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  rationale.md      # deterministic explanation from the finding fields</span><br></div></code></pre></div></div>
<p>The SQL comes straight from the audit's <code>suggested_remediation</code> block, already templated per check type, so the proposal is reproducible and reviewable rather than generated fresh each run. Where a model does help is a separate, optional step: an agent reads the batch and flags the captain's-call risks - the changes a human should look at twice - so reviewers know where to spend attention. Judgment and mutation are kept apart on purpose.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="query-before-mutation">Query before mutation<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#query-before-mutation" class="hash-link" aria-label="Direct link to Query before mutation" title="Direct link to Query before mutation" translate="no">​</a></h2>
<p>The preflight is the part worth dwelling on:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic">-- pass criterion: returns &gt;= 1 row</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> VolumeId</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">ec2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">volumes</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-2'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> VolumeId </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'vol-0a1b2c3d4e5f'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> State </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'available'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>This runs as a required status check on the pull request. It is a live query against the cloud API, not a read of a cached state file, and it asserts that the resource is still in the state the finding assumed at the moment of merge, not at the moment of audit. Findings go stale. Between the audit run and someone clicking merge, the volume may have been re-attached, deleted by someone else, or moved. A state file would not know. The API does. If the preflight returns zero rows, the check fails and the change cannot land.</p>
<p>This is the single most important property of the loop: the gap between "what the audit saw" and "what is true now" is closed by a live query, every time, automatically.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-fix-is-a-sql-statement">The fix is a SQL statement<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#the-fix-is-a-sql-statement" class="hash-link" aria-label="Direct link to The fix is a SQL statement" title="Direct link to The fix is a SQL statement" translate="no">​</a></h2>
<p>StackQL treats the cloud control plane as a queryable and mutable surface. You <code>SELECT</code> to read it and <code>DELETE</code> or <code>INSERT</code> to change it, with the same grammar across providers:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">DELETE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">ec2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">volumes</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-2'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> VolumeId </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'vol-0a1b2c3d4e5f'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>The statement is idempotent by shape. Run it twice and the end state is the same, which is exactly the property you want when a pipeline can retry. On merge, the apply workflow executes the remediation through the vendor CLI; <code>remediation.sql</code> is kept as the canonical, human-readable record of what was applied.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="policy-gates-instead-of-a-review-bottleneck">Policy gates instead of a review bottleneck<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#policy-gates-instead-of-a-review-bottleneck" class="hash-link" aria-label="Direct link to Policy gates instead of a review bottleneck" title="Direct link to Policy gates instead of a review bottleneck" translate="no">​</a></h2>
<p>Branch protection is where the safety model lives. The rule on <code>main</code> is:</p>
<ul>
<li class="">Required approvals: <code>0</code></li>
<li class="">Require status checks to pass before merging: on, so the preflight is enforced</li>
</ul>
<p>The preflight check is the gate, not a human sign-off. That sounds aggressive until you see what it replaces: instead of one person eyeballing a diff, the merge is bounded by a machine-enforced envelope. Low-severity waste can auto-merge once the preflight is green; you keep a human approver in the path for higher-severity classes by raising the required-approvals count on those. The same pattern extends to budget ceilings, region locks, and change-rate caps. Policy is the loop's safety mechanism, expressed as checks rather than as a meeting.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="onboarding-without-handing-over-keys">Onboarding without handing over keys<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#onboarding-without-handing-over-keys" class="hash-link" aria-label="Direct link to Onboarding without handing over keys" title="Direct link to Onboarding without handing over keys" translate="no">​</a></h2>
<p>The loop authenticates with OIDC and federated identity only - AWS <code>AssumeRoleWithWebIdentity</code>, GCP Workload Identity Federation, Azure federated credentials. There are no static cloud keys in the repo.</p>
<p>Bootstrap stays inside the cloud admin's own console session. The onboarding templates under <code>cicd/onboarding/</code> give you a one-click path per cloud: a CloudFormation "Launch Stack" URL for AWS, a <code>gcloud</code> script for GCP, an ARM "Deploy to Azure" template for Azure. The admin clicks, authenticates in their own console, and the only thing that comes back to the pipeline is a role ARN or a workload-identity provider. Nothing long-lived crosses a boundary. It is the same integration model SaaS security tools already use.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="run-it">Run it<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#run-it" class="hash-link" aria-label="Direct link to Run it" title="Direct link to Run it" translate="no">​</a></h2>
<p>End to end:</p>
<ol>
<li class="">Clone <a href="https://github.com/stackql-labs/stackql-ai-remediation" target="_blank" rel="noopener noreferrer" class="">stackql-labs/stackql-ai-remediation</a>.</li>
<li class="">Set branch protection on <code>main</code>: required approvals <code>0</code>, required status check for the preflight.</li>
<li class="">Run the onboarding template for each cloud you want to cover to create the OIDC role or binding.</li>
<li class="">Store the resulting role ARNs and WIF provider as repo secrets.</li>
<li class="">Dispatch the audit workflow, or let the schedule run it.</li>
</ol>
<p>Findings upload as workflow artifacts, proposals generate, and one pull request opens per finding. Merge a green one and watch the apply and post-check complete. A representative cross-cloud sweep here finished in a couple of minutes and surfaced a handful of unattached volumes, each as its own PR with the saving attached.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-this-shape">Why this shape<a href="https://stackql.io/blog/tutorials/ai-remediation-pull-requests#why-this-shape" class="hash-link" aria-label="Direct link to Why this shape" title="Direct link to Why this shape" translate="no">​</a></h2>
<p>The properties that make this worth running are all consequences of one decision: reach the control plane as data. Findings are data, the safety check is a query, the fix is a statement, and the record is the pull request. No new dashboard, no new vendor, no agent footprint in the estate. It is boring and inspectable, which is what you want from something allowed to change production.</p>
<p>The same loop runs for security posture and access findings by swapping the checks. That is the next post.</p>]]></content>
        <author>
            <name>Kieran Rimmer</name>
            <uri>https://www.linkedin.com/in/kieranrimmer/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="github-actions" term="github-actions"/>
        <category label="finops" term="finops"/>
        <category label="remediation" term="remediation"/>
        <category label="oidc" term="oidc"/>
        <category label="sre" term="sre"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Autonomous Edge Defense with AI Agents and SQL]]></title>
        <id>https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql</id>
        <link href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql"/>
        <updated>2026-06-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[An agentic loop that observes Cloudflare edge traffic, tightens rate limits in response, and writes an auditable decision trail to Kafka - all through one SQL interface.]]></summary>
        <content type="html"><![CDATA[<p>Edge defense is a natural fit for an agentic loop: traffic patterns shift constantly, rate-limit thresholds need to follow, and every adjustment should leave an auditable trail. The hard part is usually the plumbing - one API for analytics, another for the rate-limit control plane, another for the durable log.</p>
<p><strong>edgepilot</strong> collapses all of that to SQL. Two Claude agents - a recon agent and an action agent - observe a live Cloudflare zone, tighten its rate-limit rule when traffic warrants, and write a decision record to a Confluent Kafka topic. Neither agent knows anything about Cloudflare's GraphQL Analytics API, Cloudflare's rulesets engine, or Confluent's Kafka REST proxy. They know SQL. The <strong><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class="">StackQL MCP server</a></strong> does the rest.</p>
<div style="position:relative;padding-bottom:56.25%;height:0;overflow:hidden;max-width:100%;margin-bottom:1.5rem"><iframe style="position:absolute;top:0;left:0;width:100%;height:100%" src="https://www.youtube.com/embed/btCUiq1v29c?si=DI8HG7HvDc4zVh5R" title="edgepilot - two AI agents, one SQL interface, two clouds" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-setup">The setup<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#the-setup" class="hash-link" aria-label="Direct link to The setup" title="Direct link to The setup" translate="no">​</a></h2>
<p>The demo runs against a throwaway Cloudflare zone (<code>stackql.xyz</code>) and a freshly provisioned Confluent Cloud Kafka cluster. A small load generator drives synthetic traffic - some normal browsers, some AI-crawler user agents - at the zone so the analytics tables have something real to report.</p>
<!-- -->
<p>Both agents speak to a single MCP server - StackQL running in stdio mode - and that server fans out to whichever provider the query targets. The agents never see API URLs, auth headers, GraphQL query strings, or Kafka REST endpoints. They see tables.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-recon-agent">The recon agent<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#the-recon-agent" class="hash-link" aria-label="Direct link to The recon agent" title="Direct link to The recon agent" translate="no">​</a></h2>
<p>The recon agent runs three SELECTs. Notice that nothing in these queries hints that one is a managed cluster API, one is a GraphQL analytics endpoint, and one is a rulesets PUT/GET pair.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="-find-the-active-kafka-cluster">🔍 Find the active Kafka cluster<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#-find-the-active-kafka-cluster" class="hash-link" aria-label="Direct link to 🔍 Find the active Kafka cluster" title="Direct link to 🔍 Find the active Kafka cluster" translate="no">​</a></h3>
<div class="theme-tabs-container tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">Query</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">Results</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  id                                                                              </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> kafka_cluster_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.region'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">                                                  </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  LOWER</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.cloud'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">                                            </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> cloud_provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  SPLIT_PART</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">SPLIT_PART</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">spec</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.http_endpoint'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'//'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'.'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">  </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> kafka_endpoint_id</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> confluent</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">managed_kafka_clusters</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">clusters</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> environment </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'env-xxxxx'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|-----------|----------------|-------------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| kafka_cluster_id | region    | cloud_provider | kafka_endpoint_id |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|-----------|----------------|-------------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| lkc-abc123       | us-east-1 | aws            | pkc-xyz9w         |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|-----------|----------------|-------------------|</span><br></div></code></pre></div></div></div></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="-read-live-zone-analytics">📊 Read live zone analytics<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#-read-live-zone-analytics" class="hash-link" aria-label="Direct link to 📊 Read live zone analytics" title="Direct link to 📊 Read live zone analytics" translate="no">​</a></h3>
<p>This one talks to Cloudflare's GraphQL Analytics API under the hood. The agent sees a table.</p>
<div class="theme-tabs-container tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">Query</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">Results</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">datetime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> client_country_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> edge_response_status</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">       client_request_http_method_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> requests</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> bytes</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> cloudflare</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">zones</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">http_requests_adaptive_groups</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> zone_tag </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;zone_id&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain">   since    </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'2026-06-04T09:30:00Z'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain">   until    </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'2026-06-04T10:00:00Z'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------|---------------------|----------------------|---------------------------------|----------|--------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| datetime             | client_country_name | edge_response_status | client_request_http_method_name | requests | bytes  |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------|---------------------|----------------------|---------------------------------|----------|--------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| 2026-06-04T09:31:00Z | United States       | 200                  | GET                             | 412      | 184320 |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------|---------------------|----------------------|---------------------------------|----------|--------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| 2026-06-04T09:31:00Z | Germany             | 200                  | GET                             | 87       | 39424  |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------|---------------------|----------------------|---------------------------------|----------|--------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| 2026-06-04T09:32:00Z | United States       | 429                  | GET                             | 23       | 9728   |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------|---------------------|----------------------|---------------------------------|----------|--------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| 2026-06-04T09:34:00Z | Singapore           | 200                  | POST                            | 19       | 8442   |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------|---------------------|----------------------|---------------------------------|----------|--------|</span><br></div></code></pre></div></div></div></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="️-inspect-the-current-rate-limit-rule">🛡️ Inspect the current rate-limit rule<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#%EF%B8%8F-inspect-the-current-rate-limit-rule" class="hash-link" aria-label="Direct link to 🛡️ Inspect the current rate-limit rule" title="Direct link to 🛡️ Inspect the current rate-limit rule" translate="no">​</a></h3>
<div class="theme-tabs-container tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">Query</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">Results</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">       JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rules</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$[0].id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">                            </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> rule_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">       JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rules</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$[0].description'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">                   </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> description</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">       JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rules</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$[0].ratelimit.requests_per_period'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> threshold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">       JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rules</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$[0].ratelimit.period'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">              </span><span class="token keyword" style="color:rgb(127, 219, 202)">AS</span><span class="token plain"> period</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> cloudflare</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">rulesets</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">phases</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> zone_id       </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;zone_id&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain">   ruleset_phase </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'http_ratelimit'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------|----------------------------------|----------------------------------------|-----------|--------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| id                               | rule_id                          | description                            | threshold | period |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------|----------------------------------|----------------------------------------|-----------|--------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| 1a2b3c4d5e6f7890abcdef1234567890 | 9f8e7d6c5b4a3210fedcba9876543210 | edgepilot demo rule (managed by sqld)  | 100       | 10     |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------|----------------------------------|----------------------------------------|-----------|--------|</span><br></div></code></pre></div></div></div></div></div>
<p>The recon agent hands these results to the action agent as a short plain-text report.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-action-agent">The action agent<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#the-action-agent" class="hash-link" aria-label="Direct link to The action agent" title="Direct link to The action agent" translate="no">​</a></h2>
<p>The action agent does two things: tighten the rate limit on Cloudflare, then write a decision record to Confluent Kafka. Both are mutations, expressed as standard SQL.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="️-tighten-the-cloudflare-rate-limit">✏️ Tighten the Cloudflare rate limit<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#%EF%B8%8F-tighten-the-cloudflare-rate-limit" class="hash-link" aria-label="Direct link to ✏️ Tighten the Cloudflare rate limit" title="Direct link to ✏️ Tighten the Cloudflare rate limit" translate="no">​</a></h3>
<p>StackQL implements <code>REPLACE</code> against Cloudflare's modern rulesets PUT endpoint. The agent doesn't have to know that under the covers this is a full-document replace of every rule in the <code>http_ratelimit</code> phase entrypoint.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">REPLACE</span><span class="token plain"> cloudflare</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">rulesets</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">phases</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">SET</span><span class="token plain"> rules </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'[</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  {</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    "action": "block",</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    "ratelimit": {</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      "characteristics": ["ip.src", "cf.colo.id"],</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      "period": 10,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      "requests_per_period": 30,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">      "mitigation_timeout": 10</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    },</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    "expression": "len(http.request.uri.path) gt 0",</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    "description": "edgepilot demo rule (managed by stackql-deploy)",</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">    "enabled": true</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">  }</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string" style="color:rgb(173, 219, 103)">]'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> zone_id       </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;zone_id&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain">   ruleset_phase </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'http_ratelimit'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="-log-the-decision-to-kafka">📨 Log the decision to Kafka<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#-log-the-decision-to-kafka" class="hash-link" aria-label="Direct link to 📨 Log the decision to Kafka" title="Direct link to 📨 Log the decision to Kafka" translate="no">​</a></h3>
<p>And the action agent publishes a record to Confluent Kafka - again, as plain SQL. No producer client, no AVRO schema registry plumbing, no REST endpoint to look up. StackQL resolves the cluster's data-plane endpoint from the cluster id and posts the record.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">INTO</span><span class="token plain"> kafka</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">kafka</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">records</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  cluster_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> kafka_endpoint_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> cloud_provider</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  topic_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">key</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">value</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'lkc-abc123'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'pkc-xyz9w'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'aws'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'edge-autopilot-decisions'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'{"type":"STRING","data":"edgepilot.action"}'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'{"type":"JSON","data":{"agent":"action","action":"tighten_rate_limit","threshold":30,"reasoning":"elevated bot traffic, dropping threshold from 100 to 30","timestamp":"2026-06-04T10:00:00Z"}}'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>The record appears live in the <strong>Confluent Cloud UI -&gt; Topics -&gt; edge-autopilot-decisions -&gt; Messages</strong> tab.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-this-works-as-an-agentic-loop">Why this works as an agentic loop<a href="https://stackql.io/blog/tutorials/autonomous-edge-defense-ai-agents-sql#why-this-works-as-an-agentic-loop" class="hash-link" aria-label="Direct link to Why this works as an agentic loop" title="Direct link to Why this works as an agentic loop" translate="no">​</a></h2>
<p>Edge defense has three properties that make it well-suited to agents, and three properties that usually make it painful to wire up. SQL-over-MCP collapses the painful side:</p>
<ul>
<li class=""><em>The observe step (analytics), the act step (rate-limit control plane), and the audit step (durable log) normally each have their own SDK, auth model, and request shape. Here they're the same shape: a query.</em></li>
<li class=""><em>LLMs are reliable SQL generators - far more reliable than they are at chaining three provider-specific SDK calls correctly. Constrain the schema and the agent will stay on the rails.</em></li>
<li class=""><em>Adding a new signal source (WAF events, R2 logs, Workers analytics) or a new action surface (a different CDN, a different broker) is a registry pull, not a refactor of the agent loop.</em></li>
</ul>
<p>The whole loop - observe, decide, act, audit - takes about 30 to 60 seconds to run.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>The full demo, including infrastructure provisioning via <a href="https://github.com/stackql/stackql-deploy" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql-deploy</code></strong></a>, the load generator, and a Claude Desktop variant, is at <a href="https://github.com/stackql/edgepilot" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql/edgepilot</code></strong></a>.</p></div></div>
<p>Try wiring StackQL into your own agent loop:</p>
<ul>
<li class=""><em>Pick any provider in the <a href="https://registry.stackql.io/" target="_blank" rel="noopener noreferrer" class="">StackQL registry</a> and pull it.</em></li>
<li class=""><em>Point an MCP-aware client (Claude Desktop, Cline, or your own SDK loop) at the StackQL MCP server.</em></li>
<li class=""><em>Let the model discover the schema via <code>SHOW METHODS</code> and <code>DESCRIBE</code> - no fine-tuning, no provider-specific prompting.</em></li>
</ul>
<p>⭐ us on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a> and join our community!</p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="mcp" term="mcp"/>
        <category label="anthropic" term="anthropic"/>
        <category label="cloudflare" term="cloudflare"/>
        <category label="confluent" term="confluent"/>
        <category label="kafka" term="kafka"/>
        <category label="ai-agents" term="ai-agents"/>
        <category label="agentic" term="agentic"/>
        <category label="edge-security" term="edge-security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Run StackQL Queries from the Databricks Web Terminal]]></title>
        <id>https://stackql.io/blog/tutorials/stackql-in-databricks-web-terminal</id>
        <link href="https://stackql.io/blog/tutorials/stackql-in-databricks-web-terminal"/>
        <updated>2026-02-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Run StackQL SQL queries against your Databricks workspace directly from the Databricks web terminal.]]></summary>
        <content type="html"><![CDATA[<p>If you have access to a Databricks workspace, you can run StackQL queries directly from the Databricks Web Terminal using your Databricks identity.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-it-works">How It Works<a href="https://stackql.io/blog/tutorials/stackql-in-databricks-web-terminal#how-it-works" class="hash-link" aria-label="Direct link to How It Works" title="Direct link to How It Works" translate="no">​</a></h2>
<p>Download the latest release of <code>stackql</code>, then run the convenience script included (similar scripts are included for other cloud provider terminals - e.g. AWS Cloud Shell).</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">curl -L https://bit.ly/stackql-zip -O &amp;&amp; unzip stackql-zip</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-databricks-shell.sh</span><br></div></code></pre></div></div>
<video controls="" width="100%" preload="metadata"><source src="https://pub-690c90d9ca2e4ad09b9455b620bd429f.r2.dev/databricks-stackql-web-terminal-demo.mp4" type="video/mp4"></video>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-queries">Example Queries<a href="https://stackql.io/blog/tutorials/stackql-in-databricks-web-terminal#example-queries" class="hash-link" aria-label="Direct link to Example Queries" title="Direct link to Example Queries" translate="no">​</a></h2>
<p>Here are the sample queries run in the video, just change the <code>deployment_name</code> for your workspace.</p>
<p><strong>User entitlements</strong></p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  deployment_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  userName</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  displayName</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  entitlement</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> databricks_workspace</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">iam</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">vw_user_entitlements</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> deployment_name </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'dbc-74aa95f7-8c7e'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><strong>All workspace settings</strong></p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">*</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  databricks_workspace</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">settings</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">vw_all_settings</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> deployment_name </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'dbc-74aa95f7-8c7e'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><strong>Tag policies filtered by key prefix</strong></p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  tag_key </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">key</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  description</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> databricks_workspace</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">tags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">tag_policies</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> deployment_name </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'dbc-74aa95f7-8c7e'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> tag_key </span><span class="token operator" style="color:rgb(127, 219, 202)">LIKE</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'class%'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><strong>Catalog count by type</strong></p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  catalog_type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">COUNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(127, 219, 202)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> num_catalogs</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> databricks_workspace</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">catalog</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">catalogs</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> deployment_name </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'dbc-74aa95f7-8c7e'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">GROUP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">BY</span><span class="token plain"> catalog_type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="provider-coverage">Provider Coverage<a href="https://stackql.io/blog/tutorials/stackql-in-databricks-web-terminal#provider-coverage" class="hash-link" aria-label="Direct link to Provider Coverage" title="Direct link to Provider Coverage" translate="no">​</a></h2>
<p>The <code>databricks_workspace</code> provider covers workspace related services, the <code>databricks_account</code> provider covers account-level operations including provisioning, billing, and account IAM.</p>
<p>The web terminal flow covers workspace-scoped queries using the token of the logged-in user. For account-level queries (provisioning, billing, account IAM), you need a Databricks service principal with account admin rights and OAuth2 credentials:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">export DATABRICKS_ACCOUNT_ID="your-account-id"</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">export DATABRICKS_CLIENT_ID="your-client-id"</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">export DATABRICKS_CLIENT_SECRET="your-client-secret"</span><br></div></code></pre></div></div>
<p>These are the same variables used by the Databricks CLI and Terraform provider, so if you already have those configured the auth story is identical.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="get-started">Get Started<a href="https://stackql.io/blog/tutorials/stackql-in-databricks-web-terminal#get-started" class="hash-link" aria-label="Direct link to Get Started" title="Direct link to Get Started" translate="no">​</a></h2>
<p>Full provider documentation:</p>
<ul>
<li class=""><a href="https://databricks-workspace-provider.stackql.io/" target="_blank" rel="noopener noreferrer" class=""><strong>Databricks Workspace Provider for StackQL</strong></a></li>
<li class=""><a href="https://databricks-account-provider.stackql.io/" target="_blank" rel="noopener noreferrer" class=""><strong>Databricks Account Provider for StackQL</strong></a></li>
</ul>
<p>Visti <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>StackQL on GitHub</strong></a>.</p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="databricks" term="databricks"/>
        <category label="sql" term="sql"/>
        <category label="databricks workspace" term="databricks workspace"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[(Quickly) Identify Old Node Runtimes in AWS Lambda]]></title>
        <id>https://stackql.io/blog/tutorials/quickly-identify-old-node-runtimes-in-aws-lambda</id>
        <link href="https://stackql.io/blog/tutorials/quickly-identify-old-node-runtimes-in-aws-lambda"/>
        <updated>2025-04-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Query and interact with AWS resources using SQL.]]></summary>
        <content type="html"><![CDATA[<p>Have you been sent one of these?</p>
<p><strong>[Action Required] AWS Lambda end of support for Node.js 18 [AWS Account: 824123456789] [EU-CENTRAL-1]</strong></p>
<p>If you are like me and manage AWS accounts with numerous Lambda functions potentially deployed across multiple regions, you need to identify affected resources, in this case, Lambda node runtimes, which will be discontinued later this year. &nbsp;</p>
<p>With <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql</code></strong></a> this task is easy...</p>
<ol>
<li class="">Open AWS cloud shell in your AWS account (any region - it doesn't matter)</li>
<li class="">Download <code>stackql</code></li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">curl -L https://bit.ly/stackql-zip -O &amp;&amp; unzip stackql-zip</span><br></div></code></pre></div></div>
<ol start="3">
<li class="">Open an authenticated <code>stackql</code> command shell</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-aws-cloud-shell.sh</span><br></div></code></pre></div></div>
<ol start="4">
<li class="">Run some analytic queries using <code>stackql</code>; here are some examples...</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="-list-all-functions-and-runtimes-across-regions">🔍 List all functions and runtimes across regions<a href="https://stackql.io/blog/tutorials/quickly-identify-old-node-runtimes-in-aws-lambda#-list-all-functions-and-runtimes-across-regions" class="hash-link" aria-label="Direct link to 🔍 List all functions and runtimes across regions" title="Direct link to 🔍 List all functions and runtimes across regions" translate="no">​</a></h3>
<p>Run a stackql query to get the details about functions, runtimes, etc, deployed at any given time across one or more AWS regions. &nbsp;You can include all 25 AWS regions; each query will be performed asynchronously - speeding up the results.</p>
<div class="theme-tabs-container tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">Query</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">Results</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">select</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  function_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  runtime </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">lambda</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">functions </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">IN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| function_name                                | region        | runtime    |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| order-processing-handler                     | us-east-1     | nodejs16.x |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| payment-service-lambda                       | us-east-1     | nodejs18.x |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| user-notifications-service                   | us-east-1     | python3.8  |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| generate-invoice-pdf                         | eu-west-1     | nodejs18.x |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| realtime-data-stream-processor               | eu-west-1     | java11     |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| chat-message-router                          | eu-west-1     | nodejs20.x |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| scheduled-maintenance-checker                | ap-southeast-2| python3.11 |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| s3-image-thumbnail-generator                 | ap-southeast-2| nodejs16.x |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| email-delivery-status-updater                | ap-southeast-2| python3.8  |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|----------------------------------------------|---------------|------------|</span><br></div></code></pre></div></div></div></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="-group-by-runtime-and-region">📊 Group by runtime and region<a href="https://stackql.io/blog/tutorials/quickly-identify-old-node-runtimes-in-aws-lambda#-group-by-runtime-and-region" class="hash-link" aria-label="Direct link to 📊 Group by runtime and region" title="Direct link to 📊 Group by runtime and region" translate="no">​</a></h3>
<p>Perform an analytic query like a <code>group by aggregate</code> query such as...</p>
<div class="theme-tabs-container tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">Query</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">Results</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">select</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  runtime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">count</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(127, 219, 202)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> num_functions </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">lambda</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">functions </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">IN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">GROUP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">BY</span><span class="token plain"> runtime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| runtime      | region         | num_functions |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| nodejs16.x   | us-east-1      | 102           |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| nodejs18.x   | us-east-1      | 98            |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| python3.8    | us-east-1      | 138           |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| nodejs18.x   | eu-west-1      | 40            |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| java11       | eu-west-1      | 113           |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| nodejs20.x   | eu-west-1      | 120           |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| python3.11   | ap-southeast-2 | 384           |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| nodejs16.x   | ap-southeast-2 | 88            |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| python3.8    | ap-southeast-2 | 18            |</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------|----------------|---------------|</span><br></div></code></pre></div></div></div></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>You can easily visualise this data using a notebook; see <a href="https://github.com/stackql/stackql-codespaces-notebook" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql-codespaces-notebook</code></strong></a> or <a href="https://github.com/stackql/stackql-jupyter-demo" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql-jupyter-demo</code></strong></a>.</p></div></div>
<p>Using StackQL you can:</p>
<ul>
<li class=""><em>Quickly spot functions running on runtimes like <code>nodejs18.x</code> that are approaching end of support.</em></li>
<li class=""><em>Plan your upgrades region-by-region with confidence.</em></li>
</ul>
<p>⭐ us on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a> and join our community!</p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="aws" term="aws"/>
        <category label="amazon web services" term="amazon web services"/>
        <category label="iac" term="iac"/>
        <category label="analytics" term="analytics"/>
        <category label="lambda" term="lambda"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Identify Outdated TLS Versions in Azure with StackQL]]></title>
        <id>https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services</id>
        <link href="https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services"/>
        <updated>2024-10-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Use StackQL to identify Azure resources with outdated TLS versions and ensure compliance with security best practices.]]></summary>
        <content type="html"><![CDATA[<p>Have you received one of these?</p>
<p><img decoding="async" loading="lazy" alt="Azure TLS Deprecation Email" src="https://stackql.io/assets/images/azure-tls-deprecation-email-5fa5d990f1312e070728a4d66980ba6b.png" width="1041" height="684" class="img_ev3q"></p>
<p>Microsoft Azure is retiring TLS 1.0 and 1.1 for its services, requiring customers to transition to TLS 1.2 or later to ensure uninterrupted connectivity. If you have workloads still using older TLS versions, you’ll need to update them.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-stackql-to-identify-non-compliant-resources">Using StackQL to Identify Non-Compliant Resources<a href="https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services#using-stackql-to-identify-non-compliant-resources" class="hash-link" aria-label="Direct link to Using StackQL to Identify Non-Compliant Resources" title="Direct link to Using StackQL to Identify Non-Compliant Resources" translate="no">​</a></h2>
<p>With StackQL, you can quickly identify resources in your Azure environment that are still using older TLS versions. This article shows how to leverage StackQL queries to check various Azure services for compliance.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no">​</a></h3>
<ol>
<li class="">Pull the latest StackQL provider for Azure using <code>REGISTRY PULL azure</code>.</li>
<li class="">Authenticate with Azure using StackQL by setting up your credentials as environment variables (or using your existing <code>az login</code> system/session authentication).</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="queries-to-run">Queries to Run<a href="https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services#queries-to-run" class="hash-link" aria-label="Direct link to Queries to Run" title="Direct link to Queries to Run" translate="no">​</a></h3>
<p>Below are example queries you can use to identify resources affected by the TLS 1.2 requirement (use your <code>subscriptionId</code> of course):</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-check-application-gateway-configurations">1. Check Application Gateway Configurations<a href="https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services#1-check-application-gateway-configurations" class="hash-link" aria-label="Direct link to 1. Check Application Gateway Configurations" title="Direct link to 1. Check Application Gateway Configurations" translate="no">​</a></h4>
<p>Azure Application Gateways may support older TLS versions. Run the following query to get their configurations:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.sslPolicy'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> ssl_policy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.defaultPredefinedSslPolicy'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> default_predefined_ssl_policy</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    azure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">network</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">application_gateways</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	subscription_id </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'123e4567-e89b-12d3-a456-426614174000'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> ssl_policy </span><span class="token operator" style="color:rgb(127, 219, 202)">IS</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">NOT</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">NULL</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.sslPolicy'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">NOT</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">LIKE</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'%TLS12%'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>This query lists all Application Gateways configured with TLS versions lower than 1.2.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-inspect-app-service-configurations">2. Inspect App Service Configurations<a href="https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services#2-inspect-app-service-configurations" class="hash-link" aria-label="Direct link to 2. Inspect App Service Configurations" title="Direct link to 2. Inspect App Service Configurations" translate="no">​</a></h4>
<p>If you use Azure App Services (Web Apps), check their TLS configurations with this query:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.httpsOnly'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> https_only</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.siteConfig.minTlsVersion'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> min_tls_version</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    azure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">web</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">web_apps</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	subscription_id </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'123e4567-e89b-12d3-a456-426614174000'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.siteConfig.minTlsVersion'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&lt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'1.2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>This returns all web apps that allow connections using TLS versions older than 1.2.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-check-sql-server-instances">3. Check SQL Server Instances<a href="https://stackql.io/blog/tutorials/use-stackql-to-identify-old-tls-versions-for-azure-services#3-check-sql-server-instances" class="hash-link" aria-label="Direct link to 3. Check SQL Server Instances" title="Direct link to 3. Check SQL Server Instances" translate="no">​</a></h4>
<p>Azure SQL Databases and SQL Managed Instances may also have TLS configurations that need checking:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	location</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	fullyQualifiedDomainName</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	minimalTlsVersion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	state</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	azure</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">sql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">servers</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	subscription_id </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'123e4567-e89b-12d3-a456-426614174000'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> minimalTlsVersion </span><span class="token operator" style="color:rgb(127, 219, 202)">&lt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'1.2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>This shows all SQL servers with a minimal TLS version set below 1.2.</p>
<p>We’d love to hear your feedback. ⭐ us on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class="">GitHub</a> and let us know how StackQL helps you manage your Azure resources!</p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="azure" term="azure"/>
        <category label="microsoft" term="microsoft"/>
        <category label="microsoft azure" term="microsoft azure"/>
        <category label="stackql" term="stackql"/>
        <category label="stackql provider registry" term="stackql provider registry"/>
        <category label="multicloud" term="multicloud"/>
        <category label="asset management" term="asset management"/>
        <category label="cloud security" term="cloud security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Delete Default AWS VPCs with StackQL]]></title>
        <id>https://stackql.io/blog/tutorials/delete-default-aws-vpcs-with-stackql</id>
        <link href="https://stackql.io/blog/tutorials/delete-default-aws-vpcs-with-stackql"/>
        <updated>2024-07-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Use StackQL to delete default AWS VPCs across all regions to improve your cloud security posture.]]></summary>
        <content type="html"><![CDATA[<p>AWS creates default VPCs in each region for convenience. However, these default VPCs often contain noncompliant network ACLs and security group rules that do not align with best practices for AWS Config and Security Hub. Deleting these default VPCs is beneficial, especially for regions not used by your organization or architectures that do not utilize a VPC. &nbsp;</p>
<p>This guide demonstrates how to use StackQL to enumerate and delete all default VPCs and their associated resources in all AWS regions. &nbsp;</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-you-need">What you need<a href="https://stackql.io/blog/tutorials/delete-default-aws-vpcs-with-stackql#what-you-need" class="hash-link" aria-label="Direct link to What you need" title="Direct link to What you need" translate="no">​</a></h2>
<p>All you need to do is to install the <a href="https://pypi.org/project/pystackql/" target="_blank" rel="noopener noreferrer" class=""><code>pystackql</code></a> package using:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">pip install pystackql</span><br></div></code></pre></div></div>
<p>Deleting resources will require a privileged AWS IAM user. You can do this from a terminal with the <code>AWS_ACCESS_KEY_ID</code> and <code>AWS_SECRET_ACCESS_KEY</code> environment variables set (and optionally <code>AWS_SESSION_TOKEN</code> set if you are using <code>sts assume-role</code>). &nbsp;</p>
<p>You can also use the <a class="" href="https://stackql.io/blog/tutorials/using-stackql-in-native-cloud-shells-in-aws-azure-and-gcp#using-stackql-in-the-aws-cloud-shell">StackQL Cloud Shell Scripts</a>, from within AWS Cloud Shell, to run authenticated StackQL queries using:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-aws-cloud-shell.sh</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-it-works">How it works<a href="https://stackql.io/blog/tutorials/delete-default-aws-vpcs-with-stackql#how-it-works" class="hash-link" aria-label="Direct link to How it works" title="Direct link to How it works" translate="no">​</a></h2>
<p>This example uses the <a href="https://awscc-provider.stackql.io/" target="_blank" rel="noopener noreferrer" class=""><strong><code>awscc</code></strong></a> (AWS Cloud Control) provider. Cloud Control resources are read in two steps: a <code>_list_only</code> view returns the resource identifiers in a region, and the resource view returns the full properties for a single resource selected by its <code>Identifier</code>.</p>
<p>Default VPCs in AWS regions have a CIDR block of <strong><code>172.31.0.0/16</code></strong>, before deleting anything, the program ensures it is not in use by listing the network interfaces in the region and checking whether any belong to the VPC:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> id</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> awscc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">ec2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">network_interfaces_list_only</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'{region}'</span><br></div></code></pre></div></div>
<p>If any resources are using the VPC (such as EC2, RDS, ELB/ALB, VPC attached Lambda functions, etc), it will skip these VPCs. &nbsp;Once determined that the VPC is not in use, all of the resources associated with the VPC must be deleted before the VPC itself can be deleted; this includes:</p>
<ul>
<li class="">External Routes (awscc.ec2.routes)</li>
<li class="">Internet Gateways (awscc.ec2.internet_gateways)</li>
<li class="">NACLs (awscc.ec2.network_acls)</li>
<li class="">Subnets (awscc.ec2.subnets)</li>
<li class="">and then finally, the VPC (awscc.ec2.vpcs)</li>
</ul>
<blockquote>
<p>The default route table and default security group are deleted automatically when deleting the VPC</p>
</blockquote>
<p>This is done by discovering the resources using StackQL <code>SELECT</code> queries and deleting them using StackQL <code>DELETE</code> queries, like:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">DELETE FROM awscc.ec2.network_acls</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">WHERE data__Identifier = '{nacl_id}'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">AND region = '{region}'</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="complete-code">Complete code<a href="https://stackql.io/blog/tutorials/delete-default-aws-vpcs-with-stackql#complete-code" class="hash-link" aria-label="Direct link to Complete code" title="Direct link to Complete code" translate="no">​</a></h2>
<p>The following Python program uses StackQL to list and delete default VPCs and their associated resources (subnets, route tables, internet gateways, security groups, and network ACLs) across all AWS regions.</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>Get the complete code here</summary><div><div class="collapsibleContent_i85q"><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">from</span><span class="token plain"> pystackql </span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> StackQL</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> StackQL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">executeStmt</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"REGISTRY PULL awscc"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ensure_one_or_zero</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">resource_list</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> resource_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">len</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">resource_list</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">raise</span><span class="token plain"> RuntimeError</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"ah snap! multiple default </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">resource_name</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> resources found in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">elif</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">len</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">resource_list</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">==</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* no default </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">resource_name</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> found in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">return</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">False</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">return</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">True</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">get_resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> identifier</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># fetch the full properties of a single Cloud Control resource by its identifier</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    rows </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">        SELECT *</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">        FROM awscc.ec2.</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">resource</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">        WHERE region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">        AND Identifier = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">identifier</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">return</span><span class="token plain"> rows</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">len</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rows</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">else</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">find_in_vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> id_col</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># list all identifiers for a resource in a region, then keep those attached to the target VPC</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    matches </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> row </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"SELECT </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">id_col</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> FROM awscc.ec2.</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">resource</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">_list_only WHERE region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        detail </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> get_resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> row</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">id_col</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> detail </span><span class="token keyword" style="color:rgb(127, 219, 202)">and</span><span class="token plain"> detail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">'vpc_id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">==</span><span class="token plain"> vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            matches</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">append</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">detail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">return</span><span class="token plain"> matches</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">regions </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'us-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'us-west-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-central-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-central-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-3'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-north-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'eu-south-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-south-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-south-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-3'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-3'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-4'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'af-south-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string" style="color:rgb(173, 219, 103)">'ca-central-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'me-south-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'me-central-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'sa-east-1'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> region </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> regions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># find the default VPC (CIDR 172.31.0.0/16, untagged) by listing VPCs then inspecting each</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    default_vpcs </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> row </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"SELECT vpc_id FROM awscc.ec2.vpcs_list_only WHERE region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        vpc </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> get_resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'vpcs'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> row</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'vpc_id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> vpc </span><span class="token keyword" style="color:rgb(127, 219, 202)">and</span><span class="token plain"> vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">'cidr_block'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">==</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'172.31.0.0/16'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">and</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">not</span><span class="token plain"> vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">'tags'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">            default_vpcs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">append</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">not</span><span class="token plain"> ensure_one_or_zero</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">default_vpcs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'VPC'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">continue</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    vpc_id </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> default_vpcs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'vpc_id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># check if the VPC is in use</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    network_interfaces </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> find_in_vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'network_interfaces'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(130, 170, 255)">len</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">network_interfaces</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* skipping deletion of default VPC (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">vpc_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> because it is in use */\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">continue</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* deleting resources for default VPC (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">vpc_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># get the default route table for the VPC</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    route_tables </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> find_in_vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'route_tables'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'route_table_id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    ensure_one_or_zero</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">route_tables</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'route table'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    route_table_id </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> route_tables</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'route_table_id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># get the internet gateway from the default (0.0.0.0/0) route</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    default_route </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> get_resource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'routes'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">route_table_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">|0.0.0.0/0'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    inet_gateway_id </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> default_route</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'gateway_id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">if</span><span class="token plain"> default_route </span><span class="token keyword" style="color:rgb(127, 219, 202)">else</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">None</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># delete the default route</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* deleting default VPC routes in route table (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">route_table_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">DELETE FROM awscc.ec2.routes</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">WHERE data__Identifier = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">route_table_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">|0.0.0.0/0'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">AND region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">';</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># detach the internet gateway</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* detaching default VPC internet gateway (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">inet_gateway_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">DELETE FROM awscc.ec2.vpc_gateway_attachments</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">WHERE data__Identifier = 'IGW|</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">vpc_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">AND region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">';</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># delete the internet gateway</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* deleting default VPC internet gateway (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">inet_gateway_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">DELETE FROM awscc.ec2.internet_gateways</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">WHERE data__Identifier = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">inet_gateway_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">AND region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">';</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># delete the network ACL</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    nacls </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> find_in_vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'network_acls'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    ensure_one_or_zero</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">nacls</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'network acl'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    nacl_id </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> nacls</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* deleting default VPC NACL (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">nacl_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">DELETE FROM awscc.ec2.network_acls</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">WHERE data__Identifier = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">nacl_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">AND region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">';</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># delete the subnets</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    subnets </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> find_in_vpc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'subnets'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'subnet_id'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> vpc_id</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> subnet </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> subnets</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* deleting default VPC subnet (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">subnet</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string-interpolation interpolation string" style="color:rgb(173, 219, 103)">'subnet_id'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">DELETE FROM awscc.ec2.subnets</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">WHERE data__Identifier = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">subnet</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string-interpolation interpolation string" style="color:rgb(173, 219, 103)">'subnet_id'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">AND region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">';</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">        """</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># delete the VPC</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"/* deleting default VPC (</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">vpc_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">) in </span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)"> */"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">DELETE FROM awscc.ec2.vpcs</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">WHERE data__Identifier = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">vpc_id</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">AND region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">';</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div></div></div></details>
<p>run the program using:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">python3 delete-all-default-vpcs.py &gt; delete_default_vpcs.iql</span><br></div></code></pre></div></div>
<p>to generate a StackQL script you can run as a batch using <code>stackql exec</code> or as individual statements in the <code>stackql shell</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="conclusion">Conclusion<a href="https://stackql.io/blog/tutorials/delete-default-aws-vpcs-with-stackql#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Deleting default VPCs can help improve your AWS security posture by removing potentially noncompliant network configurations. This program leverages StackQL to automate the process, ensuring consistency across all regions.</p>
<p>Let us know what you think! ⭐ us on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a>.</p>]]></content>
        <author>
            <name>Kieran Rimmer</name>
            <uri>https://www.linkedin.com/in/kieranrimmer/</uri>
        </author>
        <category label="aws" term="aws"/>
        <category label="amazon web services" term="amazon web services"/>
        <category label="stackql" term="stackql"/>
        <category label="cloud security" term="cloud security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Google Firewall Analysis using StackQL]]></title>
        <id>https://stackql.io/blog/tutorials/google-firewall-analysis-using-stackql</id>
        <link href="https://stackql.io/blog/tutorials/google-firewall-analysis-using-stackql"/>
        <updated>2024-06-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Deploy, configure and query GCP resources using SQL.]]></summary>
        <content type="html"><![CDATA[<p>Analyzing firewall rules is crucial for maintaining security in your cloud infrastructure. Using StackQL, you can efficiently query and analyze Google Cloud firewall configurations to ensure that your security policies are correctly implemented and that there are no unexpected open ports or protocols that might pose a security risk. Below is a simple query that retrieves important details about the ingress firewall rules for a specific network in a Google Cloud project.</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	source_range</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	ip_protocol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	allowed_ports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	direction</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	source_ranges</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">value</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> source_range</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">allowed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.IPProtocol'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> ip_protocol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	JSON_EXTRACT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">allowed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.ports'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> allowed_ports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	direction</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">compute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">firewalls</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> json_each</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sourceRanges</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> source_ranges</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> json_each</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">allowed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> allowed</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> project </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql-k8s-the-hard-way-demo'</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> network </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'https://www.googleapis.com/compute/v1/projects/stackql-k8s-the-hard-way-demo/global/networks/kubernetes-the-hard-way-dev-vpc'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> t </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">source_range </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'0.0.0.0/0'</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">and</span><span class="token plain"> direction </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'INGRESS'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>This query provides a comprehensive list of all ingress firewall rules that apply to any IP address (<code>0.0.0.0/0</code>) within the specified Google Cloud project and network. The results include the firewall rule name, the source IP range, the protocol, the allowed ports, and the direction of the traffic, an example is shown below:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------|                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|                     name                      | source_range | ip_protocol | allowed_ports | direction |                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------|                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| default-allow-icmp                            | 0.0.0.0/0    | icmp        | null          | INGRESS   |                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------|                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| default-allow-rdp                             | 0.0.0.0/0    | tcp         | ["3389"]      | INGRESS   |                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------|                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| default-allow-ssh                             | 0.0.0.0/0    | tcp         | ["22"]        | INGRESS   |                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------|                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| kubernetes-the-hard-way-dev-allow-external-fw | 0.0.0.0/0    | tcp         | ["22"]        | INGRESS   |                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------|                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| kubernetes-the-hard-way-dev-allow-external-fw | 0.0.0.0/0    | tcp         | ["6443"]      | INGRESS   |                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------|                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| kubernetes-the-hard-way-dev-allow-external-fw | 0.0.0.0/0    | icmp        | null          | INGRESS   |                                                                                         </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|-----------------------------------------------|--------------|-------------|---------------|-----------| </span><br></div></code></pre></div></div>
<p>You can use this query to help quickly identify potential security vulnerabilities. Regularly auditing these rules ensures that your cloud environment remains secure and that only the necessary ports and protocols are open to the internet.</p>
<p>Give us your feedback! ⭐ us <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>here</strong></a>!</p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="google" term="google"/>
        <category label="gcp" term="gcp"/>
        <category label="google cloud platform" term="google cloud platform"/>
        <category label="iac" term="iac"/>
        <category label="analytics" term="analytics"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The 5 Minute Global AWS Inventory]]></title>
        <id>https://stackql.io/blog/tutorials/the-5-minute-global-aws-inventory</id>
        <link href="https://stackql.io/blog/tutorials/the-5-minute-global-aws-inventory"/>
        <updated>2024-03-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Inventory all resources across all regions in an AWS account.]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>StackQL</strong></a> allows you to query and interact with your cloud and SaaS assets using a simple SQL framework.  Use cases include CSPM, asset inventory and analysis, finops and more, as well as IaC and sysops (lifecycle management).</p>
</blockquote>
<p>Using stackql and the <a href="https://aws.stackql.io/providers/aws/" target="_blank" rel="noopener noreferrer" class=""><strong><code>aws</code></strong></a> provider (AWS Cloud Control provider for <code>stackql</code>), here's how you can query your <strong>entire AWS estate</strong> in <strong>real time <em>(globally)</em></strong> and generate a simple report like this...</p>
<p><img decoding="async" loading="lazy" alt="aws-inventory-example" src="https://stackql.io/assets/images/aws-inventory-f703b04dd42b061f3f7324a9e8a25065.png" width="628" height="746" class="img_ev3q"></p>
<p>Check out the code at <a class="" href="https://stackql.io/quick-starts/aws/aws-global-inventory"><strong>AWS Global Inventory</strong></a>!</p>
<p>Visit us and give us a ⭐ on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a></p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="aws" term="aws"/>
        <category label="stackql" term="stackql"/>
        <category label="cloud inventory" term="cloud inventory"/>
        <category label="finops" term="finops"/>
        <category label="asset management" term="asset management"/>
        <category label="cloud security" term="cloud security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Using StackQL in Native Cloud Shells in AWS, Azure and GCP]]></title>
        <id>https://stackql.io/blog/tutorials/using-stackql-in-native-cloud-shells-in-aws-azure-and-gcp</id>
        <link href="https://stackql.io/blog/tutorials/using-stackql-in-native-cloud-shells-in-aws-azure-and-gcp"/>
        <updated>2024-02-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Run StackQL direct in AWS, Azure and GCP Cloud Shells.]]></summary>
        <content type="html"><![CDATA[<blockquote>
<p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>StackQL</strong></a> allows you to query and interact with your cloud and SaaS assets using a simple SQL framework.  Use cases include CSPM, asset inventory and analysis, finops and more, as well as our IaC and ops (lifecycle management).</p>
</blockquote>
<p>The three major cloud providers all offer a built-in Linux shell for executing commands using their respective CLIs; in some cases, they come with tools like <code>terraform</code> pre-installed. They are pre-authorized with your credentials in the cloud console for the user you authenticated with.</p>
<p>Now you can easily use <code>stackql</code> - a unified analytics and IaC dev tool - in all major cloud providers' built-in shells, using cloud shell scripts packaged with the <code>stackql</code> Linux binary (available from v0.5.587 onwards).</p>
<p>StackQL is particularly useful for asynchronously querying across regions in AWS, projects in Google, or resource groups in Azure, which is challenging to do via the CLIs.  For example:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">COUNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(127, 219, 202)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> num_functions</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">lambda</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">functions</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">IN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'us-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'us-west-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-south-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-3'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'ca-central-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-central-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-3'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-north-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'sa-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">GROUP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">BY</span><span class="token plain"> region</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Additionally, you could authenticate to another provider from one cloud shell simultaneously and run multi-cloud inventory commands. For example:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  SPLIT_PART</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">machineType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'/'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">-</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> instance_type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'google'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> provider</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">compute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">instances </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> project </span><span class="token operator" style="color:rgb(127, 219, 202)">IN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">'myproject1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'myproject2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">UNION</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  instanceId </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  instanceType </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> instance_type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'aws'</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> provider</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">ec2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">instances </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">IN</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'us-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'us-west-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-south-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-3'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-southeast-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'ap-northeast-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'ca-central-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-central-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">	</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-west-3'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'eu-north-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'sa-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="getting-started">Getting Started<a href="https://stackql.io/blog/tutorials/using-stackql-in-native-cloud-shells-in-aws-azure-and-gcp#getting-started" class="hash-link" aria-label="Direct link to Getting Started" title="Direct link to Getting Started" translate="no">​</a></h2>
<p>To get started with StackQL in your preferred cloud shell environment, download the StackQL package using the following command:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">curl -L https://bit.ly/stackql-zip -O \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">&amp;&amp; unzip stackql-zip</span><br></div></code></pre></div></div>
<p>This command downloads the StackQL package, unzips it, and sets the appropriate permissions. From there, you can use our tailored scripts for AWS, Google Cloud, or Azure to integrate StackQL seamlessly into your cloud shell environment.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-stackql-in-the-aws-cloud-shell">Using StackQL in the AWS Cloud Shell<a href="https://stackql.io/blog/tutorials/using-stackql-in-native-cloud-shells-in-aws-azure-and-gcp#using-stackql-in-the-aws-cloud-shell" class="hash-link" aria-label="Direct link to Using StackQL in the AWS Cloud Shell" title="Direct link to Using StackQL in the AWS Cloud Shell" translate="no">​</a></h2>
<p>Run the <code>stackql-aws-cloud-shell.sh</code> as follows to use the StackQL command shell within the AWS cloud shell:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-aws-cloud-shell.sh</span><br></div></code></pre></div></div>
<p>An example is shown here:</p>
<p><img decoding="async" loading="lazy" alt="aws-cloud-shell-example" src="https://stackql.io/assets/images/aws-cloud-shell-example-3a8cc7e00dd4dd132225128dd532aeee.png" width="916" height="765" class="img_ev3q"></p>
<p>You can also run <code>stackql exec</code> commands using the stackql-aws-cloud-shell.sh script; for instance, this command will write a CSV file for the results of a query that could be downloaded from the Cloud Shell.</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-aws-cloud-shell.sh exec \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">--output csv --outfile instances.csv \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">"SELECT region, instanceType FROM aws.ec2.instances WHERE region IN ('us-east-1')"</span><br></div></code></pre></div></div>
<p>Additionally, you can supply an IAM role using the <code>--role-arn</code> argument to assume another role for your query or mutation operation, an example is shown here:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-aws-cloud-shell.sh \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">--role-arn arn:aws:iam::824532806693:role/SecurityReviewerRole exec \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">--infile query.iql \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">--output csv --outfile output.csv</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-stackql-in-the-azure-cloud-shell">Using StackQL in the Azure Cloud Shell<a href="https://stackql.io/blog/tutorials/using-stackql-in-native-cloud-shells-in-aws-azure-and-gcp#using-stackql-in-the-azure-cloud-shell" class="hash-link" aria-label="Direct link to Using StackQL in the Azure Cloud Shell" title="Direct link to Using StackQL in the Azure Cloud Shell" translate="no">​</a></h2>
<p>Run the <code>stackql-azure-cloud-shell.sh</code> as follows to open a StackQL command shell from the Azure Cloud Shell:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-azure-cloud-shell.sh</span><br></div></code></pre></div></div>
<p>An example is shown here:</p>
<p><img decoding="async" loading="lazy" alt="azure-cloud-shell-example" src="https://stackql.io/assets/images/azure-cloud-shell-example-e4bc3549f97efb25bc9dc325669c3259.png" width="916" height="765" class="img_ev3q"></p>
<p>Similar to the AWS script, you can also invoke <code>stackql exec</code> as well, an example is shown here:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-azure-cloud-shell.sh exec \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">--output csv --outfile instances_by_location.csv \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">"SELECT location, COUNT(*) as num_instances FROM azure.compute.virtual_machines WHERE resource_group_name =  'stackql-ops-cicd-dev-01' AND subscription_id = '631d1c6d-2a65-43e7-93c2-688bfe4e1468' GROUP BY location"</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-stackql-in-the-google-cloud-shell">Using StackQL in the Google Cloud Shell<a href="https://stackql.io/blog/tutorials/using-stackql-in-native-cloud-shells-in-aws-azure-and-gcp#using-stackql-in-the-google-cloud-shell" class="hash-link" aria-label="Direct link to Using StackQL in the Google Cloud Shell" title="Direct link to Using StackQL in the Google Cloud Shell" translate="no">​</a></h2>
<p>Run the <code>stackql-google-cloud-shell.sh</code> as shown below to launch a StackQL command shell from within the google cloud shell:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-google-cloud-shell.sh</span><br></div></code></pre></div></div>
<p>An example is shown here:</p>
<p><img decoding="async" loading="lazy" alt="google-cloud-shell-example" src="https://stackql.io/assets/images/google-cloud-shell-example-64dd020058af8c86137cf28d7f3e5601.png" width="916" height="765" class="img_ev3q"></p>
<p>As with the other two providers, you can run <code>exec</code> commands following the example below:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">sh stackql-google-cloud-shell.sh exec \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">--output csv --outfile instances.csv \</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">"SELECT name, status FROM google.compute.instances WHERE project = 'stackql-demo'"</span><br></div></code></pre></div></div>
<p>Please give us your feedback!  Star us at <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>github.com/stackql</strong></a>.</p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="azure" term="azure"/>
        <category label="aws" term="aws"/>
        <category label="google" term="google"/>
        <category label="stackql" term="stackql"/>
        <category label="stackql provider registry" term="stackql provider registry"/>
        <category label="multicloud" term="multicloud"/>
        <category label="asset management" term="asset management"/>
        <category label="cloud security" term="cloud security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Cloud and SaaS Visibility with StackQL and PowerBI]]></title>
        <id>https://stackql.io/blog/tutorials/cloud-and-saas-visibility-with-stackql-and-powerbi</id>
        <link href="https://stackql.io/blog/tutorials/cloud-and-saas-visibility-with-stackql-and-powerbi"/>
        <updated>2023-12-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[stackql is a dev tool that allows you to query and manage cloud and SaaS resources using SQL, which developers and analysts can use for CSPM, assurance, user access management reporting, IaC, XOps and more.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql</code></strong></a> is a dev tool that allows you to query and manage cloud and SaaS resources using SQL, which developers and analysts can use for CSPM, assurance, user access management reporting, IaC, XOps and more.</p></div></div>
<p>You can leverage the powerful combination of StackQL and PowerBI to create comprehensive dashboard interfaces. These dashboards are perfect for reporting on various aspects such as cloud security, inventory, and configuration.</p>
<p><img decoding="async" loading="lazy" alt="stackql-powerbi-dashboard" src="https://stackql.io/assets/images/stackql-powerbi-dashboard-8fbeb73db9da1bbb96ec502b528c47f6.png" width="1920" height="1080" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="quick-start-guide">Quick Start Guide<a href="https://stackql.io/blog/tutorials/cloud-and-saas-visibility-with-stackql-and-powerbi#quick-start-guide" class="hash-link" aria-label="Direct link to Quick Start Guide" title="Direct link to Quick Start Guide" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="set-up-stackql-server">Set Up StackQL Server<a href="https://stackql.io/blog/tutorials/cloud-and-saas-visibility-with-stackql-and-powerbi#set-up-stackql-server" class="hash-link" aria-label="Direct link to Set Up StackQL Server" title="Direct link to Set Up StackQL Server" translate="no">​</a></h3>
<p>To get started, you can run a StackQL server container on port 7432. Use the following project for easy setup: <a href="https://github.com/stackql/stackql-server" target="_blank" rel="noopener noreferrer" class="">StackQL Server on GitHub</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="create-an-odbc-connection">Create an ODBC Connection<a href="https://stackql.io/blog/tutorials/cloud-and-saas-visibility-with-stackql-and-powerbi#create-an-odbc-connection" class="hash-link" aria-label="Direct link to Create an ODBC Connection" title="Direct link to Create an ODBC Connection" translate="no">​</a></h3>
<p>Next, set up an ODBC connection using the PostgreSQL ODBC driver. You can download the latest driver from the <a href="https://www.postgresql.org/ftp/odbc/versions/msi/" target="_blank" rel="noopener noreferrer" class="">PostgreSQL ODBC Driver Versions</a>. Install this driver on your local machine to proceed.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="integrating-with-powerbi">Integrating with PowerBI<a href="https://stackql.io/blog/tutorials/cloud-and-saas-visibility-with-stackql-and-powerbi#integrating-with-powerbi" class="hash-link" aria-label="Direct link to Integrating with PowerBI" title="Direct link to Integrating with PowerBI" translate="no">​</a></h3>
<p>Once your ODBC connection is ready, you can move on to PowerBI. Here’s how you can integrate StackQL queries into PowerBI:</p>
<ol>
<li class="">
<p><strong>Create Data Sources in PowerBI</strong>: For each StackQL query that you want to visualize, create a new data source in PowerBI.</p>
</li>
<li class="">
<p><strong>Test Queries Locally</strong>: Before integrating with PowerBI, you can test your StackQL queries locally using <code>psql</code>. For example:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">$ psql -h localhost -p 7432 -U stackql -d stackql</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1), server 0.0.0)</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">Type "help" for help.</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql=&gt; select name, stargazers FROM</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">(select name, stargazers_count as stargazers</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">from github.repos.repos </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">where org = 'stackql' </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">and visibility = 'public'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">order by stargazers_count desc) t</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">limit 3;</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">               name                | stargazers </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">-----------------------------------+------------</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> stackql                           | 179</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> stackql-provider-registry         | 21</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> google-discovery-to-openapi       | 18</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">(3 rows)</span><br></div></code></pre></div></div>
</li>
<li class="">
<p><strong>Visualize with PowerBI</strong>: With your named data sources created, you can now visualize the result sets in PowerBI. Use various visualization tools like bar charts, pie charts, and line charts to create rich and insightful dashboards.</p>
</li>
</ol>
<p>Let us know your thoughts! Visit us and give us a ⭐ on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a></p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="powerbi" term="powerbi"/>
        <category label="inventory" term="inventory"/>
        <category label="cpsm" term="cpsm"/>
        <category label="analytics" term="analytics"/>
        <category label="reporting" term="reporting"/>
        <category label="dashboards" term="dashboards"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Query Resources Across AWS Regions Asynchronously]]></title>
        <id>https://stackql.io/blog/tutorials/query-resources-across-aws-regions-asynchronously</id>
        <link href="https://stackql.io/blog/tutorials/query-resources-across-aws-regions-asynchronously"/>
        <updated>2023-11-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[stackql is a dev tool that allows you to query and manage cloud and SaaS resources using SQL, which developers and analysts can use for CSPM, assurance, user access management reporting, IaC, XOps and more.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql</code></strong></a> is a dev tool that allows you to query and manage cloud and SaaS resources using SQL, which developers and analysts can use for CSPM, assurance, user access management reporting, IaC, XOps and more.</p></div></div>
<p>Most AWS services and resources are regionally scoped, meaning the UI, CLI, SDKs, and all other methods of querying the aws provider give you a regional view (<code>us-east-1</code> or <code>ap-southeast-2</code>, for instance).  Many customer AWS estates span multiple regions - for multinational organizations, for example, or organizations with numerous dispersed locations within the US.</p>
<p>Sure, you could write custom scripts wrapping the CLI or SDKs - which would require development effort (not reusable for other providers); or get an abstract view with tools like AWS Config or Systems Manager, which requires these services to be enabled and configured (not flexible and not extendible to other providers).  In either case:</p>
<ol>
<li class="">You can't write and run customized queries and generate custom reports - as you can do in SQL</li>
<li class="">Any solutions you build will have to be rebuilt entirely for other providers</li>
</ol>
<p>Using the latest (<a href="https://aws.stackql.io/providers/aws/" target="_blank" rel="noopener noreferrer" class=""><strong>AWS provider for StackQL</strong></a> - which leverages the AWS Cloud Control API) and the <a href="https://pystackql.readthedocs.io/en/latest/_modules/pystackql/stackql.html#StackQL.executeQueriesAsync" target="_blank" rel="noopener noreferrer" class=""><code>executeQueriesAsync</code></a> method in the <a href="https://pystackql.readthedocs.io/en/latest/index.html" target="_blank" rel="noopener noreferrer" class=""><code>pystackql</code></a> Python package, I've put together an example here which runs a query to bring back attributes from all AWS Lambda functions deployed across 17 different AWS regions asynchronously.  Results can be returned as a list of Python dictionaries or a Pandas dataframe.  I am doing the former here, which took less than 10s.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">from</span><span class="token plain"> pystackql </span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> StackQL</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">from</span><span class="token plain"> pprint </span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> pprint</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">from</span><span class="token plain"> asyncio </span><span class="token keyword" style="color:rgb(127, 219, 202)">import</span><span class="token plain"> run</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> StackQL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">executeStmt</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(173, 219, 103)">"REGISTRY PULL aws"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># not required if the aws provider is already installed</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">async</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">stackql_async_queries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">queries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">await</span><span class="token plain"> stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">executeQueriesAsync</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">queries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">regions</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"us-east-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"us-east-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"us-west-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"us-west-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"ap-south-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"ap-northeast-3"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"ap-northeast-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"ap-southeast-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">         </span><span class="token string" style="color:rgb(173, 219, 103)">"ap-southeast-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"ap-northeast-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"ca-central-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"eu-central-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"eu-west-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"eu-west-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"eu-west-3"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">"eu-north-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">          </span><span class="token string" style="color:rgb(173, 219, 103)">"sa-east-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># list functions from all regions asynchronously</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">get_fns </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    SELECT region, FunctionName AS function_name</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    FROM aws.lambda.functions</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    WHERE region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> region </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> regions</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">functions </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">stackql_async_queries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">get_fns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># get function details for all functions across all regions asynchronously</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">get_fn_details </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    SELECT </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    JSON_EXTRACT(Configuration, '$.FunctionName') AS function_name,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    region,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    JSON_EXTRACT(Configuration, '$.FunctionArn') AS arn,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    JSON_EXTRACT(Configuration, '$.Description') AS description,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    JSON_EXTRACT(Configuration, '$.Architectures') AS architectures,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    JSON_EXTRACT(Configuration, '$.MemorySize') AS memory_size,</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    JSON_EXTRACT(Configuration, '$.Runtime') AS runtime</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    FROM aws.lambda.functions</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    WHERE region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">function</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string-interpolation interpolation string" style="color:rgb(173, 219, 103)">'region'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    AND data__Identifier = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">function</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string-interpolation interpolation string" style="color:rgb(173, 219, 103)">'function_name'</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> function </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> functions</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">function_details </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">stackql_async_queries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">get_fn_details</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">pprint</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">function_details</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>which returns...</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string" style="color:rgb(173, 219, 103)">'architectures'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'["x86_64"]'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'arn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'arn:aws:lambda:us-east-1:824532806693:function:stackql-helloworld-fn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'description'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">''</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'function_name'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql-helloworld-fn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'memory_size'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'128'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'region'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'runtime'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'nodejs18.x'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string" style="color:rgb(173, 219, 103)">'architectures'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'["x86_64"]'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'arn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'arn:aws:lambda:us-east-2:824532806693:function:stackql-helloworld-fn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'description'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">''</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'function_name'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql-helloworld-fn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'memory_size'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'128'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'region'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-2'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'runtime'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'nodejs18.x'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string" style="color:rgb(173, 219, 103)">'architectures'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'["x86_64"]'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'arn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'arn:aws:lambda:us-west-1:824532806693:function:stackql-helloworld-fn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'description'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">''</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'function_name'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql-helloworld-fn'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'memory_size'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'128'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'region'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'us-west-1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'runtime'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'nodejs18.x'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><br></div></code></pre></div></div>
<p>You could customize the StackQL query to run specific reports and visualize the results in a Jupyter notebook, for example:</p>
<ul>
<li class="">Functions by runtimes</li>
<li class="">Function by memory size</li>
<li class="">Functions by tags</li>
<li class="">etc...</li>
</ul>
<p>You could do something similar for other hyperscalars, for example, GCP, which scopes resources by projects, or Azure, which scopes resources by resource groups.</p>
<p>Let us know your thoughts! Visit us and give us a ⭐ on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a></p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="aws" term="aws"/>
        <category label="inventory" term="inventory"/>
        <category label="cpsm" term="cpsm"/>
        <category label="analytics" term="analytics"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Use StackQL in Codespaces]]></title>
        <id>https://stackql.io/blog/tutorials/use-stackql-in-codespaces</id>
        <link href="https://stackql.io/blog/tutorials/use-stackql-in-codespaces"/>
        <updated>2023-11-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[GitHub Codespaces is a development environment completely hosted online, enabling seamless development without setting up local machines.  One of the great features of Codespaces is its compatibility with IPython, providing an interactive computing environment to test and prototype StackQL queries.]]></summary>
        <content type="html"><![CDATA[<p>GitHub Codespaces is a development environment completely hosted online, enabling seamless development without setting up local machines.  One of the great features of Codespaces is its compatibility with IPython, providing an interactive computing environment to test and prototype StackQL queries.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql</code></strong></a> is a dev tool that allows you to query and manage cloud and SaaS resources using SQL, which developers and analysts can use for CSPM, assurance, user access management reporting, IaC, XOps and more.</p></div></div>
<p>Codespaces and the power of IPython and notebooks provide a quick and easy way to use StackQL to analyze and report on your cloud estate and resource configuration.  No software necessary!</p>
<p><img decoding="async" loading="lazy" alt="stackql-codespaces-notebook" src="https://stackql.io/assets/images/codespaces-3-cf4fcfdf6b861f31fa9ff56041be942a.png" width="1306" height="829" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-up-stackql-in-codespaces">Setting Up StackQL in Codespaces<a href="https://stackql.io/blog/tutorials/use-stackql-in-codespaces#setting-up-stackql-in-codespaces" class="hash-link" aria-label="Direct link to Setting Up StackQL in Codespaces" title="Direct link to Setting Up StackQL in Codespaces" translate="no">​</a></h2>
<p>See the <a href="https://github.com/stackql/stackql-codespaces-notebook" target="_blank" rel="noopener noreferrer" class=""><strong>stackql-codespaces-notebook</strong></a> repository as an example.</p>
<p>With the example <code>devcontainer.json</code> configuration file shown below, you can use the <a href="https://hub.docker.com/r/stackql/stackql-codespaces-base" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql/stackql-codespaces-base</code></strong></a> image, which includes stackql and the <a href="https://pystackql.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer" class=""><strong><code>pystackql</code></strong></a> package (which provides the IPython magic extension used to run stackql queries and return Pandas dataframes for inspection or visualization).</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"image"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"stackql/stackql-codespaces-base"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"containerEnv"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"STACKQL_GITHUB_PASSWORD"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"${secrets:STACKQL_GITHUB_PASSWORD}"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"STACKQL_GITHUB_USERNAME"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"${secrets:STACKQL_GITHUB_USERNAME}"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"hostRequirements"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"cpus"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">  </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token property" style="color:rgb(128, 203, 196)">"customizations"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token property" style="color:rgb(128, 203, 196)">"vscode"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token property" style="color:rgb(128, 203, 196)">"extensions"</span><span class="token operator" style="color:rgb(127, 219, 202)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token string" style="color:rgb(173, 219, 103)">"ms-toolsai.jupyter"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">        </span><span class="token string" style="color:rgb(173, 219, 103)">"ms-python.python"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Note that the <code>devcontainer</code> configuration includes the essential extensions for Jupyter and Python; you can also optionally specify host requirements for the Codespaces machine.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="provider-authentication">Provider Authentication<a href="https://stackql.io/blog/tutorials/use-stackql-in-codespaces#provider-authentication" class="hash-link" aria-label="Direct link to Provider Authentication" title="Direct link to Provider Authentication" translate="no">​</a></h3>
<p>The environment variables required to authenticate to your specific provider or providers can be supplied using Codespaces secrets and passed securely to the Codespaces container using the <code>containerEnv</code> object in the example above.  For specifics about variables required for different providers, see the provider documentation for your provider in the <a class="" href="https://stackql.io/providers">StackQL Provider Registry</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="launching-the-codespaces-environment">Launching the Codespaces Environment<a href="https://stackql.io/blog/tutorials/use-stackql-in-codespaces#launching-the-codespaces-environment" class="hash-link" aria-label="Direct link to Launching the Codespaces Environment" title="Direct link to Launching the Codespaces Environment" translate="no">​</a></h2>
<p>Given the <code>devcontainer</code> configuration shown above in the root of your repository at <code>.devcontainer/devcontainer.json</code>, you can launch codespaces from <code>&lt;your_repo_slug&gt;/codespaces</code> for example <a href="https://github.com/stackql/stackql-codespaces-notebook/codespaces" target="_blank" rel="noopener noreferrer" class="">https://github.com/stackql/stackql-codespaces-notebook/codespaces</a>.  You can start a codespaces environment on any branch of your repo.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="running-queries-and-visualizing-output">Running queries and visualizing output<a href="https://stackql.io/blog/tutorials/use-stackql-in-codespaces#running-queries-and-visualizing-output" class="hash-link" aria-label="Direct link to Running queries and visualizing output" title="Direct link to Running queries and visualizing output" translate="no">​</a></h2>
<p>When the environment is provisioned (usually takes a minute or two), you can use the StackQL magic extension and the <code>%%stackql</code> magic decorator to seamlessly run stackql queries, including variable substitution, for example.</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token operator" style="color:rgb(127, 219, 202)">%</span><span class="token plain">load_ext pystackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">magic</span><br></div></code></pre></div></div>
<p>(loads the Stackql magic extension, making the <code>%%stackql</code> decorator available)</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">region </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'us-east-1'</span><br></div></code></pre></div></div>
<p>(set some notebook variables for reusability)</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token operator" style="color:rgb(127, 219, 202)">%</span><span class="token operator" style="color:rgb(127, 219, 202)">%</span><span class="token plain">stackql</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> instanceType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">COUNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(127, 219, 202)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> num_instances </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> aws</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">ec2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">instances</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> region </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$region'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">GROUP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">BY</span><span class="token plain"> instanceType</span><br></div></code></pre></div></div>
<p>(run a query)</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">_</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">plot</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">kind</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">'pie'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> y</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">'num_instances'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> labels</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain">_</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">'instanceType'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> title</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">'Instances by Type'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> autopct</span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token string" style="color:rgb(173, 219, 103)">'%1.1f%%'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>(visualize the results - using <code>matplotlib</code>, <code>plotly</code>, or any other visualization package)</p>
<p>heres an example:</p>
<p><img decoding="async" loading="lazy" alt="stackql-codespaces-notebook" src="https://stackql.io/assets/images/codespaces-6-98387bfdb61555319afc82e8876f9eb5.png" width="1306" height="829" class="img_ev3q"></p>
<p>Using the <code>pystackql</code> package, you can also run asynchronous queries such as querying assets across AWS regions, Azure resource groups (or subscriptions) or Google projects in one statement, for example:</p>
<div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token comment" style="color:rgb(99, 119, 119);font-style:italic"># get multiple regions asynchronously</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">regions </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string" style="color:rgb(173, 219, 103)">"ap-southeast-2"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">"us-east-1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">queries </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">f"""</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    SELECT '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">' as region, instanceType, COUNT(*) as num_instances</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    FROM aws.ec2.instances</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    WHERE region = '</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token string-interpolation interpolation">region</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">'</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    GROUP BY instanceType</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token string-interpolation string" style="color:rgb(173, 219, 103)">    """</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token keyword" style="color:rgb(127, 219, 202)">for</span><span class="token plain"> region </span><span class="token keyword" style="color:rgb(127, 219, 202)">in</span><span class="token plain"> regions</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">instances_df </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">await</span><span class="token plain"> stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">executeQueriesAsync</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">queries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Visit us and give us a ⭐ on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a></p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="analytics" term="analytics"/>
        <category label="github" term="github"/>
        <category label="codespaces" term="codespaces"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[5 Minute Dashboards with StackQL]]></title>
        <id>https://stackql.io/blog/tutorials/five-minute-dashboards-with-stackql</id>
        <link href="https://stackql.io/blog/tutorials/five-minute-dashboards-with-stackql"/>
        <updated>2023-10-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Five minute dashboards with StackQL and Superset, check it out!]]></summary>
        <content type="html"><![CDATA[<p>Five minute dashboards with StackQL and Superset, check it out!</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/YXNHF6YiAvU?si=rRZltbjoyLRDd8Ca" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"></iframe>
<p>Visit us and give us a ⭐ on <a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong>GitHub</strong></a></p>]]></content>
        <author>
            <name>Kieran Rimmer</name>
            <uri>https://www.linkedin.com/in/kieranrimmer/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="analytics" term="analytics"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Query and Create GitHub Releases using StackQL]]></title>
        <id>https://stackql.io/blog/tutorials/query-and-create-github-releases-using-stackql</id>
        <link href="https://stackql.io/blog/tutorials/query-and-create-github-releases-using-stackql"/>
        <updated>2023-08-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[StackQL and the StackQL GitHub provider can be used to query objects in GitHub, including releases, tags, forks, commits, and much more.  This article shows how you can automate releases using StackQL.]]></summary>
        <content type="html"><![CDATA[<p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class="">StackQL</a> and the <a class="" href="https://stackql.io/providers/github">StackQL GitHub provider</a> can be used to query objects in GitHub, including releases, tags, forks, commits, and much more.  This article shows how you can automate releases using StackQL.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="push-tags">Push tags<a href="https://stackql.io/blog/tutorials/query-and-create-github-releases-using-stackql#push-tags" class="hash-link" aria-label="Direct link to Push tags" title="Direct link to Push tags" translate="no">​</a></h2>
<p>In my case, I merged a PR to the <code>main</code> branch for an updated GitHub action in a repo called <code>stackql-exec</code>, then I pushed a tag with an updated semver:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">git tag v1.2.1</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">git push origin v1.2.1</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pull-the-stackql-github-provider">Pull the StackQL GitHub provider<a href="https://stackql.io/blog/tutorials/query-and-create-github-releases-using-stackql#pull-the-stackql-github-provider" class="hash-link" aria-label="Direct link to Pull the StackQL GitHub provider" title="Direct link to Pull the StackQL GitHub provider" translate="no">​</a></h2>
<p>From the StackQL shell or via the <code>exec</code> command, pull the latest GitHub provider for StackQL using:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">REGISTRY PULL github;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="generate-a-template-for-creating-a-release-optional">Generate a template for creating a release (optional)<a href="https://stackql.io/blog/tutorials/query-and-create-github-releases-using-stackql#generate-a-template-for-creating-a-release-optional" class="hash-link" aria-label="Direct link to Generate a template for creating a release (optional)" title="Direct link to Generate a template for creating a release (optional)" translate="no">​</a></h2>
<p>StackQL allows you to create resource templates for creating resources such as ec2 instances, google cloud storage buckets, or github releases.  This is done using the <code>SHOW INSERT INTO</code> command as seen here:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">stackql exec --output text "SHOW INSERT INTO github.repos.releases"</span><br></div></code></pre></div></div>
<p>The template will also generate an optional jsonnet variable block to define reusable or externally sourced variables (e.g., from environment variables).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="run-your-insert-statement">Run your <code>INSERT</code> statement<a href="https://stackql.io/blog/tutorials/query-and-create-github-releases-using-stackql#run-your-insert-statement" class="hash-link" aria-label="Direct link to run-your-insert-statement" title="Direct link to run-your-insert-statement" translate="no">​</a></h2>
<p>In this case, I have just used literals to keep it simple...</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">INSERT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">INTO</span><span class="token plain"> github</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">repos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">releases</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  owner</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  repo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  data__body</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  data__draft</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  data__generate_release_notes</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  data__name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  data__prerelease</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  data__tag_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  data__target_commitish</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql-exec'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'Updated authentication and added support for external variables'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">   </span><span class="token boolean" style="color:rgb(255, 88, 116)">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">   </span><span class="token boolean" style="color:rgb(255, 88, 116)">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'v1.2.1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">   </span><span class="token boolean" style="color:rgb(255, 88, 116)">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'v1.2.1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token string" style="color:rgb(173, 219, 103)">'main'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="select-from-githubreposreleases-optional"><code>SELECT FROM github.repos.releases</code> (optional)<a href="https://stackql.io/blog/tutorials/query-and-create-github-releases-using-stackql#select-from-githubreposreleases-optional" class="hash-link" aria-label="Direct link to select-from-githubreposreleases-optional" title="Direct link to select-from-githubreposreleases-optional" translate="no">​</a></h2>
<p>You can inspect the releases created for your repo, including the one you just created, using a simple <code>SELECT</code> statement as shown here...</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">select</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">tag_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">target_commitish</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">created_at</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">from</span><span class="token plain"> github</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">repos</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">releases </span><span class="token keyword" style="color:rgb(127, 219, 202)">where</span><span class="token plain"> owner </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">and</span><span class="token plain"> repo </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql-exec'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>You will see output like the following:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------------------------|-------------|------------------|----------------------|                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|              name              |  tag_name   | target_commitish |      created_at      |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------------------------|-------------|------------------|----------------------|                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| v1.2.1                         | v1.2.1      | main             | 2023-09-03T05:44:40Z |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------------------------|-------------|------------------|----------------------|                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| v1.2.0                         | v1.2.0      | main             | 2023-09-03T05:20:42Z |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------------------------|-------------|------------------|----------------------|                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| Fix composite action issue     | v1.0.1      | main             | 2023-03-01T09:14:20Z |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| with path                      |             |                  |                      |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------------------------|-------------|------------------|----------------------|                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| Production release with        | v1.0.0      | main             | 2023-02-25T23:07:32Z |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| outputs                        |             |                  |                      |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------------------------|-------------|------------------|----------------------|                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| Initial release                | v1.0.0-beta | main             | 2023-02-05T12:50:01Z |                                              </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|--------------------------------|-------------|------------------|----------------------|              </span><br></div></code></pre></div></div>
<p>More information about the GitHub Provider for StackQL can be found <a class="" href="https://stackql.io/providers/github">here</a>.</p>
<p>Enjoy!</p>]]></content>
        <author>
            <name>Jeffrey Aven</name>
            <uri>https://www.linkedin.com/in/jeffreyaven/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="github" term="github"/>
        <category label="github releases" term="github releases"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Query and Manage Google Workspace Users and Groups with StackQL]]></title>
        <id>https://stackql.io/blog/tutorials/query-and-manage-google-workspace-users-and-groups-with-stackql</id>
        <link href="https://stackql.io/blog/tutorials/query-and-manage-google-workspace-users-and-groups-with-stackql"/>
        <updated>2023-07-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Announcing the release of the StackQL provider for the Google Workspace Admin API.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql</code></strong></a> is a dev tool that allows you to query, manage, and perform analytics against cloud and SaaS resources in real time using SQL, which developers and analysts can use for CSPM, assurance, user access management reporting, IaC, XOps and more.</p></div></div>
<p>The <code>googleadmin</code> StackQL provider is now available, which allows you to query, provision, or manage Google Workspace <strong>users</strong>, <strong>groups</strong>, <strong>devices</strong>, and more using StackQL.  The <code>googleadmin</code> provider can be used with the <code>google</code> provider or other cloud providers to generate entitlements reports (or user access reviews) where Google Workspace identites are used in identity federation or IAM bindings.</p>
<p>The full documentation on how to use a Google service account for authentication to the googleadmin provider is available <a href="https://googleadmin.stackql.io/providers/googleadmin/" target="_blank" rel="noopener noreferrer" class="">here</a>.  Information about the directory resources available and their fields and methods, is available in the <a href="https://googleadmin.stackql.io/providers/googleadmin/directory/" target="_blank" rel="noopener noreferrer" class="">StackQL Provider Registry Docs</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="simple-query">Simple Query<a href="https://stackql.io/blog/tutorials/query-and-manage-google-workspace-users-and-groups-with-stackql#simple-query" class="hash-link" aria-label="Direct link to Simple Query" title="Direct link to Simple Query" translate="no">​</a></h3>
<p>A simple query using the <code>googleadmin</code> provider is shown here:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> primaryEmail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> lastLoginTime </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> googleadmin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">directory</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">users </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> domain </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql.io'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> primaryEmail </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'javen@stackql.io'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>which would return the following results...</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|--------------------------|                                                                                                                                                   </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|   primaryEmail   |      lastLoginTime       |                                                                                                                                                   </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|--------------------------|                                                                                                                                                   </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| javen@stackql.io | 2023-07-08T23:30:31.000Z |                                                                                                                                                   </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|--------------------------|  </span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-query-using-built-in-functions">Example Query Using Built-In Functions<a href="https://stackql.io/blog/tutorials/query-and-manage-google-workspace-users-and-groups-with-stackql#example-query-using-built-in-functions" class="hash-link" aria-label="Direct link to Example Query Using Built-In Functions" title="Direct link to Example Query Using Built-In Functions" translate="no">​</a></h3>
<p>Here is an example using built-in functions in StackQL (more information about built-in functions is available in the <a class="" href="https://stackql.io/">StackQL docs</a>):</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> primaryEmail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> json_extract</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'$.fullName'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> full_name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> lastLoginTime </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> googleadmin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">directory</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">users </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> domain </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql.io'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> primaryEmail </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'javen@stackql.io'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>which would return results like this...</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|--------------|--------------------------|                                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|   primaryEmail   |  full_name   |      lastLoginTime       |                                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|--------------|--------------------------|                                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| javen@stackql.io | Jeffrey Aven | 2023-07-08T23:30:31.000Z |                                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|--------------|--------------------------|  </span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="example-query-using-aggregate-functions">Example Query Using Aggregate Functions<a href="https://stackql.io/blog/tutorials/query-and-manage-google-workspace-users-and-groups-with-stackql#example-query-using-aggregate-functions" class="hash-link" aria-label="Direct link to Example Query Using Aggregate Functions" title="Direct link to Example Query Using Aggregate Functions" translate="no">​</a></h3>
<p>Here is an example of a summary query that could be useful:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  isAdmin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">COUNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(127, 219, 202)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> num_admins</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"> googleadmin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">directory</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">users </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> domain </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql.io'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">GROUP</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">BY</span><span class="token plain"> isAdmin</span><br></div></code></pre></div></div>
<p>results in...</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|---------|------------|                                                                                                                                                                          </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| isAdmin | num_admins |                                                                                                                                                                          </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|---------|------------|                                                                                                                                                                          </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| false   |          9 |                                                                                                                                                                          </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|---------|------------|                                                                                                                                                                          </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| true    |          2 |                                                                                                                                                                          </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|---------|------------|  </span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="entitlements-report-using-a-left-join-with-the-google-provider">Entitlements Report Using a <code>LEFT JOIN</code> with the <code>google</code> provider<a href="https://stackql.io/blog/tutorials/query-and-manage-google-workspace-users-and-groups-with-stackql#entitlements-report-using-a-left-join-with-the-google-provider" class="hash-link" aria-label="Direct link to entitlements-report-using-a-left-join-with-the-google-provider" title="Direct link to entitlements-report-using-a-left-join-with-the-google-provider" translate="no">​</a></h3>
<p>Using the <code>LEFT OUTER JOIN</code> capability with StackQL, you can generate entitlements or user access management reports that span across Google Workspace as an Identity Provider (IdP) and a Google Cloud resource (including Organizations, Folders, Projects, and resources), such as:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">SELECT</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  split_part</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">json_extract</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">iam</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">members</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'$[0]'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">':'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> member</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  iam</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">role </span><span class="token keyword" style="color:rgb(127, 219, 202)">as</span><span class="token plain"> role</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  users</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">lastLoginTime</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">FROM</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">cloudresourcemanager</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">organizations_iam_bindings iam</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">LEFT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">OUTER</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(127, 219, 202)">JOIN</span><span class="token plain"> googleadmin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">directory</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">users users</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">ON</span><span class="token plain"> split_part</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">json_extract</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">iam</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">members</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token string" style="color:rgb(173, 219, 103)">'$[0]'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">':'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> users</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">primaryEmail</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token keyword" style="color:rgb(127, 219, 202)">WHERE</span><span class="token plain"> users</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">domain </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'stackql.io'</span><span class="token plain"> </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> iam</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">organizationsId </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">141318256085</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token operator" style="color:rgb(127, 219, 202)">AND</span><span class="token plain"> users</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">primaryEmail </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'javen@stackql.io'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>which would return...</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|------------------------------|--------------------------|                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|      member      |             role             |      lastLoginTime       |                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|------------------------------|--------------------------|                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| javen@stackql.io | roles/bigquery.resourceAdmin | 2023-07-08T23:30:31.000Z |                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|------------------------------|--------------------------|                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">| javen@stackql.io | roles/logging.admin          | 2023-07-08T23:30:31.000Z |                                                                                                                    </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">|------------------|------------------------------|--------------------------|</span><br></div></code></pre></div></div>
<p>Let us know what you think!</p>]]></content>
        <author>
            <name>Kieran Rimmer</name>
            <uri>https://www.linkedin.com/in/kieranrimmer/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="google" term="google"/>
        <category label="google workspace" term="google workspace"/>
        <category label="google admin" term="google admin"/>
        <category label="analytics" term="analytics"/>
        <category label="reporting" term="reporting"/>
        <category label="dashboards" term="dashboards"/>
        <category label="cloud security" term="cloud security"/>
        <category label="cspm" term="cspm"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[StackQL Superset Dashboards Quickstart]]></title>
        <id>https://stackql.io/blog/tutorials/stackql-dashboards-with-superset</id>
        <link href="https://stackql.io/blog/tutorials/stackql-dashboards-with-superset"/>
        <updated>2023-05-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This quick start guide lays out how to create a StackQL dashboard using Apache Superset.]]></summary>
        <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p><a href="https://github.com/stackql/stackql" target="_blank" rel="noopener noreferrer" class=""><strong><code>stackql</code></strong></a> is a dev tool that allows you to query and manage cloud and SaaS resources using SQL, which developers and analysts can use for CSPM, assurance, user access management reporting, IaC, XOps and more.</p></div></div>
<p>This quick start guide outlines how to create a <code>superset</code> + <code>stackql</code> dashboard on your laptop using <code>docker desktop</code>, <code>helm</code>, and <code>kubernetes</code>.  We certainly do not want to go into depth on <code>superset</code>, a third-party application, so this guide is terse.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="supplying-secrets">Supplying secrets<a href="https://stackql.io/blog/tutorials/stackql-dashboards-with-superset#supplying-secrets" class="hash-link" aria-label="Direct link to Supplying secrets" title="Direct link to Supplying secrets" translate="no">​</a></h2>
<p>In this example, we use:</p>
<ul>
<li class="">AWS environment variable credentials <a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html" target="_blank" rel="noopener noreferrer" class="">as per the AWS CLI</a>.</li>
<li class="">Azure environment variables, as per <a href="https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication-service-principal?tabs=azure-cli#-option-1-authenticate-with-a-secret" target="_blank" rel="noopener noreferrer" class="">the documentation for the <strong><code>golang</code></strong> SDK</a>.</li>
<li class=""><a href="https://docs.digitalocean.com/reference/api/create-personal-access-token/" target="_blank" rel="noopener noreferrer" class=""><strong><code>digitalocean</code></strong> personal access token</a>.</li>
<li class=""><a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token" target="_blank" rel="noopener noreferrer" class=""><strong><code>github</code></strong> personal access token</a>.</li>
<li class=""><a href="https://cloud.google.com/iam/docs/keys-create-delete" target="_blank" rel="noopener noreferrer" class=""><strong><code>google</code></strong> Service Account JSON key</a>.</li>
</ul>
<p>All of the associated principals must be granted access using provider-specific access controls.</p>
<p><strong>NOTE</strong> keep all of these values secret and certainly do not commit into source control.  We have supplied examples for numerous providers, and we suggest that you configure only what you need.</p>
<p>Create a file <code>helm/stackql-dashboards/secrets/secret-values.yaml</code>, containing the following, replacing placeholders:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token key atrule" style="color:rgb(255, 203, 139)">stackql</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">extraSecretEnv</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">AWS_ACCESS_KEY_ID</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your aws access key id&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">AWS_SECRET_ACCESS_KEY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your aws secret key&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">AZURE_CLIENT_ID</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your azure client id&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">AZURE_CLIENT_SECRET</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your azure client secret&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">AZURE_TENANT_ID</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your azure tenant id&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">DIGITALOCEAN_TOKEN</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your digitalocean token&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">STACKQL_GITHUB_TOKEN</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your github personal access token&gt;'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">GOOGLE_APPLICATION_CREDENTIALS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'/opt/stackql/config/google-credentials.json'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">extraSecrets</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">google-credentials.json</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">|</span><span class="token scalar string" style="color:rgb(173, 219, 103)"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token scalar string" style="color:rgb(173, 219, 103)">      &lt;full google json key&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain"></span><span class="token key atrule" style="color:rgb(255, 203, 139)">superset</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">  </span><span class="token key atrule" style="color:rgb(255, 203, 139)">init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">    </span><span class="token key atrule" style="color:rgb(255, 203, 139)">adminUser</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">      </span><span class="token key atrule" style="color:rgb(255, 203, 139)">password</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'mypassword'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="expand-templates-and-deploy-locally">Expand templates and deploy locally<a href="https://stackql.io/blog/tutorials/stackql-dashboards-with-superset#expand-templates-and-deploy-locally" class="hash-link" aria-label="Direct link to Expand templates and deploy locally" title="Direct link to Expand templates and deploy locally" translate="no">​</a></h2>
<p>Here we will set up and expose a local dashboard using the local <code>kubernetes</code> cluster supplied with <code>docker desktop</code>.</p>
<p>These steps assume that your <code>kubectl</code> config is pointed at your local cluster (depending on your version of <code>docker</code>, something like <code>kubectl config use-context docker-desktop</code> should do the trick) and that you execute from the root directory of the <code>stackql-cloud</code> repository.  We will let the system dynamically assign a local port.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">helm dependency update  helm/stackql-dashboards</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">helm template --release-name v1 --namespace default --set superset.service.type=NodePort --set superset.service.nodePort.http="" -f helm/stackql-dashboards/secrets/secret-values.yaml helm/stackql-dashboards &gt; helm/stackql-dashboards/out/stackql-demo-dashboards.yaml</span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">kubectl apply -f helm/stackql-dashboards/out/stackql-demo-dashboards.yaml</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="log-into-and-set-up-superset">Log into and set up <strong><code>superset</code></strong><a href="https://stackql.io/blog/tutorials/stackql-dashboards-with-superset#log-into-and-set-up-superset" class="hash-link" aria-label="Direct link to log-into-and-set-up-superset" title="Direct link to log-into-and-set-up-superset" translate="no">​</a></h2>
<p>Allow a minute or so for init actions to complete.</p>
<p>First, inspect the output of <code>kubectl get svc</code> and note the host port for the service  <code>v1-superset</code>.  In my case, I see (redacted):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token plain">$ kubectl get svc | grep NodePort      </span><br></div><div class="token-line" style="color:#d6deeb"><span class="token plain">v1-superset                  NodePort    ...    ...        8088:31930/TCP   ...</span><br></div></code></pre></div></div>
<p>So, my local port is <code>31390</code> on this occasion.  Hereafter let us refer to this port as <code>&lt;SUPERSET_LOCAL_PORT&gt;</code>.</p>
<p>Go to your browser address bar and punch in <code>http://localhost:&lt;SUPERSET_LOCAL_PORT&gt;</code>.  Log in using <code>admin</code> / <code>mypassword</code> (or other if you reconfigured), and then you can begin using <code>superset</code>.</p>
<p>From the top RHS <code>Settings</code> dropdown, select <code>Database Connections</code>.  Then, select the <code>+ DATABASE</code> button (just below <code>Settings</code>) and do the following (the password does not matter in this context, add anything you want):</p>
<p><img decoding="async" loading="lazy" alt="Initial database settings" src="https://stackql.io/assets/images/db-connection-01-7a394e79e899561f479708b0a0821a1c.png" title="Initial database settings" width="1024" height="1632" class="img_ev3q"></p>
<blockquote>
<p>Press "CONNECT"</p>
</blockquote>
<p><img decoding="async" loading="lazy" alt="Follow up database settings" src="https://stackql.io/assets/images/db-connection-02-e7001929c631c14074c017fd0724b2d8.png" title="Follow up database settings" width="1016" height="1628" class="img_ev3q"></p>
<blockquote>
<p>Press "FINISH"</p>
</blockquote>
<p><strong>NOTE</strong>: we have enabled DML here so that meta queries like <code>show</code> and describe will work.  You certainly do not have to do this if you don't want to.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="experiment">Experiment<a href="https://stackql.io/blog/tutorials/stackql-dashboards-with-superset#experiment" class="hash-link" aria-label="Direct link to Experiment" title="Direct link to Experiment" translate="no">​</a></h2>
<p>Here we present a simple GCP scenario; you can follow the same pattern to create many charts and populate a dashboard...</p>
<p>Navigate to <code>SQL &gt; SQL Lab</code> and then input the below, substituting <code>&lt;your gcp project&gt;</code> for whatever google project your service account can access:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#d6deeb;--prism-background-color:#011627"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#d6deeb;background-color:#011627"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#d6deeb"><span class="token keyword" style="color:rgb(127, 219, 202)">select</span><span class="token plain"> name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> guestCpus </span><span class="token keyword" style="color:rgb(127, 219, 202)">from</span><span class="token plain"> google</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token keyword" style="color:rgb(127, 219, 202)">compute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">machine_types </span><span class="token keyword" style="color:rgb(127, 219, 202)">where</span><span class="token plain"> project </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'&lt;your gcp project&gt;'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(127, 219, 202)">and</span><span class="token plain"> zone </span><span class="token operator" style="color:rgb(127, 219, 202)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(173, 219, 103)">'australia-southeast1-a'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<blockquote>
<p>Press "RUN SELECTION"</p>
</blockquote>
<p>A table of results should appear.</p>
<blockquote>
<p>Press "Save" &gt; "Save Dataset"</p>
</blockquote>
<p>Give it whatever name you want.</p>
<p>You can click the option to create a chart immediately or navigate to your chart via the <code>Charts</code> menu item.</p>
<p>Once inside the UI for your new dataset, do something like this (we will leave it to your creativity)...</p>
<p><img decoding="async" loading="lazy" alt="My First Chart" src="https://stackql.io/assets/images/chart-01-6e50efc946d855bc219371c1ef7abbb2.png" title="My First Chart" width="3340" height="1666" class="img_ev3q"></p>
<p>...and then...</p>
<p><img decoding="async" loading="lazy" alt="Chart To Dashboard" src="https://stackql.io/assets/images/chart-to-dashboard-01-068e350964f90c13c7b108f61722a1c4.png" title="Chart To Dashboard" width="1224" height="774" class="img_ev3q"></p>
<p>Click on "SAVE &amp; GO TO NEW DASHBOARD", and you have your first dashboard + <code>stackql</code>!</p>
<p><img decoding="async" loading="lazy" alt="Dashboard" src="https://stackql.io/assets/images/dashboard-01-c66c690531aeaf83a6e8bd43b6ff4b3b.png" title="Dashboard" width="3342" height="1208" class="img_ev3q"></p>]]></content>
        <author>
            <name>Kieran Rimmer</name>
            <uri>https://www.linkedin.com/in/kieranrimmer/</uri>
        </author>
        <category label="stackql" term="stackql"/>
        <category label="superset" term="superset"/>
        <category label="analytics" term="analytics"/>
        <category label="reporting" term="reporting"/>
        <category label="dashboards" term="dashboards"/>
        <category label="cloud security" term="cloud security"/>
        <category label="cspm" term="cspm"/>
    </entry>
</feed>