Evidence Collection Script for AWS Resources: AWS Config

2 min read

Introduction

This is the second part of my attempt to create scripts for collecting evidence about AWS resources. AWS Config is often enabled in multiple regions. In that case, collecting evidence region by region is tedious, so I created the script below.

This script has been confirmed to work only in CloudShell.

Script

#!/bin/bash

# Get a list of all regions
regions=$(aws ec2 describe-regions --query 'Regions[].RegionName' --output text)

for region in $regions; do
    echo -e "\n Region: $region"

    # Create folders for each region
    mkdir -p "$region"
    
    # Get configuration recorder details for each region
    config_recorders=$(aws configservice describe-configuration-recorders --region $region)
    
    if [ -z "$config_recorders" ]; then
        echo "No configuration recorder found"
    else
        # Get recording settings for all resources
        record_all_resources=$(echo $config_recorders | jq -r '.ConfigurationRecorders[].recordingGroup.allSupported')
        echo "Recording settings for all resources: $record_all_resources"

        # Get the recording frequency of the configuration recorder
        recording_frequency=$(echo $config_recorders | jq -r '.ConfigurationRecorders[].recordingMode.recordingFrequency')
        echo "Default recording frequency: $recording_frequency"
        
        # Get settings for recording global resource configuration changes
        override_status=$(echo $config_recorders | jq -r '.ConfigurationRecorders[].recordingGroup.includeGlobalResourceTypes')
        echo "Recording global resource configuration changes: $override_status"

        # Get recording strategy settings
        recording_strategy=$(echo $config_recorders | jq -r '.ConfigurationRecorders[].recordingGroup.recordingStrategy.useOnly')
        echo "Recording strategy: $recording_strategy"

        # If the recording strategy is "EXCLUSION_BY_RESOURCE_TYPES"
        if [ "$recording_strategy" = "EXCLUSION_BY_RESOURCE_TYPES" ]; then
            # Get list of excluded resources
            exclusion_resources=$(echo $config_recorders | jq -r '.ConfigurationRecorders[].recordingGroup.exclusionByResourceTypes.resourceTypes')
            echo "List of excluded resources: $exclusion_resources"
        fi
    fi

    # Set AWS Config data retention period
    retention_period=$(aws configservice describe-retention-configurations --region $region | jq -r '.RetentionConfigurations[].RetentionPeriodInDays')
    if [ -z "$retention_period" ]; then
        retention_period=2557  # Default 7 years (2557 days)
    fi
    echo "Retain AWS Config data for $retention_period days"

    # Get IAM role ARN
    iam_role_arn=$(echo $config_recorders | jq -r '.ConfigurationRecorders[].roleARN')
    echo "IAM role ARN: $iam_role_arn"
    
    # Get delivery channel details for each region
    delivery_channels=$(aws configservice describe-delivery-channels --region $region)
    
    if [ -z "$delivery_channels" ]; then
        echo "No delivery channel found"
    else
        # Get S3 bucket name
        s3_bucket_name=$(echo $delivery_channels | jq -r '.DeliveryChannels[].s3BucketName')
        echo "S3 bucket name: $s3_bucket_name"
        
        # Get S3 bucket prefix
        s3_key_prefix=$(echo $delivery_channels | jq -r '.DeliveryChannels[].s3KeyPrefix')
        echo "S3 bucket prefix: $s3_key_prefix"

        # Get ARN of SNS topic
        sns_topic_arn=$(echo $delivery_channels | jq -r '.DeliveryChannels[].snsTopicARN')
        echo "SNS topic ARN: $sns_topic_arn"
    fi
    
    # Get template details
    template_details=$(aws cloudformation describe-stacks --region $region)
    
    if [ -z "$template_details" ]; then
        echo "No template found"
    else
        # Get conformance pack name
        compliance_pack_name=$(echo $template_details | jq -r '.Stacks[].StackName')
        echo "Conformance pack name: $compliance_pack_name"

        # Get template status
        template_status=$(echo $template_details | jq -r '.Stacks[].StackStatus')
        echo "Template status: $template_status"
    fi
    
    # File output
    echo "$config_recorders" > "$region/describe-configuration-recorders_$region.json"
    echo "$delivery_channels" > "$region/describe-delivery-channels_$region.json"
    echo "$template_details" > "$region/describe-stacks_$region.json"
done

How to use

Run the script with the command below.

sh get-awsconfig.sh

Use redirection if you want to save the script execution log as a file.

sh get-awsconfig.sh > get-awsconfig.log

Output

The standard output looks like this. You can check the settings at a glance.

Region: ap-south-1
  Recording settings for all resources: false
  Default recording frequency: DAILY
  Recording global resource configuration changes: false
  Recording strategy: EXCLUSION_BY_RESOURCE_TYPES
  List of excluded resources: [
  "AWS::IAM::Policy",
  "AWS::IAM::User",
  "AWS::IAM::Role",
  "AWS::IAM::Group"
]
  Retain AWS Config data for 2557 days
  IAM role ARN: arn:aws:iam::XXXXXXXXXXXXX:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig
  S3 bucket name: XXXXXXXXXXXXX-XXXXXXXXXXXXXX
  S3 bucket prefix: Logs/Config
  SNS topic ARN: null
  Conformance pack name: XXXXXXXXXXXXXXXXXXXXXXXXX
  Template status: CREATE_COMPLETE

 --- Omitted ---

A directory will be created for each region as shown below.

[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$ ls -l
total 112
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 ap-northeast-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 ap-northeast-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 ap-northeast-3
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 ap-south-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 ap-southeast-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 ap-southeast-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 ca-central-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 eu-central-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 eu-north-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 eu-west-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 eu-west-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 eu-west-3
-rw-r--r--. 1 cloudshell-user cloudshell-user 13037 Jun  4 08:01 get-awsconfig.log
-rw-r--r--. 1 cloudshell-user cloudshell-user  3008 Jun  4 08:01 get-awsconfig.sh
-rw-r--r--. 1 cloudshell-user cloudshell-user 21999 Jun  4 08:02 get-awsconfig.zip
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 sa-east-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 us-east-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 us-east-2
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 us-west-1
drwxr-xr-x. 2 cloudshell-user cloudshell-user  4096 Jun  4 08:01 us-west-2
[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$ 

JSON will be saved in the region directory as shown below.

[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$ ls -l ap-northeast-1/
total 60
-rw-r--r--. 1 cloudshell-user cloudshell-user 574 Jun  4 08:01 describe-configuration-recorders_ap-northeast-1.json
-rw-r--r--. 1 cloudshell-user cloudshell-user 228 Jun  4 08:01 describe-delivery-channels_ap-northeast-1.json
-rw-r--r--. 1 cloudshell-user cloudshell-user 850 Jun  4 08:01 describe-stacks_ap-northeast-1.json
[cloudshell-user@ip-XX-XXX-XXX-XXX ~]$