AWS Security ChangesHomeSearch

AWS code-library documentation change

Service: code-library · 2026-04-19 · Documentation low

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

Summary

Updated introductory bullet points for an existing code example and added a comprehensive new code example for ECS Service Connect deployment using default VPC infrastructure

Security assessment

The changes include security-related configurations such as IAM role creation, security group configuration with ingress rules (ports 80/443 open to 0.0.0.0/0), and CloudWatch logging setup. However, there is no evidence of addressing a specific security vulnerability or incident. The security group configuration opening ports 80/443 to the entire internet (0.0.0.0/0) could have security implications if not properly understood by users, but this appears to be standard tutorial configuration rather than addressing a security issue.

Diff

diff --git a/code-library/latest/ug/bash_2_servicediscovery_code_examples.md b/code-library/latest/ug/bash_2_servicediscovery_code_examples.md
index ad0780dfb..b06e22c77 100644
--- a//code-library/latest/ug/bash_2_servicediscovery_code_examples.md
+++ b//code-library/latest/ug/bash_2_servicediscovery_code_examples.md
@@ -30 +30 @@ The following code example shows how to:
-  * Create an HTTP namespace for API-based service discovery
+  * Create an Cloud Map namespace
@@ -32 +32 @@ The following code example shows how to:
-  * Create a DynamoDB table and register it as a data service with custom attributes
+  * Create a DynamoDB table
@@ -34 +34 @@ The following code example shows how to:
-  * Create Lambda functions for reading and writing data
+  * Create an Cloud Map data service and register the DynamoDB table
@@ -36 +36 @@ The following code example shows how to:
-  * Register Lambda functions as service instances with custom attributes for action-based discovery
+  * Create an IAM role for Lambda functions
@@ -38 +38 @@ The following code example shows how to:
-  * Build client applications that discover services using custom attributes
+  * Create the Lambda function to write data
@@ -40 +40,3 @@ The following code example shows how to:
-  * Clean up all resources including Lambda functions, DynamoDB table, and Cloud Map services
+  * Create an Cloud Map app service and register the Lambda write function
+
+  * Create the Lambda function to read data
@@ -953,0 +956,681 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+The following code example shows how to:
+
+  * Create the VPC infrastructure
+
+  * Set up logging
+
+  * Create the ECS cluster
+
+  * Configure IAM roles
+
+  * Create the service with Service Connect
+
+  * Verify the deployment
+
+  * 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](https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/085-amazon-ecs-service-connect) repository. 
+    
+    
+    #!/bin/bash
+    
+    # ECS Service Connect Tutorial Script v4 - Modified to use Default VPC
+    # This script creates an ECS cluster with Service Connect and deploys an nginx service
+    # Uses the default VPC to avoid VPC limits
+    
+    set -e  # Exit on any error
+    
+    # Configuration
+    SCRIPT_NAME="ECS Service Connect Tutorial"
+    LOG_FILE="ecs-service-connect-tutorial-v4-default-vpc.log"
+    REGION=${AWS_DEFAULT_REGION:-${AWS_REGION:-$(aws configure get region 2>/dev/null)}}
+    if [ -z "$REGION" ]; then
+        echo "ERROR: No AWS region configured."
+        echo "Set one with: aws configure set region us-east-1"
+        exit 1
+    fi
+    ENV_PREFIX="tutorial"
+    CLUSTER_NAME="${ENV_PREFIX}-cluster"
+    NAMESPACE_NAME="service-connect"
+    
+    # Generate random suffix for unique resource names
+    RANDOM_SUFFIX=$(openssl rand -hex 6)
+    
+    # Arrays to track created resources for cleanup
+    declare -a CREATED_RESOURCES=()
+    
+    # Logging function
+    log() {
+        echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
+    }
+    
+    # Error handling function
+    handle_error() {
+        log "ERROR: Script failed at line $1"
+        log "Attempting to clean up resources..."
+        cleanup_resources
+        exit 1
+    }
+    
+    # Set up error handling
+    trap 'handle_error $LINENO' ERR
+    
+    # Function to add resource to tracking array
+    track_resource() {
+        CREATED_RESOURCES+=("$1")
+        log "Tracking resource: $1"
+    }
+    
+    # Function to check if command output contains actual errors
+    check_for_errors() {
+        local output="$1"
+        local command_name="$2"
+        
+        # Check for specific AWS CLI error patterns, not just any occurrence of "error"
+        if echo "$output" | grep -qi "An error occurred\|InvalidParameterException\|AccessDenied\|ValidationException\|ResourceNotFoundException"; then
+            log "ERROR in $command_name: $output"
+            return 1
+        fi
+        return 0
+    }
+    
+    # Function to get AWS account ID
+    get_account_id() {
+        ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
+        log "Using AWS Account ID: $ACCOUNT_ID"
+    }
+    
+    # Function to wait for resources to be ready
+    wait_for_resource() {
+        local resource_type="$1"
+        local resource_id="$2"
+        
+        case "$resource_type" in
+            "cluster")
+                log "Waiting for cluster $resource_id to be active..."
+                local attempt=1
+                local max_attempts=30
+                while [ $attempt -le $max_attempts ]; do
+                    local status=$(aws ecs describe-clusters --clusters "$resource_id" --query 'clusters[0].status' --output text)
+                    if [ "$status" = "ACTIVE" ]; then
+                        log "Cluster is now active"
+                        return 0
+                    fi
+                    log "Cluster status: $status (attempt $attempt/$max_attempts)"
+                    sleep 10
+                    ((attempt++))
+                done
+                log "ERROR: Cluster did not become active within expected time"
+                return 1
+                ;;
+            "service")
+                log "Waiting for service $resource_id to be stable..."
+                aws ecs wait services-stable --cluster "$CLUSTER_NAME" --services "$resource_id"
+                ;;
+            "nat-gateway")
+                log "Waiting for NAT Gateway $resource_id to be available..."
+                aws ec2 wait nat-gateway-available --nat-gateway-ids "$resource_id"
+                ;;
+        esac
+    }
+    
+    # Function to use default VPC infrastructure
+    setup_default_vpc_infrastructure() {
+        log "Using default VPC infrastructure..."
+        
+        # Get default VPC
+        VPC_ID=$(aws ec2 describe-vpcs --filters "Name=isDefault,Values=true" --query 'Vpcs[0].VpcId' --output text)
+        if [[ "$VPC_ID" == "None" || -z "$VPC_ID" ]]; then
+            log "ERROR: No default VPC found. Please create a default VPC first."
+            exit 1
+        fi
+        log "Using default VPC: $VPC_ID"
+        
+        # Get default subnets
+        SUBNETS=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID" "Name=default-for-az,Values=true" --query 'Subnets[].SubnetId' --output text)
+        SUBNET_ARRAY=($SUBNETS)
+        
+        if [ ${#SUBNET_ARRAY[@]} -lt 2 ]; then
+            log "ERROR: Need at least 2 subnets for ECS Service Connect. Found: ${#SUBNET_ARRAY[@]}"
+            exit 1
+        fi
+        
+        PUBLIC_SUBNET1=${SUBNET_ARRAY[0]}
+        PUBLIC_SUBNET2=${SUBNET_ARRAY[1]}
+        
+        log "Using subnets: $PUBLIC_SUBNET1, $PUBLIC_SUBNET2"
+        
+        # Create security group for ECS tasks
+        SG_OUTPUT=$(aws ec2 create-security-group \
+            --group-name "${ENV_PREFIX}-ecs-sg-${RANDOM_SUFFIX}" \
+            --description "Security group for ECS Service Connect tutorial" \
+            --vpc-id "$VPC_ID" 2>&1)
+        check_for_errors "$SG_OUTPUT" "create-security-group"
+        SECURITY_GROUP_ID=$(echo "$SG_OUTPUT" | grep -o '"GroupId": "[^"]*"' | cut -d'"' -f4)
+        track_resource "SG:$SECURITY_GROUP_ID"
+        log "Created security group: $SECURITY_GROUP_ID"
+        
+        # Add inbound rules to security group
+        aws ec2 authorize-security-group-ingress \
+            --group-id "$SECURITY_GROUP_ID" \
+            --protocol tcp \
+            --port 80 \
+            --cidr 0.0.0.0/0 >/dev/null 2>&1 || true
+        
+        aws ec2 authorize-security-group-ingress \
+            --group-id "$SECURITY_GROUP_ID" \
+            --protocol tcp \