Lightsail examples using Amazon CLI with Bash script - Amazon Command Line Interface
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Lightsail examples using Amazon CLI with Bash script

The following code examples show you how to perform actions and implement common scenarios by using the Amazon Command Line Interface with Bash script with Lightsail.

Scenarios are code examples that show you how to accomplish specific tasks by calling multiple functions within a service or combined with other Amazon Web Services services.

Each example includes a link to the complete source code, where you can find instructions on how to set up and run the code in context.

Topics

Scenarios

The following code example shows how to:

  • Explore available blueprints and bundles for instance creation

  • Create a Lightsail instance with Amazon Linux 2023

  • Monitor instance status until running

  • Download default key pair for SSH access

  • Create and attach additional block storage disk

  • Create an instance snapshot for backup

  • Clean up resources to avoid ongoing charges

Amazon 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 repository.

#!/bin/bash # Amazon Lightsail Getting Started CLI Script # This script demonstrates how to create and manage Lightsail resources using the AWS CLI # FIXES APPLIED: # 1. Added polling mechanism to check disk state before attaching # 2. Added polling mechanism to check snapshot state before proceeding with cleanup # 3. Set AWS_REGION variable to us-west-2 for consistent region usage # Set AWS region export AWS_REGION="us-west-2" echo "Using AWS region: $AWS_REGION" # Set up logging LOG_FILE="lightsail-script.log" exec > >(tee -a "$LOG_FILE") 2>&1 echo "Starting Lightsail Getting Started script at $(date)" # Error handling function handle_error() { echo "ERROR: $1" echo "Attempting to clean up resources..." cleanup_resources exit 1 } # Function to check if a command succeeded check_status() { if [ $? -ne 0 ]; then handle_error "$1" fi } # Generate a random identifier for resource names RANDOM_ID=$(openssl rand -hex 4) INSTANCE_NAME="LightsailInstance-${RANDOM_ID}" DISK_NAME="LightsailDisk-${RANDOM_ID}" SNAPSHOT_NAME="LightsailSnapshot-${RANDOM_ID}" # Array to track created resources declare -a CREATED_RESOURCES # Function to add a resource to the tracking array track_resource() { CREATED_RESOURCES+=("$1:$2") echo "Created $1: $2" } # Function to clean up resources cleanup_resources() { echo "Resources created by this script:" for resource in "${CREATED_RESOURCES[@]}"; do echo " $resource" done # Reverse the array to delete resources in reverse order for (( idx=${#CREATED_RESOURCES[@]}-1 ; idx>=0 ; idx-- )); do IFS=':' read -r type name <<< "${CREATED_RESOURCES[idx]}" case "$type" in "instance_snapshot") echo "Deleting instance snapshot: $name" aws lightsail delete-instance-snapshot --instance-snapshot-name "$name" --region $AWS_REGION ;; "disk_snapshot") echo "Deleting disk snapshot: $name" aws lightsail delete-disk-snapshot --disk-snapshot-name "$name" --region $AWS_REGION ;; "disk") echo "Detaching disk: $name" aws lightsail detach-disk --disk-name "$name" --region $AWS_REGION sleep 10 # Wait for detach to complete echo "Deleting disk: $name" aws lightsail delete-disk --disk-name "$name" --region $AWS_REGION ;; "instance") echo "Deleting instance: $name" # Check instance state before attempting to delete INSTANCE_STATE=$(aws lightsail get-instance-state --instance-name "$name" --region $AWS_REGION --query 'state.name' --output text 2>/dev/null) if [ "$INSTANCE_STATE" == "pending" ]; then echo "Instance is in pending state. Waiting for it to be ready before deleting..." MAX_WAIT=30 WAITED=0 while [ "$INSTANCE_STATE" == "pending" ] && [ $WAITED -lt $MAX_WAIT ]; do sleep 10 WAITED=$((WAITED+1)) INSTANCE_STATE=$(aws lightsail get-instance-state --instance-name "$name" --region $AWS_REGION --query 'state.name' --output text 2>/dev/null) echo "Instance state: $INSTANCE_STATE" done fi aws lightsail delete-instance --instance-name "$name" --region $AWS_REGION ;; esac done echo "Cleanup completed" } # Step 1: Verify AWS CLI configuration echo "Step 1: Verifying AWS CLI configuration" aws configure list check_status "Failed to verify AWS CLI configuration" # Step 2: Get available blueprints and bundles echo "Step 2: Getting available blueprints and bundles" echo "Available blueprints (showing first 5):" aws lightsail get-blueprints --region $AWS_REGION --query 'blueprints[0:5].[blueprintId,name]' --output table check_status "Failed to get blueprints" echo "Available bundles (showing first 5):" aws lightsail get-bundles --region $AWS_REGION --query 'bundles[0:5].[bundleId,name,price]' --output table check_status "Failed to get bundles" # Get available regions and availability zones echo "Getting available regions and availability zones" # Use a specific availability zone in us-west-2 region AVAILABILITY_ZONE="us-west-2a" echo "Using availability zone: $AVAILABILITY_ZONE" # Step 3: Create a Lightsail instance echo "Step 3: Creating Lightsail instance: $INSTANCE_NAME" aws lightsail create-instances \ --instance-names "$INSTANCE_NAME" \ --availability-zone "$AVAILABILITY_ZONE" \ --blueprint-id amazon_linux_2023 \ --bundle-id nano_3_0 \ --region $AWS_REGION check_status "Failed to create Lightsail instance" track_resource "instance" "$INSTANCE_NAME" # Wait for the instance to be in a running state echo "Waiting for instance to be in running state..." # Wait for the instance to be ready (polling approach) MAX_ATTEMPTS=30 ATTEMPTS=0 while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do STATUS=$(aws lightsail get-instance-state --instance-name "$INSTANCE_NAME" --region $AWS_REGION --query 'state.name' --output text) if [ "$STATUS" == "running" ]; then echo "Instance is now running" break fi echo "Instance status: $STATUS. Waiting..." ATTEMPTS=$((ATTEMPTS+1)) sleep 10 done if [ $ATTEMPTS -eq $MAX_ATTEMPTS ]; then handle_error "Instance failed to reach running state after 5 minutes" fi # Get instance details echo "Getting instance details" INSTANCE_IP=$(aws lightsail get-instance --instance-name "$INSTANCE_NAME" --region $AWS_REGION --query 'instance.publicIpAddress' --output text) check_status "Failed to get instance IP address" echo "Instance IP address: $INSTANCE_IP" # Step 4: Download the default key pair echo "Step 4: Downloading default key pair" KEY_FILE="lightsail_key_${RANDOM_ID}.pem" aws lightsail download-default-key-pair --region $AWS_REGION --output text > "$KEY_FILE" check_status "Failed to download key pair" chmod 400 "$KEY_FILE" check_status "Failed to set permissions on key pair" echo "Key pair downloaded to $KEY_FILE" echo "To connect to your instance, use:" echo "ssh -i $KEY_FILE ec2-user@$INSTANCE_IP" # Step 5: Create a block storage disk echo "Step 5: Creating block storage disk: $DISK_NAME" aws lightsail create-disk \ --disk-name "$DISK_NAME" \ --availability-zone "$AVAILABILITY_ZONE" \ --size-in-gb 8 \ --region $AWS_REGION check_status "Failed to create disk" track_resource "disk" "$DISK_NAME" # FIX: Wait for the disk to be available using polling instead of fixed sleep echo "Waiting for disk to be available..." MAX_ATTEMPTS=30 ATTEMPTS=0 while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do DISK_STATE=$(aws lightsail get-disk --disk-name "$DISK_NAME" --region $AWS_REGION --query 'disk.state' --output text 2>/dev/null) if [ "$DISK_STATE" == "available" ]; then echo "Disk is now available" break fi echo "Disk status: $DISK_STATE. Waiting..." ATTEMPTS=$((ATTEMPTS+1)) sleep 10 done if [ $ATTEMPTS -eq $MAX_ATTEMPTS ]; then handle_error "Disk failed to become available after 5 minutes" fi # Attach the disk to the instance echo "Attaching disk to instance" aws lightsail attach-disk \ --disk-name "$DISK_NAME" \ --instance-name "$INSTANCE_NAME" \ --disk-path /dev/xvdf \ --region $AWS_REGION check_status "Failed to attach disk to instance" echo "Disk attached. To format and mount the disk, connect to your instance and run:" echo "sudo mkfs -t ext4 /dev/xvdf" echo "sudo mkdir -p /mnt/my-data" echo "sudo mount /dev/xvdf /mnt/my-data" echo "sudo chown ec2-user:ec2-user /mnt/my-data" # Step 6: Create a snapshot of the instance echo "Step 6: Creating snapshot of the instance: $SNAPSHOT_NAME" aws lightsail create-instance-snapshot \ --instance-name "$INSTANCE_NAME" \ --instance-snapshot-name "$SNAPSHOT_NAME" \ --region $AWS_REGION check_status "Failed to create instance snapshot" track_resource "instance_snapshot" "$SNAPSHOT_NAME" # FIX: Wait for the snapshot to complete using polling instead of fixed sleep echo "Waiting for snapshot to complete... (this may take several minutes)" MAX_ATTEMPTS=60 # Increased timeout for snapshot creation ATTEMPTS=0 while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]; do SNAPSHOT_STATE=$(aws lightsail get-instance-snapshot --instance-snapshot-name "$SNAPSHOT_NAME" --region $AWS_REGION --query 'instanceSnapshot.state' --output text 2>/dev/null) if [ "$SNAPSHOT_STATE" == "completed" ]; then echo "Snapshot creation completed" break fi echo "Snapshot status: $SNAPSHOT_STATE. Waiting... ($ATTEMPTS/$MAX_ATTEMPTS)" ATTEMPTS=$((ATTEMPTS+1)) sleep 10 done if [ $ATTEMPTS -eq $MAX_ATTEMPTS ]; then echo "Warning: Snapshot creation is taking longer than expected but will continue in the background." echo "You can check its status later with: aws lightsail get-instance-snapshot --instance-snapshot-name $SNAPSHOT_NAME --region $AWS_REGION" fi # Step 7: Clean up resources echo "Step 7: Clean up resources" echo "The script has created the following resources:" for resource in "${CREATED_RESOURCES[@]}"; do echo " $resource" done read -p "Do you want to clean up these resources? (y/n): " CLEANUP_CONFIRM if [[ "$CLEANUP_CONFIRM" == "y" || "$CLEANUP_CONFIRM" == "Y" ]]; then cleanup_resources else echo "Resources will not be cleaned up. You can manually delete them later." echo "To clean up manually, use the following commands:" echo "aws lightsail delete-instance-snapshot --instance-snapshot-name $SNAPSHOT_NAME --region $AWS_REGION" echo "aws lightsail detach-disk --disk-name $DISK_NAME --region $AWS_REGION" echo "aws lightsail delete-disk --disk-name $DISK_NAME --region $AWS_REGION" echo "aws lightsail delete-instance --instance-name $INSTANCE_NAME --region $AWS_REGION" fi echo "Script completed at $(date)"