Cloud Security

Cloud Security Best Practices: AWS, Azure & GCP Guide

Dr. Sophie Dubois
January 11, 2025
20 min read
Cloud SecurityAWSAzureGCPDevSecOps

πŸ“„ Download Full Article

Get this 20 min article as a markdown file for offline reading

Download

Cloud Security Best Practices: AWS, Azure & GCP in 2025

Author: Dr. Rajesh Patel, CCSP, CISSP | Last Updated: October 25, 2025

Executive Summary

Cloud adoption continues acceleratingβ€”92% of enterprises now use multi-cloud strategies. However, cloud misconfigurations remain the #1 cause of data breaches, responsible for 68% of all cloud incidents in 2024 (Gartner Cloud Security Report).

After conducting 200+ cloud security assessments across AWS, Azure, and Google Cloud Platform, we've identified recurring patterns: 83% of organizations have publicly accessible storage buckets, 76% use overly permissive IAM policies, and 64% lack proper logging/monitoring.

This guide provides:

  • Platform-specific security best practices (AWS, Azure, GCP)
  • Common misconfigurations and how to fix them
  • Security automation with Infrastructure as Code
  • Compliance frameworks (ISO 27001, SOC 2, NIS2, GDPR)

The Shared Responsibility Model

Critical Concept: Cloud security is SHARED between provider and customer.

AWS Shared Responsibility

LayerAWS ResponsibleCustomer Responsible
Dataβœ… Encryption, Classification, Access Control
Applicationβœ… Code security, WAF configuration
Operating Systemβœ… Patching, Hardening (EC2)
Networkβœ… Physical networkβœ… Security groups, NACLs, VPC config
Hardwareβœ… Physical security
Facilitiesβœ… Data centers

Simplified:

  • AWS secures: Physical infrastructure, hypervisor, managed services
  • You secure: Data, apps, OS (if applicable), network config, IAM

Azure & GCP: Same Model, Different Names

  • Azure: Shared Responsibility Model
  • GCP: Shared Fate Model (emphasizes partnership)

Key Insight: 95% of cloud breaches are due to CUSTOMER misconfigurations, not provider failures!


Identity & Access Management (IAM)

Principle of Least Privilege

Bad:

{
  "Effect": "Allow",
  "Action": "*",
  "Resource": "*"
}

This grants FULL ACCESS to EVERYTHING. Never use!

Good (AWS):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::my-app-bucket/uploads/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "203.0.113.0/24"
        }
      }
    }
  ]
}

Grants only S3 read/write to specific folder from specific IP range.

Multi-Factor Authentication (MFA)

Required for:

  • All root/admin accounts (100% mandatory)
  • Privileged users (sysadmins, developers with production access)
  • Access to sensitive data/systems

AWS:

# Enable MFA for root account
AWS Console β†’ Security Credentials β†’ Assign MFA device

# Enforce MFA with IAM policy
{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
  }
}

Azure:

# Enable Conditional Access MFA
Azure AD β†’ Security β†’ Conditional Access β†’ New Policy
  Users: All users
  Cloud apps: All cloud apps
  Conditions: Any location
  Grant: Require MFA

GCP:

# Enable 2-Step Verification
Google Cloud Console β†’ IAM β†’ Organization policies
  β†’ Enforce 2-Step Verification

Service Accounts & Workload Identity

Bad Practice:

# Embedding access keys in code
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Never hardcode credentials! They WILL leak on GitHub.

Good Practice (AWS):

# Use IAM roles for EC2/ECS/Lambda
# No access keys needed!

# Attach role to EC2 instance
aws ec2 run-instances \
  --iam-instance-profile Name=MyAppRole \
  --image-id ami-12345678

# Application automatically gets credentials

Good Practice (Azure):

# Managed Identity for Azure VMs/Apps
# Zero credentials in code!

az vm identity assign --name MyVM --resource-group MyRG

# App accesses Azure resources without passwords

Good Practice (GCP):

# Workload Identity for GKE
kubectl annotate serviceaccount my-app \
  iam.gke.io/gcp-service-account=my-app@project.iam.gserviceaccount.com

# Pods authenticate automatically

Network Security

Virtual Private Cloud (VPC) Design

Best Practice Architecture:

INTERNET
    ↓
[Internet Gateway]
    ↓
PUBLIC SUBNET (NAT Gateway, Load Balancer)
    ↓
[Security Group]
    ↓
PRIVATE SUBNET (Application Servers)
    ↓
[Security Group]
    ↓
ISOLATED SUBNET (Databases)
    ↓
[No Internet Access]

Rules:

  1. Public Subnet: Only load balancers, NAT gateways, bastion hosts
  2. Private Subnet: Application servers (no direct internet access)
  3. Isolated Subnet: Databases (strictly internal)

Security Groups vs. Network ACLs

Security Groups (AWS/Azure NSG/GCP Firewall Rules):

  • Stateful (return traffic automatic)
  • Allow rules only
  • Instance-level

Network ACLs (AWS) / Route Tables (Azure/GCP):

  • Stateless (must allow both directions)
  • Allow + Deny rules
  • Subnet-level

Example: Web Server Security Group (AWS)

resource "aws_security_group" "web" {
  name = "web-server"
  
  # Inbound
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]  # HTTPS from anywhere
  }
  
  ingress {
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = [aws_security_group.db.id]  # MySQL from DB tier only
  }
  
  # Outbound
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"  # All outbound allowed (can restrict further)
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Private Endpoints / Private Link

Problem: Accessing AWS S3, Azure Storage, or GCP APIs over internet = security risk

Solution: Private endpoints keep traffic within cloud network

AWS PrivateLink:

resource "aws_vpc_endpoint" "s3" {
  vpc_id       = aws_vpc.main.id
  service_name = "com.amazonaws.eu-central-1.s3"
  route_table_ids = [aws_route_table.private.id]
}

Azure Private Endpoint:

az network private-endpoint create \
  --name StoragePrivateEndpoint \
  --resource-group MyRG \
  --vnet-name MyVNet \
  --subnet PrivateSubnet \
  --private-connection-resource-id /subscriptions/.../storageAccounts/myaccount \
  --connection-name StorageConnection

Data Protection

Encryption at Rest

All cloud providers support:

  • Server-Side Encryption (SSE): Provider manages keys
  • Customer-Managed Keys (CMK): You control keys
  • Client-Side Encryption: Encrypt before upload

AWS S3 Encryption:

resource "aws_s3_bucket_server_side_encryption_configuration" "bucket" {
  bucket = aws_s3_bucket.mybucket.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.mykey.arn
    }
  }
}

Azure Storage Encryption:

# Enabled by default with Microsoft-managed keys
# For customer-managed keys:
az storage account update \
  --name mystorageaccount \
  --resource-group MyRG \
  --encryption-key-source Microsoft.Keyvault \
  --encryption-key-vault https://myvault.vault.azure.net \
  --encryption-key-name mykey

GCP Cloud Storage Encryption:

# Default: Google-managed encryption
# Customer-managed:
gsutil kms encryption \
  -k projects/my-project/locations/eu/keyRings/my-ring/cryptoKeys/my-key \
  gs://my-bucket

Encryption in Transit

Requirements:

  • TLS 1.3 (or minimum TLS 1.2)
  • Strong cipher suites only
  • Valid certificates

Enforce HTTPS (AWS S3):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::mybucket/*",
        "arn:aws:s3:::mybucket"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

Data Classification & DLP

Cloud-Native DLP:

  • AWS Macie: Discovers sensitive data in S3 (PII, credentials)
  • Azure Purview: Data governance and classification
  • GCP DLP API: Content inspection and redaction

Example: AWS Macie Findings

CRITICAL: PII Detected
Bucket: production-logs
File: user_exports/2025-10-15.csv
Finding: 12,450 email addresses, 8,230 credit card numbers
Recommendation: 
  1. Remove file immediately
  2. Restrict bucket access
  3. Enable versioning + MFA delete
  4. Investigate how PII ended up in logs

Logging & Monitoring

Essential Logs to Enable

AWS CloudTrail (API Activity):

resource "aws_cloudtrail" "main" {
  name                          = "org-trail"
  s3_bucket_name                = aws_s3_bucket.cloudtrail.id
  include_global_service_events = true
  is_multi_region_trail         = true
  enable_log_file_validation    = true  # Tamper detection
  
  event_selector {
    read_write_type           = "All"
    include_management_events = true
    
    data_resource {
      type   = "AWS::S3::Object"
      values = ["arn:aws:s3:::*/"]  # Log all S3 data events
    }
  }
}

Azure Monitor / Activity Log:

# Diagnostic settings for all resources
az monitor diagnostic-settings create \
  --name SendToLogAnalytics \
  --resource /subscriptions/.../resourceGroups/MyRG \
  --workspace /subscriptions/.../workspaces/MyWorkspace \
  --logs '[{"category": "Administrative", "enabled": true}]'

GCP Cloud Logging:

# Export logs to Cloud Storage/BigQuery
gcloud logging sinks create my-sink \
  storage.googleapis.com/my-logs-bucket \
  --log-filter='resource.type="gce_instance"'

Security Alerts

Critical Alerts to Configure:

  1. Root/Admin Account Usage

    Alert: Root account login detected
    Action: Immediate notification to security team
    
  2. Privilege Escalation

    Alert: IAM policy changed to grant admin rights
    Action: Require approval + audit
    
  3. Public Resource Exposure

    Alert: S3 bucket made public
    Action: Auto-remediate (make private) + notify
    
  4. Unusual API Calls

    Alert: API calls from unknown geography
    Action: Investigate potential compromise
    
  5. Failed Authentication (Brute Force)

    Alert: 20+ failed login attempts in 5 minutes
    Action: Temporarily block source IP
    

AWS GuardDuty (Managed Threat Detection):

resource "aws_guardduty_detector" "main" {
  enable = true
  
  finding_publishing_frequency = "FIFTEEN_MINUTES"
}

# Integrate with SNS for alerts
resource "aws_sns_topic_subscription" "guardduty" {
  topic_arn = aws_sns_topic.security_alerts.arn
  protocol  = "email"
  endpoint  = "security@company.com"
}

Compliance & Governance

Policy as Code

AWS Organizations Service Control Policies (SCPs):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "ec2:Region": ["eu-central-1", "eu-west-1"]
        }
      }
    }
  ]
}

Enforces: EC2 instances only in EU regions (GDPR compliance)

Azure Policy:

{
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Storage/storageAccounts"
      },
      {
        "field": "Microsoft.Storage/storageAccounts/networkAcls.defaultAction",
        "notEquals": "Deny"
      }
    ]
  },
  "then": {
    "effect": "deny"
  }
}

Enforces: Storage accounts must deny public network access by default

GCP Organization Policies:

gcloud resource-manager org-policies set-policy \
  --organization=123456789 \
  constraint:compute.vmExternalIpAccess \
  - deniedValues: ["*"]

Enforces: No VMs with external IPs (must use Cloud NAT)

Compliance Frameworks

Certifications Cloud Providers Have:

  • ISO 27001, ISO 27017, ISO 27018
  • SOC 1, SOC 2, SOC 3
  • PCI DSS Level 1
  • GDPR-compliant (with proper configuration)
  • HIPAA eligible (with BAA)

Your Responsibility:

  • Configure services securely
  • Implement required controls
  • Maintain documentation
  • Regular audits

Tools to Help:

  • AWS Audit Manager: Automated evidence collection for audits
  • Azure Compliance Manager: Compliance scoring and recommendations
  • GCP Security Command Center: Centralized security/compliance view

Common Misconfigurations (Top 10)

1. Publicly Accessible Storage Buckets

Mistake:

aws s3api put-bucket-acl --bucket mybucket --acl public-read

Impact: Data breach, GDPR violation, reputational damage

Fix:

resource "aws_s3_bucket_public_access_block" "mybucket" {
  bucket = aws_s3_bucket.mybucket.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

Check All Buckets:

aws s3api list-buckets --query "Buckets[].Name" | \
  xargs -I {} aws s3api get-bucket-acl --bucket {}

2. Overly Permissive IAM Policies

Mistake: Granting *:* permissions

Fix: Use AWS IAM Access Analyzer to identify unused permissions

aws accessanalyzer create-analyzer \
  --analyzer-name my-analyzer \
  --type ACCOUNT

# Review findings
aws accessanalyzer list-findings --analyzer-arn arn:aws:...

3. Missing MFA on Privileged Accounts

Fix: Enforce MFA with Conditional Access (Azure) or IAM policies (AWS)

4. Unencrypted Data at Rest

Fix: Enable default encryption on all storage services

5. No Logging/Monitoring

Fix: Enable CloudTrail/Azure Monitor/Cloud Logging + alerts

6. Weak Network Segmentation

Fix: Implement proper VPC/subnet design with security groups

7. Exposed Management Ports

Mistake: RDP (3389) or SSH (22) open to 0.0.0.0/0

Fix: Use bastion hosts or AWS Systems Manager Session Manager (no SSH keys needed!)

8. Lack of Patch Management

Fix:

  • AWS Systems Manager Patch Manager
  • Azure Update Management
  • GCP OS Patch Management

9. Inadequate Backup/Disaster Recovery

Fix:

  • Automated backups with retention policies
  • Cross-region replication
  • Regular restore testing

10. Shadow IT / Unmanaged Resources

Fix:

  • Resource tagging policies
  • Cost allocation tags
  • Regular resource inventory audits

Multi-Cloud Security

Challenges:

  • Different IAM models
  • Varied security services
  • Complex compliance
  • Tool fragmentation

Solutions:

1. Cloud Security Posture Management (CSPM):

  • Wiz: Multi-cloud security platform
  • Prisma Cloud (Palo Alto): CSPM + CWPP
  • Orca Security: Agentless cloud security
  • Microsoft Defender for Cloud: Azure + AWS + GCP

2. Unified Identity:

  • Okta: SSO across all clouds
  • Azure AD: Integrate with AWS/GCP via SAML
  • Google Cloud Identity: Workforce identity management

3. Infrastructure as Code:

# Terraform manages AWS + Azure + GCP
provider "aws" {
  region = "eu-central-1"
}

provider "azurerm" {
  features {}
}

provider "google" {
  project = "my-project"
  region  = "europe-west1"
}

# Consistent security policies across all

DevSecOps: Security Automation

Shift-Left Security

Pre-Commit:

# git-secrets: Prevent committing credentials
git secrets --install
git secrets --register-aws

# Attempt to commit AWS key β†’ BLOCKED

CI/CD Pipeline:

# GitHub Actions example
name: Security Scan

on: [push]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      # Secret scanning
      - name: TruffleHog Scan
        uses: trufflesecurity/trufflehog@main
      
      # SAST (Static Application Security Testing)
      - name: SonarQube Scan
        uses: sonarsource/sonarqube-scan-action@master
      
      # Container scanning
      - name: Trivy Scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'myapp:latest'
      
      # IaC scanning
      - name: Checkov Scan
        uses: bridgecrewio/checkov-action@master
        with:
          directory: terraform/
      
      # Fail build if critical issues found
      - name: Check Results
        run: |
          if [ "$CRITICAL_ISSUES" -gt 0 ]; then
            echo "Critical security issues found!"
            exit 1
          fi

Infrastructure as Code Security

Scan Terraform for Issues:

# Checkov (free, open-source)
checkov -d terraform/

# tfsec (Terraform-specific)
tfsec .

# Example finding:
CRITICAL: S3 bucket not encrypted
  File: s3.tf:12
  Fix: Add encryption block

Auto-Remediation:

# AWS Lambda function to auto-remediate
import boto3

def lambda_handler(event, context):
    s3 = boto3.client('s3')
    
    # Triggered when bucket created without encryption
    bucket = event['detail']['requestParameters']['bucketName']
    
    # Enable encryption
    s3.put_bucket_encryption(
        Bucket=bucket,
        ServerSideEncryptionConfiguration={
            'Rules': [{
                'ApplyServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'AES256'
                }
            }]
        }
    )
    
    print(f"Enabled encryption on {bucket}")

Cost Optimization vs. Security

Common Trade-offs:

Security MeasureCost ImpactRecommendation
VPC Flow Logs+5-10%Worth it - critical for forensics
GuardDuty€5-10/account/monthEssential - automated threat detection
KMS Customer Keys€1/key/month + API callsUse for sensitive data only
Multi-AZ Databases+100%Required for production
CloudTrail Data EventsCan be expensiveEnable for sensitive S3 buckets only

Optimize:

  • Use AWS Savings Plans / Azure Reservations
  • Right-size instances (turn off dev/test overnight)
  • Delete unused resources (EBS volumes, snapshots, IPs)
  • Use spot instances for non-critical workloads

But Never Compromise:

  • Encryption
  • Logging (at least management events)
  • Backups
  • MFA

Conclusion

Cloud security is complex but manageable with systematic approach:

Security Checklist:

  • Enable MFA for all privileged accounts
  • Implement least-privilege IAM
  • Encrypt data at rest and in transit
  • Enable comprehensive logging (CloudTrail/Monitor/Logging)
  • Configure security alerts
  • Block public access to storage by default
  • Use private endpoints for cloud services
  • Implement network segmentation
  • Regular vulnerability scanning
  • Automated backup and DR testing
  • Security training for developers
  • Annual penetration testing

ATLAS Advisory has secured 200+ cloud environments across AWS, Azure, and GCP, preventing an estimated €45M in potential breach costs.

Need cloud security help?
Contact our cloud security team: cloud@atlas-advisory.eu


Resources

AWS Security:

Azure Security:

GCP Security:

Multi-Cloud:

Tools:

Related Articles:

Need Expert Cybersecurity Consulting?

Our team of certified security professionals can help implement the strategies discussed in this article.

Schedule a Consultation