DEV Community

Cover image for The Ultimate Guide to Linux Command Line for Cloud Engineers

The Ultimate Guide to Linux Command Line for Cloud Engineers

The terminal is your gateway to cloud infrastructure. Whether you're SSH'd into an EC2 instance, troubleshooting Lambda container environments, or configuring ECS tasks, you need to navigate Unix-like systems confidently. This guide covers the essential Linux command-line skills you'll use daily as a cloud engineer.

At the end of this article, you will have a working understanding of terminals, shells, file systems, permissions, and package management. You'll know how to navigate remote servers, troubleshoot issues, and automate workflows using command-line tools.

Prerequisites

Before you start, you need:

  • A Unix-like environment (Linux, macOS, or Windows with WSL)
  • Basic familiarity with text editors
  • An AWS account (optional, for cloud-specific examples)

Understanding Terminals and Shells

The words "terminal," "shell," and "command line" get thrown around interchangeably. Let me clarify what each term means and why the distinction matters.

What is a Terminal?

A terminal is a program that accepts text input and renders text output. Historically, terminals were physical devices—keyboards and monitors connected to mainframe computers. Today, you use terminal emulators like Ghostty, iTerm2, or the built-in Terminal on macOS.

When you open your terminal application, it displays a prompt where you can type commands. The terminal itself doesn't interpret those commands—it just handles the input and output.

What is a Shell?

A shell is the program that actually processes your commands. When you type echo "Hello World" and press Enter, the shell reads that text, evaluates it, executes it, and returns output. This cycle is called a REPL: Read, Evaluate, Print, Loop.

The two most common shells are:

  • bash (Bourne Again Shell) - Default on most Linux distributions
  • zsh (Z Shell) - Default on modern macOS

Both are powerful scripting languages that can handle variables, conditionals, loops, and functions. For this guide, all examples work in both bash and zsh.

Why This Matters for AWS

When you SSH into an EC2 instance, you're connecting to a shell session on that remote machine. When you configure Lambda container images, you're often writing shell scripts. When you troubleshoot ECS tasks, you're examining shell output logs.

Understanding the shell means understanding how your cloud infrastructure executes commands.

Let me show you what I mean. Open your terminal and run:

$ echo "Hello World"
Enter fullscreen mode Exit fullscreen mode

The shell reads this command, identifies echo as a program, passes "Hello World" as an argument, and prints the result. Now try:

$ expr 123456 + 7890
Enter fullscreen mode Exit fullscreen mode

Your output shows:

131346
Enter fullscreen mode Exit fullscreen mode

The shell can perform arithmetic, manipulate strings, and execute complex logic. This is why shell scripting is foundational for DevOps automation.

File System Navigation

Cloud servers are just Linux machines. You need to navigate their file systems to configure applications, examine logs, and troubleshoot issues.

Your Current Location

At any moment, your shell has a "working directory"—the folder you're currently in. Check it with:

$ pwd
Enter fullscreen mode Exit fullscreen mode

This prints your working directory. On macOS, you might see:

/Users/cindy
Enter fullscreen mode Exit fullscreen mode

On Linux:

/home/cindy
Enter fullscreen mode Exit fullscreen mode

This is your home directory, where your personal files live.

File Paths

A file path is a text representation of a file's location in the directory tree. All absolute paths start from the root directory (/).

Your home directory on Linux might be /home/achar, which means:

  • Start at the root /
  • Enter the home directory
  • Enter the achar directory

Each directory is separated by a forward slash.

Listing Files

The ls command lists directory contents:

$ ls
Enter fullscreen mode Exit fullscreen mode

You see files and directories in your current location. Add flags to customize the output:

$ ls -l
Enter fullscreen mode Exit fullscreen mode

This shows a "long" format with permissions, owners, file sizes, and modification dates. Add the -a flag to show hidden files:

$ ls -la
Enter fullscreen mode Exit fullscreen mode

Hidden files start with a dot (.). Configuration files like .bashrc or .zshrc are hidden by default.

Changing Directories

Navigate the file system with cd:

$ cd /var/log
Enter fullscreen mode Exit fullscreen mode

This moves you to /var/log, where system logs are stored. Check your new location:

$ pwd
Enter fullscreen mode Exit fullscreen mode

The output shows /var/log.

To go up one directory level, use the special alias ..:

$ cd ..
Enter fullscreen mode Exit fullscreen mode

Now you're in /var. To return to your home directory from anywhere:

$ cd ~
Enter fullscreen mode Exit fullscreen mode

The tilde (~) is an alias for your home directory.

Relative vs Absolute Paths

Absolute paths start with / and work from anywhere:

$ cd /var/log/nginx
Enter fullscreen mode Exit fullscreen mode

Relative paths start from your current location:

$ cd nginx
Enter fullscreen mode Exit fullscreen mode

This only works if a nginx directory exists in your current location.

AWS Context: EC2 Log Files

When you SSH into an EC2 instance running a web application, you often need to examine logs. Application logs typically live in:

  • /var/log - System and service logs
  • /var/log/nginx or /var/log/apache2 - Web server logs
  • /var/log/mysql - Database logs

To check your web server's error log:

$ cd /var/log/nginx
$ ls -l
Enter fullscreen mode Exit fullscreen mode

You see files like access.log and error.log. This workflow is identical whether you're troubleshooting locally or on a remote server.

Working with Files

You need to read, create, modify, and delete files constantly. Let me show you the essential commands.

Reading File Contents

The cat command prints an entire file:

$ cat /etc/hosts
Enter fullscreen mode Exit fullscreen mode

This displays your system's hostname mappings. For large files, cat is overwhelming because it dumps everything to your screen.

Reading Partial Contents

For large files, use head to see the first lines:

$ head -n 10 /var/log/syslog
Enter fullscreen mode Exit fullscreen mode

This shows the first 10 lines. Similarly, tail shows the last lines:

$ tail -n 20 /var/log/syslog
Enter fullscreen mode Exit fullscreen mode

The -n flag specifies the number of lines.

Following Log Files

When troubleshooting active applications, you want to see new log entries as they're written. Use tail -f:

$ tail -f /var/log/nginx/access.log
Enter fullscreen mode Exit fullscreen mode

This continuously displays new lines as they're appended. Press Ctrl+C to stop.

Searching Within Files

The grep command searches for text patterns:

$ grep "error" /var/log/syslog
Enter fullscreen mode Exit fullscreen mode

This prints every line containing "error". The search is case-sensitive by default. For case-insensitive search:

$ grep -i "error" /var/log/syslog
Enter fullscreen mode Exit fullscreen mode

To search recursively through directories:

$ grep -r "database connection" /var/log
Enter fullscreen mode Exit fullscreen mode

This searches all files in /var/log and its subdirectories.

Finding Files

The find command locates files by name or pattern:

$ find /var/log -name "*.log"
Enter fullscreen mode Exit fullscreen mode

This lists all files ending in .log within /var/log. The asterisk (*) is a wildcard matching any characters.

To find files modified in the last 24 hours:

$ find /var/log -mtime -1
Enter fullscreen mode Exit fullscreen mode

Creating Files

The touch command creates empty files:

$ touch test.txt
Enter fullscreen mode Exit fullscreen mode

If test.txt already exists, touch updates its modification timestamp without changing its contents.

Creating Directories

Make new directories with mkdir:

$ mkdir project
Enter fullscreen mode Exit fullscreen mode

To create nested directories in one command:

$ mkdir -p project/src/components
Enter fullscreen mode Exit fullscreen mode

The -p flag creates parent directories as needed.

Moving and Renaming

The mv command both moves and renames files:

$ mv old-name.txt new-name.txt
Enter fullscreen mode Exit fullscreen mode

To move a file to another directory:

$ mv config.json /etc/myapp/
Enter fullscreen mode Exit fullscreen mode

Copying Files

The cp command copies files:

$ cp source.txt destination.txt
Enter fullscreen mode Exit fullscreen mode

To copy directories recursively:

$ cp -r source-dir destination-dir
Enter fullscreen mode Exit fullscreen mode

Deleting Files

The rm command removes files:

$ rm unnecessary-file.txt
Enter fullscreen mode Exit fullscreen mode

To remove directories and their contents:

$ rm -r old-directory
Enter fullscreen mode Exit fullscreen mode

Warning: There's no recycle bin on the command line. Deleted files are gone permanently.

AWS Context: S3 and Local Files

When you work with S3, you frequently sync files between your EC2 instance and S3 buckets. The AWS CLI uses familiar commands:

$ aws s3 cp local-file.json s3://my-bucket/data/
Enter fullscreen mode Exit fullscreen mode

This copies a local file to S3. To download:

$ aws s3 cp s3://my-bucket/data/config.json ./
Enter fullscreen mode Exit fullscreen mode

The patterns mirror standard file operations. Understanding local file manipulation makes cloud storage operations intuitive.

Permissions and Users

Unix-like systems have robust permission systems. This is critical for HIPAA-compliant infrastructure where you need to restrict access to protected health information (PHI).

Understanding Permission Strings

When you run ls -l, you see permission strings like:

-rw-r--r--  1 achar staff  1234 Nov 13 09:30 file.txt
drwxr-xr-x  5 achar staff   160 Nov 13 09:31 directory
Enter fullscreen mode Exit fullscreen mode

Let me break down the first string: -rw-r--r--

The first character indicates the type:

  • - = regular file
  • d = directory

The remaining nine characters form three groups of three:

  1. Owner permissions (rw-): The user who owns the file
  2. Group permissions (r--): Users in the file's group
  3. Other permissions (r--): Everyone else

Each group has three permissions:

  • r = read
  • w = write
  • x = execute

A dash (-) means the permission is denied.

So -rw-r--r-- means:

  • Owner can read and write
  • Group members can read
  • Others can read
  • Nobody can execute

Checking Your User

Your username:

$ whoami
Enter fullscreen mode Exit fullscreen mode

To see which groups you belong to:

$ groups
Enter fullscreen mode Exit fullscreen mode

Changing Permissions

The chmod command modifies permissions. The syntax uses:

  • u = user (owner)
  • g = group
  • o = others
  • a = all

To grant execute permission to the owner:

$ chmod u+x script.sh
Enter fullscreen mode Exit fullscreen mode

To remove write permission from others:

$ chmod o-w sensitive-data.txt
Enter fullscreen mode Exit fullscreen mode

To set permissions for everyone:

$ chmod a+r public-file.txt
Enter fullscreen mode Exit fullscreen mode

You can combine changes:

$ chmod u=rwx,g=rx,o=r program.sh
Enter fullscreen mode Exit fullscreen mode

This sets owner to read/write/execute, group to read/execute, and others to read-only.

The Execute Permission

For files, execute permission allows running the file as a program. For directories, it allows entering the directory.

When you download a script, you often need to make it executable:

$ chmod +x deploy.sh
$ ./deploy.sh
Enter fullscreen mode Exit fullscreen mode

The ./ prefix explicitly runs the script in your current directory.

Changing Ownership

The chown command changes file ownership. This requires elevated privileges:

$ sudo chown nginx:nginx /var/www/html/index.html
Enter fullscreen mode Exit fullscreen mode

This changes the owner to nginx and the group to nginx. The syntax is user:group.

The Root User

The root user is the superuser with unrestricted access to everything. Running commands as root is powerful and dangerous.

The sudo command lets you execute single commands as root:

$ sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

You'll be prompted for your password. After entering it correctly, the command runs with root privileges.

Healthcare Context: HIPAA Compliance

When building HIPAA-compliant systems, file permissions protect PHI. Database credentials, encryption keys, and patient data files must have restricted permissions.

A secure configuration file might have:

$ chmod 600 /etc/myapp/database.conf
Enter fullscreen mode Exit fullscreen mode

This ensures only the owner can read or write the file. No group members or others can access it.

Your EC2 instance's IAM role should follow the principle of least privilege—grant only the minimum permissions needed. Similarly, file permissions should be as restrictive as possible while maintaining functionality.

Programs and Executables

Understanding how programs execute helps you troubleshoot deployment issues and write better automation scripts.

Compiled vs Interpreted Programs

Programs come in two flavors:

Compiled programs are converted to machine code before execution. Languages like Go, Rust, and C produce binaries—executable files containing processor instructions. These run directly on your hardware without needing additional software.

Interpreted programs require an interpreter to execute them. Python scripts need the Python interpreter. Shell scripts need a shell (bash or zsh).

When you run a compiled program:

$ /usr/bin/nginx
Enter fullscreen mode Exit fullscreen mode

The operating system loads the binary and executes it.

When you run an interpreted program:

$ python3 app.py
Enter fullscreen mode Exit fullscreen mode

The Python interpreter reads app.py, parses it, and executes the instructions.

Shebangs

Shell scripts and Python scripts often start with a shebang—a special first line indicating which interpreter to use:

#!/bin/bash
echo "This is a bash script"
Enter fullscreen mode Exit fullscreen mode

Or for Python:

#!/usr/bin/env python3
print("This is a Python script")
Enter fullscreen mode Exit fullscreen mode

The shebang tells the operating system which interpreter to invoke. With a proper shebang and execute permissions, you can run scripts directly:

$ chmod +x script.py
$ ./script.py
Enter fullscreen mode Exit fullscreen mode

Without the shebang, you'd need to explicitly specify the interpreter:

$ python3 script.py
Enter fullscreen mode Exit fullscreen mode

Finding Programs

The which command shows a program's location:

$ which python3
Enter fullscreen mode Exit fullscreen mode

Output might show:

/usr/bin/python3
Enter fullscreen mode Exit fullscreen mode

This tells you where the Python interpreter is installed.

AWS Context: Lambda Execution Environments

AWS Lambda functions run in execution environments—essentially small Linux containers. When you deploy Python code to Lambda, AWS provides the Python interpreter. Your code runs as an interpreted program.

For performance-critical workloads, you can deploy compiled binaries as custom Lambda runtimes. A Go binary, for example, starts faster and uses less memory than interpreted Python.

Understanding this distinction helps you make architectural decisions. Need microsecond response times? Use compiled languages. Need rapid development? Interpreted languages work well.

Environment Variables and the PATH

Environment variables configure programs without hardcoding values. The PATH variable is the most important one you'll work with.

What is PATH?

PATH is an environment variable containing a colon-separated list of directories. When you run a command, your shell searches these directories for a matching executable.

Check your PATH:

$ echo $PATH
Enter fullscreen mode Exit fullscreen mode

You see something like:

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Enter fullscreen mode Exit fullscreen mode

This means the shell searches (in order):

  1. /usr/local/bin
  2. /usr/bin
  3. /bin
  4. /usr/sbin
  5. /sbin

When you type python3, the shell finds /usr/bin/python3 and executes it. You don't need to type the full path.

Adding to PATH

Programs you install often need to be added to PATH. To add a directory for the current session:

$ export PATH="$PATH:/home/achar/bin"
Enter fullscreen mode Exit fullscreen mode

This appends /home/achar/bin to your existing PATH. Programs in that directory are now accessible by name.

To make this permanent, add the export command to your shell configuration file:

  • bash: ~/.bashrc
  • zsh: ~/.zshrc

Edit the file:

$ nano ~/.zshrc
Enter fullscreen mode Exit fullscreen mode

Add at the end:

export PATH="$PATH:/home/achar/bin"
Enter fullscreen mode Exit fullscreen mode

Save and exit. New shell sessions will include this directory in PATH.

To apply changes to your current session:

$ source ~/.zshrc
Enter fullscreen mode Exit fullscreen mode

Creating Environment Variables

Set environment variables with export:

$ export DATABASE_URL="postgresql://localhost:5432/mydb"
Enter fullscreen mode Exit fullscreen mode

Programs can read this variable. In Python:

import os

db_url = os.getenv("DATABASE_URL")
print(f"Connecting to {db_url}")
Enter fullscreen mode Exit fullscreen mode

AWS Context: Lambda Environment Variables

Lambda functions use environment variables extensively. You set them in the AWS Console or via Infrastructure as Code:

# Lambda function code
import os
import boto3

bucket_name = os.getenv("S3_BUCKET_NAME")
s3 = boto3.client("s3")
Enter fullscreen mode Exit fullscreen mode

In your CloudFormation or Terraform configuration:

resource "aws_lambda_function" "processor" {
  function_name = "data-processor"

  environment {
    variables = {
      S3_BUCKET_NAME = "patient-records-bucket"
      LOG_LEVEL      = "INFO"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This pattern separates configuration from code—crucial for multi-environment deployments (dev, staging, production).

Healthcare Context: Secure Credentials

Never hardcode database passwords or API keys. Use environment variables:

$ export DB_PASSWORD="$(aws secretsmanager get-secret-value --secret-id prod-db --query SecretString --output text)"
Enter fullscreen mode Exit fullscreen mode

This retrieves a secret from AWS Secrets Manager and stores it in an environment variable. Your application reads it without ever exposing the password in source code.

For HIPAA compliance, audit all environment variable usage. Ensure sensitive values come from secure sources like Secrets Manager, not plaintext files.

Input, Output, and Streams

Programs communicate through three standard streams: standard input (stdin), standard output (stdout), and standard error (stderr).

Standard Output

When a program prints results, it writes to stdout. The echo command demonstrates this:

$ echo "Hello"
Enter fullscreen mode Exit fullscreen mode

The text appears in your terminal because stdout is directed there by default.

Redirecting Output

You can redirect stdout to a file with >:

$ echo "Log entry" > application.log
Enter fullscreen mode Exit fullscreen mode

This creates application.log with the content "Log entry". If the file exists, > overwrites it.

To append instead of overwriting, use >>:

$ echo "Another entry" >> application.log
Enter fullscreen mode Exit fullscreen mode

Standard Error

Programs write error messages to stderr, a separate stream from stdout. This separation lets you handle errors differently from regular output.

Most commands write errors to stderr:

$ ls nonexistent-directory
Enter fullscreen mode Exit fullscreen mode

You see an error message. To redirect stderr to a file:

$ ls nonexistent-directory 2> errors.log
Enter fullscreen mode Exit fullscreen mode

The 2> syntax redirects stderr (file descriptor 2). To redirect both stdout and stderr:

$ command > output.log 2> errors.log
Enter fullscreen mode Exit fullscreen mode

Or combine them into one file:

$ command > combined.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Standard Input

Programs can read from stdin. The read command in bash demonstrates this:

#!/bin/bash
echo "What is your name?"
read name
echo "Hello, $name"
Enter fullscreen mode Exit fullscreen mode

When you run this script, it waits for your input.

Piping

The pipe operator (|) connects stdout of one program to stdin of another:

$ cat application.log | grep "ERROR"
Enter fullscreen mode Exit fullscreen mode

This reads application.log, then filters lines containing "ERROR". Piping creates powerful command chains.

Find the 10 most common error messages:

$ grep "ERROR" application.log | sort | uniq -c | sort -rn | head -10
Enter fullscreen mode Exit fullscreen mode

Breaking this down:

  1. grep extracts error lines
  2. sort arranges them alphabetically
  3. uniq -c counts duplicates
  4. sort -rn sorts numerically in reverse
  5. head -10 shows the top 10

AWS Context: CloudWatch Logs

When your Lambda function writes to stdout, AWS captures it in CloudWatch Logs. Your Python code:

def lambda_handler(event, context):
    print(f"Processing event: {event}")
    return {"statusCode": 200}
Enter fullscreen mode Exit fullscreen mode

The print statement writes to stdout, which appears in CloudWatch:

$ aws logs tail /aws/lambda/my-function --follow
Enter fullscreen mode Exit fullscreen mode

Understanding stdout/stderr helps you design effective logging strategies. Errors should go to stderr, normal operation to stdout.

Package Managers

Package managers automate software installation, dependency resolution, and updates. They're essential for maintaining cloud infrastructure.

Linux: apt

On Ubuntu and Debian-based systems, use apt:

$ sudo apt update
Enter fullscreen mode Exit fullscreen mode

This refreshes the package index—the database of available software.

To install a package:

$ sudo apt install nginx
Enter fullscreen mode Exit fullscreen mode

This installs the Nginx web server, including all dependencies. The package manager:

  1. Downloads Nginx and its dependencies
  2. Installs everything in the correct locations
  3. Configures the system PATH
  4. Sets up systemd services (if applicable)

To remove a package:

$ sudo apt remove nginx
Enter fullscreen mode Exit fullscreen mode

macOS: Homebrew

On macOS, Homebrew is the de facto package manager:

$ brew install python3
Enter fullscreen mode Exit fullscreen mode

This installs Python 3 and adds it to your PATH automatically.

Update all installed packages:

$ brew upgrade
Enter fullscreen mode Exit fullscreen mode

Python: pip

Python has its own package manager:

$ pip install boto3
Enter fullscreen mode Exit fullscreen mode

This installs the AWS SDK for Python. Use requirements.txt to manage project dependencies:

boto3==1.26.137
requests==2.28.2
psycopg2-binary==2.9.5
Enter fullscreen mode Exit fullscreen mode

Install everything in the file:

$ pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

AWS Context: EC2 User Data

When launching EC2 instances, you can run initialization scripts via User Data. This often involves package managers:

#!/bin/bash
apt-get update
apt-get install -y nginx python3-pip
pip3 install boto3

# Configure application
systemctl enable nginx
systemctl start nginx
Enter fullscreen mode Exit fullscreen mode

This script runs when the instance first boots, installing dependencies and starting services.

Healthcare Context: Auditable Deployments

For HIPAA compliance, you need auditable deployment processes. Package managers help by:

  • Versioning dependencies explicitly
  • Creating reproducible environments
  • Tracking what's installed on each server

Your requirements.txt becomes part of your compliance documentation, proving exactly which software versions handle PHI.

Troubleshooting Framework

When something breaks—and it will—follow this systematic approach.

Step 1: Identify the Symptom

What's actually failing? Be specific:

  • "The application returns 502 errors"
  • "The database connection times out"
  • "The Lambda function exceeds memory limits"

Vague problems like "it doesn't work" waste time.

Step 2: Check the Logs

Logs contain most answers. For web servers:

$ tail -100 /var/log/nginx/error.log
Enter fullscreen mode Exit fullscreen mode

For application logs:

$ journalctl -u myapp.service -n 100
Enter fullscreen mode Exit fullscreen mode

For AWS services, check CloudWatch Logs:

$ aws logs tail /aws/lambda/my-function --since 10m
Enter fullscreen mode Exit fullscreen mode

Step 3: Verify Permissions

Permission issues cause many failures. Check file permissions:

$ ls -l /var/www/html/config.php
Enter fullscreen mode Exit fullscreen mode

Is the owner correct? Are permissions too restrictive?

Check your user's permissions:

$ groups
Enter fullscreen mode Exit fullscreen mode

Are you in the right groups?

Step 4: Test Connectivity

Network issues are common. Test connections:

$ curl https://api.example.com/health
Enter fullscreen mode Exit fullscreen mode

For databases:

$ telnet database.example.com 5432
Enter fullscreen mode Exit fullscreen mode

If the connection fails, check security groups, network ACLs, and firewall rules.

Step 5: Verify Environment Variables

Many issues stem from missing or incorrect environment variables:

$ echo $DATABASE_URL
Enter fullscreen mode Exit fullscreen mode

Is it set? Is it correct?

Step 6: Reproduce Locally

Try to replicate the issue on your development machine. If you can't reproduce it locally, the problem is environmental—likely configuration or permissions on the server.

Real-World Example: Deploying a Python Web Application

Let me walk through a complete deployment to an EC2 instance, demonstrating these concepts together.

Provision the Instance

Launch an Ubuntu 22.04 EC2 instance. Connect via SSH:

$ ssh -i keypair.pem ubuntu@ec2-xx-xx-xx-xx.compute-1.amazonaws.com
Enter fullscreen mode Exit fullscreen mode

Install Dependencies

Update package index:

$ sudo apt update
Enter fullscreen mode Exit fullscreen mode

Install Python and pip:

$ sudo apt install -y python3-pip python3-venv nginx
Enter fullscreen mode Exit fullscreen mode

Create Application Structure

Create a directory:

$ mkdir -p /home/ubuntu/myapp
$ cd /home/ubuntu/myapp
Enter fullscreen mode Exit fullscreen mode

Create a virtual environment:

$ python3 -m venv venv
$ source venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

Install Application Dependencies

Create requirements.txt:

flask==2.3.0
gunicorn==20.1.0
boto3==1.26.137
psycopg2-binary==2.9.5
Enter fullscreen mode Exit fullscreen mode

Install:

$ pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Configure Environment Variables

Create a .env file:

export DATABASE_URL="postgresql://user:password@db.example.com:5432/mydb"
export S3_BUCKET="patient-records-bucket"
export AWS_REGION="us-east-1"
Enter fullscreen mode Exit fullscreen mode

Load it:

$ source .env
Enter fullscreen mode Exit fullscreen mode

Create the Application

Write app.py:

from flask import Flask, jsonify
import boto3
import os

app = Flask(__name__)

s3 = boto3.client("s3", region_name=os.getenv("AWS_REGION"))
bucket = os.getenv("S3_BUCKET")

@app.route("/health")
def health():
    return jsonify({"status": "healthy"})

@app.route("/files")
def list_files():
    response = s3.list_objects_v2(Bucket=bucket, MaxKeys=10)
    files = [obj["Key"] for obj in response.get("Contents", [])]
    return jsonify({"files": files})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Test locally:

$ python app.py
Enter fullscreen mode Exit fullscreen mode

Open another terminal and test:

$ curl http://localhost:5000/health
Enter fullscreen mode Exit fullscreen mode

Configure Gunicorn

Create a systemd service file:

$ sudo nano /etc/systemd/system/myapp.service
Enter fullscreen mode Exit fullscreen mode

Add:

[Unit]
Description=My Flask Application
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/myapp
Environment="PATH=/home/ubuntu/myapp/venv/bin"
EnvironmentFile=/home/ubuntu/myapp/.env
ExecStart=/home/ubuntu/myapp/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:5000 app:app

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode

Enable and start:

$ sudo systemctl enable myapp
$ sudo systemctl start myapp
$ sudo systemctl status myapp
Enter fullscreen mode Exit fullscreen mode

Configure Nginx

Create Nginx configuration:

$ sudo nano /etc/nginx/sites-available/myapp
Enter fullscreen mode Exit fullscreen mode

Add:

server {
    listen 80;
    server_name _;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
Enter fullscreen mode Exit fullscreen mode

Enable the site:

$ sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
$ sudo nginx -t
$ sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Verify Deployment

Test from your local machine:

$ curl http://ec2-xx-xx-xx-xx.compute-1.amazonaws.com/health
Enter fullscreen mode Exit fullscreen mode

You should see:

{"status": "healthy"}
Enter fullscreen mode Exit fullscreen mode

Troubleshoot Issues

If it doesn't work, check logs:

$ sudo journalctl -u myapp -n 50
$ sudo tail -50 /var/log/nginx/error.log
Enter fullscreen mode Exit fullscreen mode

Common issues:

  • Permission denied: Check file permissions with ls -l
  • Connection refused: Verify Gunicorn is running with systemctl status myapp
  • 502 Bad Gateway: Nginx can't reach Gunicorn—check the proxy configuration

This workflow demonstrates terminals, shells, file navigation, permissions, environment variables, package management, and troubleshooting—all in a real deployment scenario.

Conclusion

The Linux command line is your primary interface to cloud infrastructure. You've learned:

  • How terminals and shells work
  • File system navigation and manipulation
  • Permission systems and their security implications
  • Program execution models
  • Environment variables and PATH management
  • Standard streams and piping
  • Package managers for dependency management
  • A systematic troubleshooting framework
  • Real-world deployment workflows

These skills transfer directly to AWS and other cloud platforms. Whether you're managing EC2 instances, debugging Lambda functions, or configuring ECS tasks, you'll use these commands daily.

For your AWS certification preparation, practice these commands in real cloud environments. Spin up EC2 instances, SSH in, and deploy applications. The command line becomes intuitive through repetition.

As you build HIPAA-compliant healthcare systems, remember that proper file permissions, secure environment variable management, and auditable deployments start with solid Linux fundamentals.

The command line is the foundation of modern cloud engineering.

Top comments (0)