devuplabs.cloud
Free previewLab1 hour

CLI Practice Lab

Launch CloudShell, verify your identity and region, practise variables and queries, create a small S3 resource, diagnose common failures, and clean up.

Prerequisites

0 of 5 checked

Use a training account

Do not run this lab in a production account. You will create one private S3 bucket, upload a tiny text file, and delete both before finishing.


Open CloudShell and Verify Context

Goal

Open a Bash shell that works the same way on Windows, macOS, and Linux. Confirm the AWS identity and region before making changes.

Estimated time: 10 minutes

  1. 1Sign in to the AWS Management Console
  2. 2Select ap-south-1 from the region selector
  3. 3Choose the CloudShell terminal icon in the console header
  4. 4Wait until the prompt appears
bash
aws --version
bash --version | head -n 1
jq --version
python3 --version

AWS CLI v2, Bash, jq, and Python should already be available. This preinstalled toolchain is why the rest of the course does not require PowerShell translations.

bash
aws sts get-caller-identity

Write down the Account value and read the Arn. Confirm that this is your training account and expected IAM identity.

bash
export AWS_REGION="ap-south-1"
export AWS_DEFAULT_REGION="$AWS_REGION"

printf "Account: %s\n" "$(aws sts get-caller-identity --query Account --output text)"
printf "Region:  %s\n" "$AWS_REGION"

Variables, Output, and Queries

Goal

Use environment variables and turn large JSON responses into readable tables and single values.

Estimated time: 15 minutes

Set lab variables

bash
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export LAB_SUFFIX=$(date +%s)
export LAB_PREFIX="cloudshell-lab-${LAB_SUFFIX}"
export BUCKET_NAME="${LAB_PREFIX}-${ACCOUNT_ID}"

printf "ACCOUNT_ID=%s\n" "$ACCOUNT_ID"
printf "LAB_PREFIX=%s\n" "$LAB_PREFIX"
printf "BUCKET_NAME=%s\n" "$BUCKET_NAME"

$(command) runs a command and captures its output. ${NAME} expands a variable. Quoting "$NAME" prevents spaces and wildcard characters from being interpreted by Bash.

Compare output formats

bash
# Default JSON output
aws ec2 describe-regions --all-regions

# Human-readable table
aws ec2 describe-regions \
  --all-regions \
  --query 'Regions[0:5].{Region:RegionName,Status:OptInStatus}' \
  --output table

# One value for a script
FIRST_REGION=$(aws ec2 describe-regions \
  --all-regions \
  --query 'Regions[0].RegionName' \
  --output text)

echo "First region returned: $FIRST_REGION"

The table should contain only Region and Status. The final command should save one plain-text region name in FIRST_REGION.

Inspect exit status

bash
aws sts get-caller-identity >/dev/null
printf "Successful command status: %s\n" "$?"

aws s3api head-bucket --bucket "this-bucket-should-not-exist-${ACCOUNT_ID}" 2>/dev/null
printf "Failed command status: %s\n" "$?"

The successful command returns 0. The missing-bucket check returns a non-zero status. Scripts use this status to decide whether to continue, retry, or stop.


Files and a Reusable Script

Goal

Create a persistent course directory and write a small script that verifies your AWS context.

Estimated time: 10 minutes

bash
mkdir -p "$HOME/aws-course/cloudshell-lab"
cd "$HOME/aws-course/cloudshell-lab"

pwd
ls -la
bash
cat > check-context.sh << 'EOF'
#!/usr/bin/env bash
set -euo pipefail

REGION="${AWS_REGION:-${AWS_DEFAULT_REGION:-not-set}}"
ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
ARN=$(aws sts get-caller-identity --query Arn --output text)

printf "Account: %s\n" "$ACCOUNT"
printf "Identity: %s\n" "$ARN"
printf "Region: %s\n" "$REGION"
printf "Directory: %s\n" "$PWD"
EOF

chmod +x check-context.sh
./check-context.sh

The quoted EOF prevents variables from expanding while the file is created. They expand later when the script runs. set -euo pipefail stops the script on failed commands, unset variables, and failed pipeline stages.

Close and reopen the CloudShell panel, return to ~/aws-course/cloudshell-lab, and confirm that check-context.sh still exists. Environment variables may need to be exported again.


Create, Inspect, and Delete an S3 Resource

Goal

Run a complete AWS CLI workflow: create a resource, verify it, change it, inspect it, and clean it up.

Estimated time: 20 minutes

If you opened a new CloudShell session, restore the variables first:

bash
export AWS_REGION="ap-south-1"
export AWS_DEFAULT_REGION="$AWS_REGION"
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export LAB_SUFFIX=${LAB_SUFFIX:-$(date +%s)}
export LAB_PREFIX="cloudshell-lab-${LAB_SUFFIX}"
export BUCKET_NAME="${LAB_PREFIX}-${ACCOUNT_ID}"

echo "$BUCKET_NAME"

Create a private bucket

bash
if [ "$AWS_REGION" = "us-east-1" ]; then
  aws s3api create-bucket \
    --bucket "$BUCKET_NAME" \
    --region "$AWS_REGION"
else
  aws s3api create-bucket \
    --bucket "$BUCKET_NAME" \
    --region "$AWS_REGION" \
    --create-bucket-configuration LocationConstraint="$AWS_REGION"
fi

aws s3api put-public-access-block \
  --bucket "$BUCKET_NAME" \
  --public-access-block-configuration \
    BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true

The create command returns the bucket location. The public-access command returns no output on success. No output does not mean the command was skipped.

Upload and inspect an object

bash
cat > hello.txt << EOF
Created from AWS CloudShell
Account: $ACCOUNT_ID
Region: $AWS_REGION
Created: $(date -u +%FT%TZ)
EOF

aws s3 cp hello.txt "s3://$BUCKET_NAME/hello.txt"

aws s3api list-objects-v2 \
  --bucket "$BUCKET_NAME" \
  --query 'Contents[].{Key:Key,Bytes:Size,Modified:LastModified}' \
  --output table

aws s3 cp "s3://$BUCKET_NAME/hello.txt" -

The table is produced by --query, while the final command streams the object to standard output because its destination is -.

Inspect configuration

bash
aws s3api get-public-access-block \
  --bucket "$BUCKET_NAME" \
  --query PublicAccessBlockConfiguration \
  --output table

aws s3api get-bucket-location \
  --bucket "$BUCKET_NAME"

All four public-access settings must be True. Confirm that the bucket location matches the lab region.


Diagnose a Failure

Goal

Read an error, inspect the command context, and fix the cause instead of repeatedly rerunning the same command.

Estimated time: 5 minutes

bash
WRONG_BUCKET="${BUCKET_NAME}-wrong"

aws s3api list-objects-v2 \
  --bucket "$WRONG_BUCKET"

The command should fail because the bucket name is wrong. Read the error code and operation name before continuing.

bash
printf "Expected bucket: %s\n" "$BUCKET_NAME"
printf "Wrong bucket:    %s\n" "$WRONG_BUCKET"

aws s3api head-bucket --bucket "$BUCKET_NAME"
echo "Correct bucket exists"

You diagnosed the failure by printing the variables and checking the intended resource. This is safer than blindly repeating a create command.


Cleanup

Run this before leaving

S3 storage in this lab is tiny, but cleanup is part of the course workflow. Verify the bucket name before deleting it.

bash
printf "Deleting s3://%s\n" "$BUCKET_NAME"

aws s3 rm "s3://$BUCKET_NAME" --recursive
aws s3api delete-bucket \
  --bucket "$BUCKET_NAME" \
  --region "$AWS_REGION"

if aws s3api head-bucket --bucket "$BUCKET_NAME" 2>/dev/null; then
  echo "Bucket still exists"
  exit 1
else
  echo "Cleanup verified: bucket no longer exists"
fi

rm -f "$HOME/aws-course/cloudshell-lab/hello.txt"

The verification must print Cleanup verified. Your reusable check-context.sh can remain in the persistent home directory.


Unlock all 32 AWS services & 353+ lab sessions (~225 hours)

Pricing