Batch 4: Cloud Ansible AWS & Azure Docker Apache & NGINX ← Full TOC

☁ Chapter 37 — Cloud Computing

Complete cloud computing reference covering IaaS/PaaS/SaaS, VPC networking, IAM security, compute, storage, monitoring, and cost management for AWS, Azure, and GCP.
Part of The Direct Path to Linux Ubuntu — free for all.

4Topics
95+Concepts
5Examples
aws cliTool
AWS/Azure/GCPProviders
FreeNo login
☁️ Cloud Fundamentals 💻 Compute & Storage 📊 Monitoring & Cost 🔒 Cloud Security ⚡ Examples

☁️ Cloud Fundamentals

☁️ Cloud FundamentalsIaaS, PaaS, SaaS, regions, availability zones, VPC

💻 Compute & Storage

💻 Compute & StorageVirtual machines, serverless, object storage, block storage

📊 Monitoring & Cost

📊 Cloud Monitoring & CostCloudWatch, Cost Explorer, tagging, rightsizing

🔒 Cloud Security

🔒 Cloud SecurityIAM, encryption, compliance, security best practices

⚡ Quick Examples

Install AWS CLI: pip install awscli && aws configure. Python SDK: pip install boto3.

AWS CLI Quick Reference

Most-used AWS CLI commands for daily cloud work.

# ── AWS CLI setup ────────────────────────────────────────────
pip install awscli
aws configure
# Enter: Access Key ID, Secret Access Key, Region (us-east-1), Output (json)

# ── Identity ─────────────────────────────────────────────────
aws sts get-caller-identity          # who am I?
aws iam list-users                   # list IAM users
aws iam list-roles                   # list IAM roles

# ── EC2 ──────────────────────────────────────────────────────
aws ec2 describe-instances --output table
aws ec2 describe-instances --filters Name=instance-state-name,Values=running
aws ec2 start-instances    --instance-ids i-xxx
aws ec2 stop-instances     --instance-ids i-xxx
aws ec2 describe-security-groups
aws ec2 describe-vpcs

# ── S3 ───────────────────────────────────────────────────────
aws s3 ls                            # list all buckets
aws s3 ls s3://mybucket/             # list bucket contents
aws s3 cp file.txt s3://mybucket/    # upload file
aws s3 cp s3://mybucket/file.txt ./  # download file
aws s3 sync ./local/ s3://mybucket/  # sync folder
aws s3 rm s3://mybucket/file.txt     # delete file
aws s3 mb s3://new-bucket-name       # create bucket

# ── Lambda ───────────────────────────────────────────────────
aws lambda list-functions
aws lambda invoke --function-name MyFunc --payload '{}' out.json
aws lambda get-function --function-name MyFunc
aws lambda update-function-code --function-name MyFunc --zip-file fileb://func.zip

# ── RDS ──────────────────────────────────────────────────────
aws rds describe-db-instances
aws rds start-db-instance  --db-instance-identifier mydb
aws rds stop-db-instance   --db-instance-identifier mydb
aws rds create-db-snapshot --db-instance-identifier mydb --db-snapshot-identifier snap1

# ── Cost ─────────────────────────────────────────────────────
aws ce get-cost-and-usage \
  --time-period Start=2026-06-01,End=2026-07-01 \
  --granularity MONTHLY --metrics BlendedCost

# ── CloudWatch ───────────────────────────────────────────────
aws cloudwatch list-metrics --namespace AWS/EC2
aws cloudwatch describe-alarms --state-value ALARM
aws logs describe-log-groups

Python boto3 — AWS SDK

Automate AWS with the Python boto3 library.

# pip install boto3
import boto3
import json
from datetime import datetime, timedelta

# ── S3 Operations ─────────────────────────────────────────────
s3 = boto3.client('s3', region_name='us-east-1')

# List buckets
response = s3.list_buckets()
print("Buckets:", [b['Name'] for b in response['Buckets']])

# Upload file
s3.upload_file('index.html', 'mywebuniversity-content', 'index.html',
    ExtraArgs={'ContentType': 'text/html', 'CacheControl': 'max-age=86400'})
print("Uploaded index.html")

# Generate pre-signed URL (time-limited access)
url = s3.generate_presigned_url('get_object',
    Params={'Bucket': 'mywebuniversity-content', 'Key': 'private-doc.pdf'},
    ExpiresIn=3600)
print(f"Pre-signed URL (1hr): {url[:60]}...")

# ── EC2 Operations ────────────────────────────────────────────
ec2 = boto3.resource('ec2', region_name='us-east-1')

# List running instances
instances = ec2.instances.filter(
    Filters=[{'Name': 'instance-state-name', 'Values': ['running']}])
for i in instances:
    name = next((t['Value'] for t in (i.tags or []) if t['Key']=='Name'), 'unnamed')
    print(f"  {i.id:22} {i.instance_type:12} {i.public_ip_address:16} {name}")

# ── Lambda Invocation ─────────────────────────────────────────
lam = boto3.client('lambda', region_name='us-east-1')
response = lam.invoke(
    FunctionName='MyWebUniversityAPI',
    InvocationType='RequestResponse',
    Payload=json.dumps({'path': '/courses', 'method': 'GET'})
)
result = json.loads(response['Payload'].read())
print("Lambda response:", result)

# ── SSM Parameter Store ───────────────────────────────────────
ssm = boto3.client('ssm', region_name='us-east-1')
# Put parameter
ssm.put_parameter(
    Name='/mywebuniversity/prod/db-host',
    Value='db.mywebuniversity.com',
    Type='String',
    Overwrite=True)
# Get parameter
param = ssm.get_parameter(Name='/mywebuniversity/prod/db-host')
print("DB Host:", param['Parameter']['Value'])

# ── Cost Explorer ─────────────────────────────────────────────
ce = boto3.client('ce', region_name='us-east-1')
end   = datetime.now().strftime('%Y-%m-%d')
start = (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d')
costs = ce.get_cost_and_usage(
    TimePeriod={'Start': start, 'End': end},
    Granularity='MONTHLY',
    Metrics=['BlendedCost'],
    GroupBy=[{'Type': 'DIMENSION', 'Key': 'SERVICE'}]
)
for group in sorted(costs['ResultsByTime'][0]['Groups'],
                    key=lambda x: float(x['Metrics']['BlendedCost']['Amount']),
                    reverse=True)[:5]:
    print(f"  {group['Keys'][0]:40} ${float(group['Metrics']['BlendedCost']['Amount']):>8.2f}")

# python3 boto3_demo.py

Cloud Architecture Terraform

Infrastructure as Code with Terraform for AWS.

# main.tf — AWS VPC + EC2 + S3 with Terraform
# Install: https://developer.hashicorp.com/terraform/downloads
# Usage: terraform init && terraform plan && terraform apply

terraform {
  required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
  }
}

provider "aws" {
  region = var.aws_region
}

variable "aws_region"   { default = "us-east-1" }
variable "project_name" { default = "mywebuniversity" }
variable "environment"  { default = "production" }

# ── VPC ──────────────────────────────────────────────────────
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true
  tags = { Name = "${var.project_name}-vpc", Environment = var.environment }
}

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
  tags = { Name = "${var.project_name}-igw" }
}

resource "aws_subnet" "public" {
  count             = 2
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index + 1}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true
  tags = { Name = "${var.project_name}-public-${count.index + 1}" }
}

data "aws_availability_zones" "available" { state = "available" }

# ── Security Group ────────────────────────────────────────────
resource "aws_security_group" "web" {
  name   = "${var.project_name}-web-sg"
  vpc_id = aws_vpc.main.id

  ingress { from_port=443; to_port=443; protocol="tcp"; cidr_blocks=["0.0.0.0/0"] }
  ingress { from_port=80;  to_port=80;  protocol="tcp"; cidr_blocks=["0.0.0.0/0"] }
  ingress { from_port=22;  to_port=22;  protocol="tcp"; cidr_blocks=["10.0.0.0/8"] }
  egress  { from_port=0;   to_port=0;   protocol="-1";  cidr_blocks=["0.0.0.0/0"] }
  tags = { Name = "${var.project_name}-web-sg" }
}

# ── EC2 Instance ─────────────────────────────────────────────
data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"]  # Canonical
  filter { name = "name";                values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"] }
  filter { name = "virtualization-type"; values = ["hvm"] }
}

resource "aws_instance" "web" {
  ami                    = data.aws_ami.ubuntu.id
  instance_type          = "t3.micro"
  subnet_id              = aws_subnet.public[0].id
  vpc_security_group_ids = [aws_security_group.web.id]

  user_data = <<-EOF
    #!/bin/bash
    apt-get update && apt-get install -y apache2 python3
    systemctl enable apache2 && systemctl start apache2
  EOF

  tags = { Name = "${var.project_name}-web", Environment = var.environment }
}

# ── S3 Bucket ─────────────────────────────────────────────────
resource "aws_s3_bucket" "content" {
  bucket = "${var.project_name}-content-${random_id.suffix.hex}"
  tags   = { Name = "${var.project_name}-content", Environment = var.environment }
}

resource "random_id" "suffix" { byte_length = 4 }

resource "aws_s3_bucket_versioning" "content" {
  bucket = aws_s3_bucket.content.id
  versioning_configuration { status = "Enabled" }
}

# ── Outputs ───────────────────────────────────────────────────
output "web_public_ip" { value = aws_instance.web.public_ip }
output "s3_bucket"     { value = aws_s3_bucket.content.bucket }

# Commands:
# terraform init    # download providers
# terraform plan    # preview changes
# terraform apply   # create resources
# terraform destroy # delete all resources

Multi-Cloud Comparison

AWS vs Azure vs GCP — equivalent services.

# Multi-Cloud Service Equivalents
# AWS                     Azure                    GCP
# ─────────────────────────────────────────────────────────────

# ── Compute ──────────────────────────────────────────────────
# EC2                     Azure VMs                Compute Engine
# Lambda                  Azure Functions          Cloud Functions
# ECS/Fargate             Container Instances      Cloud Run
# EKS                     AKS                      GKE
# Elastic Beanstalk       App Service              App Engine
# Lightsail               (no direct equiv)        (no direct equiv)
# Batch                   Azure Batch              Cloud Batch

# ── Storage ──────────────────────────────────────────────────
# S3                      Azure Blob Storage       Cloud Storage
# EBS                     Azure Managed Disks      Persistent Disk
# EFS                     Azure Files              Filestore
# S3 Glacier              Azure Archive Storage    Cloud Storage Archive
# Storage Gateway         Azure StorSimple         Transfer Service

# ── Databases ────────────────────────────────────────────────
# RDS (MySQL/PG/Oracle)   Azure Database           Cloud SQL
# Aurora                  Azure Database Flex      AlloyDB
# DynamoDB                Cosmos DB                Firestore / Bigtable
# ElastiCache (Redis)     Azure Cache for Redis    Memorystore
# Redshift                Azure Synapse            BigQuery
# DocumentDB              Cosmos DB (Mongo API)    Firestore

# ── Networking ───────────────────────────────────────────────
# VPC                     Virtual Network (VNet)   VPC
# Subnet                  Subnet                   Subnet
# Internet Gateway        (built-in)               Cloud Router
# NAT Gateway             NAT Gateway              Cloud NAT
# Route 53 (DNS)          Azure DNS                Cloud DNS
# CloudFront (CDN)        Azure CDN / Front Door   Cloud CDN
# ALB/NLB                 Azure Load Balancer      Cloud Load Balancing
# API Gateway             API Management           Cloud Endpoints / Apigee
# Direct Connect          ExpressRoute             Cloud Interconnect
# VPN Gateway             VPN Gateway              Cloud VPN

# ── Security & Identity ──────────────────────────────────────
# IAM                     Azure AD / Entra ID      Cloud IAM
# KMS                     Key Vault                Cloud KMS
# Secrets Manager         Key Vault Secrets        Secret Manager
# WAF                     WAF                      Cloud Armor
# GuardDuty               Defender for Cloud       Security Command Center
# CloudTrail              Activity Log             Cloud Audit Logs
# Config                  Policy                   Asset Inventory

# ── DevOps ───────────────────────────────────────────────────
# CodePipeline            Azure DevOps Pipelines   Cloud Build
# CodeBuild               Azure DevOps Build       Cloud Build
# ECR                     Azure Container Registry  Artifact Registry
# CloudFormation          ARM Templates / Bicep    Deployment Manager
# Systems Manager         Azure Automation         Cloud Shell / OS Config

# ── CLI Commands ─────────────────────────────────────────────
# AWS:   aws ec2 describe-instances
# Azure: az vm list
# GCP:   gcloud compute instances list

# Azure CLI setup
az login
az account list --output table
az group create --name mywebuniversity-rg --location eastus
az vm create --resource-group mywebuniversity-rg \
  --name webserver --image UbuntuLTS \
  --size Standard_B1s --generate-ssh-keys

# GCP CLI (gcloud) setup
gcloud auth login
gcloud config set project my-project-id
gcloud compute instances create webserver \
  --zone=us-east1-b --machine-type=e2-micro \
  --image-family=ubuntu-2204-lts --image-project=ubuntu-os-cloud

Serverless Architecture

Event-driven serverless patterns with AWS Lambda.

# Serverless Architecture — AWS Lambda patterns
# pip install boto3

# ── Lambda Function: REST API ─────────────────────────────────
# lambda_function.py
import json
import os
import boto3
from datetime import datetime

dynamodb = boto3.resource('dynamodb')
table    = dynamodb.Table(os.environ.get('TABLE_NAME', 'courses'))

def lambda_handler(event, context):
    method   = event.get('httpMethod', 'GET')
    path     = event.get('path', '/')
    path_params = event.get('pathParameters') or {}
    body     = json.loads(event.get('body') or '{}')

    try:
        if method == 'GET' and path == '/courses':
            result = table.scan()
            return response(200, result['Items'])

        elif method == 'GET' and path_params.get('id'):
            result = table.get_item(Key={'id': path_params['id']})
            if 'Item' not in result:
                return response(404, {'error': 'Course not found'})
            return response(200, result['Item'])

        elif method == 'POST' and path == '/courses':
            import uuid
            item = {
                'id':         str(uuid.uuid4()),
                'title':      body['title'],
                'instructor': body.get('instructor', 'TBD'),
                'credits':    body.get('credits', 3),
                'created':    datetime.utcnow().isoformat(),
            }
            table.put_item(Item=item)
            return response(201, item)

        elif method == 'DELETE' and path_params.get('id'):
            table.delete_item(Key={'id': path_params['id']})
            return response(204, {})

        else:
            return response(404, {'error': f'Not found: {method} {path}'})

    except Exception as e:
        print(f"Error: {e}")
        return response(500, {'error': str(e)})

def response(status_code, body):
    return {
        'statusCode': status_code,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*',
        },
        'body': json.dumps(body, default=str)
    }

# ── Deploy with SAM (Serverless Application Model) ────────────
# template.yaml
sam_template = '''
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
  Function:
    Timeout: 30
    Runtime: python3.12
    Environment:
      Variables:
        TABLE_NAME: !Ref CoursesTable

Resources:
  CoursesFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./
      Handler: lambda_function.lambda_handler
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref CoursesTable
      Events:
        GetCourses:
          Type: Api
          Properties:
            Path: /courses
            Method: get
        CreateCourse:
          Type: Api
          Properties:
            Path: /courses
            Method: post
        GetCourse:
          Type: Api
          Properties:
            Path: /courses/{id}
            Method: get
        DeleteCourse:
          Type: Api
          Properties:
            Path: /courses/{id}
            Method: delete

  CoursesTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: courses
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH

Outputs:
  ApiUrl:
    Value: !Sub https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/
'''
print(sam_template)
# sam build && sam deploy --guided
# curl https://abc123.execute-api.us-east-1.amazonaws.com/Prod/courses