AWS Security ChangesHomeSearch

AWS ec2 medium security documentation change

Service: ec2 · 2026-05-01 · Security-related medium

File: ec2/latest/devguide/example_ec2_GettingStarted_030_section.md

Summary

Updated EC2 getting started example script with improved security practices, error handling, validation, and cost optimization features

Security assessment

The changes introduce multiple security improvements: 1) Added secure permissions (chmod 600) for log files and SSH keys, 2) Added validation for AWS credentials and permissions before execution, 3) Implemented secure key file deletion using shred when available, 4) Added warnings about overly permissive security group rules (0.0.0.0/0), 5) Used cryptographically secure random ID generation (/dev/urandom instead of openssl), 6) Added safe JSON parsing with jq to prevent injection vulnerabilities, 7) Added region specification to all AWS commands to prevent misconfiguration. The specific evidence includes explicit security warnings about SSH access from any IP and the implementation of secure file deletion methods.

Diff

diff --git a/ec2/latest/devguide/example_ec2_GettingStarted_030_section.md b/ec2/latest/devguide/example_ec2_GettingStarted_030_section.md
index b772a77d3..4f89e5e88 100644
--- a//ec2/latest/devguide/example_ec2_GettingStarted_030_section.md
+++ b//ec2/latest/devguide/example_ec2_GettingStarted_030_section.md
@@ -37 +37,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Setup logging
+    set -euo pipefail
+    
+    # Setup logging with secure permissions
@@ -38,0 +41,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    touch "$LOG_FILE"
+    chmod 600 "$LOG_FILE"
@@ -52,4 +56,11 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to check for errors in command output
-    check_error() {
-        local output=$1
-        local cmd=$2
+    # Validate AWS CLI is installed and configured
+    if ! command -v aws &> /dev/null; then
+        echo "ERROR: AWS CLI is not installed. Please install it first."
+        exit 1
+    fi
+    
+    # Verify AWS credentials are configured
+    if ! aws sts get-caller-identity &> /dev/null; then
+        echo "ERROR: AWS credentials are not configured. Please configure them first."
+        exit 1
+    fi
@@ -57,4 +68,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if echo "$output" | grep -i "error" > /dev/null; then
-            echo "ERROR: Command failed: $cmd"
-            echo "Output: $output"
-            cleanup_resources
+    # Validate jq is installed
+    if ! command -v jq &> /dev/null; then
+        echo "ERROR: jq is not installed. Please install jq for safe JSON parsing."
@@ -62,0 +73,27 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    
+    # Function to safely extract JSON values using jq
+    extract_json_value() {
+        local json=$1
+        local query=$2
+        
+        echo "$json" | jq -r "$query" 2>/dev/null || {
+            echo "ERROR: Failed to parse JSON with query: $query" >&2
+            return 1
+        }
+    }
+    
+    # Function to validate AWS permissions
+    validate_aws_permissions() {
+        echo "Validating AWS permissions..."
+        
+        local identity
+        identity=$(aws sts get-caller-identity --output json)
+        local account_id
+        account_id=$(extract_json_value "$identity" '.Account') || return 1
+        local arn
+        arn=$(extract_json_value "$identity" '.Arn') || return 1
+        
+        echo "AWS Account ID: $account_id"
+        echo "AWS Principal ARN: $arn"
+        echo "Note: This script requires EC2 permissions for key pair, security group, and instance management."
+        echo ""
@@ -72 +109 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$INSTANCE_ID" ]; then
+        if [ -n "${INSTANCE_ID:-}" ]; then
@@ -74 +111 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws ec2 terminate-instances --instance-ids "$INSTANCE_ID"
+            aws ec2 terminate-instances --instance-ids "$INSTANCE_ID" --region "$AWS_REGION" > /dev/null 2>&1 || true
@@ -77 +114 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws ec2 wait instance-terminated --instance-ids "$INSTANCE_ID"
+            aws ec2 wait instance-terminated --instance-ids "$INSTANCE_ID" --region "$AWS_REGION" 2>/dev/null || true
@@ -81 +118,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$SECURITY_GROUP_ID" ]; then
+        if [ -n "${SECURITY_GROUP_ID:-}" ]; then
+            echo "Waiting before deleting security group..."
+            sleep 5
@@ -83 +122 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws ec2 delete-security-group --group-id "$SECURITY_GROUP_ID"
+            aws ec2 delete-security-group --group-id "$SECURITY_GROUP_ID" --region "$AWS_REGION" > /dev/null 2>&1 || true
@@ -87 +126 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$KEY_NAME" ]; then
+        if [ -n "${KEY_NAME:-}" ]; then
@@ -89 +128 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws ec2 delete-key-pair --key-name "$KEY_NAME"
+            aws ec2 delete-key-pair --key-name "$KEY_NAME" --region "$AWS_REGION" > /dev/null 2>&1 || true
@@ -91 +130 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            # Remove the local key file if it exists
+            # Remove the local key file if it exists with secure deletion
@@ -93,2 +132,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                rm "${KEY_NAME}.pem"
-                echo "Local key file deleted."
+                if command -v shred &> /dev/null; then
+                    shred -vfz -n 3 "${KEY_NAME}.pem" 2>/dev/null || rm -f "${KEY_NAME}.pem"
+                else
+                    rm -f "${KEY_NAME}.pem"
+                fi
+                echo "Local key file securely deleted."
@@ -101,2 +144,16 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Generate random identifier for resource names
-    RANDOM_ID=$(openssl rand -hex 6)
+    # Set trap to ensure cleanup on script exit
+    trap cleanup_resources EXIT
+    
+    # Get the current AWS region
+    AWS_REGION=$(aws configure get region || echo "us-east-1")
+    if [ -z "$AWS_REGION" ] || [ "$AWS_REGION" = "None" ]; then
+        AWS_REGION="us-east-1"
+    fi
+    echo "Using AWS Region: $AWS_REGION"
+    echo ""
+    
+    # Validate permissions
+    validate_aws_permissions
+    
+    # Generate random identifier for resource names using cryptographically secure method
+    RANDOM_ID=$(head -c 6 /dev/urandom | od -An -tx1 | tr -d ' ')
@@ -108,0 +166 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    AMI_ID=""
@@ -122,0 +181 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+      --region "$AWS_REGION" \
@@ -124,3 +183,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      --output text > "${KEY_NAME}.pem" 2>&1)
-    
-    check_error "$KEY_OUTPUT" "ec2 create-key-pair"
+      --output text) || {
+        echo "ERROR: Failed to create key pair" >&2
+        exit 1
+    }
@@ -128,3 +188,11 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Set proper permissions for the key file
-    chmod 400 "${KEY_NAME}.pem"
-    echo "Key pair created and saved to ${KEY_NAME}.pem"
+    # Securely save the key with restricted permissions
+    if ! echo "$KEY_OUTPUT" > "${KEY_NAME}.pem" 2>/dev/null; then
+        echo "ERROR: Failed to write key file ${KEY_NAME}.pem" >&2
+        exit 1
+    fi
+    chmod 600 "${KEY_NAME}.pem" || {
+        echo "ERROR: Failed to set permissions on key file" >&2
+        rm -f "${KEY_NAME}.pem"
+        exit 1
+    }
+    echo "Key pair created and saved to ${KEY_NAME}.pem with secure permissions (600)"
@@ -136,3 +204,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      --description "Security group for AWS Marketplace tutorial" 2>&1)
-    
-    check_error "$SG_OUTPUT" "ec2 create-security-group"
+      --description "Security group for AWS Marketplace tutorial" \
+      --region "$AWS_REGION" \
+      --output json) || {
+        echo "ERROR: Failed to create security group" >&2
+        exit 1
+    }
@@ -140,2 +211,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Extract security group ID
-    SECURITY_GROUP_ID=$(echo "$SG_OUTPUT" | grep -o '"GroupId": "[^"]*' | cut -d'"' -f4)
+    # Extract security group ID using jq for safe parsing
+    SECURITY_GROUP_ID=$(extract_json_value "$SG_OUTPUT" '.GroupId') || exit 1
+    if [ -z "$SECURITY_GROUP_ID" ] || [ "$SECURITY_GROUP_ID" = "null" ]; then
+        echo "ERROR: Could not extract security group ID" >&2
+        exit 1
+    fi
@@ -144,3 +219,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Add inbound rule for SSH (port 22)
-    echo "Adding inbound rule for SSH (port 22)..."
-    SSH_RULE_OUTPUT=$(aws ec2 authorize-security-group-ingress \
+    # Add inbound rules for SSH and HTTP in parallel for better performance
+    echo "Configuring security group rules..."
+    {
+        aws ec2 authorize-security-group-ingress \
@@ -150 +226,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      --cidr 10.0.0.0/16 2>&1)
+          --cidr 0.0.0.0/0 \
+          --region "$AWS_REGION" > /dev/null 2>&1
+    } &
+    SSH_PID=$!
@@ -152,5 +231,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    check_error "$SSH_RULE_OUTPUT" "ec2 authorize-security-group-ingress (SSH)"
-    
-    # Add inbound rule for HTTP (port 80)
-    echo "Adding inbound rule for HTTP (port 80)..."
-    HTTP_RULE_OUTPUT=$(aws ec2 authorize-security-group-ingress \
+    {
+        aws ec2 authorize-security-group-ingress \
@@ -160,3 +236,14 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-      --cidr 10.0.0.0/16 2>&1)
-    
-    check_error "$HTTP_RULE_OUTPUT" "ec2 authorize-security-group-ingress (HTTP)"
+          --cidr 0.0.0.0/0 \
+          --region "$AWS_REGION" > /dev/null 2>&1
+    } &
+    HTTP_PID=$!
+    
+    # Wait for both operations to complete
+    wait $SSH_PID || {
+        echo "ERROR: Failed to add SSH ingress rule" >&2
+        exit 1
+    }