AWS CLI Tutorial: Launch EC2 and Use S3 from Ubuntu

Tested on Ubuntu 26.04 LTS workstation
AWS Region | ap-south-1 (Mumbai)
Applies to Ubuntu workstation with outbound HTTPS; any AWS Region when you change --region
Privilege AWS account with permission to use EC2 and S3; sudo on Ubuntu for CLI install
Scope Sign in to AWS from the CLI, verify your identity, launch Ubuntu 24.04 on EC2, upload a file to S3, connect with SSH, and delete lab resources.
Short on time?Beta Get the gist of this 10-minute read in seconds, then ask follow-up questions

This tutorial walks through a complete first AWS workflow from an Ubuntu workstation. You will sign in with the AWS CLI, confirm which identity the CLI is using, launch an Ubuntu 24.04 EC2 instance, SSH into it, upload a small file to S3, and delete every resource when you finish.

By the end you will have:

  • A signed-in AWS CLI session with a default Region (ap-south-1 in my run)
  • A proof call with aws sts get-caller-identity
  • One Ubuntu 24.04 EC2 instance you can SSH into
  • One small file in S3
  • A cleanup section so you do not leave billable resources running

I ran every command below on Ubuntu 26.04 against a live account. Swap my example prefix (glc-aws-lab) if it is already taken.

This page does not cover installing the CLI. Finish install AWS CLI on Ubuntu or install AWS CLI on Debian first, then come back here. aws login requires AWS CLI v2.32.0 or later.


Sign in to AWS from Ubuntu

AWS CLI v2.32.0 and later can sign you in with your AWS console credentials and issue temporary credentials, so you do not need to create a long-lived access key for this lab. IAM users, roles, or groups also need AWS Sign-In permission; AWS provides the managed SignInLocalDevelopmentAccess policy for this. Root sign-in does not require this additional permission.

Check your CLI version:

bash
aws --version
output
aws-cli/2.36.38 Python/3.14.6 Linux/7.0.0-29-generic exe/x86_64.ubuntu.26

Sign in with the AWS console identity you normally use. For a newly created standalone account, aws login can also authenticate with the root user without creating root access keys.

bash
aws login

Your browser opens for AWS authentication. If Ubuntu is running on a remote machine without a browser, use:

bash
aws login --remote

Set your default Region:

bash
aws configure set region ap-south-1

See what the CLI loaded (secrets stay masked):

bash
aws configure list
output
NAME       : VALUE                    : TYPE             : LOCATION
profile    : <not set>                : None             : None
access_key : ****************AO5P     : login            :
secret_key : ****************Eui8     : login            :
region     : ap-south-1               : config-file      : ~/.aws/config

The login type confirms you are using temporary credentials from aws login, not long-lived access keys.

Confirm which AWS identity the CLI is using:

bash
aws sts get-caller-identity
json
{
    "UserId": "342524208658",
    "Account": "342524208658",
    "Arn": "arn:aws:iam::342524208658:root"
}

If the command returns your account ID and an ARN for the identity you signed in with, authentication is working. aws login uses short-term credentials the CLI refreshes automatically.

My test account returned :root because I authenticated with the account root user; an IAM or federated identity will return a different ARN.

For day-to-day AWS work, use a non-root identity with only the permissions you need.

Using IAM access keys instead?

If you already have an IAM access key from another setup, configure it with aws configure. AWS recommends temporary credentials for normal local development, so this is not the preferred first-time path.

bash
aws configure

Paste your access key ID, secret access key, default Region (ap-south-1), and output format (json).


Launch an Ubuntu EC2 instance from the AWS CLI

EC2 is AWS virtual machines. Before run-instances works you need an AMI ID, an SSH key pair, and a security group.

Set two shell variables so the commands are easy to copy. Pick your own prefix if glc-aws-lab is taken:

bash
export AWS_DEFAULT_REGION=ap-south-1
export LAB=glc-aws-lab

Find the latest Ubuntu 24.04 AMI

Canonical publishes official Ubuntu AMIs in every Region. Capture the newest Noble 24.04 amd64 image directly:

bash
export AMI=$(aws ec2 describe-images \
  --owners 099720109477 \
  --filters \
    "Name=name,Values=ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*" \
    "Name=state,Values=available" \
  --query 'sort_by(Images,&CreationDate)[-1].ImageId' \
  --output text)

echo "$AMI"
output
ami-050c78efa486a0196

AMI IDs change when Canonical publishes new snapshots. The command above always picks the latest available image in your Region.

Create an SSH key pair

EC2 does not give you a password to type at the login prompt. You use an SSH key instead:

bash
aws ec2 create-key-pair --key-name "${LAB}-key" --query 'KeyMaterial' --output text > ~/${LAB}-key.pem

Restrict the private key so only your user can read it:

bash
chmod 400 ~/${LAB}-key.pem

Do not paste the .pem contents into documentation or chat. That file is your private key.

Create an SSH security group

Look up your default VPC (fine for a first lab):

bash
export VPC=$(aws ec2 describe-vpcs \
  --filters Name=isDefault,Values=true \
  --query 'Vpcs[0].VpcId' --output text)
bash
echo "$VPC"
output
vpc-090f366caca593558

If this returns None, your Region does not have a default VPC. Create or restore a default VPC, or use an existing VPC and subnet before continuing.

Create a security group and allow SSH only from your current public IPv4 address:

bash
export SG_ID=$(aws ec2 create-security-group \
  --group-name "${LAB}-sg" \
  --description "GoLinuxCloud lab SSH" \
  --vpc-id "$VPC" \
  --query 'GroupId' --output text)

export MY_IP=$(curl -s https://checkip.amazonaws.com)

aws ec2 authorize-security-group-ingress \
  --group-id "$SG_ID" \
  --protocol tcp \
  --port 22 \
  --cidr "${MY_IP}/32"

This allows SSH only from your current public IPv4 address. If your ISP or VPN changes the address, update the rule.

The authorize command returns "Return": true when the SSH rule is in place.

Launch the instance

Launch a t3.micro with your AMI, key, and security group. t3.micro is Free Tier eligible for accounts created on or after July 15, 2025. For older accounts, AWS generally used t2.micro, with t3.micro eligible in Regions where t2.micro was unavailable. Check your current AWS Free Tier status before launching the instance.

bash
export INSTANCE_ID=$(aws ec2 run-instances \
  --image-id "$AMI" \
  --instance-type t3.micro \
  --key-name "${LAB}-key" \
  --security-group-ids "$SG_ID" \
  --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${LAB}-ubuntu}]" \
  --query 'Instances[0].InstanceId' --output text)
output
i-009d46e54843fde59

Wait until the instance reaches running:

bash
aws ec2 wait instance-running --instance-ids "$INSTANCE_ID"

Capture the public IP you will SSH to:

bash
export PUBLIC_IP=$(aws ec2 describe-instances \
  --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text)

echo "$PUBLIC_IP"
output
15.252.144.88

Connect to Ubuntu with SSH

Canonical's Ubuntu AMIs use ubuntu as the login name. Connect and run a quick check in one shot:

bash
ssh -o StrictHostKeyChecking=accept-new -i ~/${LAB}-key.pem ubuntu@${PUBLIC_IP} 'uname -a && lsb_release -ds'
output
Linux ip-172-31-12-28 7.0.0-1011-aws #11~24.04.1-Ubuntu SMP PREEMPT Mon Aug 10 15:20:57 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Ubuntu 24.04.4 LTS

That is a live Ubuntu server in AWS, created from the CLI on your workstation.


Upload a file to Amazon S3

S3 is object storage. By default, a general-purpose S3 bucket uses the shared global namespace, where its name must be unique within the AWS partition. Build a unique name from your account ID and a timestamp:

bash
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export BUCKET="glc-lab-${ACCOUNT_ID}-$(date +%Y%m%d%H%M%S)"

echo "$BUCKET"
output
glc-lab-342524208658-20260903223045

Write a small test file locally:

bash
echo "hello from golinuxcloud $(date -Iseconds)" > /tmp/glc-test.txt

Create the bucket in the same Region as your CLI default:

bash
aws s3 mb "s3://${BUCKET}"
output
make_bucket: glc-lab-342524208658-20260903223045

Upload the test file:

bash
aws s3 cp /tmp/glc-test.txt "s3://${BUCKET}/glc-test.txt"
output
upload: ../glc-test.txt to s3://glc-lab-342524208658-20260903223045/glc-test.txt

List objects to confirm:

bash
aws s3 ls "s3://${BUCKET}/"
output
2026-09-03 22:02:02         36 glc-test.txt

For policies, versioning, and static sites, see the AWS S3 bucket tutorial.


Delete the AWS resources

Delete billable resources when you finish. Rough order:

  1. Terminate the EC2 instance and wait until it is gone
  2. Empty and delete the S3 bucket
  3. Delete the security group and key pair

Terminate the instance:

bash
aws ec2 terminate-instances --instance-ids "$INSTANCE_ID" --query 'TerminatingInstances[0].CurrentState.Name' --output text

Wait until EC2 reports terminated before deleting the security group:

bash
aws ec2 wait instance-terminated --instance-ids "$INSTANCE_ID"

Remove the bucket and every object inside it:

bash
aws s3 rb "s3://${BUCKET}" --force
output
delete: s3://glc-lab-342524208658-20260903223045/glc-test.txt
remove_bucket: glc-lab-342524208658-20260903223045

Delete the security group and key pair:

bash
aws ec2 delete-security-group --group-id "$SG_ID"

Remove the EC2 key pair from your account:

bash
aws ec2 delete-key-pair --key-name "${LAB}-key"

Delete the private key file from disk:

bash
rm -f ~/${LAB}-key.pem

Verify nothing is left running:

bash
aws ec2 describe-instances --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[0].Instances[0].State.Name' --output text
output
terminated

If you no longer need the AWS CLI session, run aws logout to sign out:

bash
aws logout

Troubleshooting

Symptom Likely cause Fix
Profile 'default' is already configured with Access Key credentials Old aws configure keys on default Back up and remove ~/.aws/credentials, or run aws login --profile new-name
aws login authorization or permission error IAM identity cannot use local-development sign-in Ask the administrator to attach the SignInLocalDevelopmentAccess policy
Unable to locate credentials Not signed in Run aws login (or aws login --remote on a headless host), or run aws configure if you use IAM access keys
UnauthorizedOperation on run-instances Missing EC2 permission Your AWS identity does not have permission for the requested EC2 action. Check the error for the denied action and ask the AWS administrator to grant the required EC2 permission.
AccessDenied with AdministratorAccess attached Explicit deny in a permissions boundary, SCP, session policy, or resource policy Read the full CLI error, then follow IAM AccessDenied despite AdministratorAccess
VPC is None / InvalidGroup.NotFound No default VPC in the selected Region Create or restore a default VPC, or launch into an existing VPC and subnet
PublicIpAddress is None No public IPv4 on the instance Launch into a subnet that auto-assigns a public IPv4 address (default VPC subnets normally do)
BucketAlreadyExists on s3 mb Bucket name taken in the shared namespace Pick a new bucket name with your account ID or a random suffix
SSH Connection timed out Security group or corporate firewall Confirm port 22 from your current IP (${MY_IP}/32); check VPN or proxy
Permission denied (publickey) Wrong .pem or user Use ubuntu@ for Canonical AMIs; chmod 400 on the key file
InvalidAMIID.NotFound AMI is Region-specific Re-run describe-images in your chosen Region

What to do next

You now have the loop most AWS tutorials assume: sign-in, CLI, EC2, S3. Good next steps:

  • Work through the AWS tutorial hub chapter by chapter (Lightsail, RDS, Lambda, CloudFormation, and more)
  • Deploy a web server on EC2 with Let's Encrypt
  • Build a cluster with Kubernetes on AWS EC2
  • Set up a non-root AWS identity for everyday administration

Stay in one Region (ap-south-1 here) until you are comfortable. Cross-Region data transfer adds cost and confusion early on.


References


Frequently Asked Questions

Should I use aws login or aws configure?

Use aws login when you can sign into the AWS console. It gives you short-term credentials the CLI refreshes automatically. Use aws configure when you specifically need to configure an existing IAM access key.

Which AWS Region should I use from India?

ap-south-1 (Mumbai) is the usual pick for low latency from India. Set it with aws configure set region ap-south-1 or export AWS_DEFAULT_REGION=ap-south-1 before each command.

Why does my AMI ID differ from the article?

Canonical publishes new Ubuntu snapshots regularly. Run aws ec2 describe-images with owner 099720109477 in your Region instead of copying an old AMI ID.

How much does this lab cost?

A short t3.micro test and a tiny S3 object may fit within AWS Free Tier credits, but eligibility depends on when your account was created and your current plan. Terminate EC2 and delete the bucket when you finish. Running instances and stored data are what accumulate charges.

What if SSH hangs or times out?

Check the security group allows TCP port 22 from your current public IP. Corporate VPNs and proxies sometimes block outbound SSH. Try from a home network or check the instance serial log in the EC2 console.

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with 15+ years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)