Easily Query your Cloud Inventory with Steampipe
Tags: aws, cloud, operations
Published: 2022-09-27 22:05:21

<!-- wp:heading -->
<h2>Cloud Inventory is a Challenge</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Anyone who has worked with AWS for a while will be quite familiar with the difficulties of getting a complete picture of the inventory of resources in your accounts.   While AWS has made some limited strides in this area with tools like the <a href="https://aws.amazon.com/about-aws/whats-new/2021/09/amazon-ec2-global-view-console-regions/" target="_blank" rel="noopener">EC2 Global View</a> and the ability to get a count of all VPCs in the VPC dashboard, the bottom line is that AWS does not provide a comprehensive inventory solution for an AWS account or group of accounts.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>While there are many excellent third party commercial tools you can use to solve this problem, not everyone (including me!) has the budget available to pay for these tools.   So for the past month or two I've been spending time looking at some open source tools to add to my team's toolchain to help us with the inventory problem.   One of the tools I've been looking at is an interesting solution called Steampipe.  In this post I'm going to dive into this tool and share some of the things I've learned about it.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Steampipe - Query your cloud inventory like it's 1992</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://steampipe.io/" target="_blank" rel="noopener">Steampipe.io</a> is an open source tool that is maintained by the commercial tool company <a href="https://turbot.com" target="_blank" rel="noopener">Turbot</a>.   In a nutshell, the software allows you to query your favorite cloud services with SQL.  By providing a consistent command line interface that works across multiple IaaS, PasS and SaaS services, Steampipe aims to reduce the time wasted on context switching between different cloud provider's native interfaces.  As the end user, you write your queries in a consistent SQL syntax, and Steampipe translates that query into native API calls that are executed in real time against the cloud service's API.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Interaction with various cloud service's APIs is handled via Steampipe plugins for each service.  As of this writing there are 86 different plugins available on the <a href="https://hub.steampipe.io/plugins" target="_blank" rel="noopener">Steampipe Hub</a>, including plugins for all the major cloud players (AWS, Alibaba, Azure, Cloudflare, GCP, Digital Ocean, IBM, Oracle, Heroku), SaaS services (Datadog, PagerDuty, Salesforce, Stripe, Twilio, Zendesk, Zoom), as well as some more intriguing options like VMware vSphere, Terraform, Reddit, and Slack.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Getting Started</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The easiest way to get started playing with Steampipe is to install it on your local workstation.   The Steampipe Downloads page provides step by step instructions for installation on MacOS, Linux, and Windows operating systems.  </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>On a Mac with the <a href="https://brew.sh" target="_blank" rel="noopener">Homebrew</a> package manager installed, the process could not be any simpler:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Tap Turbot's Cask:  <code>~$brew tap turbot/tap</code></li><li>Install Steampipe: <code>~$brew install steampipe</code></li><li>Validate the installation is working by checking the installed version of Steampipe:          <code>~$steampipe - v</code></li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Once you have the core Steampipe engine installed, you need to install plugins for whichever cloud services you want to query.   First, let's install the <a href="https://hub.steampipe.io/plugins/turbot/steampipe" target="_blank" rel="noopener">Steampipe plugin</a> which will allow us to query Steampipe components, such as the available plugins in the Steampipe hub.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>~$ steampipe plugin install steampipe

steampipe            &#91;====================================================================] Done                

Installed plugin: steampipe@latest v0.5.0
Documentation:    https://hub.steampipe.io/plugins/turbot/steampipe</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Next, let's install the <a href="https://hub.steampipe.io/plugins/turbot/aws" target="_blank" rel="noopener">AWS plugin</a> so we can start querying our AWS environments.  Use the following command:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>~$ steampipe plugin install aws

aws                  &#91;====================================================================] Done                

Installed plugin: aws@latest v0.78.0
Documentation:    https://hub.steampipe.io/plugins/turbot/aws</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Now that we have our AWS plugin installed, we need to do configure some credentials for the plugin so we can start querying our AWS accounts.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Configure Credentials</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3>Basic Setup</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>When you install the Steampipe AWS plugin, the tool will automatically create a configuration file for you located at the following path:  <code>~/.steampipe/config/aws.spc</code></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Within this configuration file you can setup one or more AWS accounts to query with Steampipe.   You can setup credentials directly in the aws.spc file if you want, but even more handy is the fact that Steampipe can refer to credential profiles you've already setup for AWS CLI.   Best of all, you can even use AWS SSO profiles with Steampipe!</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Credentials statements in my aws.spc file look like this:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>connection "itprod" {
  plugin = "aws"
  profile = "sso-itprod"
  regions = &#91;"*"]
}
connection "itshared"
  plugin = "aws"
  profile = "sso-itshared"
  regions = &#91;"*"]
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>As you can see, each connection entry in my aws.spc starts with a name definition, followed by which plugin you are using, the profile name in my <code>~./aws/config</code> file, and finally a region specification.  You can put a list of individual regions here or use * to query all regions simultaneously.  </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Advanced Configuration</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If you have a multi account setup, and you've configured multiple connection entries in your aws.spc file, you can also create what is called an "aggregator connection" which allows you to query against multiple connections from a plugin in a single query.  </p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>connection "aws_all" {
  type = aggregator
  plugin = aws
  connections = &#91;"itprod", "itshared"]
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>You can even use wildcards in your aggregator specification, like so:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>connection "aws_it_all" {
  type = aggregator
  plugin = aws
  connections = &#91;"it*"]
}</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Another handy capability comes into play if you are running Steampipe on an EC2 instance inside your AWS Account.  If you have an <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html" target="_blank" rel="noopener">IAM Instance profile</a> attached to the instance with appropriate permissions, Steampipe will automatically use that IAM role with no other credentials being configured.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now that we have some credentials configured for Steampipe, let's see what we can do with this tool!</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Basic Queries</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The Steampipe AWS plugin organizes the many AWS services into discrete tables that you can then write queries against.  As of this writing there are 344 discrete tables defined in the AWS plugin, you can review them all <a href="https://hub.steampipe.io/plugins/turbot/aws/tables" target="_blank" rel="noopener">here</a>.   You can run queries in two different modes with Steampipe:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Enter an interactive query console by entering the command <code>steampipe query</code></li><li>Run a specific query directly by entering it all in a single command: <code>steampipe query "select * from cloud"</code></li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>I believe it is easier to get started using the interactive query console as it provides you with hints and autocomplete as you write your queries.   Let's enter the console and see what commands are available:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>➜  steampipe query
Welcome to Steampipe v0.15.4
For more information, type .help
&gt; .help
Welcome to Steampipe shell.

To start, simply enter your SQL query at the prompt:

  select * from aws_iam_user

Common commands:

.help     Show steampipe help                           
.inspect  View connections, tables &amp; column information 
.exit     Exit from steampipe terminal                  

Advanced commands:

.cache &#91;mode]        Enable, disable or clear the query cache                                                     
.clear               Clear the console                                                                            
.connections         List active connections                                                                      
.header on|off       Enable or disable column headers                                                             
.multi on|off        Enable or disable multiline mode                                                             
.output &#91;mode]       Set output format: csv, json, table or line                                                  
.quit                Exit from steampipe terminal                                                                 
.search_path         Display the current search path, or set the search-path by passing in a comma-separated list 
.search_path_prefix  Set a prefix to the current search-path                                                      
.separator           Set csv output separator                                                                     
.tables              List or describe tables                                                                      
.timing on|off       Enable or disable query execution timing                                                     </code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>As the help file suggests, you can use the .tables command to get a list of all the tables available in Steampipe:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":983,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe_tables-1024x412.jpg" alt="" class="wp-image-983"/><figcaption>Steampipe .tables command</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>You can use the .inspect command to view details on connections and tables.   Inspect is particularly powerful as you can use it to drill into a specific table to see what fields are available.  For example here's a screenshot showing the <code>.inspect aws_vpc</code> command result:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":982,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe_inspect-1024x377.jpg" alt="" class="wp-image-982"/><figcaption>Steampipe .inpsect aws_vpc command</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p> Once you've seen the connections and tables, you can get an idea of what types of queries you can run.   As the help file suggests, you can start by getting a list of all the IAM users in all your configured accounts with the command <code>select * from aws_iam_user</code> which returns a table like this:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":975,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/select_iam_users-1024x300.jpg" alt="" class="wp-image-975"/><figcaption>Steampipe query for all IAM users</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>If you have an aggregator configuration setup, you will get results for all configured AWS accounts by default.  If you want to limit your scope to a specific AWS Account, simply prefix the table name with the connection name e.g. <code>select * from itshared.aws_ec2_instance</code>:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":976,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/select_ec2_instances-1024x178.jpg" alt="" class="wp-image-976"/><figcaption>Steampipe query for EC2 instances in a specific account</figcaption></figure>
<!-- /wp:image -->

<!-- wp:heading -->
<h2>Advanced Queries</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If you review the table definitions published on the <a href="https://hub.steampipe.io/plugins/turbot/aws/tables" target="_blank" rel="noopener">AWS plugin page at Steampipe Hub</a>, you will see lots of more advanced examples of what you can do with Steampipe.   For example, let's say you want to get a count of IAM access keys that are between 45 and 90 days old:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":977,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/select_access_keys_45_to_90_days-1024x274.jpg" alt="" class="wp-image-977"/><figcaption>Steampipe query of access keys between 45 and 90 days old</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Or perhaps a list of your S3 buckets that are not encrypted:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":978,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/select_unecrypted_buckets-2-1024x421.jpg" alt="" class="wp-image-978"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Maybe you'd like to get a quick count of EC2 instances grouped by region across all your accounts?</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":979,"sizeSlug":"medium","linkDestination":"none"} -->
<figure class="wp-block-image size-medium"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/count-instance-by-region-300x289.jpg" alt="" class="wp-image-979"/><figcaption>Steampipe query counting number of EC2 instances by region</figcaption></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Lastly, let's get really fancy and create an age table of all our EC2 instances:</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":980,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://cloudyadvice.com/wp-content/uploads/2022/09/steampipe-ec2-instance-age-table-2-1024x531.jpg" alt="" class="wp-image-980"/><figcaption>Steampipe EC2 instance age table</figcaption></figure>
<!-- /wp:image -->

<!-- wp:heading -->
<h2>Wrap-up</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As you can hopefully see from this brief introduction, there is a ton of things you can do with this tool, especially leveraging the power of SQL.  While I personally do not have a lot of SQL experience, I was still able to get up and running pretty quickly following the excellent documentation and examples provided by the Steampipe project.   </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In the future I hope to do a follow up post on some of the more advanced capabilities of Steampipe including the ability to serve custom dashboards based on the Steampipe engine.   In the meantime, if you've tried this tool yourself, please share your experience with me in the comments section.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Happy querying!</p>
<!-- /wp:paragraph -->