AWS Security ChangesHomeSearch

AWS code-library high security documentation change

Service: code-library · 2026-05-01 · Security-related high

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

Summary

Updated AWS Cloud Map tutorial script with improved error handling, resource management, and security practices including least privilege IAM policies and input validation.

Security assessment

The changes implement critical security improvements: 1) Replaced PowerUserAccess with least privilege custom IAM policy (reducing attack surface), 2) Added input validation and error handling in Lambda functions to prevent attribute injection, 3) Implemented safe variable quoting throughout the script to prevent shell injection attacks, 4) Added resource existence checks before deletion to avoid privilege escalation via error conditions. These directly address potential security vulnerabilities in resource handling and access control.

Diff

diff --git a/code-library/latest/ug/servicediscovery_example_cloudmap_CustomAttributes_section.md b/code-library/latest/ug/servicediscovery_example_cloudmap_CustomAttributes_section.md
index 30fce94d6..484c623c1 100644
--- a//code-library/latest/ug/servicediscovery_example_cloudmap_CustomAttributes_section.md
+++ b//code-library/latest/ug/servicediscovery_example_cloudmap_CustomAttributes_section.md
@@ -45,0 +46,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    set -euo pipefail
+    
@@ -48,2 +50,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "AWS Cloud Map Tutorial Script" > $LOG_FILE
-    echo "Started at $(date)" >> $LOG_FILE
+    echo "AWS Cloud Map Tutorial Script" > "$LOG_FILE"
+    echo "Started at $(date)" >> "$LOG_FILE"
@@ -56,2 +58,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "$ $1" | tee -a $LOG_FILE
-      eval "$1" | tee -a $LOG_FILE
+      echo "$ $1" | tee -a "$LOG_FILE"
+      eval "$1" | tee -a "$LOG_FILE"
@@ -63,2 +65,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "An error occurred at line $LINE" | tee -a $LOG_FILE
-      echo "Resources created so far:" | tee -a $LOG_FILE
+      echo "An error occurred at line $LINE" | tee -a "$LOG_FILE"
+      echo "Resources created so far:" | tee -a "$LOG_FILE"
@@ -66 +68 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        echo "- $resource" | tee -a $LOG_FILE
+        echo "- $resource" | tee -a "$LOG_FILE"
@@ -68 +70 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Attempting to clean up resources..." | tee -a $LOG_FILE
+      echo "Attempting to clean up resources..." | tee -a "$LOG_FILE"
@@ -80 +82,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      local START_TIME=$(date +%s)
+      local START_TIME
+      START_TIME=$(date +%s)
@@ -83 +86,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        local STATUS=$(aws servicediscovery get-operation --operation-id $OPERATION_ID --query 'Operation.Status' --output text)
+        local STATUS
+        STATUS=$(aws servicediscovery get-operation --operation-id "$OPERATION_ID" --query 'Operation.Status' --output text 2>/dev/null || echo "UNKNOWN")
@@ -86 +90 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          echo "Operation completed successfully" | tee -a $LOG_FILE
+          echo "Operation completed successfully" | tee -a "$LOG_FILE"
@@ -89 +93 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          echo "Operation failed" | tee -a $LOG_FILE
+          echo "Operation failed" | tee -a "$LOG_FILE"
@@ -93 +97,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        local CURRENT_TIME=$(date +%s)
+        local CURRENT_TIME
+        CURRENT_TIME=$(date +%s)
@@ -95 +100 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          echo "Operation timed out" | tee -a $LOG_FILE
+          echo "Operation timed out" | tee -a "$LOG_FILE"
@@ -107 +112 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Cleaning up resources..." | tee -a $LOG_FILE
+      echo "Cleaning up resources..." | tee -a "$LOG_FILE"
@@ -112 +117 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        echo "Deleting $resource..." | tee -a $LOG_FILE
+        echo "Deleting $resource..." | tee -a "$LOG_FILE"
@@ -116,2 +121,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          SERVICE_ID=$(echo $resource | cut -d':' -f2)
-          INSTANCE_ID=$(echo $resource | cut -d':' -f3)
+          SERVICE_ID=$(echo "$resource" | cut -d':' -f2)
+          INSTANCE_ID=$(echo "$resource" | cut -d':' -f3)
@@ -120 +125 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          INSTANCE_EXISTS=$(aws servicediscovery list-instances --service-id $SERVICE_ID --query "Instances[?Id=='$INSTANCE_ID'].Id" --output text 2>/dev/null || echo "")
+          INSTANCE_EXISTS=$(aws servicediscovery list-instances --service-id "$SERVICE_ID" --query "Instances[?Id=='$INSTANCE_ID'].Id" --output text 2>/dev/null || echo "")
@@ -122 +127 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            OPERATION_ID=$(aws servicediscovery deregister-instance --service-id $SERVICE_ID --instance-id $INSTANCE_ID --query 'OperationId' --output text)
+            OPERATION_ID=$(aws servicediscovery deregister-instance --service-id "$SERVICE_ID" --instance-id "$INSTANCE_ID" --query 'OperationId' --output text)
@@ -125,2 +130,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            echo "Waiting for instance deregistration to complete..." | tee -a $LOG_FILE
-            wait_for_operation $OPERATION_ID
+            echo "Waiting for instance deregistration to complete..." | tee -a "$LOG_FILE"
+            wait_for_operation "$OPERATION_ID" || true
@@ -128 +133 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            echo "Instance $INSTANCE_ID already deregistered" | tee -a $LOG_FILE
+            echo "Instance $INSTANCE_ID already deregistered" | tee -a "$LOG_FILE"
@@ -132,2 +137,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          FUNCTION_NAME=$(echo $resource | cut -d':' -f2)
-          aws lambda delete-function --function-name $FUNCTION_NAME
+          FUNCTION_NAME=$(echo "$resource" | cut -d':' -f2)
+          aws lambda delete-function --function-name "$FUNCTION_NAME" 2>/dev/null || echo "Function already deleted" | tee -a "$LOG_FILE"
@@ -136 +141 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          ROLE_NAME=$(echo $resource | cut -d':' -f2)
+          ROLE_NAME=$(echo "$resource" | cut -d':' -f2)
@@ -139,2 +144,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          for POLICY_ARN in $(aws iam list-attached-role-policies --role-name $ROLE_NAME --query 'AttachedPolicies[*].PolicyArn' --output text); do
-            aws iam detach-role-policy --role-name $ROLE_NAME --policy-arn $POLICY_ARN
+          for POLICY_ARN in $(aws iam list-attached-role-policies --role-name "$ROLE_NAME" --query 'AttachedPolicies[*].PolicyArn' --output text); do
+            aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn "$POLICY_ARN"
@@ -144 +149 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          aws iam delete-role --role-name $ROLE_NAME
+          aws iam delete-role --role-name "$ROLE_NAME" 2>/dev/null || echo "Role already deleted" | tee -a "$LOG_FILE"
@@ -147,2 +152,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          TABLE_NAME=$(echo $resource | cut -d':' -f2)
-          aws dynamodb delete-table --table-name $TABLE_NAME
+          TABLE_NAME=$(echo "$resource" | cut -d':' -f2)
+          aws dynamodb delete-table --table-name "$TABLE_NAME" 2>/dev/null || echo "Table already deleted" | tee -a "$LOG_FILE"
@@ -151,2 +156,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          echo "Waiting for DynamoDB table deletion to complete..." | tee -a $LOG_FILE
-          aws dynamodb wait table-not-exists --table-name $TABLE_NAME
+          echo "Waiting for DynamoDB table deletion to complete..." | tee -a "$LOG_FILE"
+          aws dynamodb wait table-not-exists --table-name "$TABLE_NAME" 2>/dev/null || true
@@ -161,2 +166,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          SERVICE_ID=$(echo $resource | cut -d':' -f2)
-          echo "Deleting service $SERVICE_ID..." | tee -a $LOG_FILE
+          SERVICE_ID=$(echo "$resource" | cut -d':' -f2)
+          echo "Deleting service $SERVICE_ID..." | tee -a "$LOG_FILE"
@@ -165 +170 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          INSTANCES=$(aws servicediscovery list-instances --service-id $SERVICE_ID --query 'Instances[*].Id' --output text)
+          INSTANCES=$(aws servicediscovery list-instances --service-id "$SERVICE_ID" --query 'Instances[*].Id' --output text 2>/dev/null || echo "")
@@ -167 +172 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            echo "Service still has instances. Waiting before deletion..." | tee -a $LOG_FILE
+            echo "Service still has instances. Waiting before deletion..." | tee -a "$LOG_FILE"
@@ -172 +177 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          aws servicediscovery delete-service --id $SERVICE_ID
+          aws servicediscovery delete-service --id "$SERVICE_ID" 2>/dev/null || echo "Service already deleted" | tee -a "$LOG_FILE"
@@ -182,2 +187,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          NAMESPACE_ID=$(echo $resource | cut -d':' -f2)
-          echo "Deleting namespace $NAMESPACE_ID..." | tee -a $LOG_FILE
+          NAMESPACE_ID=$(echo "$resource" | cut -d':' -f2)
+          echo "Deleting namespace $NAMESPACE_ID..." | tee -a "$LOG_FILE"
@@ -186 +191 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          SERVICES=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query 'Services[*].Id' --output text)
+          SERVICES=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query 'Services[*].Id' --output text 2>/dev/null || echo "")
@@ -188 +193 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            echo "Namespace still has services. Deleting them first..." | tee -a $LOG_FILE
+            echo "Namespace still has services. Deleting them first..." | tee -a "$LOG_FILE"
@@ -190,2 +195,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-              echo "Deleting service $SERVICE_ID..." | tee -a $LOG_FILE
-              aws servicediscovery delete-service --id $SERVICE_ID
+              echo "Deleting service $SERVICE_ID..." | tee -a "$LOG_FILE"
+              aws servicediscovery delete-service --id "$SERVICE_ID" 2>/dev/null || true
@@ -197 +202 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          OPERATION_ID=$(aws servicediscovery delete-namespace --id $NAMESPACE_ID --query 'OperationId' --output text 2>/dev/null || echo "")
+          OPERATION_ID=$(aws servicediscovery delete-namespace --id "$NAMESPACE_ID" --query 'OperationId' --output text 2>/dev/null || echo "")
@@ -199,2 +204,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            echo "Waiting for namespace deletion to complete..." | tee -a $LOG_FILE
-            wait_for_operation $OPERATION_ID
+            echo "Waiting for namespace deletion to complete..." | tee -a "$LOG_FILE"
+            wait_for_operation "$OPERATION_ID" || true
@@ -202 +207 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            echo "Failed to delete namespace or namespace already deleted" | tee -a $LOG_FILE
+            echo "Failed to delete namespace or namespace already deleted" | tee -a "$LOG_FILE"
@@ -207 +212 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Cleanup complete" | tee -a $LOG_FILE
+      echo "Cleanup complete" | tee -a "$LOG_FILE"
@@ -211 +216 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "Step 1: Creating AWS Cloud Map namespace..." | tee -a $LOG_FILE
+    echo "Step 1: Creating AWS Cloud Map namespace..." | tee -a "$LOG_FILE"
@@ -214 +219 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    NAMESPACE_ID=$(aws servicediscovery list-namespaces --query "Namespaces[?Name=='cloudmap-tutorial'].Id" --output text)
+    NAMESPACE_ID=$(aws servicediscovery list-namespaces --query "Namespaces[?Name=='cloudmap-tutorial'].Id" --output text 2>/dev/null || echo "")
@@ -217,2 +222,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      log_cmd "aws servicediscovery create-http-namespace --name cloudmap-tutorial --creator-request-id namespace-request"
-      OPERATION_ID=$(aws servicediscovery create-http-namespace --name cloudmap-tutorial --creator-request-id namespace-request --query 'OperationId' --output text)
+      log_cmd "aws servicediscovery create-http-namespace --name cloudmap-tutorial --creator-request-id namespace-request-\$(date +%s)"
+      OPERATION_ID=$(aws servicediscovery create-http-namespace --name cloudmap-tutorial --creator-request-id "namespace-request-$(date +%s)" --query 'OperationId' --output text)
@@ -221,2 +226,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Waiting for namespace creation to complete..." | tee -a $LOG_FILE
-      wait_for_operation $OPERATION_ID
+      echo "Waiting for namespace creation to complete..." | tee -a "$LOG_FILE"
+      wait_for_operation "$OPERATION_ID"
@@ -226 +231 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Namespace created with ID: $NAMESPACE_ID" | tee -a $LOG_FILE
+      echo "Namespace created with ID: $NAMESPACE_ID" | tee -a "$LOG_FILE"
@@ -228 +233 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Namespace cloudmap-tutorial already exists with ID: $NAMESPACE_ID" | tee -a $LOG_FILE
+      echo "Namespace cloudmap-tutorial already exists with ID: $NAMESPACE_ID" | tee -a "$LOG_FILE"
@@ -234 +239 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "Step 2: Creating DynamoDB table..." | tee -a $LOG_FILE
+    echo "Step 2: Creating DynamoDB table..." | tee -a "$LOG_FILE"
@@ -243 +248 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Waiting for DynamoDB table to become active..." | tee -a $LOG_FILE
+      echo "Waiting for DynamoDB table to become active..." | tee -a "$LOG_FILE"
@@ -246 +251 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "DynamoDB table cloudmap already exists" | tee -a $LOG_FILE
+      echo "DynamoDB table cloudmap already exists" | tee -a "$LOG_FILE"
@@ -252 +257 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "Step 3: Creating AWS Cloud Map data service..." | tee -a $LOG_FILE
+    echo "Step 3: Creating AWS Cloud Map data service..." | tee -a "$LOG_FILE"
@@ -255,3 +260,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    echo "Listing all services in namespace $NAMESPACE_ID..." | tee -a $LOG_FILE
-    SERVICES=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query 'Services[*].[Id,Name]' --output text)
-    echo "Services found: $SERVICES" | tee -a $LOG_FILE
+    echo "Listing all services in namespace $NAMESPACE_ID..." | tee -a "$LOG_FILE"
+    SERVICES=$(aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NAMESPACE_ID,Condition=EQ" --query 'Services[*].[Id,Name]' --output text 2>/dev/null || echo "")
+    echo "Services found: $SERVICES" | tee -a "$LOG_FILE"
@@ -262 +267 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Checking service: ID=$id, Name=$name" | tee -a $LOG_FILE
+      echo "Checking service: ID=$id, Name=$name" | tee -a "$LOG_FILE"
@@ -270 +275 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Data service does not exist, creating it..." | tee -a $LOG_FILE
+      echo "Data service does not exist, creating it..." | tee -a "$LOG_FILE"
@@ -272,3 +277,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "$ aws servicediscovery create-service --name data-service --namespace-id $NAMESPACE_ID --creator-request-id data-service-request" | tee -a $LOG_FILE
-      CREATE_OUTPUT=$(aws servicediscovery create-service --name data-service --namespace-id $NAMESPACE_ID --creator-request-id data-service-request)
-      echo "$CREATE_OUTPUT" | tee -a $LOG_FILE
+      echo "$ aws servicediscovery create-service --name data-service --namespace-id $NAMESPACE_ID --creator-request-id data-service-request-\$(date +%s)" | tee -a "$LOG_FILE"
+      CREATE_OUTPUT=$(aws servicediscovery create-service --name data-service --namespace-id "$NAMESPACE_ID" --creator-request-id "data-service-request-$(date +%s)")
+      echo "$CREATE_OUTPUT" | tee -a "$LOG_FILE"
@@ -278 +283 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      echo "Data service created with ID: $DATA_SERVICE_ID" | tee -a $LOG_FILE