Custom Controls

Powerpipe makes it easy to create your own controls and benchmarks. This allows you to define the controls that are important to you and your organization, and organize them in a way that reflects your organization's standards and practices. (Of course, there are controls and benchmarks already available in mods on the Powerpipe Hub as well if you don't want to write your own).

Tutorial

Let's walk through building a simple benchmark that will introduce the key concepts as we go along.

Prerequisites

For this tutorial, we'll be using Steampipe with the AWS plugin:

  1. Download and install Powerpipe for your platform.
  2. Download and install Steampipe for your platform.
  3. Install and configure the latest AWS plugin.
  4. Start the Steampipe database service (steampipe service start)

Create a mod

Powerpipe resources are packaged into mods. First, create a mod for your controls and benchmarks.

Create a Control

Now let's create a control. Create a new file in the folder called untagged.pp and paste in the following code:

control "s3_untagged" {
title = "S3 Untagged"
sql = <<EOT
select
arn as resource,
case
when tags is not null then 'ok'
else 'alarm'
end as status,
case
when tags is not null then name || ' has tags.'
else name || ' has no tags.'
end as reason,
region,
account_id
from
aws_s3_bucket
EOT
}

This snippet defines a control named s3_untagged, including an SQL query to find untagged S3 buckets. Note that the query returns the required control columns (resource, status, and reason), as well as additional columns, or dimensions, to provide context that is specific to AWS (region, account_id).

Now let's run our control:

powerpipe control run s3_untagged

Controls provide an easy-to-use mechanism for auditing your environment with Powerpipe. Benchmarks allow you to group and organize your controls. Let's add another control to the untagged.pp, as well as a benchmark that has both of our controls as children:

control "lambda_untagged" {
title = "Lambda Untagged"
sql = <<EOT
select
arn as resource,
case
when tags is not null then 'ok'
else 'alarm'
end as status,
case
when tags is not null then name || ' has tags.'
else name || ' has no tags.'
end as reason,
region,
account_id
from
aws_lambda_function
order by reason
EOT
}
benchmark "untagged" {
title = "Untagged"
children = [
control.lambda_untagged,
control.s3_untagged,
]
}

Now we can run both of our controls via the benchmark:

powerpipe benchmark run untagged

Benchmarks may also have other benchmarks as children, allowing you to create rich hierarchies of controls. There are many more examples to explore on the Powerpipe Hub!