01 · Setup & AWS CLI¶
Every module in this course assumes you have an AWS account and a working AWS CLI on your machine. This module walks through creating the account safely (never using the root user day-to-day), installing the CLI, creating an IAM user just for CLI access, and understanding the basic shape of every CLI command you'll run from here on. Getting this right up front saves you from two common beginner mistakes: doing everything as the root user (a security risk), and not understanding regions/profiles (a source of very confusing "where did my resource go?" bugs).
Create your AWS account¶
- Go to aws.amazon.com and click Create an AWS Account.
- Provide an email, password, and AWS account name.
- Add a payment method (required even for free-tier usage) and complete identity verification (phone/SMS).
- Choose the Basic support plan (free) unless you have a reason for more.
The email/password you just created is the root user — it has unrestricted access to everything in the account, including billing. AWS's own guidance, and this course's, is: use the root user only to create your first IAM user, then stop using it for daily work.
Never use the root user for day-to-day work
The root user cannot be restricted by any policy. If its credentials leak, an attacker has full control of your account and your bill. Lock it down with MFA (covered in the next module) and set it aside.
Enable an IAM user for yourself¶
Log in as root once, go to the IAM console, and create an administrative IAM user for yourself:
- IAM → Users → Create user.
- Username: e.g.
yourname-admin. - Attach the AWS-managed policy
AdministratorAccess(broad on purpose — this is your day-to-day login, not a service credential; least-privilege for service roles is covered in the next module). - Under Security credentials, create an access key with use case "Command Line Interface (CLI)". Save the Access Key ID and Secret Access Key somewhere safe (a password manager) — the secret is shown only once.
From now on, log in to the console and run the CLI as this IAM user, not root.
Install the AWS CLI¶
# macOS (Homebrew)
brew install awscli
# Linux (x86_64)
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Windows: download and run the MSI installer from
# https://awscli.amazonaws.com/AWSCLIV2.msi
Verify the install:
Configure your credentials¶
aws configure
# AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
# AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# Default region name [None]: us-east-1
# Default output format [None]: json
This writes two files under ~/.aws/:
# ~/.aws/credentials
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# ~/.aws/config
[default]
region = us-east-1
output = json
Confirm the CLI can authenticate as you:
aws sts get-caller-identity
# {
# "UserId": "AIDACKCEVSQ6C2EXAMPLE",
# "Account": "123456789012",
# "Arn": "arn:aws:iam::123456789012:user/yourname-admin"
# }
If this returns your IAM user's ARN (not an error), the CLI is correctly configured.
Regions and why they matter¶
AWS resources live in a region (e.g. us-east-1 = N. Virginia,
eu-west-1 = Ireland, ap-south-1 = Mumbai). Most services are
region-scoped: an EC2 instance you launch in us-east-1 simply does not
exist when you list instances in eu-west-1 — it's not hidden, it's a
different set of servers entirely. A few services are global (IAM, Route 53,
CloudFront) and don't have this distinction.
# List instances in the default region (from config)
aws ec2 describe-instances
# Override the region for a single command
aws ec2 describe-instances --region eu-west-1
# List every region available to your account
aws ec2 describe-regions --query "Regions[].RegionName" --output table
Pick one region for this whole course (e.g. us-east-1, which typically has
the earliest access to new features and the lowest prices) and stick with it
unless a module says otherwise — it avoids the "I can't find my S3 bucket"
confusion later.
Profiles: managing more than one identity¶
Profiles let the CLI hold multiple named credential sets — useful once you have a personal account and a work account, or separate admin vs. read-only credentials.
# Add a second, named profile interactively
aws configure --profile training
# Use it for a single command
aws s3 ls --profile training
# Or export it for the whole shell session
export AWS_PROFILE=training
aws sts get-caller-identity # now uses the "training" profile
# ~/.aws/credentials can hold several profiles side by side
[default]
aws_access_key_id = AKIA...DEFAULT
aws_secret_access_key = ...
[training]
aws_access_key_id = AKIA...TRAINING
aws_secret_access_key = ...
Anatomy of a CLI command¶
Every AWS CLI command follows the same shape:
# service = ec2, operation = describe-instances
aws ec2 describe-instances \
--region us-east-1 \
--profile training \
--output table \
--query "Reservations[].Instances[].[InstanceId,State.Name]"
--query runs a JMESPath expression against the
JSON response to filter it down to just what you need — indispensable once
responses get large (describe-instances returns a lot of nested detail per
instance).
Cheat sheet¶
| Command / file | Purpose |
|---|---|
aws configure |
Interactively set access key, secret key, region, output format for the default profile. |
aws configure --profile NAME |
Same, but for a named profile. |
aws sts get-caller-identity |
Confirm who the CLI is currently authenticated as. |
~/.aws/credentials |
Stores access key / secret key per profile. |
~/.aws/config |
Stores region / output format per profile. |
--region |
Override the region for one command. |
--profile |
Override which credential set to use for one command. |
--output json\|table\|text |
Controls response formatting. |
--query "JMESPath" |
Filters/reshapes the JSON response client-side. |
AWS_PROFILE env var |
Sets the default profile for the whole shell session. |
How It Actually Works¶
The AWS CLI is a thin client over Signature Version 4 (SigV4) request
signing and the same REST/JSON control-plane APIs the Console calls in your
browser — there is no special "CLI protocol." Every aws command builds an
HTTPS request, computes an HMAC-SHA256 signature derived from your secret
access key, the request contents, the target region, and the current
timestamp, and attaches it as an Authorization header. The signature binds
the request to a 5-minute time window specifically to defeat replay attacks —
if your clock drifts more than ~15 minutes from AWS's servers, every call
starts failing with RequestTimeTooSkewed even though your credentials are
fine.
"Regions" are not just a routing label: each AWS region is an
almost-fully-isolated deployment of the control plane, with its own instances
of most services' metadata stores. When you create a bucket in
us-east-1, that record genuinely does not exist in eu-west-1 — there is
no background replication of your resource inventory across regions unless a
service explicitly offers cross-region replication as a feature. That's why
switching --region mid-troubleshooting is the single most common cause of
"my resource disappeared" confusion.
Under ~/.aws/credentials, a profile is nothing more than a named set of
key material the CLI substitutes into the SigV4 signing step before the
request ever leaves your machine — profile switching has zero server-side
component; AWS never sees "profile B" as a concept, only the access key ID
embedded in the signature.
Exercise¶
- Create a second IAM user called
readonly-testwith the AWS-managedReadOnlyAccesspolicy attached, and generate a CLI access key for it. - Configure it as a new CLI profile named
readonly. - Run
aws sts get-caller-identity --profile readonlyto confirm it authenticates as the new user. - Run
aws ec2 describe-instances --profile readonly --output table— it should succeed (empty list is fine, you haven't launched anything yet). - Try
aws ec2 run-instances --profile readonly ...with any parameters — confirm it's denied with anUnauthorizedOperationerror, sinceReadOnlyAccesscan view but not create resources. This is your first hands-on look at least-privilege access, covered fully in the next module.