AWS Security ChangesHomeSearch

AWS code-library high security documentation change

Service: code-library · 2025-08-13 · Security-related high

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

Summary

Added multiple scenarios demonstrating VPC setup with security configurations including IMDSv2 enforcement, security groups, IAM roles, and NAT gateways. The first scenario explicitly implements IMDSv2 compliance in EC2 launch templates.

Security assessment

The change introduces IMDSv2 compliance by setting 'MetadataOptions.HttpTokens' to 'required' in the launch template, which addresses SSRF vulnerabilities by enforcing token-based metadata access. This is a direct security improvement against a known vulnerability (CWE-918). The documentation also adds security group configurations and IAM role guidance, enhancing security posture.

Diff

diff --git a/code-library/latest/ug/bash_2_ec2_code_examples.md b/code-library/latest/ug/bash_2_ec2_code_examples.md
index c67734b3a..5b6086417 100644
--- a//code-library/latest/ug/bash_2_ec2_code_examples.md
+++ b//code-library/latest/ug/bash_2_ec2_code_examples.md
@@ -5 +5 @@
-BasicsActions
+BasicsActionsScenarios
@@ -16,0 +17,2 @@ _Actions_ are code excerpts from larger programs and must be run in context. Whi
+_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.
+
@@ -24,0 +27,2 @@ Each example includes a link to the complete source code, where you can find ins
+  * Scenarios
+
@@ -4584,0 +4589,2086 @@ The utility functions used in this example.
+## Scenarios
+
+The following code example shows how to:
+
+  * Create a VPC with private subnets and NAT gateways using the CLI.
+
+  * Set up the necessary components including VPC, subnets, route tables, and NAT gateways.
+
+  * Configure security groups and IAM roles for proper access and security.
+
+  * Use CLI commands to automate the creation and configuration of these 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/008-vpc-private-servers-gs) repository. 
+    
+    
+    #!/bin/bash
+    
+    # VPC with Private Subnets and NAT Gateways (IMDSv2 Compliant Version)
+    # This script creates a VPC with public and private subnets in two Availability Zones,
+    # NAT gateways, an internet gateway, route tables, a VPC endpoint for S3,
+    # security groups, a launch template, an Auto Scaling group, and an Application Load Balancer.
+    
+    # Set up logging
+    LOG_FILE="vpc-private-subnets-nat.log"
+    exec > >(tee -a "$LOG_FILE") 2>&1
+    
+    # Cleanup function to delete all created resources
+    cleanup_resources() {
+      echo "Cleaning up resources..."
+      
+      # Delete Auto Scaling group if it exists
+      if [ -n "${ASG_NAME:-}" ]; then
+        echo "Deleting Auto Scaling group: $ASG_NAME"
+        aws autoscaling delete-auto-scaling-group --auto-scaling-group-name "$ASG_NAME" --force-delete
+        echo "Waiting for Auto Scaling group to be deleted..."
+        aws autoscaling wait auto-scaling-groups-deleted --auto-scaling-group-names "$ASG_NAME"
+      fi
+      
+      # Delete load balancer if it exists
+      if [ -n "${LB_ARN:-}" ]; then
+        echo "Deleting load balancer: $LB_ARN"
+        aws elbv2 delete-load-balancer --load-balancer-arn "$LB_ARN"
+        # Wait for load balancer to be deleted
+        sleep 30
+      fi
+      
+      # Delete target group if it exists
+      if [ -n "${TARGET_GROUP_ARN:-}" ]; then
+        echo "Deleting target group: $TARGET_GROUP_ARN"
+        aws elbv2 delete-target-group --target-group-arn "$TARGET_GROUP_ARN"
+      fi
+      
+      # Delete launch template if it exists
+      if [ -n "${LAUNCH_TEMPLATE_NAME:-}" ]; then
+        echo "Deleting launch template: $LAUNCH_TEMPLATE_NAME"
+        aws ec2 delete-launch-template --launch-template-name "$LAUNCH_TEMPLATE_NAME"
+      fi
+      
+      # Delete NAT Gateways if they exist
+      if [ -n "${NAT_GW1_ID:-}" ]; then
+        echo "Deleting NAT Gateway 1: $NAT_GW1_ID"
+        aws ec2 delete-nat-gateway --nat-gateway-id "$NAT_GW1_ID"
+      fi
+      
+      if [ -n "${NAT_GW2_ID:-}" ]; then
+        echo "Deleting NAT Gateway 2: $NAT_GW2_ID"
+        aws ec2 delete-nat-gateway --nat-gateway-id "$NAT_GW2_ID"
+      fi
+      
+      # Wait for NAT Gateways to be deleted
+      if [ -n "${NAT_GW1_ID:-}" ] || [ -n "${NAT_GW2_ID:-}" ]; then
+        echo "Waiting for NAT Gateways to be deleted..."
+        sleep 60
+      fi
+      
+      # Release Elastic IPs if they exist
+      if [ -n "${EIP1_ALLOC_ID:-}" ]; then
+        echo "Releasing Elastic IP 1: $EIP1_ALLOC_ID"
+        aws ec2 release-address --allocation-id "$EIP1_ALLOC_ID"
+      fi
+      
+      if [ -n "${EIP2_ALLOC_ID:-}" ]; then
+        echo "Releasing Elastic IP 2: $EIP2_ALLOC_ID"
+        aws ec2 release-address --allocation-id "$EIP2_ALLOC_ID"
+      fi
+      
+      # Delete VPC endpoint if it exists
+      if [ -n "${VPC_ENDPOINT_ID:-}" ]; then
+        echo "Deleting VPC endpoint: $VPC_ENDPOINT_ID"
+        aws ec2 delete-vpc-endpoints --vpc-endpoint-ids "$VPC_ENDPOINT_ID"
+      fi
+      
+      # Delete security groups if they exist
+      if [ -n "${APP_SG_ID:-}" ]; then
+        echo "Deleting application security group: $APP_SG_ID"
+        aws ec2 delete-security-group --group-id "$APP_SG_ID"
+      fi
+      
+      if [ -n "${LB_SG_ID:-}" ]; then
+        echo "Deleting load balancer security group: $LB_SG_ID"
+        aws ec2 delete-security-group --group-id "$LB_SG_ID"
+      fi
+      
+      # Detach and delete Internet Gateway if it exists
+      if [ -n "${IGW_ID:-}" ] && [ -n "${VPC_ID:-}" ]; then
+        echo "Detaching Internet Gateway: $IGW_ID from VPC: $VPC_ID"
+        aws ec2 detach-internet-gateway --internet-gateway-id "$IGW_ID" --vpc-id "$VPC_ID"
+        echo "Deleting Internet Gateway: $IGW_ID"
+        aws ec2 delete-internet-gateway --internet-gateway-id "$IGW_ID"
+      fi
+      
+      # Delete route table associations and route tables if they exist
+      if [ -n "${PUBLIC_RT_ASSOC1_ID:-}" ]; then
+        echo "Disassociating public route table from subnet 1: $PUBLIC_RT_ASSOC1_ID"
+        aws ec2 disassociate-route-table --association-id "$PUBLIC_RT_ASSOC1_ID"
+      fi
+      
+      if [ -n "${PUBLIC_RT_ASSOC2_ID:-}" ]; then
+        echo "Disassociating public route table from subnet 2: $PUBLIC_RT_ASSOC2_ID"
+        aws ec2 disassociate-route-table --association-id "$PUBLIC_RT_ASSOC2_ID"
+      fi
+      
+      if [ -n "${PRIVATE_RT1_ASSOC_ID:-}" ]; then
+        echo "Disassociating private route table 1: $PRIVATE_RT1_ASSOC_ID"
+        aws ec2 disassociate-route-table --association-id "$PRIVATE_RT1_ASSOC_ID"
+      fi
+      
+      if [ -n "${PRIVATE_RT2_ASSOC_ID:-}" ]; then
+        echo "Disassociating private route table 2: $PRIVATE_RT2_ASSOC_ID"
+        aws ec2 disassociate-route-table --association-id "$PRIVATE_RT2_ASSOC_ID"
+      fi
+      
+      if [ -n "${PUBLIC_RT_ID:-}" ]; then
+        echo "Deleting public route table: $PUBLIC_RT_ID"
+        aws ec2 delete-route-table --route-table-id "$PUBLIC_RT_ID"
+      fi
+      
+      if [ -n "${PRIVATE_RT1_ID:-}" ]; then
+        echo "Deleting private route table 1: $PRIVATE_RT1_ID"
+        aws ec2 delete-route-table --route-table-id "$PRIVATE_RT1_ID"
+      fi
+      
+      if [ -n "${PRIVATE_RT2_ID:-}" ]; then
+        echo "Deleting private route table 2: $PRIVATE_RT2_ID"
+        aws ec2 delete-route-table --route-table-id "$PRIVATE_RT2_ID"
+      fi
+      
+      # Delete subnets if they exist
+      if [ -n "${PUBLIC_SUBNET1_ID:-}" ]; then
+        echo "Deleting public subnet 1: $PUBLIC_SUBNET1_ID"
+        aws ec2 delete-subnet --subnet-id "$PUBLIC_SUBNET1_ID"
+      fi
+      
+      if [ -n "${PUBLIC_SUBNET2_ID:-}" ]; then
+        echo "Deleting public subnet 2: $PUBLIC_SUBNET2_ID"
+        aws ec2 delete-subnet --subnet-id "$PUBLIC_SUBNET2_ID"
+      fi
+      
+      if [ -n "${PRIVATE_SUBNET1_ID:-}" ]; then
+        echo "Deleting private subnet 1: $PRIVATE_SUBNET1_ID"
+        aws ec2 delete-subnet --subnet-id "$PRIVATE_SUBNET1_ID"
+      fi
+      
+      if [ -n "${PRIVATE_SUBNET2_ID:-}" ]; then
+        echo "Deleting private subnet 2: $PRIVATE_SUBNET2_ID"
+        aws ec2 delete-subnet --subnet-id "$PRIVATE_SUBNET2_ID"
+      fi
+      
+      # Delete VPC if it exists
+      if [ -n "${VPC_ID:-}" ]; then
+        echo "Deleting VPC: $VPC_ID"
+        aws ec2 delete-vpc --vpc-id "$VPC_ID"
+      fi
+      
+      echo "Cleanup completed."
+    }
+    
+    # Error handling function