Skip to main content
AWS · lesson 1 of 10
AWS beginner Lesson 1 of 10

Introduction to AWS

What AWS regions and availability zones really are, then configure the CLI and confirm your identity against LocalStack with no AWS account required.

By SkillByExample · Published

aws cli localstack getting-started

AWS is around 200 services built on top of compute, storage, and networking that Amazon rents out by the second. The service catalogue looks overwhelming until you notice that almost everything sits on the same three primitives: a place to run code, a place to store bytes, and a network to move them — and that every one of those is scoped to a region.

Regions and availability zones

Region codeLocationAvailability zones
us-east-1N. Virginia6 (a-f)
us-west-2Oregon4 (a-d)
eu-west-1Ireland3 (a-c)
ap-south-1Mumbai3 (a-c)

A region is a self-contained geographic area. Nothing replicates across regions unless you explicitly configure it to — an S3 bucket in eu-west-1 is invisible from us-east-1. Inside a region, AWS operates multiple availability zones (AZs): physically separate data centers, each with independent power and networking, connected to the others by low-latency private links. Spreading a database across two AZs in the same region survives a data center failure; nothing survives a whole region going down except a second region.

This lesson uses LocalStack (https://localstack.cloud), an open-source AWS emulator that runs the real AWS CLI against a local server on port 4566. It costs nothing, needs no account, and every command is identical to real AWS except for one added flag (--endpoint-url). Where a later lesson needs behaviour LocalStack cannot emulate faithfully, it says so and switches to a real free-tier account.

Installing and starting LocalStack

pip install localstack awscli-local
localstack start -d
$ localstack start -d
     __                     _______ __             __
    / /   ____  _________ _/ / ___// /_____ ______/ /__
   / /   / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
  / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
 /_____/\____/\___/\__,_/_/____/\__/\__,_/\___/_/|_|

  LocalStack CLI 3.4.0

[16:02:11] starting LocalStack in Docker mode 🐳
[16:02:14] Waiting for all LocalStack services to be ready
[16:02:19] Ready.
localstack status services
$ localstack status services
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Service          ┃ Status        ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ acm               │ ✔ available   │
│ cloudformation    │ ✔ available   │
│ cloudwatch        │ ✔ available   │
│ ec2               │ ✔ available   │
│ iam               │ ✔ available   │
│ lambda            │ ✔ available   │
│ s3                │ ✔ running     │
│ sts               │ ✔ running     │
└──────────────────┴───────────────┘

Configuring the CLI

LocalStack does not validate credentials, so any non-empty values work. Real AWS needs a real access key pair from IAM instead — the iam lesson covers issuing one properly.

aws configure --profile localstack
$ aws configure --profile localstack
AWS Access Key ID [None]: test
AWS Secret Access Key [None]: test
Default region name [None]: us-east-1
Default output format [None]: json

Confirming identity

aws sts get-caller-identity is the smallest possible AWS call — it asks “who am I?” and proves credentials, network access, and region are all wired up correctly.

aws --endpoint-url=http://localhost:4566 --profile localstack sts get-caller-identity
$ aws --endpoint-url=http://localhost:4566 --profile localstack sts get-caller-identity
{
    "UserId": "AKIAIOSFODNN7EXAMPLE",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:root"
}

000000000000 is LocalStack’s fixed test account — every request returns it regardless of which access key was supplied. Against a real AWS account, the same command (dropping --endpoint-url and pointing the profile at real credentials) returns your genuine account ID and the ARN of the actual IAM identity:

$ aws --profile personal sts get-caller-identity
{
    "UserId": "AIDAJQABLZS4A3QDU576Q",
    "Account": "482719503661",
    "Arn": "arn:aws:iam::482719503661:user/abhishek"
}

Listing regions and zones for real

describe-regions and describe-availability-zones are read-only EC2 metadata calls — no resources are created, so they are safe to run against a real account too.

aws --endpoint-url=http://localhost:4566 --profile localstack \
  ec2 describe-regions --query 'Regions[].RegionName' --output table
$ aws --endpoint-url=http://localhost:4566 --profile localstack ec2 describe-regions --query 'Regions[].RegionName' --output table
-------------------------
|     DescribeRegions    |
+-------------------------+
|  us-east-1              |
|  us-east-2              |
|  us-west-1              |
|  us-west-2              |
|  eu-west-1              |
|  ap-south-1             |
+-------------------------+
aws --endpoint-url=http://localhost:4566 --profile localstack \
  ec2 describe-availability-zones --region us-east-1 \
  --query 'AvailabilityZones[].ZoneName' --output text
$ aws --endpoint-url=http://localhost:4566 --profile localstack ec2 describe-availability-zones --region us-east-1 --query 'AvailabilityZones[].ZoneName' --output text
us-east-1a	us-east-1b	us-east-1c	us-east-1d	us-east-1e	us-east-1f

Six AZs for one region is exactly the table above — this is the same API a real account hits, just served locally.

awslocal: the shortcut

Typing --endpoint-url=http://localhost:4566 --profile localstack on every command gets old fast. awslocal, installed alongside awscli-local, is a thin wrapper that adds both automatically — the rest of this track uses it wherever a lesson runs on LocalStack.

awslocal sts get-caller-identity
$ awslocal sts get-caller-identity
{
    "UserId": "AKIAIOSFODNN7EXAMPLE",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:root"
}

Identical output to the long form above, because it is the long form — awslocal just saves the typing.

Practice

1. Start LocalStack and confirm the S3 and Lambda services are running.
localstack status services | grep -E 's3|lambda'
│ lambda            │ ✔ available   │
│ s3                │ ✔ running     │

running means the service has handled at least one request this session; available means it is registered but has not been called yet — both are healthy states.

2. Run aws sts get-caller-identity against LocalStack twice with different (fake) access keys.
aws --endpoint-url=http://localhost:4566 configure set aws_access_key_id fake-key-1
aws --endpoint-url=http://localhost:4566 sts get-caller-identity
aws --endpoint-url=http://localhost:4566 configure set aws_access_key_id fake-key-2
aws --endpoint-url=http://localhost:4566 sts get-caller-identity
{
    "UserId": "AKIAIOSFODNN7EXAMPLE",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:root"
}
{
    "UserId": "AKIAIOSFODNN7EXAMPLE",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:root"
}

Same output both times — proof that LocalStack Community does not check the key at all. This is exactly why the iam lesson, which needs AccessDenied to be real, uses an actual AWS account instead.

3. List availability zones for eu-west-1 and count them.
awslocal ec2 describe-availability-zones --region eu-west-1 \
  --query 'length(AvailabilityZones)'
3

Matches the table at the top of the lesson — Ireland has three AZs against Virginia’s six, which is why some architectures pin multi-AZ RDS specifically to us-east-1 or eu-west-1 rather than smaller regions.

4. Find the region name for zone ap-south-1b without hardcoding it.
awslocal ec2 describe-availability-zones \
  --filters Name=zone-name,Values=ap-south-1b \
  --query 'AvailabilityZones[0].RegionName' --output text
ap-south-1

--filters on Name=zone-name is the general pattern for turning a partial fact into a full record — the same shape reappears filtering EC2 instances by tag in the ec2 lesson.

5. Configure a second profile pointed at a real AWS account and compare its get-caller-identity output to LocalStack's.
aws configure --profile real
aws --profile real sts get-caller-identity
{
    "UserId": "AIDAJQABLZS4A3QDU576Q",
    "Account": "482719503661",
    "Arn": "arn:aws:iam::482719503661:user/abhishek"
}

A 12-digit account ID that is not 000000000000, and an ARN naming your actual IAM user — this is the tell for “am I accidentally about to create real, billable resources?” Get in the habit of checking it before any command with a create-* or run-* verb.

Next: IAM — users, roles, and the least-privilege policy that turns into an AccessDenied you have to debug.

Frequently Asked Questions

Do I need an AWS account to follow this lesson?
No. This lesson runs against LocalStack, an open-source emulator that implements the AWS APIs locally, so every command below produces real AWS CLI output with zero billing risk and zero account. Later lessons that need genuine infrastructure behaviour (VPC routing, RDS, real cold starts) say so explicitly and switch to a real free-tier account.
What is the difference between a region and an availability zone?
A region is a geographic area such as us-east-1 (North Virginia) containing multiple physically separate data centers. Each of those data centers, or a cluster of them, is an availability zone (AZ), such as us-east-1a. Regions are isolated from each other; AZs within a region are connected by low-latency links so you can spread a workload across them for fault tolerance.
Why does aws sts get-caller-identity return account 000000000000 in this lesson?
That is LocalStack's fixed test account ID, returned for every request regardless of the credentials supplied — LocalStack does not validate credentials by default. Against real AWS the same command returns your actual 12-digit account ID and the ARN of the IAM identity making the call.
Is LocalStack a full replacement for a real AWS account?
For learning the CLI and API shapes, yes for a wide range of services in the open-source Community edition (S3, Lambda, DynamoDB, CloudFormation, basic CloudWatch). It does not enforce IAM permissions realistically and some services — full VPC routing, RDS, and multi-AZ behaviour — need the paid Pro edition or a real account, which this track calls out lesson by lesson.