33# Amazon Lightsail Getting Started CLI Script
44# This script demonstrates how to create and manage Lightsail resources using the AWS CLI
55
6+ set -euo pipefail
67
78# Set AWS region
8- export AWS_REGION=" us-west-2"
9+ export AWS_REGION=" ${AWS_REGION :- us-west-2} "
910echo " Using AWS region: $AWS_REGION "
1011
1112# Set up logging
@@ -16,9 +17,9 @@ echo "Starting Lightsail Getting Started script at $(date)"
1617
1718# Error handling function
1819handle_error () {
19- echo " ERROR: $1 "
20+ echo " ERROR: $1 " >&2
2021 echo " Attempting to clean up resources..."
21- cleanup_resources
22+ cleanup_resources || true
2223 exit 1
2324}
2425
@@ -58,35 +59,34 @@ cleanup_resources() {
5859 case " $type " in
5960 " instance_snapshot" )
6061 echo " Deleting instance snapshot: $name "
61- aws lightsail delete-instance-snapshot --instance-snapshot-name " $name " --region $AWS_REGION
62+ aws lightsail delete-instance-snapshot --instance-snapshot-name " $name " --region " $AWS_REGION " 2> /dev/null || true
6263 ;;
6364 " disk_snapshot" )
6465 echo " Deleting disk snapshot: $name "
65- aws lightsail delete-disk-snapshot --disk-snapshot-name " $name " --region $AWS_REGION
66+ aws lightsail delete-disk-snapshot --disk-snapshot-name " $name " --region " $AWS_REGION " 2> /dev/null || true
6667 ;;
6768 " disk" )
6869 echo " Detaching disk: $name "
69- aws lightsail detach-disk --disk-name " $name " --region $AWS_REGION
70- sleep 10 # Wait for detach to complete
70+ aws lightsail detach-disk --disk-name " $name " --region " $AWS_REGION " 2> /dev/null || true
71+ sleep 10
7172 echo " Deleting disk: $name "
72- aws lightsail delete-disk --disk-name " $name " --region $AWS_REGION
73+ aws lightsail delete-disk --disk-name " $name " --region " $AWS_REGION " 2> /dev/null || true
7374 ;;
7475 " instance" )
7576 echo " Deleting instance: $name "
76- # Check instance state before attempting to delete
77- INSTANCE_STATE=$( aws lightsail get-instance-state --instance-name " $name " --region $AWS_REGION --query ' state.name' --output text 2> /dev/null)
77+ INSTANCE_STATE=$( aws lightsail get-instance-state --instance-name " $name " --region " $AWS_REGION " --query ' state.name' --output text 2> /dev/null || echo " unknown" )
7878 if [ " $INSTANCE_STATE " == " pending" ]; then
7979 echo " Instance is in pending state. Waiting for it to be ready before deleting..."
8080 MAX_WAIT=30
8181 WAITED=0
8282 while [ " $INSTANCE_STATE " == " pending" ] && [ $WAITED -lt $MAX_WAIT ]; do
8383 sleep 10
8484 WAITED=$(( WAITED+ 1 ))
85- INSTANCE_STATE=$( aws lightsail get-instance-state --instance-name " $name " --region $AWS_REGION --query ' state.name' --output text 2> /dev/null)
85+ INSTANCE_STATE=$( aws lightsail get-instance-state --instance-name " $name " --region " $AWS_REGION " --query ' state.name' --output text 2> /dev/null || echo " unknown " )
8686 echo " Instance state: $INSTANCE_STATE "
8787 done
8888 fi
89- aws lightsail delete-instance --instance-name " $name " --region $AWS_REGION
89+ aws lightsail delete-instance --instance-name " $name " --region " $AWS_REGION " 2> /dev/null || true
9090 ;;
9191 esac
9292 done
@@ -102,11 +102,11 @@ check_status "Failed to verify AWS CLI configuration"
102102# Step 2: Get available blueprints and bundles
103103echo " Step 2: Getting available blueprints and bundles"
104104echo " Available blueprints (showing first 5):"
105- aws lightsail get-blueprints --region $AWS_REGION --query ' blueprints[0:5].[blueprintId,name]' --output table
105+ aws lightsail get-blueprints --region " $AWS_REGION " --query ' blueprints[0:5].[blueprintId,name]' --output table
106106check_status " Failed to get blueprints"
107107
108108echo " Available bundles (showing first 5):"
109- aws lightsail get-bundles --region $AWS_REGION --query ' bundles[0:5].[bundleId,name,price]' --output table
109+ aws lightsail get-bundles --region " $AWS_REGION " --query ' bundles[0:5].[bundleId,name,price]' --output table
110110check_status " Failed to get bundles"
111111
112112# Get available regions and availability zones
@@ -122,17 +122,16 @@ aws lightsail create-instances \
122122 --availability-zone " $AVAILABILITY_ZONE " \
123123 --blueprint-id amazon_linux_2023 \
124124 --bundle-id nano_3_0 \
125- --region $AWS_REGION
125+ --region " $AWS_REGION "
126126check_status " Failed to create Lightsail instance"
127127track_resource " instance" " $INSTANCE_NAME "
128128
129129# Wait for the instance to be in a running state
130130echo " Waiting for instance to be in running state..."
131- # Wait for the instance to be ready (polling approach)
132131MAX_ATTEMPTS=30
133132ATTEMPTS=0
134133while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do
135- STATUS=$( aws lightsail get-instance-state --instance-name " $INSTANCE_NAME " --region $AWS_REGION --query ' state.name' --output text)
134+ STATUS=$( aws lightsail get-instance-state --instance-name " $INSTANCE_NAME " --region " $AWS_REGION " --query ' state.name' --output text 2> /dev/null || echo " unknown " )
136135 if [ " $STATUS " == " running" ]; then
137136 echo " Instance is now running"
138137 break
148147
149148# Get instance details
150149echo " Getting instance details"
151- INSTANCE_IP=$( aws lightsail get-instance --instance-name " $INSTANCE_NAME " --region $AWS_REGION --query ' instance.publicIpAddress' --output text)
150+ INSTANCE_IP=$( aws lightsail get-instance --instance-name " $INSTANCE_NAME " --region " $AWS_REGION " --query ' instance.publicIpAddress' --output text)
152151check_status " Failed to get instance IP address"
153152echo " Instance IP address: $INSTANCE_IP "
154153
154+ # Validate IP address format
155+ if ! [[ " $INSTANCE_IP " =~ ^[0-9]{1,3}\. [0-9]{1,3}\. [0-9]{1,3}\. [0-9]{1,3}$ ]]; then
156+ handle_error " Invalid IP address format: $INSTANCE_IP "
157+ fi
158+
155159# Step 4: Download the default key pair
156160echo " Step 4: Downloading default key pair"
157161KEY_FILE=" lightsail_key_${RANDOM_ID} .pem"
158- aws lightsail download-default-key-pair --region $AWS_REGION --output text > " $KEY_FILE "
162+ umask 077
163+ aws lightsail download-default-key-pair --region " $AWS_REGION " --output text > " $KEY_FILE "
159164check_status " Failed to download key pair"
165+
166+ if [ ! -f " $KEY_FILE " ] || [ ! -s " $KEY_FILE " ]; then
167+ handle_error " Key pair file was not created or is empty"
168+ fi
169+
160170chmod 400 " $KEY_FILE "
161171check_status " Failed to set permissions on key pair"
162172echo " Key pair downloaded to $KEY_FILE "
@@ -170,16 +180,16 @@ aws lightsail create-disk \
170180 --disk-name " $DISK_NAME " \
171181 --availability-zone " $AVAILABILITY_ZONE " \
172182 --size-in-gb 8 \
173- --region $AWS_REGION
183+ --region " $AWS_REGION "
174184check_status " Failed to create disk"
175185track_resource " disk" " $DISK_NAME "
176186
177- # FIX: Wait for the disk to be available using polling instead of fixed sleep
187+ # Wait for the disk to be available using polling
178188echo " Waiting for disk to be available..."
179189MAX_ATTEMPTS=30
180190ATTEMPTS=0
181191while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do
182- DISK_STATE=$( aws lightsail get-disk --disk-name " $DISK_NAME " --region $AWS_REGION --query ' disk.state' --output text 2> /dev/null)
192+ DISK_STATE=$( aws lightsail get-disk --disk-name " $DISK_NAME " --region " $AWS_REGION " --query ' disk.state' --output text 2> /dev/null || echo " unknown " )
183193 if [ " $DISK_STATE " == " available" ]; then
184194 echo " Disk is now available"
185195 break
@@ -199,7 +209,7 @@ aws lightsail attach-disk \
199209 --disk-name " $DISK_NAME " \
200210 --instance-name " $INSTANCE_NAME " \
201211 --disk-path /dev/xvdf \
202- --region $AWS_REGION
212+ --region " $AWS_REGION "
203213check_status " Failed to attach disk to instance"
204214
205215echo " Disk attached. To format and mount the disk, connect to your instance and run:"
@@ -213,16 +223,16 @@ echo "Step 6: Creating snapshot of the instance: $SNAPSHOT_NAME"
213223aws lightsail create-instance-snapshot \
214224 --instance-name " $INSTANCE_NAME " \
215225 --instance-snapshot-name " $SNAPSHOT_NAME " \
216- --region $AWS_REGION
226+ --region " $AWS_REGION "
217227check_status " Failed to create instance snapshot"
218228track_resource " instance_snapshot" " $SNAPSHOT_NAME "
219229
220- # FIX: Wait for the snapshot to complete using polling instead of fixed sleep
230+ # Wait for the snapshot to complete using polling
221231echo " Waiting for snapshot to complete... (this may take several minutes)"
222- MAX_ATTEMPTS=60 # Increased timeout for snapshot creation
232+ MAX_ATTEMPTS=60
223233ATTEMPTS=0
224234while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do
225- SNAPSHOT_STATE=$( aws lightsail get-instance-snapshot --instance-snapshot-name " $SNAPSHOT_NAME " --region $AWS_REGION --query ' instanceSnapshot.state' --output text 2> /dev/null)
235+ SNAPSHOT_STATE=$( aws lightsail get-instance-snapshot --instance-snapshot-name " $SNAPSHOT_NAME " --region " $AWS_REGION " --query ' instanceSnapshot.state' --output text 2> /dev/null || echo " unknown " )
226236 if [ " $SNAPSHOT_STATE " == " completed" ]; then
227237 echo " Snapshot creation completed"
228238 break
@@ -244,16 +254,7 @@ for resource in "${CREATED_RESOURCES[@]}"; do
244254 echo " $resource "
245255done
246256
247- read -p " Do you want to clean up these resources? (y/n): " CLEANUP_CONFIRM
248- if [[ " $CLEANUP_CONFIRM " == " y" || " $CLEANUP_CONFIRM " == " Y" ]]; then
249- cleanup_resources
250- else
251- echo " Resources will not be cleaned up. You can manually delete them later."
252- echo " To clean up manually, use the following commands:"
253- echo " aws lightsail delete-instance-snapshot --instance-snapshot-name $SNAPSHOT_NAME --region $AWS_REGION "
254- echo " aws lightsail detach-disk --disk-name $DISK_NAME --region $AWS_REGION "
255- echo " aws lightsail delete-disk --disk-name $DISK_NAME --region $AWS_REGION "
256- echo " aws lightsail delete-instance --instance-name $INSTANCE_NAME --region $AWS_REGION "
257- fi
257+ echo " Cleaning up these resources automatically..."
258+ cleanup_resources
258259
259- echo " Script completed at $( date) "
260+ echo " Script completed at $( date) "
0 commit comments