Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aws_config_delivery_channel table closes #2325 #2343

Merged
merged 3 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions aws/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"aws_config_aggregate_authorization": tableAwsConfigAggregateAuthorization(ctx),
"aws_config_configuration_recorder": tableAwsConfigConfigurationRecorder(ctx),
"aws_config_conformance_pack": tableAwsConfigConformancePack(ctx),
"aws_config_delivery_channel": tableAwsConfigDeliveryChannel(ctx),
"aws_config_retention_configuration": tableAwsConfigRetentionConfiguration(ctx),
"aws_config_rule": tableAwsConfigRule(ctx),
"aws_cost_by_account_daily": tableAwsCostByLinkedAccountDaily(ctx),
Expand Down
179 changes: 179 additions & 0 deletions aws/table_aws_config_delivery_channel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package aws

import (
"context"

"github.com/aws/aws-sdk-go-v2/service/configservice"
"github.com/aws/aws-sdk-go-v2/service/configservice/types"

configservicev1 "github.com/aws/aws-sdk-go/service/configservice"

"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
)

//// TABLE DEFINITION

func tableAwsConfigDeliveryChannel(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "aws_config_delivery_channel",
Description: "AWS Config Delivery Channel",
List: &plugin.ListConfig{
Hydrate: listConfigDeliveryChannels,
KeyColumns: []*plugin.KeyColumn{
{
Name: "name",
Require: plugin.Optional,
},
},
IgnoreConfig: &plugin.IgnoreConfig{
ShouldIgnoreErrorFunc: shouldIgnoreErrors([]string{"NoSuchDeliveryChannelException"}),
},
Tags: map[string]string{"service": "config", "action": "DescribeDeliveryChannels"},
},
GetMatrixItemFunc: SupportedRegionMatrix(configservicev1.EndpointsID),
Columns: awsRegionalColumns([]*plugin.Column{
{
Name: "name",
Description: "The name of the delivery channel.",
Type: proto.ColumnType_STRING,
},
{
Name: "s3_bucket_name",
Description: "The name of the Amazon S3 bucket to which AWS Config delivers configuration snapshots and configuration history files.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("S3BucketName"),
},
{
Name: "s3_key_prefix",
Description: "The prefix for the specified Amazon S3 bucket.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("S3KeyPrefix"),
},
{
Name: "s3_kms_key_arn",
Description: "The Amazon Resource Name (ARN) of the KMS key.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("S3KmsKeyArn"),
},
{
Name: "sns_topic_arn",
Description: "The Amazon Resource Name (ARN) of the Amazon SNS topic to which AWS Config sends notifications about configuration changes.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("SnsTopicARN"),
},
{
Name: "delivery_frequency",
Description: "The frequency with which the AWS Config delivers configuration snapshots to the Amazon S3 bucket.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ConfigSnapshotDeliveryProperties.DeliveryFrequency"),
},
{
Name: "status",
Description: "The current status of the delivery channel.",
Type: proto.ColumnType_JSON,
Hydrate: getConfigDeliveryChannelStatus,
Transform: transform.FromValue(),
},

// Steampipe standard columns
{
Name: "akas",
Description: resourceInterfaceDescription("akas"),
Type: proto.ColumnType_JSON,
Hydrate: getAwsDeliveryChannelAkas,
Transform: transform.FromValue().Transform(transform.EnsureStringArray),
},
{
Name: "title",
Description: resourceInterfaceDescription("title"),
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Name"),
},
}),
}
}

//// LIST FUNCTION

func listConfigDeliveryChannels(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
// Create session
svc, err := ConfigClient(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("aws_config_delivery_channel.listConfigDeliveryChannels", "get_client_error", err)
return nil, err
}

input := &configservice.DescribeDeliveryChannelsInput{}

// Additonal Filter
equalQuals := d.EqualsQuals
if equalQuals["name"] != nil {
input.DeliveryChannelNames = []string{equalQuals["name"].GetStringValue()}
}

op, err := svc.DescribeDeliveryChannels(ctx, input)
if err != nil {
plugin.Logger(ctx).Error("aws_config_delivery_channel.listConfigDeliveryChannels", "api_error", err)
return nil, err
}

if op.DeliveryChannels != nil {
for _, deliveryChannel := range op.DeliveryChannels {
d.StreamListItem(ctx, deliveryChannel)

// Context can be cancelled due to manual cancellation or limit being reached
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
}

return nil, nil
}

//// HYDRATE FUNCTIONS

func getConfigDeliveryChannelStatus(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
deliveryChannel := h.Item.(types.DeliveryChannel)

// Create session
svc, err := ConfigClient(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("aws_config_delivery_channel.getConfigDeliveryChannelStatus", "get_client_error", err)
return nil, err
}

params := &configservice.DescribeDeliveryChannelStatusInput{
DeliveryChannelNames: []string{*deliveryChannel.Name},
}

status, err := svc.DescribeDeliveryChannelStatus(ctx, params)
if err != nil {
plugin.Logger(ctx).Error("aws_config_delivery_channel.getConfigDeliveryChannelStatus", "api_error", err)
return nil, err
}

if len(status.DeliveryChannelsStatus) < 1 {
return nil, nil
}

return status.DeliveryChannelsStatus[0], nil
}

func getAwsDeliveryChannelAkas(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
region := d.EqualsQualString(matrixKeyRegion)

deliveryChannel := h.Item.(types.DeliveryChannel)

c, err := getCommonColumns(ctx, d, h)
if err != nil {
plugin.Logger(ctx).Error("aws_config_delivery_channel.getAwsDeliveryChannelAkas", "api_error", err)
return nil, err
}
commonColumnData := c.(*awsCommonColumnData)
arn := "arn:" + commonColumnData.Partition + ":config:" + region + ":" + commonColumnData.AccountId + ":delivery-channel" + "/" + *deliveryChannel.Name
misraved marked this conversation as resolved.
Show resolved Hide resolved

return arn, nil
}
149 changes: 149 additions & 0 deletions docs/tables/aws_config_delivery_channel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
---
title: "Steampipe Table: aws_config_delivery_channel - Query AWS Config Delivery Channels using SQL"
description: "Allows users to query AWS Config Delivery Channels"
---

# Table: aws_config_delivery_channel - Query AWS Config Delivery Channels using SQL

The AWS Config Delivery Channel is a feature that enables AWS Config to deliver configuration snapshots and configuration change notifications to specified destinations. It plays a key role in ensuring that your configuration data is stored securely and notifications are sent promptly for compliance or operational purposes.

## Table Usage Guide

The `aws_config_delivery_channel` table in Steampipe provides insights into the Delivery Channels associated with AWS Config. This table enables DevOps engineers, security analysts, and cloud administrators to query delivery channel details such as the destination S3 bucket, SNS topic for notifications, and delivery status. Use this table to ensure your configuration change data is being delivered correctly and troubleshoot delivery-related issues.

## Examples

### Retrieve basic delivery channel information
Get a detailed view of your AWS Config Delivery Channels, including their destinations and notification settings.

```sql+postgres
select
name,
s3_bucket_name,
s3_key_prefix,
sns_topic_arn,
delivery_frequency,
status,
title,
akas
from
aws_config_delivery_channel;
```

```sql+sqlite
select
name,
s3_bucket_name,
s3_key_prefix,
sns_topic_arn,
delivery_frequency,
status,
title,
akas
from
aws_config_delivery_channel;
```

### List delivery channels without SNS topic configured
Identify delivery channels that do not have an SNS topic configured for notifications. This can help ensure you have proper alerting mechanisms in place.

```sql+postgres
select
name,
s3_bucket_name,
sns_topic_arn
from
aws_config_delivery_channel
where
sns_topic_arn is null;
```

```sql+sqlite
select
name,
s3_bucket_name,
sns_topic_arn
from
aws_config_delivery_channel
where
sns_topic_arn is null;
```

### Check delivery channels with delivery failures
Discover delivery channels with failed deliveries to address issues in your AWS Config setup.

```sql+postgres
select
name,
status ->> 'LastStatus' as last_status,
status ->> 'LastStatusChangeTime' as last_status_change_time,
status ->> 'LastErrorCode' as last_error_code,
status ->> 'LastErrorMessage' as last_error_message
from
aws_config_delivery_channel
where
(status ->> 'LastStatus') = 'FAILURE';
```

```sql+sqlite
select
name,
json_extract(status, '$.LastStatus') as last_status,
json_extract(status, '$.LastStatusChangeTime') as last_status_change_time,
json_extract(status, '$.LastErrorCode') as last_error_code,
json_extract(status, '$.LastErrorMessage') as last_error_message
from
aws_config_delivery_channel
where
json_extract(status, '$.LastStatus') = 'FAILURE';
```

### List delivery channels sending to a specific S3 bucket
Query the delivery channels that are configured to send data to a particular S3 bucket.

```sql+postgres
select
name,
s3_bucket_name,
sns_topic_arn,
delivery_frequency
from
aws_config_delivery_channel
where
s3_bucket_name = 'test-bucket-delivery-channel';
```

```sql+sqlite
select
name,
s3_bucket_name,
sns_topic_arn,
delivery_frequency
from
aws_config_delivery_channel
where
s3_bucket_name = 'test-bucket-delivery-channel';
```

### Analyze delivery frequency of all channels
Get an overview of how often your delivery channels send data, ensuring they align with organizational requirements.

```sql+postgres
select
name,
delivery_frequency,
s3_bucket_name,
sns_topic_arn
from
aws_config_delivery_channel;
```

```sql+sqlite
select
name,
delivery_frequency,
s3_bucket_name,
sns_topic_arn
from
aws_config_delivery_channel;
```
Loading