Getting started with Config
The following code example shows how to:
Create an Amazon S3 bucket
Create an Amazon SNS topic
Create an IAM role for Config
Set up the Config configuration recorder
Set up the Config delivery channel
Start the configuration recorder
Verify the Config setup
- Bash
-
- AWS CLI with Bash script
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the Sample developer tutorials
repository. #!/bin/bash # AWS Config Setup Script (v2) # This script sets up AWS Config with the AWS CLI # Error handling set -e LOGFILE="aws-config-setup-v2.log" touch $LOGFILE exec > >(tee -a $LOGFILE) exec 2>&1 # Function to handle errors handle_error() { echo "ERROR: An error occurred at line $1" echo "Attempting to clean up resources..." cleanup_resources exit 1 } # Set trap for error handling trap 'handle_error $LINENO' ERR # Function to generate random identifier generate_random_id() { echo $(openssl rand -hex 6) } # Function to check if command was successful check_command() { if echo "$1" | grep -i "error" > /dev/null; then echo "ERROR: $1" return 1 fi return 0 } # Function to clean up resources cleanup_resources() { if [ -n "$CONFIG_RECORDER_NAME" ]; then echo "Stopping configuration recorder..." aws configservice stop-configuration-recorder --configuration-recorder-name "$CONFIG_RECORDER_NAME" 2>/dev/null || true fi # Check if we created a new delivery channel before trying to delete it if [ -n "$DELIVERY_CHANNEL_NAME" ] && [ "$CREATED_NEW_DELIVERY_CHANNEL" = "true" ]; then echo "Deleting delivery channel..." aws configservice delete-delivery-channel --delivery-channel-name "$DELIVERY_CHANNEL_NAME" 2>/dev/null || true fi if [ -n "$CONFIG_RECORDER_NAME" ] && [ "$CREATED_NEW_CONFIG_RECORDER" = "true" ]; then echo "Deleting configuration recorder..." aws configservice delete-configuration-recorder --configuration-recorder-name "$CONFIG_RECORDER_NAME" 2>/dev/null || true fi if [ -n "$ROLE_NAME" ]; then if [ -n "$POLICY_NAME" ]; then echo "Detaching custom policy from role..." aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name "$POLICY_NAME" 2>/dev/null || true fi if [ -n "$MANAGED_POLICY_ARN" ]; then echo "Detaching managed policy from role..." aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn "$MANAGED_POLICY_ARN" 2>/dev/null || true fi echo "Deleting IAM role..." aws iam delete-role --role-name "$ROLE_NAME" 2>/dev/null || true fi if [ -n "$SNS_TOPIC_ARN" ]; then echo "Deleting SNS topic..." aws sns delete-topic --topic-arn "$SNS_TOPIC_ARN" 2>/dev/null || true fi if [ -n "$S3_BUCKET_NAME" ]; then echo "Emptying S3 bucket..." aws s3 rm "s3://$S3_BUCKET_NAME" --recursive 2>/dev/null || true echo "Deleting S3 bucket..." aws s3api delete-bucket --bucket "$S3_BUCKET_NAME" 2>/dev/null || true fi } # Function to display created resources display_resources() { echo "" echo "===========================================" echo "CREATED RESOURCES" echo "===========================================" echo "S3 Bucket: $S3_BUCKET_NAME" echo "SNS Topic ARN: $SNS_TOPIC_ARN" echo "IAM Role: $ROLE_NAME" if [ "$CREATED_NEW_CONFIG_RECORDER" = "true" ]; then echo "Configuration Recorder: $CONFIG_RECORDER_NAME (newly created)" else echo "Configuration Recorder: $CONFIG_RECORDER_NAME (existing)" fi if [ "$CREATED_NEW_DELIVERY_CHANNEL" = "true" ]; then echo "Delivery Channel: $DELIVERY_CHANNEL_NAME (newly created)" else echo "Delivery Channel: $DELIVERY_CHANNEL_NAME (existing)" fi echo "===========================================" } # Get AWS account ID echo "Getting AWS account ID..." ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) if [ -z "$ACCOUNT_ID" ]; then echo "ERROR: Failed to get AWS account ID" exit 1 fi echo "AWS Account ID: $ACCOUNT_ID" # Generate random identifier for resources RANDOM_ID=$(generate_random_id) echo "Generated random identifier: $RANDOM_ID" # Step 1: Create an S3 bucket S3_BUCKET_NAME="configservice-${RANDOM_ID}" echo "Creating S3 bucket: $S3_BUCKET_NAME" # Get the current region AWS_REGION=$(aws configure get region) if [ -z "$AWS_REGION" ]; then AWS_REGION="us-east-1" # Default to us-east-1 if no region is configured fi echo "Using AWS Region: $AWS_REGION" # Create bucket with appropriate command based on region if [ "$AWS_REGION" = "us-east-1" ]; then BUCKET_RESULT=$(aws s3api create-bucket --bucket "$S3_BUCKET_NAME") else BUCKET_RESULT=$(aws s3api create-bucket --bucket "$S3_BUCKET_NAME" --create-bucket-configuration LocationConstraint="$AWS_REGION") fi check_command "$BUCKET_RESULT" echo "S3 bucket created: $S3_BUCKET_NAME" # Block public access for the bucket aws s3api put-public-access-block \ --bucket "$S3_BUCKET_NAME" \ --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true" echo "Public access blocked for bucket" # Step 2: Create an SNS topic TOPIC_NAME="config-topic-${RANDOM_ID}" echo "Creating SNS topic: $TOPIC_NAME" SNS_RESULT=$(aws sns create-topic --name "$TOPIC_NAME") check_command "$SNS_RESULT" SNS_TOPIC_ARN=$(echo "$SNS_RESULT" | grep -o 'arn:aws:sns:[^"]*') echo "SNS topic created: $SNS_TOPIC_ARN" # Step 3: Create an IAM role for AWS Config ROLE_NAME="config-role-${RANDOM_ID}" POLICY_NAME="config-delivery-permissions" MANAGED_POLICY_ARN="arn:aws:iam::aws:policy/service-role/AWS_ConfigRole" echo "Creating trust policy document..." cat > config-trust-policy.json << EOF { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "config.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF echo "Creating IAM role: $ROLE_NAME" ROLE_RESULT=$(aws iam create-role --role-name "$ROLE_NAME" --assume-role-policy-document file://config-trust-policy.json) check_command "$ROLE_RESULT" ROLE_ARN=$(echo "$ROLE_RESULT" | grep -o 'arn:aws:iam::[^"]*' | head -1) echo "IAM role created: $ROLE_ARN" echo "Attaching AWS managed policy to role..." ATTACH_RESULT=$(aws iam attach-role-policy --role-name "$ROLE_NAME" --policy-arn "$MANAGED_POLICY_ARN") check_command "$ATTACH_RESULT" echo "AWS managed policy attached" echo "Creating custom policy document for S3 and SNS access..." cat > config-delivery-permissions.json << EOF { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::${S3_BUCKET_NAME}/AWSLogs/${ACCOUNT_ID}/*", "Condition": { "StringLike": { "s3:x-amz-acl": "bucket-owner-full-control" } } }, { "Effect": "Allow", "Action": [ "s3:GetBucketAcl" ], "Resource": "arn:aws:s3:::${S3_BUCKET_NAME}" }, { "Effect": "Allow", "Action": [ "sns:Publish" ], "Resource": "${SNS_TOPIC_ARN}" } ] } EOF echo "Attaching custom policy to role..." POLICY_RESULT=$(aws iam put-role-policy --role-name "$ROLE_NAME" --policy-name "$POLICY_NAME" --policy-document file://config-delivery-permissions.json) check_command "$POLICY_RESULT" echo "Custom policy attached" # Wait for IAM role to propagate echo "Waiting for IAM role to propagate (15 seconds)..." sleep 15 # Step 4: Check if configuration recorder already exists CONFIG_RECORDER_NAME="default" CREATED_NEW_CONFIG_RECORDER="false" echo "Checking for existing configuration recorder..." EXISTING_RECORDERS=$(aws configservice describe-configuration-recorders 2>/dev/null || echo "") if echo "$EXISTING_RECORDERS" | grep -q "name"; then echo "Configuration recorder already exists. Will update it." # Get the name of the existing recorder CONFIG_RECORDER_NAME=$(echo "$EXISTING_RECORDERS" | grep -o '"name": "[^"]*"' | head -1 | cut -d'"' -f4) echo "Using existing configuration recorder: $CONFIG_RECORDER_NAME" else echo "No existing configuration recorder found. Will create a new one." CREATED_NEW_CONFIG_RECORDER="true" fi echo "Creating configuration recorder configuration..." cat > configurationRecorder.json << EOF { "name": "${CONFIG_RECORDER_NAME}", "roleARN": "${ROLE_ARN}", "recordingMode": { "recordingFrequency": "CONTINUOUS" } } EOF echo "Creating recording group configuration..." cat > recordingGroup.json << EOF { "allSupported": true, "includeGlobalResourceTypes": true } EOF echo "Setting up configuration recorder..." RECORDER_RESULT=$(aws configservice put-configuration-recorder --configuration-recorder file://configurationRecorder.json --recording-group file://recordingGroup.json) check_command "$RECORDER_RESULT" echo "Configuration recorder set up" # Step 5: Check if delivery channel already exists DELIVERY_CHANNEL_NAME="default" CREATED_NEW_DELIVERY_CHANNEL="false" echo "Checking for existing delivery channel..." EXISTING_CHANNELS=$(aws configservice describe-delivery-channels 2>/dev/null || echo "") if echo "$EXISTING_CHANNELS" | grep -q "name"; then echo "Delivery channel already exists." # Get the name of the existing channel DELIVERY_CHANNEL_NAME=$(echo "$EXISTING_CHANNELS" | grep -o '"name": "[^"]*"' | head -1 | cut -d'"' -f4) echo "Using existing delivery channel: $DELIVERY_CHANNEL_NAME" # Update the existing delivery channel echo "Creating delivery channel configuration for update..." cat > deliveryChannel.json << EOF { "name": "${DELIVERY_CHANNEL_NAME}", "s3BucketName": "${S3_BUCKET_NAME}", "snsTopicARN": "${SNS_TOPIC_ARN}", "configSnapshotDeliveryProperties": { "deliveryFrequency": "Six_Hours" } } EOF echo "Updating delivery channel..." CHANNEL_RESULT=$(aws configservice put-delivery-channel --delivery-channel file://deliveryChannel.json) check_command "$CHANNEL_RESULT" echo "Delivery channel updated" else echo "No existing delivery channel found. Will create a new one." CREATED_NEW_DELIVERY_CHANNEL="true" echo "Creating delivery channel configuration..." cat > deliveryChannel.json << EOF { "name": "${DELIVERY_CHANNEL_NAME}", "s3BucketName": "${S3_BUCKET_NAME}", "snsTopicARN": "${SNS_TOPIC_ARN}", "configSnapshotDeliveryProperties": { "deliveryFrequency": "Six_Hours" } } EOF echo "Creating delivery channel..." CHANNEL_RESULT=$(aws configservice put-delivery-channel --delivery-channel file://deliveryChannel.json) check_command "$CHANNEL_RESULT" echo "Delivery channel created" fi # Step 6: Start the configuration recorder echo "Checking configuration recorder status..." RECORDER_STATUS=$(aws configservice describe-configuration-recorder-status 2>/dev/null || echo "") if echo "$RECORDER_STATUS" | grep -q '"recording": true'; then echo "Configuration recorder is already running." else echo "Starting configuration recorder..." START_RESULT=$(aws configservice start-configuration-recorder --configuration-recorder-name "$CONFIG_RECORDER_NAME") check_command "$START_RESULT" echo "Configuration recorder started" fi # Step 7: Verify the AWS Config setup echo "Verifying delivery channel..." VERIFY_CHANNEL=$(aws configservice describe-delivery-channels) check_command "$VERIFY_CHANNEL" echo "$VERIFY_CHANNEL" echo "Verifying configuration recorder..." VERIFY_RECORDER=$(aws configservice describe-configuration-recorders) check_command "$VERIFY_RECORDER" echo "$VERIFY_RECORDER" echo "Verifying configuration recorder status..." VERIFY_STATUS=$(aws configservice describe-configuration-recorder-status) check_command "$VERIFY_STATUS" echo "$VERIFY_STATUS" # Display created resources display_resources # Ask if user wants to clean up resources echo "" echo "===========================================" echo "CLEANUP CONFIRMATION" echo "===========================================" echo "Do you want to clean up all created resources? (y/n): " read -r CLEANUP_CHOICE if [[ "$CLEANUP_CHOICE" =~ ^[Yy]$ ]]; then echo "Cleaning up resources..." cleanup_resources echo "Cleanup completed." else echo "Resources will not be cleaned up. You can manually clean them up later." fi echo "Script completed successfully!"-
For API details, see the following topics in AWS CLI Command Reference.
-
For a complete list of AWS SDK developer guides and code examples, see Developing with Amazon S3 using the AWS SDKs. This topic also includes information about getting started and details about previous SDK versions.
Getting started with Amazon Textract
Lock Amazon S3 objects