View a markdown version of this page

AWS IoT examples using AWS CLI with Bash script - AWS Command Line Interface

AWS IoT examples using AWS CLI with Bash script

The following code examples show you how to perform actions and implement common scenarios by using the AWS Command Line Interface with Bash script with AWS IoT.

Scenarios are code examples that show you how to accomplish specific tasks by calling multiple functions within a service or combined with other AWS services.

Each example includes a link to the complete source code, where you can find instructions on how to set up and run the code in context.

Topics

Scenarios

The following code example shows how to:

  • Create Required IAM Roles

  • Enable IoT Device Defender Audit Checks

  • Run an On-Demand Audit

  • Create a Mitigation Action

  • Apply Mitigation Actions to Findings

  • Set Up SNS Notifications (Optional)

  • Enable IoT Logging

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 IoT Device Defender Getting Started Script # This script demonstrates how to use AWS IoT Device Defender to enable audit checks, # view audit results, create mitigation actions, and apply them to findings. # Set up logging LOG_FILE="iot-device-defender-script-$(date +%Y%m%d%H%M%S).log" exec > >(tee -a "$LOG_FILE") 2>&1 echo "===================================================" echo "AWS IoT Device Defender Getting Started Script" echo "===================================================" echo "Starting script execution at $(date)" echo "" # Function to check for errors in command output check_error() { if echo "$1" | grep -i "An error occurred\|Exception\|Failed\|usage: aws" > /dev/null; then echo "ERROR: Command failed with the following output:" echo "$1" return 1 fi return 0 } # Function to create IAM roles create_iam_role() { local ROLE_NAME=$1 local TRUST_POLICY=$2 local MANAGED_POLICY=$3 echo "Creating IAM role: $ROLE_NAME" # Check if role already exists ROLE_EXISTS=$(aws iam get-role --role-name "$ROLE_NAME" 2>&1 || echo "NOT_EXISTS") if echo "$ROLE_EXISTS" | grep -i "NoSuchEntity" > /dev/null; then # Create the role with trust policy ROLE_RESULT=$(aws iam create-role \ --role-name "$ROLE_NAME" \ --assume-role-policy-document "$TRUST_POLICY" 2>&1) if ! check_error "$ROLE_RESULT"; then echo "Failed to create role $ROLE_NAME" return 1 fi # For IoT logging role, create an inline policy instead of using a managed policy if [[ "$ROLE_NAME" == "AWSIoTLoggingRole" ]]; then LOGGING_POLICY='{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:PutMetricFilter", "logs:PutRetentionPolicy", "logs:GetLogEvents", "logs:DescribeLogStreams" ], "Resource": [ "arn:aws:logs:*:*:*" ] } ] }' POLICY_RESULT=$(aws iam put-role-policy \ --role-name "$ROLE_NAME" \ --policy-name "${ROLE_NAME}Policy" \ --policy-document "$LOGGING_POLICY" 2>&1) if ! check_error "$POLICY_RESULT"; then echo "Failed to attach inline policy to role $ROLE_NAME" return 1 fi elif [[ "$ROLE_NAME" == "IoTMitigationActionErrorLoggingRole" ]]; then MITIGATION_POLICY='{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:UpdateCACertificate", "iot:UpdateCertificate", "iot:SetV2LoggingOptions", "iot:SetLoggingOptions", "iot:AddThingToThingGroup", "iot:PublishToTopic" ], "Resource": "*" }, { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "*", "Condition": { "StringEquals": { "iam:PassedToService": "iot.amazonaws.com" } } } ] }' POLICY_RESULT=$(aws iam put-role-policy \ --role-name "$ROLE_NAME" \ --policy-name "${ROLE_NAME}Policy" \ --policy-document "$MITIGATION_POLICY" 2>&1) if ! check_error "$POLICY_RESULT"; then echo "Failed to attach inline policy to role $ROLE_NAME" return 1 fi else # Attach managed policy to role if provided if [ -n "$MANAGED_POLICY" ]; then ATTACH_RESULT=$(aws iam attach-role-policy \ --role-name "$ROLE_NAME" \ --policy-arn "$MANAGED_POLICY" 2>&1) if ! check_error "$ATTACH_RESULT"; then echo "Failed to attach policy to role $ROLE_NAME" return 1 fi fi fi echo "Role $ROLE_NAME created successfully" else echo "Role $ROLE_NAME already exists, skipping creation" fi # Get the role ARN ROLE_ARN=$(aws iam get-role --role-name "$ROLE_NAME" --query 'Role.Arn' --output text) echo "Role ARN: $ROLE_ARN" return 0 } # Array to store created resources for cleanup declare -a CREATED_RESOURCES # Step 1: Create IAM roles needed for the tutorial echo "===================================================" echo "Step 1: Creating required IAM roles" echo "===================================================" # Create IoT Device Defender Audit role IOT_DEFENDER_AUDIT_TRUST_POLICY='{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' create_iam_role "AWSIoTDeviceDefenderAuditRole" "$IOT_DEFENDER_AUDIT_TRUST_POLICY" "arn:aws:iam::aws:policy/service-role/AWSIoTDeviceDefenderAudit" AUDIT_ROLE_ARN=$ROLE_ARN CREATED_RESOURCES+=("IAM Role: AWSIoTDeviceDefenderAuditRole") # Create IoT Logging role IOT_LOGGING_TRUST_POLICY='{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' create_iam_role "AWSIoTLoggingRole" "$IOT_LOGGING_TRUST_POLICY" "" LOGGING_ROLE_ARN=$ROLE_ARN CREATED_RESOURCES+=("IAM Role: AWSIoTLoggingRole") # Create IoT Mitigation Action role IOT_MITIGATION_TRUST_POLICY='{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "iot.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }' create_iam_role "IoTMitigationActionErrorLoggingRole" "$IOT_MITIGATION_TRUST_POLICY" "" MITIGATION_ROLE_ARN=$ROLE_ARN CREATED_RESOURCES+=("IAM Role: IoTMitigationActionErrorLoggingRole") # Step 2: Enable audit checks echo "" echo "===================================================" echo "Step 2: Enabling AWS IoT Device Defender audit checks" echo "===================================================" # Get current audit configuration echo "Getting current audit configuration..." CURRENT_CONFIG=$(aws iot describe-account-audit-configuration) echo "$CURRENT_CONFIG" # Enable specific audit checks echo "Enabling audit checks..." UPDATE_RESULT=$(aws iot update-account-audit-configuration \ --role-arn "$AUDIT_ROLE_ARN" \ --audit-check-configurations '{"LOGGING_DISABLED_CHECK":{"enabled":true}}') if ! check_error "$UPDATE_RESULT"; then echo "Failed to update audit configuration" exit 1 fi echo "Audit checks enabled successfully" # Step 3: Run an on-demand audit echo "" echo "===================================================" echo "Step 3: Running an on-demand audit" echo "===================================================" echo "Starting on-demand audit task..." AUDIT_TASK_RESULT=$(aws iot start-on-demand-audit-task \ --target-check-names LOGGING_DISABLED_CHECK) if ! check_error "$AUDIT_TASK_RESULT"; then echo "Failed to start on-demand audit task" exit 1 fi TASK_ID=$(echo "$AUDIT_TASK_RESULT" | grep -o '"taskId": "[^"]*' | cut -d'"' -f4) echo "Audit task started with ID: $TASK_ID" CREATED_RESOURCES+=("Audit Task: $TASK_ID") # Wait for the audit task to complete echo "Waiting for audit task to complete (this may take a few minutes)..." TASK_STATUS="IN_PROGRESS" while [ "$TASK_STATUS" != "COMPLETED" ]; do sleep 10 TASK_DETAILS=$(aws iot describe-audit-task --task-id "$TASK_ID") TASK_STATUS=$(echo "$TASK_DETAILS" | grep -o '"taskStatus": "[^"]*' | cut -d'"' -f4) echo "Current task status: $TASK_STATUS" if [ "$TASK_STATUS" == "FAILED" ]; then echo "Audit task failed" exit 1 fi done echo "Audit task completed successfully" # Get audit findings echo "Getting audit findings..." FINDINGS=$(aws iot list-audit-findings \ --task-id "$TASK_ID") echo "Audit findings:" echo "$FINDINGS" # Check if we have any non-compliant findings if echo "$FINDINGS" | grep -q '"findingId"'; then FINDING_ID=$(echo "$FINDINGS" | grep -o '"findingId": "[^"]*' | head -1 | cut -d'"' -f4) echo "Found non-compliant finding with ID: $FINDING_ID" HAS_FINDINGS=true else echo "No non-compliant findings detected" HAS_FINDINGS=false fi # Step 4: Create a mitigation action echo "" echo "===================================================" echo "Step 4: Creating a mitigation action" echo "===================================================" # Check if mitigation action already exists MITIGATION_EXISTS=$(aws iot list-mitigation-actions --action-name "EnableErrorLoggingAction" 2>&1) if echo "$MITIGATION_EXISTS" | grep -q "EnableErrorLoggingAction"; then echo "Mitigation action 'EnableErrorLoggingAction' already exists, deleting it first..." aws iot delete-mitigation-action --action-name "EnableErrorLoggingAction" # Wait a moment for deletion to complete sleep 5 fi echo "Creating mitigation action to enable AWS IoT logging..." MITIGATION_RESULT=$(aws iot create-mitigation-action \ --action-name "EnableErrorLoggingAction" \ --role-arn "$MITIGATION_ROLE_ARN" \ --action-params "{\"enableIoTLoggingParams\":{\"roleArnForLogging\":\"$LOGGING_ROLE_ARN\",\"logLevel\":\"ERROR\"}}") echo "$MITIGATION_RESULT" if ! check_error "$MITIGATION_RESULT"; then echo "Failed to create mitigation action" exit 1 fi echo "Mitigation action created successfully" CREATED_RESOURCES+=("Mitigation Action: EnableErrorLoggingAction") # Step 5: Apply mitigation action to findings (if any) if [ "$HAS_FINDINGS" = true ]; then echo "" echo "===================================================" echo "Step 5: Applying mitigation action to findings" echo "===================================================" MITIGATION_TASK_ID="MitigationTask-$(date +%s)" echo "Starting mitigation actions task with ID: $MITIGATION_TASK_ID" MITIGATION_TASK_RESULT=$(aws iot start-audit-mitigation-actions-task \ --task-id "$MITIGATION_TASK_ID" \ --target "{\"findingIds\":[\"$FINDING_ID\"]}" \ --audit-check-to-actions-mapping "{\"LOGGING_DISABLED_CHECK\":[\"EnableErrorLoggingAction\"]}") if ! check_error "$MITIGATION_TASK_RESULT"; then echo "Failed to start mitigation actions task" exit 1 fi echo "Mitigation actions task started successfully" CREATED_RESOURCES+=("Mitigation Task: $MITIGATION_TASK_ID") # Wait for the mitigation task to complete echo "Waiting for mitigation task to complete..." sleep 10 # Use a more reliable date format for the API call START_TIME=$(date -u -d 'today' '+%Y-%m-%dT%H:%M:%S.000Z') END_TIME=$(date -u '+%Y-%m-%dT%H:%M:%S.000Z') MITIGATION_TASKS=$(aws iot list-audit-mitigation-actions-tasks \ --start-time "$START_TIME" \ --end-time "$END_TIME" 2>&1) if check_error "$MITIGATION_TASKS"; then echo "Mitigation tasks:" echo "$MITIGATION_TASKS" else echo "Could not retrieve mitigation task status, but task was started successfully" fi else echo "" echo "===================================================" echo "Step 5: Skipping mitigation action application (no findings)" echo "===================================================" fi # Step 6: Set up SNS notifications (optional) echo "" echo "===================================================" echo "Step 6: Setting up SNS notifications" echo "===================================================" # Check if SNS topic already exists SNS_TOPICS=$(aws sns list-topics) if echo "$SNS_TOPICS" | grep -q "IoTDDNotifications"; then echo "SNS topic 'IoTDDNotifications' already exists, using existing topic..." TOPIC_ARN=$(echo "$SNS_TOPICS" | grep -o '"TopicArn": "[^"]*IoTDDNotifications' | cut -d'"' -f4) else echo "Creating SNS topic for notifications..." SNS_RESULT=$(aws sns create-topic --name "IoTDDNotifications") if ! check_error "$SNS_RESULT"; then echo "Failed to create SNS topic" exit 1 fi TOPIC_ARN=$(echo "$SNS_RESULT" | grep -o '"TopicArn": "[^"]*' | cut -d'"' -f4) echo "SNS topic created with ARN: $TOPIC_ARN" CREATED_RESOURCES+=("SNS Topic: IoTDDNotifications") fi echo "Updating audit configuration to enable SNS notifications..." SNS_UPDATE_RESULT=$(aws iot update-account-audit-configuration \ --audit-notification-target-configurations "{\"SNS\":{\"targetArn\":\"$TOPIC_ARN\",\"roleArn\":\"$AUDIT_ROLE_ARN\",\"enabled\":true}}") if ! check_error "$SNS_UPDATE_RESULT"; then echo "Failed to update audit configuration for SNS notifications" exit 1 fi echo "SNS notifications enabled successfully" # Step 7: Enable AWS IoT logging echo "" echo "===================================================" echo "Step 7: Enabling AWS IoT logging" echo "===================================================" echo "Setting up AWS IoT logging options..." # Create the logging options payload LOGGING_OPTIONS_PAYLOAD="{\"roleArn\":\"$LOGGING_ROLE_ARN\",\"logLevel\":\"ERROR\"}" LOGGING_RESULT=$(aws iot set-v2-logging-options \ --role-arn "$LOGGING_ROLE_ARN" \ --default-log-level "ERROR" 2>&1) if ! check_error "$LOGGING_RESULT"; then echo "Failed to set up AWS IoT v2 logging, trying v1 logging..." # Try the older set-logging-options command with proper payload format LOGGING_RESULT_V1=$(aws iot set-logging-options \ --logging-options-payload "$LOGGING_OPTIONS_PAYLOAD" 2>&1) if ! check_error "$LOGGING_RESULT_V1"; then echo "Failed to set up AWS IoT logging with both v1 and v2 methods" echo "V2 result: $LOGGING_RESULT" echo "V1 result: $LOGGING_RESULT_V1" exit 1 else echo "AWS IoT v1 logging enabled successfully" fi else echo "AWS IoT v2 logging enabled successfully" fi # Verify logging is enabled echo "Verifying logging configuration..." LOGGING_CONFIG=$(aws iot get-v2-logging-options 2>&1) if check_error "$LOGGING_CONFIG"; then echo "V2 Logging configuration:" echo "$LOGGING_CONFIG" else echo "Checking v1 logging configuration..." LOGGING_CONFIG_V1=$(aws iot get-logging-options 2>&1) if check_error "$LOGGING_CONFIG_V1"; then echo "V1 Logging configuration:" echo "$LOGGING_CONFIG_V1" else echo "Could not retrieve logging configuration" fi fi # Script completed successfully echo "" echo "===================================================" echo "AWS IoT Device Defender setup completed successfully!" echo "===================================================" echo "The following resources were created:" for resource in "${CREATED_RESOURCES[@]}"; do echo "- $resource" done echo "" # Ask if user wants to clean up resources 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 "Starting cleanup process..." # Disable AWS IoT logging echo "Disabling AWS IoT logging..." # Try to disable v2 logging first DISABLE_V2_RESULT=$(aws iot set-v2-logging-options \ --default-log-level "DISABLED" 2>&1) if ! check_error "$DISABLE_V2_RESULT"; then echo "Failed to disable v2 logging, trying v1..." # Try v1 logging disable DISABLE_V1_RESULT=$(aws iot set-logging-options \ --logging-options-payload "{\"logLevel\":\"DISABLED\"}" 2>&1) if ! check_error "$DISABLE_V1_RESULT"; then echo "Warning: Could not disable logging through either v1 or v2 methods" else echo "V1 logging disabled successfully" fi else echo "V2 logging disabled successfully" fi # Delete mitigation action echo "Deleting mitigation action..." aws iot delete-mitigation-action --action-name "EnableErrorLoggingAction" # Reset audit configuration echo "Resetting IoT Device Defender audit configuration..." aws iot update-account-audit-configuration \ --audit-check-configurations '{"LOGGING_DISABLED_CHECK":{"enabled":false}}' 2>&1 | grep -qi "error" && echo "Warning: Failed to disable audit check" aws iot delete-account-audit-configuration --delete-scheduled-audits 2>&1 | grep -qi "error" && echo "Warning: Failed to delete audit configuration" # Delete SNS topic echo "Deleting SNS topic..." aws sns delete-topic --topic-arn "$TOPIC_ARN" # Detach policies from roles and delete roles (in reverse order) echo "Cleaning up IAM roles..." # Check if policies exist before trying to delete them ROLE_POLICIES=$(aws iam list-role-policies --role-name "IoTMitigationActionErrorLoggingRole" 2>&1) if ! echo "$ROLE_POLICIES" | grep -q "NoSuchEntity"; then if echo "$ROLE_POLICIES" | grep -q "IoTMitigationActionErrorLoggingRolePolicy"; then aws iam delete-role-policy \ --role-name "IoTMitigationActionErrorLoggingRole" \ --policy-name "IoTMitigationActionErrorLoggingRolePolicy" fi fi aws iam delete-role --role-name "IoTMitigationActionErrorLoggingRole" ROLE_POLICIES=$(aws iam list-role-policies --role-name "AWSIoTLoggingRole" 2>&1) if ! echo "$ROLE_POLICIES" | grep -q "NoSuchEntity"; then if echo "$ROLE_POLICIES" | grep -q "AWSIoTLoggingRolePolicy"; then aws iam delete-role-policy \ --role-name "AWSIoTLoggingRole" \ --policy-name "AWSIoTLoggingRolePolicy" fi fi aws iam delete-role --role-name "AWSIoTLoggingRole" aws iam detach-role-policy \ --role-name "AWSIoTDeviceDefenderAuditRole" \ --policy-arn "arn:aws:iam::aws:policy/service-role/AWSIoTDeviceDefenderAudit" aws iam delete-role --role-name "AWSIoTDeviceDefenderAuditRole" echo "Cleanup completed successfully" else echo "Skipping cleanup. Resources will remain in your AWS account." fi echo "" echo "Script execution completed at $(date)" echo "Log file: $LOG_FILE"

The following code example shows how to:

  • Create IoT resources

  • Configure your device

  • Run the sample application

  • Clean up resources

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 IoT Core Getting Started Script # This script creates AWS IoT resources, configures a device, and runs a sample application # Set up logging LOG_FILE="iot-core-setup.log" echo "Starting AWS IoT Core setup at $(date)" > $LOG_FILE # Function to log commands and their outputs log_cmd() { echo "$(date): Running command: $1" >> $LOG_FILE eval "$1" 2>&1 | tee -a $LOG_FILE return ${PIPESTATUS[0]} } # Function to check for errors check_error() { if [ $1 -ne 0 ]; then echo "ERROR: Command failed with exit code $1" | tee -a $LOG_FILE echo "Please check the log file $LOG_FILE for details" | tee -a $LOG_FILE cleanup_on_error exit $1 fi } # Function to cleanup resources on error cleanup_on_error() { echo "Error encountered. Attempting to clean up resources..." | tee -a $LOG_FILE echo "Resources created:" | tee -a $LOG_FILE if [ ! -z "$CERTIFICATE_ARN" ]; then echo "Certificate ARN: $CERTIFICATE_ARN" | tee -a $LOG_FILE if [ ! -z "$POLICY_NAME" ]; then log_cmd "aws iot detach-policy --policy-name $POLICY_NAME --target $CERTIFICATE_ARN" fi if [ ! -z "$THING_NAME" ]; then log_cmd "aws iot detach-thing-principal --thing-name $THING_NAME --principal $CERTIFICATE_ARN" fi if [ ! -z "$CERTIFICATE_ID" ]; then log_cmd "aws iot update-certificate --certificate-id $CERTIFICATE_ID --new-status INACTIVE" log_cmd "aws iot delete-certificate --certificate-id $CERTIFICATE_ID" fi fi if [ ! -z "$THING_NAME" ]; then echo "Thing Name: $THING_NAME" | tee -a $LOG_FILE log_cmd "aws iot delete-thing --thing-name $THING_NAME" fi if [ ! -z "$POLICY_NAME" ]; then echo "Policy Name: $POLICY_NAME" | tee -a $LOG_FILE log_cmd "aws iot delete-policy --policy-name $POLICY_NAME" fi if [ ! -z "$SHARED_POLICY_NAME" ]; then echo "Shared Policy Name: $SHARED_POLICY_NAME" | tee -a $LOG_FILE log_cmd "aws iot delete-policy --policy-name $SHARED_POLICY_NAME" fi } # Generate unique identifiers RANDOM_SUFFIX=$(openssl rand -hex 4) THING_NAME="MyIoTThing-${RANDOM_SUFFIX}" POLICY_NAME="MyIoTPolicy-${RANDOM_SUFFIX}" SHARED_POLICY_NAME="SharedSubPolicy-${RANDOM_SUFFIX}" CERTS_DIR="$HOME/certs" echo "==================================================" | tee -a $LOG_FILE echo "AWS IoT Core Getting Started" | tee -a $LOG_FILE echo "==================================================" | tee -a $LOG_FILE echo "This script will:" | tee -a $LOG_FILE echo "1. Create AWS IoT resources (policy, thing, certificate)" | tee -a $LOG_FILE echo "2. Configure your device" | tee -a $LOG_FILE echo "3. Set up for running the sample application" | tee -a $LOG_FILE echo "" | tee -a $LOG_FILE echo "Thing Name: $THING_NAME" | tee -a $LOG_FILE echo "Policy Name: $POLICY_NAME" | tee -a $LOG_FILE echo "Certificates Directory: $CERTS_DIR" | tee -a $LOG_FILE echo "==================================================" | tee -a $LOG_FILE echo "" | tee -a $LOG_FILE # Get AWS account ID echo "Getting AWS account ID..." | tee -a $LOG_FILE ACCOUNT_ID=$(log_cmd "aws sts get-caller-identity --query Account --output text") check_error $? # Get AWS region echo "Getting AWS region..." | tee -a $LOG_FILE REGION=$(log_cmd "aws configure get region") check_error $? if [ -z "$REGION" ]; then echo "AWS region not configured. Please run 'aws configure' to set your region." | tee -a $LOG_FILE exit 1 fi echo "Using AWS Account ID: $ACCOUNT_ID and Region: $REGION" | tee -a $LOG_FILE # Step 1: Create AWS IoT Resources echo "" | tee -a $LOG_FILE echo "Step 1: Creating AWS IoT Resources..." | tee -a $LOG_FILE # Create IoT policy echo "Creating IoT policy document..." | tee -a $LOG_FILE cat > iot-policy.json << EOF { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:Connect" ], "Resource": [ "arn:aws:iot:$REGION:$ACCOUNT_ID:client/test-*" ] }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive" ], "Resource": [ "arn:aws:iot:$REGION:$ACCOUNT_ID:topic/test/topic" ] }, { "Effect": "Allow", "Action": [ "iot:Subscribe" ], "Resource": [ "arn:aws:iot:$REGION:$ACCOUNT_ID:topicfilter/test/topic" ] } ] } EOF echo "Creating IoT policy: $POLICY_NAME..." | tee -a $LOG_FILE log_cmd "aws iot create-policy --policy-name $POLICY_NAME --policy-document file://iot-policy.json" check_error $? # Create IoT thing echo "Creating IoT thing: $THING_NAME..." | tee -a $LOG_FILE log_cmd "aws iot create-thing --thing-name $THING_NAME" check_error $? # Create directory for certificates echo "Creating certificates directory..." | tee -a $LOG_FILE log_cmd "mkdir -p $CERTS_DIR" check_error $? # Create keys and certificate echo "Creating keys and certificate..." | tee -a $LOG_FILE CERT_OUTPUT=$(log_cmd "aws iot create-keys-and-certificate --set-as-active --certificate-pem-outfile $CERTS_DIR/device.pem.crt --public-key-outfile $CERTS_DIR/public.pem.key --private-key-outfile $CERTS_DIR/private.pem.key") check_error $? # Extract certificate ARN and ID CERTIFICATE_ARN=$(echo "$CERT_OUTPUT" | grep "certificateArn" | cut -d'"' -f4) CERTIFICATE_ID=$(echo "$CERTIFICATE_ARN" | cut -d/ -f2) if [ -z "$CERTIFICATE_ARN" ] || [ -z "$CERTIFICATE_ID" ]; then echo "Failed to extract certificate ARN or ID" | tee -a $LOG_FILE cleanup_on_error exit 1 fi echo "Certificate ARN: $CERTIFICATE_ARN" | tee -a $LOG_FILE echo "Certificate ID: $CERTIFICATE_ID" | tee -a $LOG_FILE # Attach policy to certificate echo "Attaching policy to certificate..." | tee -a $LOG_FILE log_cmd "aws iot attach-policy --policy-name $POLICY_NAME --target $CERTIFICATE_ARN" check_error $? # Attach certificate to thing echo "Attaching certificate to thing..." | tee -a $LOG_FILE log_cmd "aws iot attach-thing-principal --thing-name $THING_NAME --principal $CERTIFICATE_ARN" check_error $? # Download Amazon Root CA certificate echo "Downloading Amazon Root CA certificate..." | tee -a $LOG_FILE log_cmd "curl -s -o $CERTS_DIR/Amazon-root-CA-1.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem" check_error $? # Step 2: Configure Your Device echo "" | tee -a $LOG_FILE echo "Step 2: Configuring Your Device..." | tee -a $LOG_FILE # Check if Git is installed echo "Checking if Git is installed..." | tee -a $LOG_FILE if ! command -v git &> /dev/null; then echo "Git is not installed. Please install Git and run this script again." | tee -a $LOG_FILE cleanup_on_error exit 1 fi # Check if Python is installed echo "Checking if Python is installed..." | tee -a $LOG_FILE if ! command -v python3 &> /dev/null; then echo "Python 3 is not installed. Please install Python 3 and run this script again." | tee -a $LOG_FILE cleanup_on_error exit 1 fi # Install AWS IoT Device SDK for Python echo "Installing AWS IoT Device SDK for Python..." | tee -a $LOG_FILE log_cmd "python3 -m pip install awsiotsdk" check_error $? # Clone the AWS IoT Device SDK for Python repository echo "Cloning AWS IoT Device SDK for Python repository..." | tee -a $LOG_FILE if [ ! -d "$HOME/aws-iot-device-sdk-python-v2" ]; then log_cmd "cd $HOME && git clone https://github.com/aws/aws-iot-device-sdk-python-v2.git" check_error $? else echo "AWS IoT Device SDK for Python repository already exists." | tee -a $LOG_FILE fi # Step 3: Get AWS IoT Endpoint echo "" | tee -a $LOG_FILE echo "Step 3: Getting AWS IoT Endpoint..." | tee -a $LOG_FILE IOT_ENDPOINT=$(log_cmd "aws iot describe-endpoint --endpoint-type iot:Data-ATS --query endpointAddress --output text") check_error $? echo "AWS IoT Endpoint: $IOT_ENDPOINT" | tee -a $LOG_FILE # Create a shared subscription policy (optional) echo "" | tee -a $LOG_FILE echo "Creating shared subscription policy (optional)..." | tee -a $LOG_FILE cat > shared-sub-policy.json << EOF { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:Connect" ], "Resource": [ "arn:aws:iot:$REGION:$ACCOUNT_ID:client/*" ] }, { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Receive" ], "Resource": [ "arn:aws:iot:$REGION:$ACCOUNT_ID:topic/test/topic" ] }, { "Effect": "Allow", "Action": [ "iot:Subscribe" ], "Resource": [ "arn:aws:iot:$REGION:$ACCOUNT_ID:topicfilter/test/topic", "arn:aws:iot:$REGION:$ACCOUNT_ID:topicfilter/\$share/*/test/topic" ] } ] } EOF log_cmd "aws iot create-policy --policy-name $SHARED_POLICY_NAME --policy-document file://shared-sub-policy.json" check_error $? log_cmd "aws iot attach-policy --policy-name $SHARED_POLICY_NAME --target $CERTIFICATE_ARN" check_error $? # Summary of created resources echo "" | tee -a $LOG_FILE echo "==================================================" | tee -a $LOG_FILE echo "Setup Complete! Resources Created:" | tee -a $LOG_FILE echo "==================================================" | tee -a $LOG_FILE echo "Thing Name: $THING_NAME" | tee -a $LOG_FILE echo "Policy Name: $POLICY_NAME" | tee -a $LOG_FILE echo "Shared Subscription Policy Name: $SHARED_POLICY_NAME" | tee -a $LOG_FILE echo "Certificate ID: $CERTIFICATE_ID" | tee -a $LOG_FILE echo "Certificate ARN: $CERTIFICATE_ARN" | tee -a $LOG_FILE echo "Certificate Files Location: $CERTS_DIR" | tee -a $LOG_FILE echo "AWS IoT Endpoint: $IOT_ENDPOINT" | tee -a $LOG_FILE echo "==================================================" | tee -a $LOG_FILE # Instructions for running the sample application echo "" | tee -a $LOG_FILE echo "To run the sample application, execute:" | tee -a $LOG_FILE echo "cd $HOME/aws-iot-device-sdk-python-v2/samples" | tee -a $LOG_FILE echo "python3 pubsub.py \\" | tee -a $LOG_FILE echo " --endpoint $IOT_ENDPOINT \\" | tee -a $LOG_FILE echo " --ca_file $CERTS_DIR/Amazon-root-CA-1.pem \\" | tee -a $LOG_FILE echo " --cert $CERTS_DIR/device.pem.crt \\" | tee -a $LOG_FILE echo " --key $CERTS_DIR/private.pem.key" | tee -a $LOG_FILE echo "" | tee -a $LOG_FILE echo "To run the shared subscription example, execute:" | tee -a $LOG_FILE echo "cd $HOME/aws-iot-device-sdk-python-v2/samples" | tee -a $LOG_FILE echo "python3 mqtt5_shared_subscription.py \\" | tee -a $LOG_FILE echo " --endpoint $IOT_ENDPOINT \\" | tee -a $LOG_FILE echo " --ca_file $CERTS_DIR/Amazon-root-CA-1.pem \\" | tee -a $LOG_FILE echo " --cert $CERTS_DIR/device.pem.crt \\" | tee -a $LOG_FILE echo " --key $CERTS_DIR/private.pem.key \\" | tee -a $LOG_FILE echo " --group_identifier consumer" | tee -a $LOG_FILE # Ask if user wants to clean up resources echo "" | tee -a $LOG_FILE echo "==================================================" | tee -a $LOG_FILE echo "CLEANUP CONFIRMATION" | tee -a $LOG_FILE echo "==================================================" | tee -a $LOG_FILE echo "Do you want to clean up all created resources? (y/n): " | tee -a $LOG_FILE read -r CLEANUP_CHOICE if [[ $CLEANUP_CHOICE =~ ^[Yy]$ ]]; then echo "Cleaning up resources..." | tee -a $LOG_FILE # Detach policies from certificate echo "Detaching policies from certificate..." | tee -a $LOG_FILE log_cmd "aws iot detach-policy --policy-name $POLICY_NAME --target $CERTIFICATE_ARN" log_cmd "aws iot detach-policy --policy-name $SHARED_POLICY_NAME --target $CERTIFICATE_ARN" # Detach certificate from thing echo "Detaching certificate from thing..." | tee -a $LOG_FILE log_cmd "aws iot detach-thing-principal --thing-name $THING_NAME --principal $CERTIFICATE_ARN" # Update certificate status to INACTIVE echo "Setting certificate to inactive..." | tee -a $LOG_FILE log_cmd "aws iot update-certificate --certificate-id $CERTIFICATE_ID --new-status INACTIVE" # Delete certificate echo "Deleting certificate..." | tee -a $LOG_FILE log_cmd "aws iot delete-certificate --certificate-id $CERTIFICATE_ID" # Delete thing echo "Deleting thing..." | tee -a $LOG_FILE log_cmd "aws iot delete-thing --thing-name $THING_NAME" # Delete policies echo "Deleting policies..." | tee -a $LOG_FILE log_cmd "aws iot delete-policy --policy-name $POLICY_NAME" log_cmd "aws iot delete-policy --policy-name $SHARED_POLICY_NAME" echo "Cleanup complete!" | tee -a $LOG_FILE else echo "Resources were not cleaned up. You can manually clean them up later." | tee -a $LOG_FILE echo "To clean up resources, run the following commands:" | tee -a $LOG_FILE echo "aws iot detach-policy --policy-name $POLICY_NAME --target $CERTIFICATE_ARN" | tee -a $LOG_FILE echo "aws iot detach-policy --policy-name $SHARED_POLICY_NAME --target $CERTIFICATE_ARN" | tee -a $LOG_FILE echo "aws iot detach-thing-principal --thing-name $THING_NAME --principal $CERTIFICATE_ARN" | tee -a $LOG_FILE echo "aws iot update-certificate --certificate-id $CERTIFICATE_ID --new-status INACTIVE" | tee -a $LOG_FILE echo "aws iot delete-certificate --certificate-id $CERTIFICATE_ID" | tee -a $LOG_FILE echo "aws iot delete-thing --thing-name $THING_NAME" | tee -a $LOG_FILE echo "aws iot delete-policy --policy-name $POLICY_NAME" | tee -a $LOG_FILE echo "aws iot delete-policy --policy-name $SHARED_POLICY_NAME" | tee -a $LOG_FILE fi echo "" | tee -a $LOG_FILE echo "Script execution completed. See $LOG_FILE for details." | tee -a $LOG_FILE