card

A card is used to show a value to the user, or some change in value. A card can also present itself in different types e.g. show me a count of public S3 buckets and if the value is greater than 0 show as an alert, else as ok.

Cards can be declared as named resources at the top level of a mod, or be declared as anonymous blocks inside a dashboard or container, or be re-used inside a dashboard or container by using a card with base = <mod>.card.<card_resource_name>.

Example Usage


card {
sql = <<-EOQ
select
count(*) as "Buckets"
from
aws_s3_bucket
EOQ
icon = "hashtag"
width = 2
}

Argument Reference

ArgumentTypeOptional?Description
argsMapOptionalA map of arguments to pass to the query.
baseCard ReferenceOptionalA reference to a named card resource that this card should source its definition from. label, title, value, type and width can be overridden after sourcing via base.
iconStringOptionalAn icon to use for the elements with this category.
hrefStringOptionalA url that the card should link to. The href may use a jq template to dynamically generate the link the card.
labelStringOptionalInferred from the first column name in simple data format. Else can be set explicitly in HCL, or returned by the query in the label column in the formal data format.
paramBlockOptionalA param block that defines the parameters that can be passed in to the query. param blocks may only be specified for cards that specify the sql argument.
queryQuery ReferenceOptionalA reference to a query resource that defines the query to run. A card may either specify the query argument or the sql argument, but not both.
sqlStringOptionalAn SQL string to provide data for the card. A card may either specify the query argument or the sql argument, but not both.
titleStringOptionalA plain text title to display for this card.
typeStringOptionalplain (default), alert, info or ok. You can also use table to review the raw data.
valueStringOptionalInferred from the first column's value in simple data format.
widthNumberOptionalThe width as a number of grid units that this item should consume from its parent.

Data Structure

A card supports 2 data structures.

  1. A simple structure where column 1's name is the card label and column 1's value is the card value.
  2. A formal data structure where the column names map to properties of the card.

Simple data structure:

<label>
<value>

For example:

Unencrypted Buckets
25

Formal data structure:

labelvaluetype
Unencrypted Buckets10alert

JQ Templates

The href argument allows you to specify a jq template to dynamically generate a hyperlink from the data in the row. To use a jq template, enclose the jq in double curly braces ({{ }}).

Steampipe will pass the first row of data to jq in the same format that is returned by steampipe query json mode output, where the keys are the column names and the values are the data for that row.

For example, this query:

select
s.volume_id as value,
'Source Volume' as label,
'info' as type,
v.arn
from
aws_ebs_snapshot as s,
aws_ebs_volume as v
where
s.volume_id = v.volume_id
and s.snapshot_id = 'snap-0cc613495a9fe5c1c';

will present rows to the jq template in this format:

{
"arn": "arn:aws:ec2:us-east-2:123456789012:volume/vol-0566e02dcc2c08e77",
"label": "Source Volume",
"type": "info",
"value": "vol-0566e02dcc2c08e77"
}

which you can then use in a jq template in the href argument:

card {
sql = <<-EOQ
select
s.volume_id as value,
'Source Volume' as label,
'info' as type,
v.arn
from
aws_ebs_snapshot as s,
aws_ebs_volume as v
where
s.volume_id = v.volume_id
and s.snapshot_id = 'snap-0cc613495a9fe5c1c';
EOQ
width = 3
href = "/aws_insights.dashboard.aws_ebs_volume_detail?input.volume_arn={{.arn | @uri}}"
}

Note that for a card, we pass label , value , type or icon HCL attributes in the JQ context, but the columns from the SQL query will overwrite any of the statically-defined HCL attributes.

Refer to JQ Escaping & Interpolation for more advanced examples.

More Examples

Alert Card


card {
sql = "select 0 as alert"
type = "alert"
width = 2
}

OK Card


card {
sql = "select 0 as ok"
type = "ok"
width = 2
}

Info Card


card {
sql = "select 0 as info"
type = "info"
width = 2
}

Dynamic Styling via formal query data structure


card {
sql = <<-EOQ
select
'Unencrypted Buckets' as label,
count(*) as value,
case
when count(*) > 0 then 'alert'
else 'ok'
end as type
from
aws_s3_bucket
where
server_side_encryption_configuration is null;
EOQ
width = 2
}

card {
value = "github"
label = "site"
width = 2
href = "https://github.com"
}

card {
sql = <<-EOQ
select
count(*) as value,
'Has Public Bucket Policy' as label,
case
count(*)
when 0 then 'ok'
else 'alert'
end as "type"
from
aws_s3_bucket
where
bucket_policy_is_public;
EOQ
icon = "hashtag"
width = 2
href = "${dashboard.aws_s3_bucket_public_access_report.url_path}"
}

card {
sql = <<-EOQ
select
s.volume_id as value,
'Source Volume' as label,
'info' as type,
v.arn
from
aws_ebs_snapshot as s,
aws_ebs_volume as v
where
s.volume_id = v.volume_id
and s.snapshot_id = 'snap-0cc613495a9fe5c1c';
EOQ
width = 3
href = "/aws_insights.dashboard.aws_ebs_volume_detail?input.volume_arn={{.arn | @uri}}"
}