# Fichier: python_cheats/cheatsheets/VPC.txt
# Cheatsheet AWS VPC - Virtual Private Cloud Expliqué en Détail


═══════════════════════════════════════════════════════════════════════════════
[OK] AWS VPC - C'EST QUOI?
═══════════════════════════════════════════════════════════════════════════════

VPC = Virtual Private Cloud = "Votre propre réseau privé dans AWS"

ANALOGIE SIMPLE:
- VPC = Votre maison avec plusieurs pièces
- Subnets = Les pièces de la maison
- Internet Gateway = La porte d'entrée principale
- NAT Gateway = Une porte de service (sortie seulement)
- Security Groups = Gardes de sécurité à chaque porte
- Route Tables = Panneaux d'indication pour le trafic

POURQUOI UTILISER VPC?
[OK] Isoler vos ressources AWS (sécurité)
[OK] Contrôler le trafic réseau (qui peut communiquer avec qui)
[OK] Connecter votre datacenter on-premise à AWS
[OK] Organiser resources par environnement (prod, dev, staging)
[OK] Respecter conformité (données sensibles isolées)

COMPOSANTS PRINCIPAUX:
1. VPC -> Le réseau global
2. Subnets -> Sous-réseaux (public ou privé)
3. Internet Gateway -> Accès Internet
4. NAT Gateway -> Internet sortant pour subnets privés
5. Route Tables -> Règles de routage
6. Security Groups -> Firewall instances
7. Network ACLs -> Firewall subnets

CIDR (Classless Inter-Domain Routing):
= Format pour définir plages d'adresses IP
= Exemple: 10.0.0.0/16
  * 10.0.0.0 = adresse de base
  * /16 = taille du réseau (16 bits fixes)
  * Résultat: 10.0.0.0 à 10.0.255.255 (65,536 adresses)

PLAGES CIDR COMMUNES:
- /16 = 65,536 adresses (ex: 10.0.0.0/16)
- /24 = 256 adresses (ex: 10.0.1.0/24)
- /28 = 16 adresses (ex: 10.0.1.0/28)
- /32 = 1 adresse (ex: 10.0.1.5/32)

PLAGES IP PRIVÉES (RFC 1918):
- 10.0.0.0/8 (10.0.0.0 -> 10.255.255.255)
- 172.16.0.0/12 (172.16.0.0 -> 172.31.255.255)
- 192.168.0.0/16 (192.168.0.0 -> 192.168.255.255)

DIFFÉRENCE PUBLIC vs PRIVÉ:
- PUBLIC = Accessible depuis Internet (avec IP publique)
- PRIVÉ = Accessible seulement dans VPC (pas d'IP publique)


═══════════════════════════════════════════════════════════════════════════════
[OK] CRÉER VPC - EXPLICATIONS DÉTAILLÉES
═══════════════════════════════════════════════════════════════════════════════

# ÉTAPE 1: CRÉER LE VPC
════════════════════════════════════════════════════════════════════════════════

# Créer VPC basique
aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16

# EXPLICATION:
# --cidr-block 10.0.0.0/16
#   = Créer réseau avec plage 10.0.0.0 à 10.0.255.255
#   = 65,536 adresses IP disponibles
#   = /16 signifie "16 premiers bits fixes"
#   = Calcul: 2^(32-16) = 2^16 = 65,536 adresses

# RÉSULTAT:
# {
#   "Vpc": {
#     "VpcId": "vpc-0123456789abcdef0",
#     "State": "available",
#     "CidrBlock": "10.0.0.0/16",
#     "DhcpOptionsId": "dopt-abc123",
#     "InstanceTenancy": "default"
#   }
# }

# [ATTENTION] IMPORTANT: Notez le VpcId (vpc-0123456789abcdef0)
# Vous en aurez besoin pour toutes les commandes suivantes!

# Créer VPC avec nom (recommandé)
aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=MyProductionVPC}]'

# EXPLICATION:
# --tag-specifications = Ajouter tags (métadonnées)
# ResourceType=vpc = Type de ressource à tagger
# Tags=[{Key=Name,Value=MyProductionVPC}] = Nom du VPC
# Les tags facilitent l'organisation et facturation

# Créer VPC avec tenancy dédiée (plus cher)
aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --instance-tenancy dedicated

# EXPLICATION:
# --instance-tenancy dedicated
#   = Instances lancées dans ce VPC seront sur hardware dédié
#   = Plus cher mais requis pour certaines conformités
#   = Options: default, dedicated, host

# Activer DNS resolution et DNS hostnames
aws ec2 modify-vpc-attribute \
  --vpc-id vpc-0123456789abcdef0 \
  --enable-dns-support

aws ec2 modify-vpc-attribute \
  --vpc-id vpc-0123456789abcdef0 \
  --enable-dns-hostnames

# EXPLICATION:
# enable-dns-support = Résolution DNS dans VPC (obligatoire)
# enable-dns-hostnames = Instances ont noms DNS publics
# Exemple hostname: ec2-54-123-45-67.compute-1.amazonaws.com

# LISTER VPCs
════════════════════════════════════════════════════════════════════════════════

# Lister tous les VPCs
aws ec2 describe-vpcs

# Lister avec format simplifié
aws ec2 describe-vpcs \
  --query 'Vpcs[*].[VpcId,CidrBlock,State,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# RÉSULTAT EXEMPLE:
# -------------------------------------------------------------------------
# |                           DescribeVpcs                                |
# +-------------------------+---------------+------------+----------------+
# | vpc-0123456789abcdef0   | 10.0.0.0/16   | available  | MyProductionVPC|
# | vpc-abc123def456        | 172.31.0.0/16 | available  | DefaultVPC     |
# +-------------------------+---------------+------------+----------------+

# Obtenir VPC par défaut (créé automatiquement par AWS)
aws ec2 describe-vpcs \
  --filters "Name=isDefault,Values=true"

# EXPLICATION:
# Chaque région AWS a un VPC par défaut
# CIDR: 172.31.0.0/16
# Subnets créés automatiquement dans chaque AZ

# Obtenir VPC spécifique par ID
aws ec2 describe-vpcs \
  --vpc-ids vpc-0123456789abcdef0

# Obtenir VPC par nom
aws ec2 describe-vpcs \
  --filters "Name=tag:Name,Values=MyProductionVPC"


═══════════════════════════════════════════════════════════════════════════════
[OK] SUBNETS - DÉCOUPER LE VPC
═══════════════════════════════════════════════════════════════════════════════

SUBNET = Sous-réseau = "Pièce dans la maison (VPC)"

TYPES DE SUBNETS:
1. PUBLIC -> A accès Internet direct (via Internet Gateway)
2. PRIVÉ -> Pas d'accès Internet direct (utilise NAT Gateway)

BEST PRACTICE:
- Créer AU MOINS 2 subnets dans 2 Availability Zones différentes
- Pour haute disponibilité (si une AZ tombe, l'autre continue)

EXEMPLE ARCHITECTURE:
VPC: 10.0.0.0/16 (65,536 IPs)
├─ Public Subnet 1: 10.0.1.0/24 (256 IPs) - us-east-1a
├─ Public Subnet 2: 10.0.2.0/24 (256 IPs) - us-east-1b
├─ Private Subnet 1: 10.0.10.0/24 (256 IPs) - us-east-1a
├─ Private Subnet 2: 10.0.11.0/24 (256 IPs) - us-east-1b
├─ Database Subnet 1: 10.0.20.0/24 (256 IPs) - us-east-1a
└─ Database Subnet 2: 10.0.21.0/24 (256 IPs) - us-east-1b

# CRÉER SUBNETS
════════════════════════════════════════════════════════════════════════════════

# Créer subnet PUBLIC dans us-east-1a
aws ec2 create-subnet \
  --vpc-id vpc-0123456789abcdef0 \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-1A}]'

# EXPLICATION:
# --vpc-id = VPC parent (doit exister)
# --cidr-block 10.0.1.0/24 = 256 adresses (10.0.1.0 à 10.0.1.255)
# --availability-zone us-east-1a = Zone de disponibilité
# [ATTENTION] CIDR subnet doit être DANS le CIDR VPC!

# RÉSULTAT:
# {
#   "Subnet": {
#     "SubnetId": "subnet-0123456789abcdef0",
#     "VpcId": "vpc-0123456789abcdef0",
#     "CidrBlock": "10.0.1.0/24",
#     "AvailabilityZone": "us-east-1a",
#     "AvailableIpAddressCount": 251
#   }
# }

# [ATTENTION] POURQUOI 251 IPs au lieu de 256?
# AWS réserve 5 IPs par subnet:
# - 10.0.1.0 = adresse réseau
# - 10.0.1.1 = VPC router
# - 10.0.1.2 = DNS server
# - 10.0.1.3 = réservé (usage futur AWS)
# - 10.0.1.255 = broadcast
# Résultat: 256 - 5 = 251 IPs utilisables

# Créer subnet PUBLIC dans us-east-1b (haute disponibilité)
aws ec2 create-subnet \
  --vpc-id vpc-0123456789abcdef0 \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1b \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-1B}]'

# Créer subnet PRIVÉ dans us-east-1a
aws ec2 create-subnet \
  --vpc-id vpc-0123456789abcdef0 \
  --cidr-block 10.0.10.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-Subnet-1A},{Key=Type,Value=Private}]'

# Créer subnet PRIVÉ dans us-east-1b
aws ec2 create-subnet \
  --vpc-id vpc-0123456789abcdef0 \
  --cidr-block 10.0.11.0/24 \
  --availability-zone us-east-1b \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-Subnet-1B},{Key=Type,Value=Private}]'

# EXPLICATION TAGS MULTIPLES:
# Tags=[{Key=Name,Value=Private-Subnet-1B},{Key=Type,Value=Private}]
# Tag 1: Name = Private-Subnet-1B (nom lisible)
# Tag 2: Type = Private (facilite filtrage)

# ACTIVER AUTO-ASSIGN PUBLIC IP (pour subnets publics)
════════════════════════════════════════════════════════════════════════════════

# Activer attribution automatique d'IP publiques
aws ec2 modify-subnet-attribute \
  --subnet-id subnet-0123456789abcdef0 \
  --map-public-ip-on-launch

# EXPLICATION:
# map-public-ip-on-launch = Auto-assigner IP publique
# Instances lancées dans ce subnet auront IP publique automatiquement
# [ATTENTION] À faire SEULEMENT pour subnets publics!

# Désactiver auto-assign public IP
aws ec2 modify-subnet-attribute \
  --subnet-id subnet-0123456789abcdef0 \
  --no-map-public-ip-on-launch

# LISTER SUBNETS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les subnets
aws ec2 describe-subnets

# Lister subnets d'un VPC spécifique
aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0"

# Format tableau lisible
aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0" \
  --query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone,AvailableIpAddressCount,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# RÉSULTAT EXEMPLE:
# -------------------------------------------------------------------------------------
# | subnet-abc123    | 10.0.1.0/24  | us-east-1a | 251 | Public-Subnet-1A  |
# | subnet-def456    | 10.0.2.0/24  | us-east-1b | 251 | Public-Subnet-1B  |
# | subnet-ghi789    | 10.0.10.0/24 | us-east-1a | 251 | Private-Subnet-1A |
# -------------------------------------------------------------------------------------

# Filtrer subnets par tag
aws ec2 describe-subnets \
  --filters "Name=tag:Type,Values=Private"

# Obtenir subnet par ID
aws ec2 describe-subnets \
  --subnet-ids subnet-0123456789abcdef0


═══════════════════════════════════════════════════════════════════════════════
[OK] INTERNET GATEWAY - ACCÈS INTERNET
═══════════════════════════════════════════════════════════════════════════════

INTERNET GATEWAY (IGW) = "Porte d'entrée/sortie vers Internet"

RÔLE:
- Permet communication entre VPC et Internet
- Traduit IPs privées en IPs publiques (NAT)
- OBLIGATOIRE pour subnets publics

RÈGLES:
- 1 VPC = 1 Internet Gateway maximum
- IGW doit être attaché au VPC
- Route table doit pointer vers IGW

# CRÉER INTERNET GATEWAY
════════════════════════════════════════════════════════════════════════════════

# Créer Internet Gateway
aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=MyIGW}]'

# RÉSULTAT:
# {
#   "InternetGateway": {
#     "InternetGatewayId": "igw-0123456789abcdef0",
#     "Attachments": [],
#     "Tags": [{"Key": "Name", "Value": "MyIGW"}]
#   }
# }

# [ATTENTION] Notez InternetGatewayId: igw-0123456789abcdef0

# ATTACHER INTERNET GATEWAY AU VPC
════════════════════════════════════════════════════════════════════════════════

aws ec2 attach-internet-gateway \
  --internet-gateway-id igw-0123456789abcdef0 \
  --vpc-id vpc-0123456789abcdef0

# EXPLICATION:
# Après attachement, IGW devient actif
# Instances dans subnets publics peuvent communiquer avec Internet
# [ATTENTION] MAIS: Il faut aussi configurer route table!

# Vérifier attachement
aws ec2 describe-internet-gateways \
  --internet-gateway-ids igw-0123456789abcdef0

# RÉSULTAT montre:
# "Attachments": [
#   {
#     "State": "available",
#     "VpcId": "vpc-0123456789abcdef0"
#   }
# ]

# LISTER INTERNET GATEWAYS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les IGWs
aws ec2 describe-internet-gateways

# Lister IGWs d'un VPC
aws ec2 describe-internet-gateways \
  --filters "Name=attachment.vpc-id,Values=vpc-0123456789abcdef0"

# Format lisible
aws ec2 describe-internet-gateways \
  --query 'InternetGateways[*].[InternetGatewayId,Attachments[0].VpcId,Attachments[0].State,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# DÉTACHER INTERNET GATEWAY
════════════════════════════════════════════════════════════════════════════════

# Détacher IGW du VPC (avant suppression)
aws ec2 detach-internet-gateway \
  --internet-gateway-id igw-0123456789abcdef0 \
  --vpc-id vpc-0123456789abcdef0

# EXPLICATION:
# Détacher = retirer connexion VPC <-> IGW
# Nécessaire avant de supprimer IGW

# Supprimer Internet Gateway
aws ec2 delete-internet-gateway \
  --internet-gateway-id igw-0123456789abcdef0

# [ATTENTION] ERREUR COMMUNE:
# "Network igw-xxx has some mapped public address(es)"
# SOLUTION: Arrêter instances avec IPs publiques d'abord


═══════════════════════════════════════════════════════════════════════════════
[OK] ROUTE TABLES - DIRIGER LE TRAFIC
═══════════════════════════════════════════════════════════════════════════════

ROUTE TABLE = "Panneau d'indication pour le trafic réseau"

RÔLE:
- Définir où envoyer le trafic selon destination
- Chaque subnet doit avoir une route table
- Route table contient des routes (règles)

TYPES DE ROUTES:
1. Local -> Trafic dans VPC (automatique)
2. Internet -> Trafic vers Internet (via IGW)
3. NAT -> Trafic sortant (via NAT Gateway)
4. Peering -> Trafic vers autre VPC

ROUTE TABLE PAR DÉFAUT:
- Créée automatiquement avec VPC
- Contient seulement route "local"
- Tous les subnets l'utilisent par défaut

# CRÉER ROUTE TABLE
════════════════════════════════════════════════════════════════════════════════

# Créer route table pour subnets publics
aws ec2 create-route-table \
  --vpc-id vpc-0123456789abcdef0 \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Public-Route-Table}]'

# RÉSULTAT:
# {
#   "RouteTable": {
#     "RouteTableId": "rtb-0123456789abcdef0",
#     "VpcId": "vpc-0123456789abcdef0",
#     "Routes": [
#       {
#         "DestinationCidrBlock": "10.0.0.0/16",
#         "GatewayId": "local",
#         "State": "active"
#       }
#     ]
#   }
# }

# EXPLICATION ROUTE LOCALE:
# DestinationCidrBlock: 10.0.0.0/16
# = Trafic vers n'importe quelle IP dans VPC
# GatewayId: local
# = Reste dans VPC (pas de gateway)
# Cette route est AUTOMATIQUE et NON SUPPRIMABLE

# [ATTENTION] Notez RouteTableId: rtb-0123456789abcdef0

# Créer route table pour subnets privés
aws ec2 create-route-table \
  --vpc-id vpc-0123456789abcdef0 \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Private-Route-Table}]'

# AJOUTER ROUTES
════════════════════════════════════════════════════════════════════════════════

# Ajouter route vers Internet Gateway (pour subnet public)
aws ec2 create-route \
  --route-table-id rtb-0123456789abcdef0 \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id igw-0123456789abcdef0

# EXPLICATION:
# --destination-cidr-block 0.0.0.0/0
#   = "Tout le trafic" (toutes destinations)
#   = 0.0.0.0/0 signifie "n'importe quelle adresse IP"
# --gateway-id igw-0123456789abcdef0
#   = Envoyer vers Internet Gateway
# Résultat: Trafic vers Internet -> IGW

# EXEMPLE CONCRET:
# Instance dans subnet public veut accéder google.com (8.8.8.8)
# 1. Cherche route pour 8.8.8.8
# 2. Trouve route 0.0.0.0/0 -> IGW
# 3. Envoie trafic via IGW
# 4. IGW traduit IP privée en IP publique
# 5. Trafic atteint google.com

# Ajouter route spécifique
aws ec2 create-route \
  --route-table-id rtb-0123456789abcdef0 \
  --destination-cidr-block 192.168.1.0/24 \
  --vpc-peering-connection-id pcx-0123456789abcdef0

# EXPLICATION:
# Trafic vers 192.168.1.0/24 -> peering connection
# Plus spécifique que 0.0.0.0/0 donc prioritaire

# ASSOCIER ROUTE TABLE À SUBNET
════════════════════════════════════════════════════════════════════════════════

# Associer route table public à subnet public
aws ec2 associate-route-table \
  --route-table-id rtb-0123456789abcdef0 \
  --subnet-id subnet-0123456789abcdef0

# RÉSULTAT:
# {
#   "AssociationId": "rtbassoc-0123456789abcdef0"
# }

# EXPLICATION:
# Maintenant subnet utilise cette route table
# Instances dans subnet suivent ces routes
# [ATTENTION] Notez AssociationId pour désassocier plus tard

# Associer route table à deuxième subnet public
aws ec2 associate-route-table \
  --route-table-id rtb-0123456789abcdef0 \
  --subnet-id subnet-abcdef0123456789

# EXPLICATION:
# Même route table peut être utilisée par plusieurs subnets
# Utile pour subnets avec même comportement réseau

# LISTER ROUTE TABLES
════════════════════════════════════════════════════════════════════════════════

# Lister toutes les route tables
aws ec2 describe-route-tables

# Lister route tables d'un VPC
aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0"

# Voir routes d'une route table spécifique
aws ec2 describe-route-tables \
  --route-table-ids rtb-0123456789abcdef0 \
  --query 'RouteTables[0].Routes' \
  --output table

# RÉSULTAT EXEMPLE:
# -------------------------------------------------------------------
# |                          Routes                                 |
# +---------------------+-----------------+---------+---------------+
# | DestinationCidrBlock| GatewayId       | State   | Origin        |
# +---------------------+-----------------+---------+---------------+
# | 10.0.0.0/16         | local           | active  | CreateRouteTable|
# | 0.0.0.0/0           | igw-abc123      | active  | CreateRoute   |
# +---------------------+-----------------+---------+---------------+

# Voir associations subnet
aws ec2 describe-route-tables \
  --route-table-ids rtb-0123456789abcdef0 \
  --query 'RouteTables[0].Associations' \
  --output table

# MODIFIER/SUPPRIMER ROUTES
════════════════════════════════════════════════════════════════════════════════

# Remplacer route existante
aws ec2 replace-route \
  --route-table-id rtb-0123456789abcdef0 \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id nat-0123456789abcdef0

# EXPLICATION:
# Remplace route 0.0.0.0/0 pour utiliser NAT Gateway au lieu d'IGW

# Supprimer route
aws ec2 delete-route \
  --route-table-id rtb-0123456789abcdef0 \
  --destination-cidr-block 0.0.0.0/0

# [ATTENTION] Ne peut pas supprimer route "local"!

# Désassocier route table d'un subnet
aws ec2 disassociate-route-table \
  --association-id rtbassoc-0123456789abcdef0

# EXPLICATION:
# Subnet retourne à la route table par défaut du VPC


═══════════════════════════════════════════════════════════════════════════════
[OK] NAT GATEWAY - INTERNET SORTANT POUR SUBNETS PRIVÉS
═══════════════════════════════════════════════════════════════════════════════

NAT GATEWAY = "Porte de service pour sortir (pas entrer)"

PROBLÈME:
- Instances dans subnet privé = pas d'IP publique
- Ne peuvent pas accéder Internet directement
- Mais ont besoin d'Internet pour updates, APIs, etc.

SOLUTION: NAT GATEWAY
- Permet instances privées d'accéder Internet
- Internet NE PEUT PAS initier connexions vers instances
- One-way traffic: sortant seulement

DIFFÉRENCE NAT Gateway vs Internet Gateway:
┌──────────────────────┬─────────────────────┬────────────────────┐
│                      │  Internet Gateway   │   NAT Gateway      │
├──────────────────────┼─────────────────────┼────────────────────┤
│ Trafic entrant       │  [OK] Oui             │  [X] Non            │
│ Trafic sortant       │  [OK] Oui             │  [OK] Oui            │
│ Placement            │  VPC level          │  Subnet public     │
│ Coût                 │  Gratuit            │  ~$0.045/heure     │
│ Usage                │  Subnets publics    │  Subnets privés    │
└──────────────────────┴─────────────────────┴────────────────────┘

ARCHITECTURE TYPIQUE:
Internet
   ^v
Internet Gateway (IGW)
   ^v
Subnet Public (10.0.1.0/24)
   └─ NAT Gateway (avec Elastic IP)
        v (one-way)
   Subnet Privé (10.0.10.0/24)
     └─ Instances privées

# CRÉER NAT GATEWAY - PROCÉDURE COMPLÈTE
════════════════════════════════════════════════════════════════════════════════

# ÉTAPE 1: Allouer Elastic IP (IP publique statique)
aws ec2 allocate-address --domain vpc

# RÉSULTAT:
# {
#   "AllocationId": "eipalloc-0123456789abcdef0",
#   "PublicIp": "54.123.45.67",
#   "Domain": "vpc"
# }

# EXPLICATION:
# AllocationId = ID de l'Elastic IP
# PublicIp = Adresse IP publique
# Domain = vpc (pour VPC, pas EC2-Classic)
# [ATTENTION] Notez AllocationId: eipalloc-0123456789abcdef0

# Nommer l'Elastic IP (optionnel mais recommandé)
aws ec2 create-tags \
  --resources eipalloc-0123456789abcdef0 \
  --tags Key=Name,Value=NAT-Gateway-EIP

# ÉTAPE 2: Créer NAT Gateway dans subnet PUBLIC
aws ec2 create-nat-gateway \
  --subnet-id subnet-0123456789abcdef0 \
  --allocation-id eipalloc-0123456789abcdef0 \
  --tag-specifications 'ResourceType=nat-gateway,Tags=[{Key=Name,Value=MyNAT}]'

# RÉSULTAT:
# {
#   "NatGateway": {
#     "NatGatewayId": "nat-0123456789abcdef0",
#     "SubnetId": "subnet-0123456789abcdef0",
#     "State": "pending",
#     "NatGatewayAddresses": [
#       {
#         "AllocationId": "eipalloc-0123456789abcdef0",
#         "PublicIp": "54.123.45.67"
#       }
#     ]
#   }
# }

# EXPLICATION:
# --subnet-id = Subnet PUBLIC (avec IGW access)
# --allocation-id = Elastic IP allouée précédemment
# State = pending (devient "available" après ~2 min)
# [ATTENTION] Notez NatGatewayId: nat-0123456789abcdef0

# [ATTENTION] POURQUOI SUBNET PUBLIC?
# NAT Gateway a besoin d'accès Internet via IGW
# Il reçoit trafic de subnets privés et le forward vers Internet
# Donc DOIT être dans subnet avec route vers IGW

# ÉTAPE 3: Attendre que NAT Gateway soit disponible
aws ec2 wait nat-gateway-available \
  --nat-gateway-ids nat-0123456789abcdef0

# EXPLICATION:
# Commande attend que State = "available"
# Prend environ 2-5 minutes
# IMPORTANT: Ne pas continuer avant que NAT soit prêt!

# Vérifier état NAT Gateway
aws ec2 describe-nat-gateways \
  --nat-gateway-ids nat-0123456789abcdef0 \
  --query 'NatGateways[0].State'

# RÉSULTAT: "available" (quand prêt)

# ÉTAPE 4: Ajouter route dans route table PRIVÉE
aws ec2 create-route \
  --route-table-id rtb-private123456 \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id nat-0123456789abcdef0

# EXPLICATION:
# rtb-private123456 = Route table des subnets PRIVÉS
# 0.0.0.0/0 = Tout trafic vers Internet
# nat-gateway-id = Envoyer via NAT Gateway

# COMMENT ÇA MARCHE:
# 1. Instance privée (10.0.10.5) veut accéder api.example.com
# 2. Route table privée: 0.0.0.0/0 -> NAT Gateway
# 3. NAT Gateway (dans subnet public) reçoit requête
# 4. NAT traduit IP source: 10.0.10.5 -> 54.123.45.67 (Elastic IP)
# 5. NAT envoie via Internet Gateway
# 6. Réponse revient à 54.123.45.67
# 7. NAT traduit destination: 54.123.45.67 -> 10.0.10.5
# 8. Instance privée reçoit réponse

# LISTER NAT GATEWAYS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les NAT Gateways
aws ec2 describe-nat-gateways

# Lister NAT Gateways d'un VPC
aws ec2 describe-nat-gateways \
  --filter "Name=vpc-id,Values=vpc-0123456789abcdef0"

# Format lisible
aws ec2 describe-nat-gateways \
  --query 'NatGateways[*].[NatGatewayId,State,SubnetId,NatGatewayAddresses[0].PublicIp,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# RÉSULTAT EXEMPLE:
# --------------------------------------------------------------------------------
# | nat-abc123    | available | subnet-pub1  | 54.123.45.67 | MyNAT           |
# | nat-def456    | available | subnet-pub2  | 54.234.56.78 | MyNAT-AZ2       |
# --------------------------------------------------------------------------------

# Obtenir NAT Gateway par ID
aws ec2 describe-nat-gateways \
  --nat-gateway-ids nat-0123456789abcdef0

# Voir details complets (JSON)
aws ec2 describe-nat-gateways \
  --nat-gateway-ids nat-0123456789abcdef0 \
  --output json

# HAUTE DISPONIBILITÉ - NAT GATEWAY PAR AZ
════════════════════════════════════════════════════════════════════════════════

# PROBLÈME:
# 1 NAT Gateway = Single Point of Failure
# Si AZ tombe, instances privées perdent Internet

# SOLUTION: 1 NAT Gateway par Availability Zone

# Architecture recommandée:
# AZ 1 (us-east-1a):
#   - Public Subnet 1 -> NAT Gateway 1
#   - Private Subnet 1 -> Route vers NAT Gateway 1
#
# AZ 2 (us-east-1b):
#   - Public Subnet 2 -> NAT Gateway 2
#   - Private Subnet 2 -> Route vers NAT Gateway 2

# Créer NAT Gateway dans AZ 2
# 1. Allouer nouvelle Elastic IP
aws ec2 allocate-address --domain vpc

# Notez AllocationId: eipalloc-abcdef0123456789

# 2. Créer NAT Gateway dans subnet public AZ 2
aws ec2 create-nat-gateway \
  --subnet-id subnet-public-az2 \
  --allocation-id eipalloc-abcdef0123456789 \
  --tag-specifications 'ResourceType=nat-gateway,Tags=[{Key=Name,Value=MyNAT-AZ2}]'

# Notez NatGatewayId: nat-abcdef0123456789

# 3. Attendre disponibilité
aws ec2 wait nat-gateway-available \
  --nat-gateway-ids nat-abcdef0123456789

# 4. Créer route dans route table privée AZ 2
aws ec2 create-route \
  --route-table-id rtb-private-az2 \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id nat-abcdef0123456789

# EXPLICATION:
# Maintenant: Chaque AZ a son propre NAT Gateway
# Si AZ 1 tombe -> instances AZ 2 continuent (via NAT Gateway 2)
# Coût: 2× NAT Gateway ($0.045/h × 2 = $0.09/h)

# SUPPRIMER NAT GATEWAY
════════════════════════════════════════════════════════════════════════════════

# Supprimer NAT Gateway
aws ec2 delete-nat-gateway \
  --nat-gateway-id nat-0123456789abcdef0

# EXPLICATION:
# State devient "deleting" puis "deleted"
# Elastic IP reste allouée (continue à coûter!)

# Attendre suppression complète
aws ec2 wait nat-gateway-deleted \
  --nat-gateway-ids nat-0123456789abcdef0

# Libérer Elastic IP (important pour éviter coûts!)
aws ec2 release-address \
  --allocation-id eipalloc-0123456789abcdef0

# [ATTENTION] IMPORTANT:
# Toujours libérer Elastic IP après supprimer NAT Gateway
# Sinon: Vous payez $0.005/heure pour IP inutilisée!

# COÛTS NAT GATEWAY
════════════════════════════════════════════════════════════════════════════════

# NAT Gateway pricing (us-east-1):
# - $0.045 par heure (toujours en cours)
# - $0.045 par GB de données traitées

# EXEMPLE CALCUL:
# - 730 heures/mois × $0.045 = $32.85/mois
# - 100 GB données × $0.045 = $4.50
# - Total = $37.35/mois

# ALTERNATIVE MOINS CHÈRE: NAT Instance
# EC2 instance configurée comme NAT (au lieu de NAT Gateway)
# Plus complexe à gérer mais moins cher
# [ATTENTION] Non recommandé pour production (NAT Gateway plus fiable)


═══════════════════════════════════════════════════════════════════════════════
[OK] SECURITY GROUPS - FIREWALL INSTANCES
═══════════════════════════════════════════════════════════════════════════════

SECURITY GROUP = "Garde de sécurité devant chaque instance"

CARACTÉRISTIQUES:
- Firewall au niveau instance (pas subnet)
- STATEFUL = Si trafic entrant autorisé, réponse sortante automatique
- Règles ALLOW seulement (pas de DENY)
- Par défaut: TOUT refusé sauf ce qui est explicitement autorisé

DIFFÉRENCE Security Group vs Network ACL:
┌──────────────────────┬─────────────────────┬────────────────────┐
│                      │  Security Group     │   Network ACL      │
├──────────────────────┼─────────────────────┼────────────────────┤
│ Niveau               │  Instance           │  Subnet            │
│ Stateful             │  [OK] Oui             │  [X] Non (stateless)│
│ Règles               │  ALLOW seulement    │  ALLOW et DENY     │
│ Ordre règles         │  Toutes évaluées    │  Ordre numérique   │
│ Défaut               │  Tout refusé        │  Tout refusé       │
└──────────────────────┴─────────────────────┴────────────────────┘

EXEMPLE STATEFUL:
- Règle: Autoriser HTTP entrant (port 80)
- Résultat automatique: Réponse HTTP sortante autorisée
- Pas besoin de règle sortante!

# CRÉER SECURITY GROUP
════════════════════════════════════════════════════════════════════════════════

# Créer security group pour web servers
aws ec2 create-security-group \
  --group-name web-servers-sg \
  --description "Security group for web servers" \
  --vpc-id vpc-0123456789abcdef0 \
  --tag-specifications 'ResourceType=security-group,Tags=[{Key=Name,Value=WebServers-SG}]'

# RÉSULTAT:
# {
#   "GroupId": "sg-0123456789abcdef0"
# }

# EXPLICATION:
# --group-name = Nom unique du security group
# --description = Description (obligatoire)
# --vpc-id = VPC parent
# [ATTENTION] Notez GroupId: sg-0123456789abcdef0

# RÈGLES PAR DÉFAUT CRÉÉES:
# Entrantes: RIEN (tout refusé)
# Sortantes: 0.0.0.0/0 (tout autorisé)

# AJOUTER RÈGLES ENTRANTES (INGRESS)
════════════════════════════════════════════════════════════════════════════════

# Autoriser HTTP (port 80) depuis n'importe où
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0

# EXPLICATION:
# --protocol tcp = Protocole TCP (options: tcp, udp, icmp, -1=all)
# --port 80 = Port HTTP
# --cidr 0.0.0.0/0 = Depuis n'importe quelle IP Internet

# Autoriser HTTPS (port 443) depuis n'importe où
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# Autoriser SSH (port 22) depuis IP spécifique
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 22 \
  --cidr 203.0.113.25/32

# EXPLICATION:
# --cidr 203.0.113.25/32 = Seulement cette IP
# /32 = 1 seule adresse IP
# [ATTENTION] SÉCURITÉ: Jamais autoriser SSH depuis 0.0.0.0/0 en production!

# Autoriser plage de ports (ex: 8000-8100)
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 8000-8100 \
  --cidr 10.0.0.0/16

# EXPLICATION:
# --port 8000-8100 = Plage de ports
# --cidr 10.0.0.0/16 = Seulement depuis VPC

# Autoriser depuis autre security group
aws ec2 authorize-security-group-ingress \
  --group-id sg-database123 \
  --protocol tcp \
  --port 3306 \
  --source-group sg-0123456789abcdef0

# EXPLICATION:
# --source-group = Autoriser traffic depuis autre SG
# Exemple: Database SG autorise MySQL depuis Web Servers SG
# Avantage: Si IP web server change, règle reste valide

# Autoriser ICMP (ping)
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol icmp \
  --port -1 \
  --cidr 10.0.0.0/16

# EXPLICATION:
# --protocol icmp = ICMP (ping, traceroute)
# --port -1 = Tous les types ICMP

# Autoriser tous les protocoles
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol -1 \
  --cidr 10.0.0.0/16

# EXPLICATION:
# --protocol -1 = Tous les protocoles
# [ATTENTION] À utiliser avec précaution!

# AJOUTER RÈGLE AVEC ip-permissions (format avancé)
════════════════════════════════════════════════════════════════════════════════

# Format JSON pour règles complexes
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --ip-permissions '[
    {
      "IpProtocol": "tcp",
      "FromPort": 80,
      "ToPort": 80,
      "IpRanges": [
        {"CidrIp": "0.0.0.0/0", "Description": "Allow HTTP from Internet"}
      ]
    },
    {
      "IpProtocol": "tcp",
      "FromPort": 443,
      "ToPort": 443,
      "IpRanges": [
        {"CidrIp": "0.0.0.0/0", "Description": "Allow HTTPS from Internet"}
      ]
    }
  ]'

# EXPLICATION:
# Ajouter plusieurs règles en une commande
# Description = documentation de la règle
# Plus lisible et maintenable

# AJOUTER RÈGLES SORTANTES (EGRESS)
════════════════════════════════════════════════════════════════════════════════

# Par défaut: TOUT sortant autorisé (0.0.0.0/0)
# Mais on peut restreindre pour plus de sécurité

# Retirer règle sortante par défaut
aws ec2 revoke-security-group-egress \
  --group-id sg-0123456789abcdef0 \
  --protocol -1 \
  --cidr 0.0.0.0/0

# Autoriser sortant vers port 443 (HTTPS)
aws ec2 authorize-security-group-egress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# Autoriser sortant vers base de données
aws ec2 authorize-security-group-egress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 3306 \
  --destination-group sg-database123

# LISTER SECURITY GROUPS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les security groups
aws ec2 describe-security-groups

# Lister security groups d'un VPC
aws ec2 describe-security-groups \
  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0"

# Obtenir security group par ID
aws ec2 describe-security-groups \
  --group-ids sg-0123456789abcdef0

# Format lisible (voir règles)
aws ec2 describe-security-groups \
  --group-ids sg-0123456789abcdef0 \
  --query 'SecurityGroups[0].IpPermissions' \
  --output table

# RÉSULTAT EXEMPLE:
# --------------------------------------------------------------------------
# |                           IpPermissions                                |
# +-------------+----------+-----------+-----------------------------------+
# | FromPort    | IpProtocol| ToPort  | IpRanges                           |
# +-------------+----------+-----------+-----------------------------------+
# | 80          | tcp       | 80       | [{'CidrIp': '0.0.0.0/0'}]         |
# | 443         | tcp       | 443      | [{'CidrIp': '0.0.0.0/0'}]         |
# | 22          | tcp       | 22       | [{'CidrIp': '203.0.113.25/32'}]   |
# +-------------+----------+-----------+-----------------------------------+

# Voir règles sortantes
aws ec2 describe-security-groups \
  --group-ids sg-0123456789abcdef0 \
  --query 'SecurityGroups[0].IpPermissionsEgress' \
  --output table

# RETIRER RÈGLES
════════════════════════════════════════════════════════════════════════════════

# Retirer règle entrante
aws ec2 revoke-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0

# EXPLICATION:
# Spécifier exactement même paramètres que lors de création
# Retirer = inverser authorize-security-group-ingress

# Retirer règle sortante
aws ec2 revoke-security-group-egress \
  --group-id sg-0123456789abcdef0 \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# SUPPRIMER SECURITY GROUP
════════════════════════════════════════════════════════════════════════════════

aws ec2 delete-security-group \
  --group-id sg-0123456789abcdef0

# [ATTENTION] ERREUR POSSIBLE:
# "resource sg-xxx has a dependent object"
# CAUSE: Security group attaché à instances ou autre SG
# SOLUTION: Détacher d'abord, puis supprimer

# EXEMPLES CONFIGURATIONS TYPIQUES
════════════════════════════════════════════════════════════════════════════════

# Configuration 1: Web Server (public)
# - Entrantes: HTTP (80), HTTPS (443) depuis 0.0.0.0/0
# - Entrantes: SSH (22) depuis IP admin seulement
# - Sortantes: Tout (pour updates, APIs)

aws ec2 create-security-group \
  --group-name web-sg \
  --description "Web servers" \
  --vpc-id vpc-0123456789abcdef0

aws ec2 authorize-security-group-ingress \
  --group-id sg-web123 \
  --ip-permissions '[
    {"IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "IpRanges": [{"CidrIp": "0.0.0.0/0"}]},
    {"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443, "IpRanges": [{"CidrIp": "0.0.0.0/0"}]},
    {"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "IpRanges": [{"CidrIp": "203.0.113.25/32"}]}
  ]'

# Configuration 2: App Server (private)
# - Entrantes: Port 8080 depuis Web Server SG
# - Entrantes: SSH depuis Bastion SG
# - Sortantes: MySQL vers Database SG

aws ec2 create-security-group \
  --group-name app-sg \
  --description "Application servers" \
  --vpc-id vpc-0123456789abcdef0

aws ec2 authorize-security-group-ingress \
  --group-id sg-app456 \
  --ip-permissions '[
    {"IpProtocol": "tcp", "FromPort": 8080, "ToPort": 8080, "UserIdGroupPairs": [{"GroupId": "sg-web123"}]},
    {"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "UserIdGroupPairs": [{"GroupId": "sg-bastion789"}]}
  ]'

# Retirer règle sortante par défaut
aws ec2 revoke-security-group-egress \
  --group-id sg-app456 \
  --protocol -1 \
  --cidr 0.0.0.0/0

# Autoriser sortant vers database
aws ec2 authorize-security-group-egress \
  --group-id sg-app456 \
  --protocol tcp \
  --port 3306 \
  --destination-group sg-db789

# Configuration 3: Database (private)
# - Entrantes: MySQL (3306) depuis App Server SG
# - Sortantes: Rien (isolé)

aws ec2 create-security-group \
  --group-name db-sg \
  --description "Database servers" \
  --vpc-id vpc-0123456789abcdef0

aws ec2 authorize-security-group-ingress \
  --group-id sg-db789 \
  --protocol tcp \
  --port 3306 \
  --source-group sg-app456

# Retirer règle sortante (database ne sort jamais)
aws ec2 revoke-security-group-egress \
  --group-id sg-db789 \
  --protocol -1 \
  --cidr 0.0.0.0/0


═══════════════════════════════════════════════════════════════════════════════
[OK] NETWORK ACL (NACL) - FIREWALL SUBNET
═══════════════════════════════════════════════════════════════════════════════

NETWORK ACL = "Firewall au niveau subnet (pas instance)"

DIFFÉRENCES CLÉS avec Security Groups:
- STATELESS = Trafic entrant et sortant évalués séparément
- Règles ALLOW et DENY
- Évaluation par ordre numérique (première règle match gagne)
- S'applique à TOUT le subnet

QUAND UTILISER NACL?
- Protection supplémentaire (défense en profondeur)
- Bloquer IPs malveillantes (DENY)
- Règles globales subnet

NACL PAR DÉFAUT:
- Créée automatiquement avec VPC
- TOUT autorisé (entrée et sortie)
- Associée à tous les subnets par défaut

# CRÉER NETWORK ACL
════════════════════════════════════════════════════════════════════════════════

# Créer NACL custom
aws ec2 create-network-acl \
  --vpc-id vpc-0123456789abcdef0 \
  --tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=Public-NACL}]'

# RÉSULTAT:
# {
#   "NetworkAcl": {
#     "NetworkAclId": "acl-0123456789abcdef0",
#     "VpcId": "vpc-0123456789abcdef0",
#     "IsDefault": false,
#     "Entries": [
#       {
#         "RuleNumber": 32767,
#         "Protocol": "-1",
#         "RuleAction": "deny",
#         "Egress": true,
#         "CidrBlock": "0.0.0.0/0"
#       },
#       {
#         "RuleNumber": 32767,
#         "Protocol": "-1",
#         "RuleAction": "deny",
#         "Egress": false,
#         "CidrBlock": "0.0.0.0/0"
#       }
#     ]
#   }
# }

# EXPLICATION RÈGLES PAR DÉFAUT:
# RuleNumber 32767 = Règle implicite finale (deny all)
# Egress: true = Sortante
# Egress: false = Entrante
# NACL custom commence avec TOUT refusé!

# [ATTENTION] Notez NetworkAclId: acl-0123456789abcdef0

# AJOUTER RÈGLES ENTRANTES
════════════════════════════════════════════════════════════════════════════════

# Autoriser HTTP (port 80) - Règle 100
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 100 \
  --protocol 6 \
  --port-range From=80,To=80 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --ingress

# EXPLICATION:
# --rule-number 100 = Numéro de priorité (1-32766)
#   * Plus petit = plus prioritaire
#   * Recommandé: Incrémenter par 100 (100, 200, 300...)
#   * Laisse espace pour insérer règles entre
# --protocol 6 = TCP (6=TCP, 17=UDP, 1=ICMP, -1=all)
# --port-range From=80,To=80 = Port 80 seulement
# --rule-action allow = Autoriser (options: allow, deny)
# --ingress = Règle entrante (vs --egress)

# Autoriser HTTPS (port 443) - Règle 110
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 110 \
  --protocol 6 \
  --port-range From=443,To=443 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --ingress

# Autoriser SSH depuis IP admin - Règle 120
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 120 \
  --protocol 6 \
  --port-range From=22,To=22 \
  --cidr-block 203.0.113.25/32 \
  --rule-action allow \
  --ingress

# [ATTENTION] IMPORTANT: PORTS ÉPHÉMÈRES
# Connexions TCP utilisent ports éphémères pour réponses (1024-65535)
# NACL est STATELESS -> doit autoriser réponses explicitement!

# Autoriser ports éphémères (réponses) - Règle 130
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 130 \
  --protocol 6 \
  --port-range From=1024,To=65535 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --ingress

# EXPLICATION:
# Quand instance initie connexion sortante (ex: apt-get update)
# Réponse revient sur port éphémère (ex: 54321)
# Sans cette règle -> réponses bloquées!

# BLOQUER IP malveillante - Règle 50 (prioritaire)
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 50 \
  --protocol -1 \
  --cidr-block 198.51.100.50/32 \
  --rule-action deny \
  --ingress

# EXPLICATION:
# Règle 50 évaluée AVANT règle 100
# Bloque TOUS les protocoles depuis cette IP
# Utile contre attaques DDoS

# AJOUTER RÈGLES SORTANTES
════════════════════════════════════════════════════════════════════════════════

# Autoriser HTTP sortant - Règle 100
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 100 \
  --protocol 6 \
  --port-range From=80,To=80 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --egress

# Autoriser HTTPS sortant - Règle 110
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 110 \
  --protocol 6 \
  --port-range From=443,To=443 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --egress

# Autoriser ports éphémères sortants (réponses HTTP/HTTPS) - Règle 120
aws ec2 create-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 120 \
  --protocol 6 \
  --port-range From=1024,To=65535 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --egress

# EXPLICATION:
# Quand client externe envoie requête HTTP (port 80)
# Instance répond depuis port éphémère (ex: 54321)
# Cette règle autorise la réponse sortante

# ASSOCIER NACL À SUBNET
════════════════════════════════════════════════════════════════════════════════

# D'abord, obtenir AssociationId actuelle
aws ec2 describe-network-acls \
  --filters "Name=association.subnet-id,Values=subnet-0123456789abcdef0" \
  --query 'NetworkAcls[0].Associations[0].NetworkAclAssociationId'

# RÉSULTAT: "aclassoc-0123456789abcdef0"

# Remplacer association (NACL custom remplace NACL par défaut)
aws ec2 replace-network-acl-association \
  --association-id aclassoc-0123456789abcdef0 \
  --network-acl-id acl-0123456789abcdef0

# EXPLICATION:
# Subnet utilise maintenant NACL custom
# Ancienne NACL (par défaut) n'est plus utilisée par ce subnet

# LISTER NETWORK ACLs (suite)
════════════════════════════════════════════════════════════════════════════════

# Lister toutes les NACLs
aws ec2 describe-network-acls

# Lister NACLs d'un VPC
aws ec2 describe-network-acls \
  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0"

# Obtenir NACL spécifique
aws ec2 describe-network-acls \
  --network-acl-ids acl-0123456789abcdef0

# Voir règles d'une NACL (format lisible)
aws ec2 describe-network-acls \
  --network-acl-ids acl-0123456789abcdef0 \
  --query 'NetworkAcls[0].Entries' \
  --output table

# RÉSULTAT EXEMPLE:
# --------------------------------------------------------------------------------
# | RuleNumber | Protocol | RuleAction | Egress | CidrBlock     | PortRange    |
# +------------+----------+------------+--------+---------------+--------------+
# | 50         | -1       | deny       | False  | 198.51.100.50/32 | None      |
# | 100        | 6        | allow      | False  | 0.0.0.0/0     | 80-80        |
# | 110        | 6        | allow      | False  | 0.0.0.0/0     | 443-443      |
# | 130        | 6        | allow      | False  | 0.0.0.0/0     | 1024-65535   |
# | 32767      | -1       | deny       | False  | 0.0.0.0/0     | None         |
# | 100        | 6        | allow      | True   | 0.0.0.0/0     | 80-80        |
# | 110        | 6        | allow      | True   | 0.0.0.0/0     | 443-443      |
# | 120        | 6        | allow      | True   | 0.0.0.0/0     | 1024-65535   |
# | 32767      | -1       | deny       | True   | 0.0.0.0/0     | None         |
# --------------------------------------------------------------------------------

# Voir subnets associés à NACL
aws ec2 describe-network-acls \
  --network-acl-ids acl-0123456789abcdef0 \
  --query 'NetworkAcls[0].Associations[*].[SubnetId]' \
  --output table

# MODIFIER/SUPPRIMER RÈGLES
════════════════════════════════════════════════════════════════════════════════

# Remplacer règle existante
aws ec2 replace-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 100 \
  --protocol 6 \
  --port-range From=8080,To=8080 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --ingress

# EXPLICATION:
# Remplace règle 100 (était port 80, maintenant port 8080)

# Supprimer règle
aws ec2 delete-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 100 \
  --ingress

# Supprimer règle sortante
aws ec2 delete-network-acl-entry \
  --network-acl-id acl-0123456789abcdef0 \
  --rule-number 100 \
  --egress

# SUPPRIMER NETWORK ACL
════════════════════════════════════════════════════════════════════════════════

# Supprimer NACL
aws ec2 delete-network-acl \
  --network-acl-id acl-0123456789abcdef0

# [ATTENTION] ERREUR POSSIBLE:
# "network ACL acl-xxx has dependencies and cannot be deleted"
# CAUSE: NACL encore associée à subnets
# SOLUTION: Désassocier d'abord (subnets retournent à NACL par défaut)

# EXEMPLE CONFIGURATION COMPLÈTE - WEB SERVER PUBLIC
════════════════════════════════════════════════════════════════════════════════

# NACL pour subnet public avec web servers

# Créer NACL
aws ec2 create-network-acl \
  --vpc-id vpc-0123456789abcdef0 \
  --tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=Public-Web-NACL}]'

# Notez: acl-web123

# RÈGLES ENTRANTES:
# Bloquer IP malveillante (priorité haute)
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 10 \
  --protocol -1 \
  --cidr-block 198.51.100.50/32 \
  --rule-action deny \
  --ingress

# HTTP depuis Internet
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 100 \
  --protocol 6 \
  --port-range From=80,To=80 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --ingress

# HTTPS depuis Internet
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 110 \
  --protocol 6 \
  --port-range From=443,To=443 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --ingress

# SSH depuis IP admin
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 120 \
  --protocol 6 \
  --port-range From=22,To=22 \
  --cidr-block 203.0.113.25/32 \
  --rule-action allow \
  --ingress

# Ports éphémères (réponses)
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 140 \
  --protocol 6 \
  --port-range From=1024,To=65535 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --ingress

# RÈGLES SORTANTES:
# HTTP vers Internet (pour updates)
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 100 \
  --protocol 6 \
  --port-range From=80,To=80 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --egress

# HTTPS vers Internet
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 110 \
  --protocol 6 \
  --port-range From=443,To=443 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --egress

# Ports éphémères (réponses HTTP/HTTPS vers clients)
aws ec2 create-network-acl-entry \
  --network-acl-id acl-web123 \
  --rule-number 140 \
  --protocol 6 \
  --port-range From=1024,To=65535 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow \
  --egress


═══════════════════════════════════════════════════════════════════════════════
[OK] VPC PEERING - CONNECTER 2 VPCs
═══════════════════════════════════════════════════════════════════════════════

VPC PEERING = "Pont réseau entre 2 VPCs"

UTILISATION:
- Connecter VPC prod <-> VPC dev
- Connecter VPC différentes régions
- Connecter VPC différents comptes AWS
- Partager ressources entre VPCs

CARACTÉRISTIQUES:
- Communication privée (pas via Internet)
- Pas de single point of failure
- Pas de bandwidth bottleneck
- Pas de transitivité (A<->B, B<->C ≠ A<->C)

EXEMPLE SCENARIO:
VPC-A (10.0.0.0/16) <--> VPC-B (172.31.0.0/16)
- Instances VPC-A peuvent communiquer avec VPC-B
- Via IPs privées (pas IPs publiques)

[ATTENTION] PRÉREQUIS:
- CIDRs ne doivent PAS se chevaucher
- Exemple INVALIDE: VPC-A (10.0.0.0/16) + VPC-B (10.0.0.0/24)
- Exemple VALIDE: VPC-A (10.0.0.0/16) + VPC-B (172.31.0.0/16)

# CRÉER VPC PEERING CONNECTION
════════════════════════════════════════════════════════════════════════════════

# Créer peering entre 2 VPCs (même région)
aws ec2 create-vpc-peering-connection \
  --vpc-id vpc-0123456789abcdef0 \
  --peer-vpc-id vpc-abcdef0123456789 \
  --tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=VPC-A-to-VPC-B}]'

# RÉSULTAT:
# {
#   "VpcPeeringConnection": {
#     "VpcPeeringConnectionId": "pcx-0123456789abcdef0",
#     "Status": {"Code": "pending-acceptance"},
#     "RequesterVpcInfo": {
#       "VpcId": "vpc-0123456789abcdef0",
#       "CidrBlock": "10.0.0.0/16"
#     },
#     "AccepterVpcInfo": {
#       "VpcId": "vpc-abcdef0123456789",
#       "CidrBlock": "172.31.0.0/16"
#     }
#   }
# }

# EXPLICATION:
# --vpc-id = VPC requester (qui initie)
# --peer-vpc-id = VPC accepter (qui doit accepter)
# Status = pending-acceptance (en attente)
# [ATTENTION] Notez VpcPeeringConnectionId: pcx-0123456789abcdef0

# Créer peering entre 2 VPCs (différentes régions)
aws ec2 create-vpc-peering-connection \
  --vpc-id vpc-0123456789abcdef0 \
  --peer-vpc-id vpc-abcdef0123456789 \
  --peer-region us-west-2 \
  --tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=US-East-to-US-West}]'

# EXPLICATION:
# --peer-region = Région du VPC peer
# Inter-region peering = plus de latence mais possible

# Créer peering entre 2 comptes AWS
aws ec2 create-vpc-peering-connection \
  --vpc-id vpc-0123456789abcdef0 \
  --peer-vpc-id vpc-abcdef0123456789 \
  --peer-owner-id 123456789012 \
  --tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=Account-A-to-Account-B}]'

# EXPLICATION:
# --peer-owner-id = AWS Account ID du VPC peer
# Utile pour organisations multi-comptes

# ACCEPTER VPC PEERING CONNECTION
════════════════════════════════════════════════════════════════════════════════

# Accepter peering (depuis VPC accepter)
aws ec2 accept-vpc-peering-connection \
  --vpc-peering-connection-id pcx-0123456789abcdef0

# RÉSULTAT:
# {
#   "VpcPeeringConnection": {
#     "Status": {"Code": "active"}
#   }
# }

# EXPLICATION:
# Status devient "active"
# Peering maintenant fonctionnel
# [ATTENTION] MAIS: Faut encore ajouter routes!

# Accepter peering (différente région)
aws ec2 accept-vpc-peering-connection \
  --vpc-peering-connection-id pcx-0123456789abcdef0 \
  --region us-west-2

# EXPLICATION:
# --region = Région du VPC accepter
# Commande doit être exécutée dans la région du peer

# AJOUTER ROUTES POUR PEERING
════════════════════════════════════════════════════════════════════════════════

# [ATTENTION] IMPORTANT:
# Peering actif ≠ communication possible
# Il faut ajouter routes dans CHAQUE VPC!

# VPC-A (10.0.0.0/16): Ajouter route vers VPC-B (172.31.0.0/16)
aws ec2 create-route \
  --route-table-id rtb-vpc-a-123456 \
  --destination-cidr-block 172.31.0.0/16 \
  --vpc-peering-connection-id pcx-0123456789abcdef0

# EXPLICATION:
# rtb-vpc-a-123456 = Route table de VPC-A
# Destination = CIDR de VPC-B
# Trafic vers 172.31.x.x -> peering connection

# VPC-B (172.31.0.0/16): Ajouter route vers VPC-A (10.0.0.0/16)
aws ec2 create-route \
  --route-table-id rtb-vpc-b-789012 \
  --destination-cidr-block 10.0.0.0/16 \
  --vpc-peering-connection-id pcx-0123456789abcdef0

# EXPLICATION:
# Routes bidirectionnelles nécessaires
# VPC-A peut maintenant communiquer avec VPC-B et vice versa

# EXEMPLE COMPLET:
# Instance VPC-A (10.0.1.50) ping Instance VPC-B (172.31.10.100)
# 1. Instance VPC-A: ping 172.31.10.100
# 2. Route table VPC-A: 172.31.0.0/16 -> pcx-xxx
# 3. Trafic traverse peering connection
# 4. Instance VPC-B reçoit ping
# 5. Instance VPC-B répond
# 6. Route table VPC-B: 10.0.0.0/16 -> pcx-xxx
# 7. Réponse revient à VPC-A

# [ATTENTION] SÉCURITÉ: SECURITY GROUPS
# Autoriser trafic depuis VPC peer dans security groups!

# Security Group VPC-B: Autoriser SSH depuis VPC-A
aws ec2 authorize-security-group-ingress \
  --group-id sg-vpc-b-123 \
  --protocol tcp \
  --port 22 \
  --cidr 10.0.0.0/16

# LISTER VPC PEERING CONNECTIONS
════════════════════════════════════════════════════════════════════════════════

# Lister toutes les peering connections
aws ec2 describe-vpc-peering-connections

# Lister peering d'un VPC spécifique
aws ec2 describe-vpc-peering-connections \
  --filters "Name=requester-vpc-info.vpc-id,Values=vpc-0123456789abcdef0"

# Format lisible
aws ec2 describe-vpc-peering-connections \
  --query 'VpcPeeringConnections[*].[VpcPeeringConnectionId,Status.Code,RequesterVpcInfo.VpcId,AccepterVpcInfo.VpcId,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# RÉSULTAT EXEMPLE:
# ----------------------------------------------------------------------------------
# | pcx-abc123  | active  | vpc-0123456789abcdef0 | vpc-abcdef0123456789 | VPC-A-to-VPC-B |
# ----------------------------------------------------------------------------------

# Obtenir peering par ID
aws ec2 describe-vpc-peering-connections \
  --vpc-peering-connection-ids pcx-0123456789abcdef0

# SUPPRIMER VPC PEERING CONNECTION
════════════════════════════════════════════════════════════════════════════════

# Supprimer peering (par requester ou accepter)
aws ec2 delete-vpc-peering-connection \
  --vpc-peering-connection-id pcx-0123456789abcdef0

# EXPLICATION:
# Suppression immédiate
# Communication entre VPCs coupée
# [ATTENTION] Penser à supprimer routes aussi!

# Supprimer routes associées (VPC-A)
aws ec2 delete-route \
  --route-table-id rtb-vpc-a-123456 \
  --destination-cidr-block 172.31.0.0/16

# Supprimer routes associées (VPC-B)
aws ec2 delete-route \
  --route-table-id rtb-vpc-b-789012 \
  --destination-cidr-block 10.0.0.0/16

# REFUSER VPC PEERING REQUEST
════════════════════════════════════════════════════════════════════════════════

# Si vous ne voulez pas accepter
aws ec2 reject-vpc-peering-connection \
  --vpc-peering-connection-id pcx-0123456789abcdef0


═══════════════════════════════════════════════════════════════════════════════
[OK] VPC ENDPOINTS - ACCÉDER SERVICES AWS SANS INTERNET
═══════════════════════════════════════════════════════════════════════════════

VPC ENDPOINT = "Connexion privée vers services AWS"

PROBLÈME SANS VPC ENDPOINT:
- Instance privée veut accéder S3
- Trafic doit passer par NAT Gateway -> Internet -> S3
- Coût NAT Gateway + Bande passante
- Latence plus élevée

SOLUTION: VPC ENDPOINT
- Connexion directe VPC -> Service AWS
- Trafic reste dans réseau AWS (pas Internet)
- Pas de NAT Gateway nécessaire
- Gratuit (pour Gateway Endpoints)

TYPES D'ENDPOINTS:
1. GATEWAY ENDPOINT (gratuit)
   - S3 et DynamoDB seulement
   - Route ajoutée à route table
   
2. INTERFACE ENDPOINT (payant: ~$0.01/h)
   - Tous les autres services AWS
   - ENI (Elastic Network Interface) dans subnet
   - Plus de 100 services supportés

# GATEWAY ENDPOINT - S3
════════════════════════════════════════════════════════════════════════════════

# Créer endpoint S3 (Gateway)
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids rtb-private123456 \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=S3-Endpoint}]'

# RÉSULTAT:
# {
#   "VpcEndpoint": {
#     "VpcEndpointId": "vpce-0123456789abcdef0",
#     "VpcEndpointType": "Gateway",
#     "VpcId": "vpc-0123456789abcdef0",
#     "ServiceName": "com.amazonaws.us-east-1.s3",
#     "State": "available",
#     "RouteTableIds": ["rtb-private123456"]
#   }
# }

# EXPLICATION:
# --service-name = Service AWS (format: com.amazonaws.REGION.SERVICE)
# --route-table-ids = Route tables à modifier (ajoute route automatique)
# VpcEndpointType = Gateway (gratuit)
# [ATTENTION] Notez VpcEndpointId: vpce-0123456789abcdef0

# Vérifier route ajoutée automatiquement
aws ec2 describe-route-tables \
  --route-table-ids rtb-private123456 \
  --query 'RouteTables[0].Routes'

# RÉSULTAT MONTRE:
# {
#   "DestinationPrefixListId": "pl-63a5400a",  # S3 prefix list
#   "GatewayId": "vpce-0123456789abcdef0",
#   "State": "active"
# }

# EXPLICATION:
# pl-63a5400a = Prefix list S3 (toutes IPs S3 région)
# Route automatique: Trafic S3 -> VPC Endpoint

# COMMENT ÇA MARCHE:
# 1. Instance privée: aws s3 ls s3://my-bucket
# 2. DNS résout: s3.amazonaws.com -> IP S3
# 3. Route table: IP S3 match prefix list -> VPC Endpoint
# 4. Trafic va directement à S3 (pas via NAT/IGW)
# 5. Gratuit et rapide!

# Créer endpoint DynamoDB (Gateway)
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --service-name com.amazonaws.us-east-1.dynamodb \
  --route-table-ids rtb-private123456 rtb-private789012 \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=DynamoDB-Endpoint}]'

# EXPLICATION:
# Même principe que S3
# Peut spécifier plusieurs route tables

# INTERFACE ENDPOINT - AUTRES SERVICES
════════════════════════════════════════════════════════════════════════════════

# Lister services disponibles
aws ec2 describe-vpc-endpoint-services \
  --query 'ServiceNames' \
  --output table

# RÉSULTAT PARTIEL:
# com.amazonaws.us-east-1.ec2
# com.amazonaws.us-east-1.lambda
# com.amazonaws.us-east-1.sns
# com.amazonaws.us-east-1.sqs
# com.amazonaws.us-east-1.ssm
# ... 100+ services

# Créer endpoint EC2 (Interface)
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --vpc-endpoint-type Interface \
  --service-name com.amazonaws.us-east-1.ec2 \
  --subnet-ids subnet-private1 subnet-private2 \
  --security-group-ids sg-endpoint123 \
  --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=EC2-Endpoint}]'

# RÉSULTAT:
# {
#   "VpcEndpoint": {
#     "VpcEndpointId": "vpce-abc123def456",
#     "VpcEndpointType": "Interface",
#     "ServiceName": "com.amazonaws.us-east-1.ec2",
#     "State": "pending",
#     "SubnetIds": ["subnet-private1", "subnet-private2"],
#     "Groups": [{"GroupId": "sg-endpoint123"}],
#     "PrivateDnsEnabled": true
#   }
# }

# EXPLICATION:
# --vpc-endpoint-type Interface = ENI créée dans subnets
# --subnet-ids = Subnets pour ENIs (recommandé: 2+ pour HA)
# --security-group-ids = Security group pour ENIs
# PrivateDnsEnabled = true (résolution DNS privée)

# [ATTENTION] DIFFÉRENCE vs GATEWAY:
# Interface Endpoint = ENI avec IP privée dans subnet
# Instances communiquent via cette IP
# Coût: ~$0.01/heure + $0.01/GB

# Security Group pour Interface Endpoint
aws ec2 create-security-group \
  --group-name vpc-endpoint-sg \
  --description "Security group for VPC endpoints" \
  --vpc-id vpc-0123456789abcdef0

# Autoriser HTTPS depuis VPC
aws ec2 authorize-security-group-ingress \
  --group-id sg-endpoint123 \
  --protocol tcp \
  --port 443 \
  --cidr 10.0.0.0/16

# EXPLICATION:
# Interface Endpoints utilisent HTTPS (port 443)
# Autoriser depuis tout le VPC

# Créer endpoint SSM (Systems Manager) pour Session Manager
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --vpc-endpoint-type Interface \
  --service-name com.amazonaws.us-east-1.ssm \
  --subnet-ids subnet-private1 subnet-private2 \
  --security-group-ids sg-endpoint123

# EXPLICATION:
# SSM Endpoint permet Session Manager sans bastion host
# Se connecter à instances privées sans SSH/RDP public

# Pour Session Manager complet, créer 3 endpoints:
# 1. ssm
# 2. ssmmessages
# 3. ec2messages

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --vpc-endpoint-type Interface \
  --service-name com.amazonaws.us-east-1.ssmmessages \
  --subnet-ids subnet-private1 subnet-private2 \
  --security-group-ids sg-endpoint123

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --vpc-endpoint-type Interface \
  --service-name com.amazonaws.us-east-1.ec2messages \
  --subnet-ids subnet-private1 subnet-private2 \
  --security-group-ids sg-endpoint123

# LISTER VPC ENDPOINTS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les endpoints
aws ec2 describe-vpc-endpoints

# Lister endpoints d'un VPC
aws ec2 describe-vpc-endpoints \
  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0"

# Format lisible
aws ec2 describe-vpc-endpoints \
  --filters "Name=vpc-id,Values=vpc-0123456789abcdef0" \
  --query 'VpcEndpoints[*].[VpcEndpointId,VpcEndpointType,ServiceName,State,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# RÉSULTAT EXEMPLE:
# ------------------------------------------------------------------------------------
# | vpce-abc123  | Gateway   | com.amazonaws.us-east-1.s3      | available | S3-Endpoint    |
# | vpce-def456  | Interface | com.amazonaws.us-east-1.ec2     | available | EC2-Endpoint   |
# | vpce-ghi789  | Interface | com.amazonaws.us-east-1.ssm     | available | SSM-Endpoint   |
# ------------------------------------------------------------------------------------

# Obtenir détails endpoint
aws ec2 describe-vpc-endpoints \
  --vpc-endpoint-ids vpce-0123456789abcdef0

# MODIFIER VPC ENDPOINT
════════════════════════════════════════════════════════════════════════════════

# Ajouter route table à Gateway Endpoint
aws ec2 modify-vpc-endpoint \
  --vpc-endpoint-id vpce-0123456789abcdef0 \
  --add-route-table-ids rtb-789012

# Retirer route table
aws ec2 modify-vpc-endpoint \
  --vpc-endpoint-id vpce-0123456789abcdef0 \
  --remove-route-table-ids rtb-789012

# Modifier subnets (Interface Endpoint)
aws ec2 modify-vpc-endpoint \
  --vpc-endpoint-id vpce-abc123def456 \
  --add-subnet-ids subnet-private3

# Modifier security groups (Interface Endpoint)
aws ec2 modify-vpc-endpoint \
  --vpc-endpoint-id vpce-abc123def456 \
  --add-security-group-ids sg-newgroup123

# SUPPRIMER VPC ENDPOINT
════════════════════════════════════════════════════════════════════════════════

aws ec2 delete-vpc-endpoints \
  --vpc-endpoint-ids vpce-0123456789abcdef0

# EXPLICATION:
# Suppression immédiate
# Routes automatiquement retirées (Gateway)
# ENIs supprimées (Interface)


═══════════════════════════════════════════════════════════════════════════════
[OK] VPC FLOW LOGS - CAPTURER TRAFIC RÉSEAU
═══════════════════════════════════════════════════════════════════════════════

FLOW LOGS = "Enregistrement trafic réseau"

UTILISATION:
- Troubleshooting connectivité
- Analyse sécurité (détecter attaques)
- Audit et conformité
- Monitoring patterns trafic

NIVEAUX CAPTURE:
1. VPC -> Tout le trafic VPC
2. Subnet -> Trafic d'un subnet
3. ENI -> Trafic d'une interface réseau spécifique

DESTINATIONS:
1. CloudWatch Logs -> Analyse en temps réel
2. S3 -> Stockage long terme (moins cher)
3. Kinesis Data Firehose -> Streaming vers outils tiers

FORMAT FLOW LOG (exemple):
2 123456789012 eni-abc123 10.0.1.5 172.217.14.206 49152 443 6 20 4000 1620000000 1620000060 ACCEPT OK

CHAMPS:
- version: 2
- account-id: 123456789012
- interface-id: eni-abc123
- srcaddr: 10.0.1.5 (source)
- dstaddr: 172.217.14.206 (destination)
- srcport: 49152
- dstport: 443 (HTTPS)
- protocol: 6 (TCP)
- packets: 20
- bytes: 4000
- start: timestamp
- end: timestamp
- action: ACCEPT (ou REJECT)
- log-status: OK

# CRÉER FLOW LOGS - CLOUDWATCH
════════════════════════════════════════════════════════════════════════════════

# Créer IAM role pour Flow Logs
cat > flow-logs-trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "vpc-flow-logs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

aws iam create-role \
  --role-name VPC-FlowLogs-Role \
  --assume-role-policy-document file://flow-logs-trust-policy.json

# Créer policy pour écrire dans CloudWatch Logs
cat > flow-logs-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams"
      ],
      "Resource": "*"
    }
  ]
}
EOF

aws iam put-role-policy \
  --role-name VPC-FlowLogs-Role \
  --policy-name VPC-FlowLogs-Policy \
  --policy-document file://flow-logs-policy.json

# Créer log group CloudWatch
aws logs create-log-group \
  --log-group-name /aws/vpc/flowlogs

# Définir retention (optionnel - éviter coûts)
aws logs put-retention-policy \
  --log-group-name /aws/vpc/flowlogs \
  --retention-in-days 7

# EXPLICATION:
# --retention-in-days = Garder logs 7 jours
# Options: 1, 3, 5, 7, 14, 30, 60, 90, etc.
# Sans retention = logs gardés indéfiniment = $$$

# Créer Flow Logs pour VPC (vers CloudWatch)
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-0123456789abcdef0 \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /aws/vpc/flowlogs \
  --deliver-logs-permission-arn arn:aws:iam::123456789012:role/VPC-FlowLogs-Role \
  --tag-specifications 'ResourceType=vpc-flow-log,Tags=[{Key=Name,Value=VPC-FlowLogs}]'

# RÉSULTAT:
# {
#   "FlowLogIds": ["fl-0123456789abcdef0"],
#   "Unsuccessful": []
# }

# EXPLICATION:
# --resource-type VPC = Capturer tout le VPC
#   Options: VPC, Subnet, NetworkInterface
# --resource-ids = ID de la ressource
# --traffic-type ALL = Tout le trafic
#   Options: ALL, ACCEPT (seulement accepté), REJECT (seulement rejeté)
# --log-destination-type = Où envoyer logs
# --deliver-logs-permission-arn = IAM role

# [ATTENTION] Notez FlowLogIds: fl-0123456789abcdef0

# Créer Flow Logs pour subnet spécifique
aws ec2 create-flow-logs \
  --resource-type Subnet \
  --resource-ids subnet-0123456789abcdef0 \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /aws/vpc/flowlogs \
  --deliver-logs-permission-arn arn:aws:iam::123456789012:role/VPC-FlowLogs-Role

# Créer Flow Logs pour ENI spécifique
aws ec2 create-flow-logs \
  --resource-type NetworkInterface \
  --resource-ids eni-0123456789abcdef0 \
  --traffic-type REJECT \
  --log-destination-type cloud-watch-logs \
  --log-group-name /aws/vpc/flowlogs-rejected \
  --deliver-logs-permission-arn arn:aws:iam::123456789012:role/VPC-FlowLogs-Role

# EXPLICATION:
# --traffic-type REJECT = Seulement trafic rejeté
# Utile pour analyser problèmes de connectivité

# CRÉER FLOW LOGS - S3 (MOINS CHER)
════════════════════════════════════════════════════════════════════════════════

# Créer bucket S3
aws s3 mb s3://my-vpc-flow-logs-bucket

# Créer bucket policy pour Flow Logs
cat > s3-flow-logs-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSLogDeliveryWrite",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::my-vpc-flow-logs-bucket/*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "bucket-owner-full-control"
        }
      }
    },
    {
      "Sid": "AWSLogDeliveryAclCheck",
      "Effect": "Allow",
      "Principal": {
        "Service": "delivery.logs.amazonaws.com"
      },
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::my-vpc-flow-logs-bucket"
    }
  ]
}
EOF

aws s3api put-bucket-policy \
  --bucket my-vpc-flow-logs-bucket \
  --policy file://s3-flow-logs-policy.json

# Créer Flow Logs vers S3
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-0123456789abcdef0 \
  --traffic-type ALL \
  --log-destination-type s3 \
  --log-destination arn:aws:s3:::my-vpc-flow-logs-bucket \
  --tag-specifications 'ResourceType=vpc-flow-log,Tags=[{Key=Name,Value=VPC-FlowLogs-S3}]'

# EXPLICATION:
# --log-destination = ARN du bucket S3
# Logs stockés comme fichiers compressés (.gz)
# Format: s3://bucket/prefix/AWSLogs/account_id/vpcflowlogs/region/year/month/day/

# Organiser avec préfixe
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-0123456789abcdef0 \
  --traffic-type ALL \
  --log-destination-type s3 \
  --log-destination arn:aws:s3:::my-vpc-flow-logs-bucket/production/ \
  --log-format '${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}'

# EXPLICATION:
# --log-format = Format custom des logs
# Permet choisir quels champs inclure
# Plus compact = moins cher

# FORMAT PAR DÉFAUT:
# ${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}

# FORMAT CUSTOM MINIMAL (économiser):
# ${srcaddr} ${dstaddr} ${action}

# CRÉER FLOW LOGS - KINESIS DATA FIREHOSE
════════════════════════════════════════════════════════════════════════════════

# Pour streaming vers outils externes (Splunk, Datadog, etc.)

aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-0123456789abcdef0 \
  --traffic-type ALL \
  --log-destination-type kinesis-data-firehose \
  --log-destination arn:aws:firehose:us-east-1:123456789012:deliverystream/my-flow-logs-stream

# LISTER FLOW LOGS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les flow logs
aws ec2 describe-flow-logs

# Lister flow logs d'un VPC
aws ec2 describe-flow-logs \
  --filter "Name=resource-id,Values=vpc-0123456789abcdef0"

# Format lisible
aws ec2 describe-flow-logs \
  --query 'FlowLogs[*].[FlowLogId,ResourceId,TrafficType,LogDestinationType,FlowLogStatus,Tags[?Key==`Name`].Value|[0]]' \
  --output table

# RÉSULTAT EXEMPLE:
# --------------------------------------------------------------------------------
# | fl-abc123  | vpc-0123456789abcdef0 | ALL | cloud-watch-logs | ACTIVE | VPC-FlowLogs |
# | fl-def456  | subnet-abc123         | ALL | s3               | ACTIVE | Subnet-Logs  |
# --------------------------------------------------------------------------------

# Obtenir flow log spécifique
aws ec2 describe-flow-logs \
  --flow-log-ids fl-0123456789abcdef0

# VOIR LES LOGS (CLOUDWATCH)
════════════════════════════════════════════════════════════════════════════════

# Voir logs en temps réel
aws logs tail /aws/vpc/flowlogs --follow

# Filtrer par IP source
aws logs filter-log-events \
  --log-group-name /aws/vpc/flowlogs \
  --filter-pattern "10.0.1.5"

# Filtrer trafic rejeté
aws logs filter-log-events \
  --log-group-name /aws/vpc/flowlogs \
  --filter-pattern "REJECT"

# Filtrer par port (ex: SSH port 22)
aws logs filter-log-events \
  --log-group-name /aws/vpc/flowlogs \
  --filter-pattern "[version, account, eni, source, destination, srcport, dstport=22, protocol, packets, bytes, windowstart, windowend, action, flowlogstatus]"

# Voir logs d'une période spécifique
aws logs filter-log-events \
  --log-group-name /aws/vpc/flowlogs \
  --start-time 1620000000000 \
  --end-time 1620086400000

# ANALYSER LOGS (EXEMPLES PRATIQUES)
════════════════════════════════════════════════════════════════════════════════

# EXEMPLE 1: Trouver top IPs qui génèrent le plus de trafic
# (Requiert CloudWatch Insights ou télécharger logs S3)

# CloudWatch Insights query:
# fields @timestamp, srcaddr, dstaddr, bytes
# | stats sum(bytes) as totalBytes by srcaddr
# | sort totalBytes desc
# | limit 10

# EXEMPLE 2: Identifier connexions rejetées (problèmes connectivité)
# Filter pattern CloudWatch: "REJECT"

# EXEMPLE 3: Analyser trafic vers port spécifique
# Filter: [version, account, eni, source, destination, srcport, dstport=3306, ...]

# EXEMPLE 4: Détecter scan de ports
# Chercher nombreuses connexions rejetées depuis même IP
# Filter: "REJECT" puis grouper par srcaddr

# EXEMPLE LOG ENTRY EXPLIQUÉ:
# 2 123456789012 eni-abc123 10.0.1.5 172.217.14.206 49152 443 6 20 4000 1620000000 1620000060 ACCEPT OK
# 
# version: 2
# account-id: 123456789012
# interface-id: eni-abc123
# srcaddr: 10.0.1.5 (IP source - instance)
# dstaddr: 172.217.14.206 (IP destination - Google)
# srcport: 49152 (port éphémère)
# dstport: 443 (HTTPS)
# protocol: 6 (TCP)
# packets: 20
# bytes: 4000
# start: 1620000000 (timestamp début)
# end: 1620000060 (timestamp fin)
# action: ACCEPT (autorisé)
# log-status: OK (log valide)

# SUPPRIMER FLOW LOGS
════════════════════════════════════════════════════════════════════════════════

# Supprimer flow log
aws ec2 delete-flow-logs \
  --flow-log-ids fl-0123456789abcdef0

# EXPLICATION:
# Logs existants restent dans CloudWatch/S3
# Nouveaux logs ne seront plus capturés

# Supprimer log group CloudWatch (si plus utilisé)
aws logs delete-log-group \
  --log-group-name /aws/vpc/flowlogs

# [ATTENTION] Cela supprime TOUS les logs!

# COÛTS FLOW LOGS
════════════════════════════════════════════════════════════════════════════════

# CloudWatch Logs:
# - Ingestion: $0.50 per GB
# - Stockage: $0.03 per GB par mois
# - CHER pour gros volumes!

# S3:
# - Pas de frais ingestion
# - Stockage: $0.023 per GB par mois (Standard)
# - $0.0125 per GB (Intelligent-Tiering)
# - MOINS CHER pour long terme

# RECOMMANDATION:
# - CloudWatch: Analyse temps réel, troubleshooting
# - S3: Archive, conformité, analyse batch


═══════════════════════════════════════════════════════════════════════════════
[OK] ARCHITECTURE VPC COMPLÈTE - EXEMPLE PRODUCTION
═══════════════════════════════════════════════════════════════════════════════

# ARCHITECTURE 3-TIER (Web + App + Database)
# 
# VPC: 10.0.0.0/16 (us-east-1)
# 
# PUBLIC SUBNETS (2 AZs):
#   - 10.0.1.0/24 (us-east-1a) -> Web servers, Load Balancer
#   - 10.0.2.0/24 (us-east-1b) -> Web servers, Load Balancer
#   - Internet Gateway
#   - NAT Gateway (1 par AZ)
# 
# PRIVATE SUBNETS (Application - 2 AZs):
#   - 10.0.10.0/24 (us-east-1a) -> App servers
#   - 10.0.11.0/24 (us-east-1b) -> App servers
#   - Route vers NAT Gateway pour Internet sortant
# 
# PRIVATE SUBNETS (Database - 2 AZs):
#   - 10.0.20.0/24 (us-east-1a) -> RDS Primary
#   - 10.0.21.0/24 (us-east-1b) -> RDS Standby
#   - Isolé (pas d'accès Internet)
# 
# SECURITY GROUPS:
#   - ALB-SG: 80,443 depuis 0.0.0.0/0
#   - Web-SG: 80,443 depuis ALB-SG
#   - App-SG: 8080 depuis Web-SG
#   - DB-SG: 3306 depuis App-SG
#   - Bastion-SG: 22 depuis IP admin

# SCRIPT COMPLET CRÉATION ARCHITECTURE
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Création VPC production complet

set -e  # Arrêter si erreur

# Variables
VPC_CIDR="10.0.0.0/16"
REGION="us-east-1"
AZ1="us-east-1a"
AZ2="us-east-1b"

echo "=== Création VPC ==="
VPC_ID=$(aws ec2 create-vpc \
  --cidr-block $VPC_CIDR \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=Production-VPC}]' \
  --query 'Vpc.VpcId' \
  --output text)

echo "VPC créé: $VPC_ID"

# Activer DNS
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-support
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames

echo "=== Création Subnets ==="

# Public Subnets
PUBLIC_SUBNET_1=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.1.0/24 \
  --availability-zone $AZ1 \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-1A}]' \
  --query 'Subnet.SubnetId' \
  --output text)

PUBLIC_SUBNET_2=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.2.0/24 \
  --availability-zone $AZ2 \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-1B}]' \
  --query 'Subnet.SubnetId' \
  --output text)

# Activer auto-assign public IP
aws ec2 modify-subnet-attribute --subnet-id $PUBLIC_SUBNET_1 --map-public-ip-on-launch
aws ec2 modify-subnet-attribute --subnet-id $PUBLIC_SUBNET_2 --map-public-ip-on-launch

# Private Subnets (App)
PRIVATE_APP_SUBNET_1=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.10.0/24 \
  --availability-zone $AZ1 \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-App-Subnet-1A}]' \
  --query 'Subnet.SubnetId' \
  --output text)

PRIVATE_APP_SUBNET_2=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.11.0/24 \
  --availability-zone $AZ2 \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-App-Subnet-1B}]' \
  --query 'Subnet.SubnetId' \
  --output text)

# Private Subnets (Database)
PRIVATE_DB_SUBNET_1=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.20.0/24 \
  --availability-zone $AZ1 \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-DB-Subnet-1A}]' \
  --query 'Subnet.SubnetId' \
  --output text)

PRIVATE_DB_SUBNET_2=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.21.0/24 \
  --availability-zone $AZ2 \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-DB-Subnet-1B}]' \
  --query 'Subnet.SubnetId' \
  --output text)

echo "Subnets créés"

echo "=== Création Internet Gateway ==="
IGW_ID=$(aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=Production-IGW}]' \
  --query 'InternetGateway.InternetGatewayId' \
  --output text)

aws ec2 attach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID
echo "Internet Gateway créé et attaché: $IGW_ID"

echo "=== Création NAT Gateways ==="

# Elastic IPs pour NAT Gateways
EIP1_ALLOC=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)
EIP2_ALLOC=$(aws ec2 allocate-address --domain vpc --query 'AllocationId' --output text)

# NAT Gateway AZ1
NAT_GW_1=$(aws ec2 create-nat-gateway \
  --subnet-id $PUBLIC_SUBNET_1 \
  --allocation-id $EIP1_ALLOC \
  --tag-specifications 'ResourceType=nat-gateway,Tags=[{Key=Name,Value=NAT-Gateway-1A}]' \
  --query 'NatGateway.NatGatewayId' \
  --output text)

# NAT Gateway AZ2
NAT_GW_2=$(aws ec2 create-nat-gateway \
  --subnet-id $PUBLIC_SUBNET_2 \
  --allocation-id $EIP2_ALLOC \
  --tag-specifications 'ResourceType=nat-gateway,Tags=[{Key=Name,Value=NAT-Gateway-1B}]' \
  --query 'NatGateway.NatGatewayId' \
  --output text)

echo "Attente NAT Gateways disponibles..."
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW_1 $NAT_GW_2
echo "NAT Gateways créés: $NAT_GW_1, $NAT_GW_2"

echo "=== Création Route Tables ==="

# Route Table Public
PUBLIC_RT=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Public-RT}]' \
  --query 'RouteTable.RouteTableId' \
  --output text)

# Route vers Internet Gateway
aws ec2 create-route \
  --route-table-id $PUBLIC_RT \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id $IGW_ID

# Associer subnets publics
aws ec2 associate-route-table --route-table-id $PUBLIC_RT --subnet-id $PUBLIC_SUBNET_1
aws ec2 associate-route-table --route-table-id $PUBLIC_RT --subnet-id $PUBLIC_SUBNET_2

# Route Table Private AZ1
PRIVATE_RT_1=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Private-RT-1A}]' \
  --query 'RouteTable.RouteTableId' \
  --output text)

aws ec2 create-route \
  --route-table-id $PRIVATE_RT_1 \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id $NAT_GW_1

aws ec2 associate-route-table --route-table-id $PRIVATE_RT_1 --subnet-id $PRIVATE_APP_SUBNET_1

# Route Table Private AZ2
PRIVATE_RT_2=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Private-RT-1B}]' \
  --query 'RouteTable.RouteTableId' \
  --output text)

aws ec2 create-route \
  --route-table-id $PRIVATE_RT_2 \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id $NAT_GW_2

aws ec2 associate-route-table --route-table-id $PRIVATE_RT_2 --subnet-id $PRIVATE_APP_SUBNET_2

# Route Table Database (pas d'Internet)
DB_RT=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Database-RT}]' \
  --query 'RouteTable.RouteTableId' \
  --output text)

aws ec2 associate-route-table --route-table-id $DB_RT --subnet-id $PRIVATE_DB_SUBNET_1
aws ec2 associate-route-table --route-table-id $DB_RT --subnet-id $PRIVATE_DB_SUBNET_2

echo "Route Tables créées"

echo "=== Création Security Groups ==="

# ALB Security Group
ALB_SG=$(aws ec2 create-security-group \
  --group-name ALB-SG \
  --description "Security group for Application Load Balancer" \
  --vpc-id $VPC_ID \
  --query 'GroupId' \
  --output text)

aws ec2 authorize-security-group-ingress \
  --group-id $ALB_SG \
  --ip-permissions '[
    {"IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "IpRanges": [{"CidrIp": "0.0.0.0/0"}]},
    {"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443, "IpRanges": [{"CidrIp": "0.0.0.0/0"}]}
  ]'

# Web Security Group
WEB_SG=$(aws ec2 create-security-group \
  --group-name Web-SG \
  --description "Security group for web servers" \
  --vpc-id $VPC_ID \
  --query 'GroupId' \
  --output text)

aws ec2 authorize-security-group-ingress \
  --group-id $WEB_SG \
  --ip-permissions '[
    {"IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "UserIdGroupPairs": [{"GroupId": "'$ALB_SG'"}]},
    {"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443, "UserIdGroupPairs": [{"GroupId": "'$ALB_SG'"}]}
  ]'

# App Security Group
APP_SG=$(aws ec2 create-security-group \
  --group-name App-SG \
  --description "Security group for application servers" \
  --vpc-id $VPC_ID \
  --query 'GroupId' \
  --output text)

aws ec2 authorize-security-group-ingress \
  --group-id $APP_SG \
  --protocol tcp \
  --port 8080 \
  --source-group $WEB_SG

# Database Security Group
DB_SG=$(aws ec2 create-security-group \
  --group-name DB-SG \
  --description "Security group for database" \
  --vpc-id $VPC_ID \
  --query 'GroupId' \
  --output text)

aws ec2 authorize-security-group-ingress \
  --group-id $DB_SG \
  --protocol tcp \
  --port 3306 \
  --source-group $APP_SG

echo "Security Groups créés"

echo "=== Création VPC Endpoints ==="

# S3 Gateway Endpoint
S3_ENDPOINT=$(aws ec2 create-vpc-endpoint \
  --vpc-id $VPC_ID \
  --service-name com.amazonaws.$REGION.s3 \
  --route-table-ids $PRIVATE_RT_1 $PRIVATE_RT_2 \
  --query 'VpcEndpoint.VpcEndpointId' \
  --output text)

echo "S3 Endpoint créé: $S3_ENDPOINT"

echo "=== Activation Flow Logs ==="

# Créer log group
aws logs create-log-group --log-group-name /aws/vpc/production-flowlogs
aws logs put-retention-policy --log-group-name /aws/vpc/production-flowlogs --retention-in-days 7

# Flow Logs (supposant role déjà créé)
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids $VPC_ID \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /aws/vpc/production-flowlogs \
  --deliver-logs-permission-arn arn:aws:iam::123456789012:role/VPC-FlowLogs-Role

echo "=== ARCHITECTURE COMPLÈTE CRÉÉE ==="
echo "VPC ID: $VPC_ID"
echo "Public Subnets: $PUBLIC_SUBNET_1, $PUBLIC_SUBNET_2"
echo "Private App Subnets: $PRIVATE_APP_SUBNET_1, $PRIVATE_APP_SUBNET_2"
echo "Private DB Subnets: $PRIVATE_DB_SUBNET_1, $PRIVATE_DB_SUBNET_2"
echo "Security Groups: ALB=$ALB_SG, Web=$WEB_SG, App=$APP_SG, DB=$DB_SG"


═══════════════════════════════════════════════════════════════════════════════
[OK] TROUBLESHOOTING VPC - PROBLÈMES COURANTS
═══════════════════════════════════════════════════════════════════════════════

# PROBLÈME 1: Instance ne peut pas accéder Internet
════════════════════════════════════════════════════════════════════════════════

# CAUSE POSSIBLE 1: Pas de route vers IGW/NAT
# Vérifier route table
aws ec2 describe-route-tables \
  --filters "Name=association.subnet-id,Values=subnet-xxx" \
  --query 'RouteTables[0].Routes'

# SOLUTION: Ajouter route
aws ec2 create-route \
  --route-table-id rtb-xxx \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id igw-xxx  # ou --nat-gateway-id nat-xxx

# CAUSE POSSIBLE 2: Security Group bloque trafic sortant
# Vérifier règles sortantes
aws ec2 describe-security-groups \
  --group-ids sg-xxx \
  --query 'SecurityGroups[0].IpPermissionsEgress'

# SOLUTION: Autoriser trafic sortant
aws ec2 authorize-security-group-egress \
  --group-id sg-xxx \
  --protocol -1 \
  --cidr 0.0.0.0/0

# CAUSE POSSIBLE 3: NACL bloque trafic
# Vérifier NACL
aws ec2 describe-network-acls \
  --filters "Name=association.subnet-id,Values=subnet-xxx"

# SOLUTION: Ajouter règles NACL (voir section NACL)


# PROBLÈME 2: Impossible de SSH vers instance
════════════════════════════════════════════════════════════════════════════════

# CAUSE 1: Security Group ne permet pas SSH
aws ec2 describe-security-groups \
  --group-ids sg-xxx \
  --query 'SecurityGroups[0].IpPermissions'

# SOLUTION: Autoriser SSH
aws ec2 authorize-security-group-ingress \
  --group-id sg-xxx \
  --protocol tcp \
  --port 22 \
  --cidr YOUR_IP/32

# CAUSE 2: Instance dans subnet privé sans bastion
# SOLUTION: Utiliser bastion host ou AWS Systems Manager Session Manager

# CAUSE 3: NACL bloque port 22 ou ports éphémères
# Vérifier NACL entrante (port 22) et sortante (ports 1024-65535)


# PROBLÈME 3: RDS dans VPC inaccessible depuis Lambda
════════════════════════════════════════════════════════════════════════════════

# CAUSE: Lambda pas dans même VPC que RDS

# SOLUTION: Mettre Lambda dans VPC
aws lambda update-function-configuration \
  --function-name my-function \
  --vpc-config SubnetIds=subnet-private1,subnet-private2,SecurityGroupIds=sg-lambda

# Puis autoriser Lambda SG dans RDS SG
aws ec2 authorize-security-group-ingress \
  --group-id sg-rds \
  --protocol tcp \
  --port 3306 \
  --source-group sg-lambda


# PROBLÈME 4: VPC Peering ne fonctionne pas
════════════════════════════════════════════════════════════════════════════════

# CAUSE 1: Peering accepté mais pas de routes
# Vérifier routes des DEUX côtés

aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=vpc-A" \
  --query 'RouteTables[*].Routes'

# SOLUTION: Ajouter routes dans les deux VPCs

# CAUSE 2: Security Groups bloquent trafic
# Security Groups ne reconnaissent pas automatiquement peering
# SOLUTION: Autoriser par CIDR, pas par SG

aws ec2 authorize-security-group-ingress \
  --group-id sg-vpc-b \
  --protocol tcp \
  --port 80 \
  --cidr 10.0.0.0/16  # CIDR de VPC-A


# PROBLÈME 5: Flow Logs ne montrent rien
════════════════════════════════════════════════════════════════════════════════

# CAUSE 1: IAM role manque permissions
# Vérifier permissions role

aws iam get-role-policy \
  --role-name VPC-FlowLogs-Role \
  --policy-name VPC-FlowLogs-Policy

# CAUSE 2: Flow Logs juste créés (délai 10-15 min)
# Attendre quelques minutes

# CAUSE 3: Pas de trafic réseau
# Générer trafic pour tester
ping 8.8.8.8


# PROBLÈME 6: NAT Gateway trop cher
════════════════════════════════════════════════════════════════════════════════

# COÛT: ~$0.045/heure + $0.045/GB

# SOLUTION 1: Utiliser VPC Endpoints pour services AWS
# Évite NAT Gateway pour S3, DynamoDB, etc.

# SOLUTION 2: Utiliser 1 NAT Gateway au lieu de 1 par AZ
# [ATTENTION] Perd haute disponibilité!

# SOLUTION 3: Arrêter instances privées quand non utilisées
# Réduire trafic sortant


# PROBLÈME 7: "CIDR block overlaps with existing CIDR block"
════════════════════════════════════════════════════════════════════════════════

# CAUSE: Tentative créer subnet/VPC avec CIDR qui existe déjà

# Lister CIDRs existants
aws ec2 describe-vpcs \
  --query 'Vpcs[*].[VpcId,CidrBlock]' \
  --output table

aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=vpc-xxx" \
  --query 'Subnets[*].[SubnetId,CidrBlock]' \
  --output table

# SOLUTION: Utiliser CIDR différent non-chevauchant


# PROBLÈME 8: "Network acl acl-xxx has dependencies"
════════════════════════════════════════════════════════════════════════════════

# CAUSE: NACL encore associée à subnets

# Voir associations
aws ec2 describe-network-acls \
  --network-acl-ids acl-xxx \
  --query 'NetworkAcls[0].Associations'

# SOLUTION: Désassocier d'abord
# (Subnets retournent à NACL par défaut automatiquement)


═══════════════════════════════════════════════════════════════════════════════
[OK] BEST PRACTICES VPC
═══════════════════════════════════════════════════════════════════════════════

# [OK] SÉCURITÉ
════════════════════════════════════════════════════════════════════════════════

1. PRINCIPE DU MOINDRE PRIVILÈGE
   - Security Groups: Autoriser SEULEMENT ports nécessaires
   - NACL: Bloquer IPs malveillantes connues
   - Ne JAMAIS autoriser 0.0.0.0/0 sur SSH (port 22)

2. DÉFENSE EN PROFONDEUR
   - Security Groups (instance) + NACL (subnet)
   - Public subnet -> Web servers seulement
   - Private subnet -> App servers, databases
   - Database subnet -> Isolé, pas d'Internet

3. BASTION HOST ou SESSION MANAGER
   - Ne PAS exposer SSH directement sur Internet
   - Utiliser bastion dans subnet public
   - OU AWS Systems Manager Session Manager (meilleur)

4. VPC FLOW LOGS
   - Activer pour audit et troubleshooting
   - Retention court (7 jours) pour réduire coûts
   - Analyser logs régulièrement

5. ENCRYPTION
   - VPC endpoints pour S3/DynamoDB
   - HTTPS entre services
   - TLS pour RDS

# [OK] HAUTE DISPONIBILITÉ
════════════════════════════════════════════════════════════════════════════════

1. MULTI-AZ
   - Au moins 2 subnets dans 2 AZs différentes
   - Load Balancer couvre 2+ AZs
   - RDS Multi-AZ

2. NAT GATEWAY
   - 1 par AZ pour HA (sinon single point of failure)
   - Coût: 2× mais critique

3. ROUTE TABLES
   - Route table privée par AZ
   - Chaque AZ route vers son propre NAT Gateway

# [OK] COÛTS
════════════════════════════════════════════════════════════════════════════════

1. VPC ENDPOINTS
   - S3/DynamoDB Gateway Endpoints (gratuit)
   - Évite coûts NAT Gateway pour AWS services

2. NAT GATEWAY vs NAT INSTANCE
   - NAT Gateway: Simple mais $$$
   - NAT Instance: Moins cher mais complexe
   - Pour prod: NAT Gateway (fiabilité)

3. FLOW LOGS
   - S3 moins cher que CloudWatch
   - Retention court
   - Filtrer traffic type (REJECT seulement)

4. ELASTIC IPs
   - Libérer IPs non utilisées ($0.005/h)
   - 1 EIP gratuite par instance en cours

# [OK] DESIGN CIDR
════════════════════════════════════════════════════════════════════════════════

1. TAILLE VPC
   - Commencer grand: /16 (65k IPs)
   - Permet croissance future
   - Impossible d'agrandir VPC après!

2. SUBNETS
   - Utiliser /24 (256 IPs) pour subnets
   - Réserver ranges pour expansion:
     * 10.0.0.0/20 = Public (16 subnets /24)
     * 10.0.16.0/20 = Private App (16 subnets /24)
     * 10.0.32.0/20 = Private DB (16 subnets /24)
     * 10.0.48.0/20 = Réservé futur

3. ÉVITER OVERLAPS
   - On-premise: 192.168.0.0/16
   - AWS VPC: 10.0.0.0/16
   - Jamais même range!

# [OK] NAMING CONVENTIONS
════════════════════════════════════════════════════════════════════════════════

# Tags standardisés:
# - Name: Production-VPC
# - Environment: prod / dev / staging
# - Owner: team-platform
# - CostCenter: engineering
# - Project: webapp

# Exemple:
aws ec2 create-tags \
  --resources vpc-xxx subnet-xxx \
  --tags \
    Key=Name,Value=Production-VPC \
    Key=Environment,Value=prod \
    Key=Owner,Value=team-platform \
    Key=CostCenter,Value=engineering


# [OK] DOCUMENTATION
════════════════════════════════════════════════════════════════════════════════

# Documenter:
# - Diagramme architecture réseau
# - CIDR allocations
# - Security Groups et leurs règles
# - NACLs et leurs règles
# - VPC Peerings
# - VPC Endpoints

# Exemple diagram:
# Production VPC (10.0.0.0/16)
# ├─ Public Subnets
# │  ├─ 10.0.1.0/24 (us-east-1a) - ALB, Bastion
# │  └─ 10.0.2.0/24 (us-east-1b) - ALB, Bastion
# ├─ Private App Subnets
# │  ├─ 10.0.10.0/24 (us-east-1a) - App Servers
# │  └─ 10.0.11.0/24 (us-east-1b) - App Servers
# └─ Private DB Subnets
#    ├─ 10.0.20.0/24 (us-east-1a) - RDS Primary
#    └─ 10.0.21.0/24 (us-east-1b) - RDS Standby


═══════════════════════════════════════════════════════════════════════════════
[OK] SUPPRIMER VPC - NETTOYAGE COMPLET
═══════════════════════════════════════════════════════════════════════════════

# [ATTENTION] ORDRE IMPORTANT: Supprimer dépendances d'abord!

# 1. Supprimer instances EC2
aws ec2 terminate-instances --instance-ids i-xxx i-yyy

# Attendre terminaison
aws ec2 wait instance-terminated --instance-ids i-xxx i-yyy

# 2. Supprimer NAT Gateways
aws ec2 delete-nat-gateway --nat-gateway-id nat-xxx

# Attendre suppression (prend 5-10 min)
aws ec2 wait nat-gateway-deleted --nat-gateway-ids nat-xxx

# 3. Libérer Elastic IPs
aws ec2 release-address --allocation-id eipalloc-xxx

# 4. Supprimer VPC Endpoints
aws ec2 delete-vpc-endpoints --vpc-endpoint-ids vpce-xxx vpce-yyy

# 5. Supprimer Load Balancers (si présents)
aws elbv2 delete-load-balancer --load-balancer-arn arn:xxx

# Attendre suppression
aws elbv2 wait load-balancer-deleted --load-balancer-arns arn:xxx

# 6. Supprimer Target Groups
aws elbv2 delete-target-group --target-group-arn arn:xxx

# 7. Supprimer RDS instances (si présentes)
aws rds delete-db-instance \
  --db-instance-identifier mydb \
  --skip-final-snapshot

# 8. Supprimer VPC Peering Connections
aws ec2 delete-vpc-peering-connection --vpc-peering-connection-id pcx-xxx

# 9. Supprimer Custom Route Tables
# (Obtenir IDs d'abord)
aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=vpc-xxx" \
  --query 'RouteTables[?Associations[0].Main==`false`].RouteTableId' \
  --output text

# Désassocier subnets
aws ec2 disassociate-route-table --association-id rtbassoc-xxx

# Supprimer route table
aws ec2 delete-route-table --route-table-id rtb-xxx

# 10. Détacher et supprimer Internet Gateway
aws ec2 detach-internet-gateway \
  --internet-gateway-id igw-xxx \
  --vpc-id vpc-xxx

aws ec2 delete-internet-gateway --internet-gateway-id igw-xxx

# 11. Supprimer Subnets
aws ec2 delete-subnet --subnet-id subnet-xxx

# 12. Supprimer Custom NACLs
aws ec2 delete-network-acl --network-acl-id acl-xxx

# 13. Supprimer Custom Security Groups
aws ec2 delete-security-group --group-id sg-xxx

# 14. Supprimer VPC
aws ec2 delete-vpc --vpc-id vpc-xxx

# SCRIPT AUTOMATIQUE NETTOYAGE
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Supprimer VPC et toutes dépendances

VPC_ID="vpc-0123456789abcdef0"

echo "Suppression VPC: $VPC_ID"

# Instances
echo "Terminaison instances..."
INSTANCES=$(aws ec2 describe-instances \
  --filters "Name=vpc-id,Values=$VPC_ID" "Name=instance-state-name,Values=running,stopped" \
  --query 'Reservations[*].Instances[*].InstanceId' \
  --output text)

if [ ! -z "$INSTANCES" ]; then
  aws ec2 terminate-instances --instance-ids $INSTANCES
  aws ec2 wait instance-terminated --instance-ids $INSTANCES
fi

# NAT Gateways
echo "Suppression NAT Gateways..."
NAT_GWS=$(aws ec2 describe-nat-gateways \
  --filter "Name=vpc-id,Values=$VPC_ID" "Name=state,Values=available" \
  --query 'NatGateways[*].NatGatewayId' \
  --output text)

for nat in $NAT_GWS; do
  aws ec2 delete-nat-gateway --nat-gateway-id $nat
done

# Attendre suppression NAT Gateways
if [ ! -z "$NAT_GWS" ]; then
  sleep 60
fi

# Elastic IPs
echo "Libération Elastic IPs..."
EIPS=$(aws ec2 describe-addresses \
  --filters "Name=domain,Values=vpc" \
  --query 'Addresses[?AssociationId==null].AllocationId' \
  --output text)

for eip in $EIPS; do
  aws ec2 release-address --allocation-id $eip 2>/dev/null || true
done

# VPC Endpoints
echo "Suppression VPC Endpoints..."
ENDPOINTS=$(aws ec2 describe-vpc-endpoints \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'VpcEndpoints[*].VpcEndpointId' \
  --output text)

if [ ! -z "$ENDPOINTS" ]; then
  aws ec2 delete-vpc-endpoints --vpc-endpoint-ids $ENDPOINTS
fi

# VPC Peering Connections
echo "Suppression Peering Connections..."
PEERINGS=$(aws ec2 describe-vpc-peering-connections \
  --filters "Name=requester-vpc-info.vpc-id,Values=$VPC_ID" \
  --query 'VpcPeeringConnections[*].VpcPeeringConnectionId' \
  --output text)

for peer in $PEERINGS; do
  aws ec2 delete-vpc-peering-connection --vpc-peering-connection-id $peer
done

# Internet Gateways
echo "Suppression Internet Gateways..."
IGWS=$(aws ec2 describe-internet-gateways \
  --filters "Name=attachment.vpc-id,Values=$VPC_ID" \
  --query 'InternetGateways[*].InternetGatewayId' \
  --output text)

for igw in $IGWS; do
  aws ec2 detach-internet-gateway --internet-gateway-id $igw --vpc-id $VPC_ID
  aws ec2 delete-internet-gateway --internet-gateway-id $igw
done

# Subnets
echo "Suppression Subnets..."
SUBNETS=$(aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'Subnets[*].SubnetId' \
  --output text)

for subnet in $SUBNETS; do
  aws ec2 delete-subnet --subnet-id $subnet 2>/dev/null || true
done

# Route Tables (non-main)
echo "Suppression Route Tables..."
ROUTE_TABLES=$(aws ec2 describe-route-tables \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'RouteTables[?Associations[0].Main==`false`].RouteTableId' \
  --output text)

for rt in $ROUTE_TABLES; do
  aws ec2 delete-route-table --route-table-id $rt 2>/dev/null || true
done

# Network ACLs (non-default)
echo "Suppression Network ACLs..."
NACLS=$(aws ec2 describe-network-acls \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'NetworkAcls[?IsDefault==`false`].NetworkAclId' \
  --output text)

for nacl in $NACLS; do
  aws ec2 delete-network-acl --network-acl-id $nacl 2>/dev/null || true
done

# Security Groups (non-default)
echo "Suppression Security Groups..."
SGS=$(aws ec2 describe-security-groups \
  --filters "Name=vpc-id,Values=$VPC_ID" \
  --query 'SecurityGroups[?GroupName!=`default`].GroupId' \
  --output text)

for sg in $SGS; do
  aws ec2 delete-security-group --group-id $sg 2>/dev/null || true
done

# VPC
echo "Suppression VPC..."
aws ec2 delete-vpc --vpc-id $VPC_ID

echo "VPC supprimé: $VPC_ID"


═══════════════════════════════════════════════════════════════════════════════
[OK] COMMANDES RAPIDES - QUICK REFERENCE
═══════════════════════════════════════════════════════════════════════════════

# VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16
aws ec2 describe-vpcs
aws ec2 delete-vpc --vpc-id vpc-xxx

# Subnets
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.1.0/24 --availability-zone us-east-1a
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-xxx"
aws ec2 delete-subnet --subnet-id subnet-xxx

# Internet Gateway
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway --internet-gateway-id igw-xxx --vpc-id vpc-xxx
aws ec2 detach-internet-gateway --internet-gateway-id igw-xxx --vpc-id vpc-xxx
aws ec2 delete-internet-gateway --internet-gateway-id igw-xxx

# NAT Gateway
aws ec2 allocate-address --domain vpc
aws ec2 create-nat-gateway --subnet-id subnet-xxx --allocation-id eipalloc-xxx
aws ec2 delete-nat-gateway --nat-gateway-id nat-xxx
aws ec2 release-address --allocation-id eipalloc-xxx

# Route Tables
aws ec2 create-route-table --vpc-id vpc-xxx
aws ec2 create-route --route-table-id rtb-xxx --destination-cidr-block 0.0.0.0/0 --gateway-id igw-xxx
aws ec2 associate-route-table --route-table-id rtb-xxx --subnet-id subnet-xxx
aws ec2 describe-route-tables --filters "Name=vpc-id,Values=vpc-xxx"

# Security Groups
aws ec2 create-security-group --group-name NAME --description "DESC" --vpc-id vpc-xxx
aws ec2 authorize-security-group-ingress --group-id sg-xxx --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 describe-security-groups --group-ids sg-xxx
aws ec2 delete-security-group --group-id sg-xxx

# VPC Peering
aws ec2 create-vpc-peering-connection --vpc-id vpc-xxx --peer-vpc-id vpc-yyy
aws ec2 accept-vpc-peering-connection --vpc-peering-connection-id pcx-xxx
aws ec2 delete-vpc-peering-connection --vpc-peering-connection-id pcx-xxx

# VPC Endpoints
aws ec2 create-vpc-endpoint --vpc-id vpc-xxx --service-name com.amazonaws.REGION.s3 --route-table-ids rtb-xxx
aws ec2 describe-vpc-endpoints --filters "Name=vpc-id,Values=vpc-xxx"
aws ec2 delete-vpc-endpoints --vpc-endpoint-ids vpce-xxx

# Flow Logs
aws ec2 create-flow-logs --resource-type VPC --resource-ids vpc-xxx --traffic-type ALL \
  --log-destination-type cloud-watch-logs --log-group-name /aws/vpc/flowlogs \
  --deliver-logs-permission-arn arn:xxx
aws ec2 describe-flow-logs
aws ec2 delete-flow-logs --flow-log-ids fl-xxx


═══════════════════════════════════════════════════════════════════════════════
[OK] RESSOURCES UTILES
═══════════════════════════════════════════════════════════════════════════════

# Documentation officielle
https://docs.aws.amazon.com/vpc/

# VPC Pricing
https://aws.amazon.com/vpc/pricing/

# CIDR Calculator
https://www.ipaddressguide.com/cidr

# VPC Best Practices
https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-best-practices.html

# VPC Flow Logs Analysis
https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html

# Outil visualisation: VPC Reachability Analyzer
https://docs.aws.amazon.com/vpc/latest/reachability/

# AWS Network Firewall (protection avancée)
https://aws.amazon.com/network-firewall/