AWS Security ChangesHomeSearch

AWS code-library documentation change

Service: code-library · 2026-05-01 · Documentation low

File: code-library/latest/ug/sns_example_iot_GettingStarted_079_section.md

Summary

Enhanced AWS IoT Device Defender setup script with improved error handling, JSON validation, retry logic, and automated cleanup. Added prerequisite checks, better IAM role management, and more robust AWS CLI command execution.

Security assessment

The changes improve the reliability and safety of an IoT security setup script but don't address a specific security vulnerability. The script sets up AWS IoT Device Defender audit configurations, mitigation actions, and logging - all security features - but the changes are primarily about code quality, error handling, and robustness rather than fixing security issues. The script now validates JSON inputs, adds retry logic for IAM operations, and includes better cleanup procedures, which indirectly improves security by reducing misconfiguration risks.

Diff

diff --git a/code-library/latest/ug/sns_example_iot_GettingStarted_079_section.md b/code-library/latest/ug/sns_example_iot_GettingStarted_079_section.md
index 249fa0de9..f0e4a18f4 100644
--- a//code-library/latest/ug/sns_example_iot_GettingStarted_079_section.md
+++ b//code-library/latest/ug/sns_example_iot_GettingStarted_079_section.md
@@ -46,0 +47,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    set -euo pipefail
+    
@@ -59 +61 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if echo "$1" | grep -i "An error occurred\|Exception\|Failed\|usage: aws" > /dev/null; then
+        if echo "$1" | grep -iE "An error occurred|Exception|Failed|usage: aws" > /dev/null; then
@@ -67 +69,39 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to create IAM roles
+    # Function to safely extract JSON values using jq
+    extract_json_value() {
+        local json="$1"
+        local key="$2"
+        echo "$json" | jq -r ".${key} // empty" 2>/dev/null || echo ""
+    }
+    
+    # Function to validate JSON
+    validate_json() {
+        local json="$1"
+        echo "$json" | jq empty 2>/dev/null
+    }
+    
+    # Function to check AWS CLI availability
+    check_aws_cli() {
+        if ! command -v aws &> /dev/null; then
+            echo "ERROR: AWS CLI is not installed or not in PATH"
+            return 1
+        fi
+        if ! command -v jq &> /dev/null; then
+            echo "ERROR: jq is not installed or not in PATH"
+            return 1
+        fi
+        return 0
+    }
+    
+    # Function to get AWS account ID
+    get_account_id() {
+        local account_id
+        account_id=$(aws sts get-caller-identity --query 'Account' --output text 2>/dev/null) || true
+        if [ -z "$account_id" ]; then
+            echo "ERROR: Could not retrieve AWS account ID"
+            return 1
+        fi
+        echo "$account_id"
+        return 0
+    }
+    
+    # Function to create IAM roles with retry logic
@@ -71,0 +112,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        local RETRY_COUNT=0
+        local MAX_RETRIES=3
@@ -74,0 +117,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        # Validate trust policy JSON
+        if ! validate_json "$TRUST_POLICY"; then
+            echo "ERROR: Invalid trust policy JSON for role $ROLE_NAME"
+            return 1
+        fi
+        
@@ -76 +124,10 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        ROLE_EXISTS=$(aws iam get-role --role-name "$ROLE_NAME" 2>&1 || echo "NOT_EXISTS")
+        if aws iam get-role --role-name "$ROLE_NAME" >/dev/null 2>&1; then
+            echo "Role $ROLE_NAME already exists, skipping creation"
+            ROLE_ARN=$(aws iam get-role --role-name "$ROLE_NAME" --query 'Role.Arn' --output text 2>/dev/null) || true
+            if [ -z "$ROLE_ARN" ]; then
+                echo "ERROR: Could not retrieve ARN for existing role $ROLE_NAME"
+                return 1
+            fi
+            echo "Role ARN: $ROLE_ARN"
+            return 0
+        fi
@@ -78,2 +135,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if echo "$ROLE_EXISTS" | grep -i "NoSuchEntity" > /dev/null; then
-            # Create the role with trust policy
+        # Create the role with trust policy and retry logic
+        while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
@@ -82 +139,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                --assume-role-policy-document "$TRUST_POLICY" 2>&1)
+                --assume-role-policy-document "$TRUST_POLICY" 2>&1) || true
+            
+            if check_error "$ROLE_RESULT"; then
+                break
+            fi
+            
+            RETRY_COUNT=$((RETRY_COUNT + 1))
+            if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then
+                echo "Retrying role creation (attempt $((RETRY_COUNT + 1))/$MAX_RETRIES)..."
+                sleep $((RETRY_COUNT * 2))
+            fi
+        done
@@ -85 +153 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                echo "Failed to create role $ROLE_NAME"
+            echo "Failed to create role $ROLE_NAME after $MAX_RETRIES attempts"
@@ -91 +159,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                LOGGING_POLICY='{
+            local LOGGING_POLICY
+            LOGGING_POLICY=$(cat <<'EOF'
+    {
@@ -105,3 +175 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                            "Resource": [
-                                "arn:aws:logs:*:*:*"
-                            ]
+                "Resource": "arn:aws:logs:*:*:*"
@@ -110 +178,8 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                }'
+    }
+    EOF
+    )
+            
+            if ! validate_json "$LOGGING_POLICY"; then
+                echo "ERROR: Invalid logging policy JSON"
+                return 1
+            fi
@@ -115 +190 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    --policy-document "$LOGGING_POLICY" 2>&1)
+                --policy-document "$LOGGING_POLICY" 2>&1) || true
@@ -122 +197,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                MITIGATION_POLICY='{
+            local MITIGATION_POLICY
+            MITIGATION_POLICY=$(cat <<'EOF'
+    {
@@ -132,2 +209 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                                "iot:AddThingToThingGroup",
-                                "iot:PublishToTopic"
+                    "iot:AddThingToThingGroup"
@@ -135 +211 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                            "Resource": "*"
+                "Resource": "arn:aws:iot:*:*:*"
@@ -148 +224,8 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                }'
+    }
+    EOF
+    )
+            
+            if ! validate_json "$MITIGATION_POLICY"; then
+                echo "ERROR: Invalid mitigation policy JSON"
+                return 1
+            fi
@@ -153 +236 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    --policy-document "$MITIGATION_POLICY" 2>&1)
+                --policy-document "$MITIGATION_POLICY" 2>&1) || true
@@ -164 +247 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                        --policy-arn "$MANAGED_POLICY" 2>&1)
+                    --policy-arn "$MANAGED_POLICY" 2>&1) || true
@@ -174,3 +256,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        else
-            echo "Role $ROLE_NAME already exists, skipping creation"
-        fi
@@ -178,2 +258,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        # Get the role ARN
-        ROLE_ARN=$(aws iam get-role --role-name "$ROLE_NAME" --query 'Role.Arn' --output text)
+        # Get the role ARN with error handling
+        ROLE_ARN=$(aws iam get-role --role-name "$ROLE_NAME" --query 'Role.Arn' --output text 2>/dev/null) || true
+        if [ -z "$ROLE_ARN" ]; then
+            echo "ERROR: Could not retrieve ARN for newly created role $ROLE_NAME"
+            return 1
+        fi
@@ -186,0 +271,11 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Validate prerequisites
+    echo "Validating prerequisites..."
+    if ! check_aws_cli; then
+        echo "ERROR: Prerequisites not met"
+        exit 1
+    fi
+    
+    ACCOUNT_ID=$(get_account_id) || exit 1
+    echo "AWS Account ID: $ACCOUNT_ID"
+    echo ""
+    
@@ -193 +288,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    IOT_DEFENDER_AUDIT_TRUST_POLICY='{
+    IOT_DEFENDER_AUDIT_TRUST_POLICY=$(cat <<'EOF'
+    {
@@ -204 +300,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    }'
+    }
+    EOF
+    )
@@ -206 +304,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    create_iam_role "AWSIoTDeviceDefenderAuditRole" "$IOT_DEFENDER_AUDIT_TRUST_POLICY" "arn:aws:iam::aws:policy/service-role/AWSIoTDeviceDefenderAudit"
+    if ! create_iam_role "AWSIoTDeviceDefenderAuditRole" "$IOT_DEFENDER_AUDIT_TRUST_POLICY" "arn:aws:iam::aws:policy/service-role/AWSIoTDeviceDefenderAudit"; then
+        echo "ERROR: Failed to create audit role"
+        exit 1
+    fi
@@ -211 +312,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    IOT_LOGGING_TRUST_POLICY='{
+    IOT_LOGGING_TRUST_POLICY=$(cat <<'EOF'
+    {
@@ -222 +324,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    }'
+    }
+    EOF
+    )
@@ -224 +328,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    create_iam_role "AWSIoTLoggingRole" "$IOT_LOGGING_TRUST_POLICY" ""
+    if ! create_iam_role "AWSIoTLoggingRole" "$IOT_LOGGING_TRUST_POLICY" ""; then
+        echo "ERROR: Failed to create logging role"
+        exit 1