Skip to content

Commit

Permalink
Enhanced the table aws_cost_usage to accept custom time frame as inpu…
Browse files Browse the repository at this point in the history
…t param Closes #2149
  • Loading branch information
ParthaI committed Mar 29, 2024
1 parent 6bd37a1 commit b2d235c
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 10 deletions.
9 changes: 4 additions & 5 deletions aws/cost_explorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/costexplorer"
"github.com/aws/aws-sdk-go-v2/service/costexplorer/types"
"github.com/golang/protobuf/ptypes/timestamp"

"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
Expand Down Expand Up @@ -270,8 +269,8 @@ func getCEStartDateForGranularity(granularity string) time.Time {

type CEQuals struct {
// Quals stuff
SearchStartTime *timestamp.Timestamp
SearchEndTime *timestamp.Timestamp
SearchStartTime time.Time
SearchEndTime time.Time
Granularity string
DimensionType1 string
DimensionType2 string
Expand All @@ -284,8 +283,8 @@ func hydrateCostAndUsageQuals(ctx context.Context, d *plugin.QueryData, _ *plugi
//plugin.Logger(ctx).Warn("hydrateKeyQuals", "d.EqualsQuals", d.EqualsQuals)

return &CEQuals{
SearchStartTime: d.EqualsQuals["search_start_time"].GetTimestampValue(),
SearchEndTime: d.EqualsQuals["search_end_time"].GetTimestampValue(),
SearchStartTime: d.EqualsQuals["search_start_time"].GetTimestampValue().AsTime(),
SearchEndTime: d.EqualsQuals["search_end_time"].GetTimestampValue().AsTime(),
Granularity: d.EqualsQuals["granularity"].GetStringValue(),
DimensionType1: d.EqualsQuals["dimension_type_1"].GetStringValue(),
DimensionType2: d.EqualsQuals["dimension_type_2"].GetStringValue(),
Expand Down
36 changes: 32 additions & 4 deletions aws/table_aws_cost_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,33 @@ func tableAwsCostAndUsage(_ context.Context) *plugin.Table {
Name: "aws_cost_usage",
Description: "AWS Cost Explorer - Cost and Usage",
List: &plugin.ListConfig{
//KeyColumns: plugin.AllColumns([]string{"search_start_time", "search_end_time", "granularity", "dimension_type_1", "dimension_type_2"}),
KeyColumns: plugin.AllColumns([]string{"granularity", "dimension_type_1", "dimension_type_2"}),
Hydrate: listCostAndUsage,
Tags: map[string]string{"service": "ce", "action": "GetCostAndUsage"},
KeyColumns: plugin.KeyColumnSlice{
{
Name: "granularity",
Require: plugin.Required,
},
{
Name: "dimension_type_1",
Require: plugin.Required,
},
{
Name: "dimension_type_2",
Require: plugin.Required,
},
{
Name: "search_start_time",
Require: plugin.Optional,
Operators: []string{"="},
},
{
Name: "search_end_time",
Require: plugin.Optional,
Operators: []string{"="},
},
},

Hydrate: listCostAndUsage,
Tags: map[string]string{"service": "ce", "action": "GetCostAndUsage"},
},
Columns: awsGlobalRegionColumns(
costExplorerColumns([]*plugin.Column{
Expand Down Expand Up @@ -122,6 +145,11 @@ func buildInputFromQuals(keyQuals map[string]*proto.QualValue) *costexplorer.Get
endTime := time.Now().Format(timeFormat)
startTime := getCEStartDateForGranularity(granularity).Format(timeFormat)

if keyQuals["search_start_time"] != nil && keyQuals["search_end_time"] != nil {
startTime = keyQuals["search_start_time"].GetTimestampValue().AsTime().Format(timeFormat)
endTime = keyQuals["search_end_time"].GetTimestampValue().AsTime().Format(timeFormat)
}

dim1 := strings.ToUpper(keyQuals["dimension_type_1"].GetStringValue())
dim2 := strings.ToUpper(keyQuals["dimension_type_2"].GetStringValue())

Expand Down
51 changes: 50 additions & 1 deletion docs/tables/aws_cost_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ The `aws_cost_usage` table in Steampipe provides you with information about cost
Amazon Cost Explorer assists you in visualizing, understanding, and managing your AWS costs and usage. The `aws_cost_usage` table offers you a simplified yet flexible view of cost for your account (or all linked accounts when run against the organization master). You need to specify a granularity (`MONTHLY`, `DAILY`), and 2 dimension types (`AZ` , `INSTANCE_TYPE`, `LEGAL_ENTITY_NAME`, `LINKED_ACCOUNT`, `OPERATION`, `PLATFORM`, `PURCHASE_TYPE`, `SERVICE`, `TENANCY`, `RECORD_TYPE`, and `USAGE_TYPE`)

**Important Notes**

- This table requires an '=' qualifier for all of the following columns: granularity, dimension_type_1, dimension_type_2.
- The [pricing for the Cost Explorer API](https://aws.amazon.com/aws-cost-management/pricing/) is per API request - Each request will incur a cost of $0.01 for you.

## Examples

### Monthly net unblended cost by account and service

Explore the monthly expenditure for each linked account and service in your AWS environment. This query can help you understand your cost trends and identify areas for potential savings.

```sql+postgres
Expand Down Expand Up @@ -56,7 +58,52 @@ order by
period_start;
```

### Get unblended cost and usage details within a custom time frame

This query is useful for organizations looking to gain a detailed understanding of their AWS costs on a per-service and per-account basis, within a specified time frame, and on a monthly granularity.

```sql+postgres
select
period_start,
period_end,
dimension_1 as account_id,
dimension_2 as service_name,
net_unblended_cost_amount::numeric::money
from
aws_cost_usage
where
granularity = 'MONTHLY'
and dimension_type_1 = 'LINKED_ACCOUNT'
and dimension_type_2 = 'SERVICE'
and search_start_time = '2023-04-01T05:30:00+05:30'
and search_end_time = '2023-04-05T05:30:00+05:30'
order by
dimension_1,
period_start;
```

```sql+sqlite
select
period_start,
period_end,
dimension_1 as account_id,
dimension_2 as service_name,
net_unblended_cost_amount::numeric::money
from
aws_cost_usage
where
granularity = 'MONTHLY'
and dimension_type_1 = 'LINKED_ACCOUNT'
and dimension_type_2 = 'SERVICE'
and search_start_time = '2023-04-01T05:30:00+05:30'
and search_end_time = '2023-04-05T05:30:00+05:30'
order by
dimension_1,
period_start;
```

### Top 5 most expensive services (net unblended cost) in each account

Identify the top five most costly services in each account to manage and optimize your AWS expenses effectively.

```sql+postgres
Expand Down Expand Up @@ -87,6 +134,7 @@ Error: SQLite does not support rank window functions.
```

### Monthly net unblended cost by account and record type

Analyze your monthly AWS account costs by record type to better understand your expenses. This can help you identify areas where costs may be reduced or controlled.

```sql+postgres
Expand Down Expand Up @@ -124,6 +172,7 @@ order by
```

### List monthly discounts and credits by account

This query allows users to monitor their AWS account's monthly spending by tracking discounts and credits. It's beneficial for budgeting purposes and helps in optimizing cost management strategies.

```sql+postgres
Expand Down Expand Up @@ -160,4 +209,4 @@ where
order by
dimension_1,
period_start;
```
```

0 comments on commit b2d235c

Please sign in to comment.