# Fichier: python_cheats/cheatsheets/route_53.txt
# Cheatsheet AWS Route 53 - DNS Service Expliqué en Détail


═══════════════════════════════════════════════════════════════════════════════
[OK] AWS ROUTE 53 - C'EST QUOI?
═══════════════════════════════════════════════════════════════════════════════

ROUTE 53 = "Service DNS géré par AWS"

DNS (Domain Name System) = "Annuaire téléphonique d'Internet"

ANALOGIE:
- Vous tapez: www.example.com (nom facile à retenir)
- DNS traduit: 203.0.113.25 (adresse IP réelle)
- Comme annuaire: "Jean Dupont" -> "01 23 45 67 89"

POURQUOI "ROUTE 53"?
- Port DNS = 53
- Route = Router le trafic
- 53 = Clin d'œil au protocole DNS

PROBLÈME SANS ROUTE 53:
[X] Gérer serveurs DNS soi-même (complexe)
[X] Pas de haute disponibilité automatique
[X] Pas d'intégration AWS services
[X] Configuration manuelle fastidieuse

SOLUTION ROUTE 53:
[OK] DNS géré (pas de serveurs à maintenir)
[OK] 100% disponibilité (SLA)
[OK] Intégration AWS (ELB, CloudFront, S3)
[OK] Routing policies avancées
[OK] Health checks automatiques
[OK] Domain registration (acheter domaines)

FONCTIONNALITÉS PRINCIPALES:
1. DOMAIN REGISTRATION -> Acheter domaines (.com, .fr, etc.)
2. DNS HOSTING -> Héberger zones DNS
3. HEALTH CHECKS -> Surveiller santé endpoints
4. TRAFFIC MANAGEMENT -> Router intelligemment trafic
5. DNSSEC -> Sécurité DNS

CONCEPTS CLÉS:
- HOSTED ZONE = Zone DNS pour un domaine
- RECORD = Entrée DNS (A, CNAME, MX, etc.)
- TTL (Time To Live) = Durée cache DNS
- ALIAS = Record spécial AWS (gratuit, meilleur)
- NAMESERVERS = Serveurs DNS autoritaires

TYPES DE RECORDS DNS:
- A -> Nom -> IPv4 (ex: example.com -> 203.0.113.25)
- AAAA -> Nom -> IPv6
- CNAME -> Alias vers autre nom (ex: www -> example.com)
- MX -> Serveurs mail
- TXT -> Texte (vérification domaine, SPF)
- NS -> Nameservers
- SOA -> Start of Authority (info zone)
- ALIAS -> Spécial AWS (comme CNAME mais mieux)

PRICING:
- Hosted zone: $0.50/mois par zone
- Requêtes DNS: $0.40 par million (premier milliard)
- Health checks: $0.50/mois par check
- Domain registration: Variable ($12-50/an)

QUAND UTILISER ROUTE 53?
[OK] Site web/application avec domaine
[OK] Load balancing intelligent
[OK] Disaster recovery (failover)
[OK] Applications multi-régions
[OK] Microservices discovery

SLA:
- 100% disponibilité pour DNS queries
- Réseau anycast global (faible latence)


═══════════════════════════════════════════════════════════════════════════════
[OK] HOSTED ZONES - ZONES DNS
═══════════════════════════════════════════════════════════════════════════════

HOSTED ZONE = "Container pour tous les records d'un domaine"

TYPES:
1. PUBLIC HOSTED ZONE -> Internet public (example.com)
2. PRIVATE HOSTED ZONE -> VPC privé (internal.company.local)

EXEMPLE:
Domaine: example.com
Hosted Zone contient:
- example.com -> 203.0.113.25
- www.example.com -> 203.0.113.25
- mail.example.com -> 203.0.113.50
- api.example.com -> ALB DNS

# CRÉER HOSTED ZONE PUBLIC
════════════════════════════════════════════════════════════════════════════════

aws route53 create-hosted-zone \
  --name example.com \
  --caller-reference $(date +%s)

# EXPLICATION PARAMÈTRES:

# --name example.com
#   = Nom du domaine
#   = Peut être: example.com, subdomain.example.com
#   = Doit être unique

# --caller-reference $(date +%s)
#   = ID unique pour cette requête
#   = $(date +%s) = timestamp Unix
#   = Évite créer duplicatas par accident
#   = Toute valeur unique fonctionne

# RÉSULTAT:
# {
#   "HostedZone": {
#     "Id": "/hostedzone/Z1234567890ABC",
#     "Name": "example.com.",
#     "CallerReference": "1705334400",
#     "Config": {
#       "PrivateZone": false
#     },
#     "ResourceRecordSetCount": 2
#   },
#   "ChangeInfo": {
#     "Id": "/change/C1234567890DEF",
#     "Status": "PENDING",
#     "SubmittedAt": "2024-01-15T10:30:00.000Z"
#   },
#   "DelegationSet": {
#     "NameServers": [
#       "ns-123.awsdns-12.com",
#       "ns-456.awsdns-45.net",
#       "ns-789.awsdns-78.org",
#       "ns-012.awsdns-01.co.uk"
#     ]
#   }
# }

# IMPORTANT:
# [ATTENTION] Notez HostedZone.Id: Z1234567890ABC (besoin pour créer records)
# [ATTENTION] Notez NameServers (configurer chez registrar)

# QU'EST-CE QUI EST CRÉÉ:
# 1. Hosted Zone (container)
# 2. Record NS (nameservers)
# 3. Record SOA (Start of Authority)

# Créer hosted zone avec tags
aws route53 create-hosted-zone \
  --name example.com \
  --caller-reference $(date +%s) \
  --hosted-zone-config Comment="Production website" \
  --tags Key=Environment,Value=Production Key=Owner,Value=DevTeam

# EXPLICATION:
# --hosted-zone-config Comment="..."
#   = Description de la zone
# --tags = Tags pour organisation/facturation

# CRÉER HOSTED ZONE PRIVÉE (VPC)
════════════════════════════════════════════════════════════════════════════════

aws route53 create-hosted-zone \
  --name internal.company.local \
  --caller-reference $(date +%s) \
  --vpc VPCRegion=us-east-1,VPCId=vpc-0123456789abcdef0 \
  --hosted-zone-config PrivateZone=true

# EXPLICATION:

# --vpc VPCRegion=us-east-1,VPCId=vpc-xxx
#   = VPC où cette zone est accessible
#   = DNS résolu SEULEMENT dans ce VPC
#   = Parfait pour noms internes

# --hosted-zone-config PrivateZone=true
#   = Zone privée (pas publique)

# USE CASE PRIVATE ZONE:
# - database.internal.company.local -> RDS endpoint
# - api.internal.company.local -> Internal ALB
# - cache.internal.company.local -> ElastiCache
# Pas exposé à Internet!

# Associer VPC additionnel à zone privée
aws route53 associate-vpc-with-hosted-zone \
  --hosted-zone-id Z1234567890ABC \
  --vpc VPCRegion=us-west-2,VPCId=vpc-abcdef0123456789

# EXPLICATION:
# Même zone DNS accessible depuis plusieurs VPCs
# Utile pour multi-région

# LISTER HOSTED ZONES
════════════════════════════════════════════════════════════════════════════════

# Lister toutes les hosted zones
aws route53 list-hosted-zones

# Format lisible
aws route53 list-hosted-zones \
  --query 'HostedZones[*].[Id,Name,Config.PrivateZone,ResourceRecordSetCount]' \
  --output table

# RÉSULTAT EXEMPLE:
# ---------------------------------------------------------------------------
# | /hostedzone/Z123ABC | example.com.      | False | 5  |
# | /hostedzone/Z456DEF | internal.local.   | True  | 3  |
# ---------------------------------------------------------------------------

# Filtrer par nom
aws route53 list-hosted-zones \
  --query "HostedZones[?Name=='example.com.']"

# [ATTENTION] NOTEZ LE POINT FINAL:
# AWS ajoute automatiquement "." à la fin
# example.com -> example.com.
# C'est normal (FQDN = Fully Qualified Domain Name)

# OBTENIR HOSTED ZONE SPÉCIFIQUE
════════════════════════════════════════════════════════════════════════════════

# Obtenir détails hosted zone
aws route53 get-hosted-zone \
  --id Z1234567890ABC

# EXPLICATION:
# --id = ID de la hosted zone
# Peut être avec ou sans /hostedzone/ prefix
# Z1234567890ABC = valide
# /hostedzone/Z1234567890ABC = valide aussi

# Voir seulement nameservers
aws route53 get-hosted-zone \
  --id Z1234567890ABC \
  --query 'DelegationSet.NameServers' \
  --output table

# RÉSULTAT:
# ---------------------------------
# | ns-123.awsdns-12.com          |
# | ns-456.awsdns-45.net          |
# | ns-789.awsdns-78.org          |
# | ns-012.awsdns-01.co.uk        |
# ---------------------------------

# CONFIGURER NAMESERVERS CHEZ REGISTRAR
════════════════════════════════════════════════════════════════════════════════

# Après création hosted zone:
# 1. Obtenir nameservers Route 53
aws route53 get-hosted-zone \
  --id Z1234567890ABC \
  --query 'DelegationSet.NameServers'

# 2. Aller chez registrar (GoDaddy, Namecheap, etc.)
# 3. Remplacer nameservers par ceux de Route 53
# 4. Attendre propagation (5 min - 48h)

# EXEMPLE CONFIGURATION:
# Chez GoDaddy:
# Nameserver 1: ns-123.awsdns-12.com
# Nameserver 2: ns-456.awsdns-45.net
# Nameserver 3: ns-789.awsdns-78.org
# Nameserver 4: ns-012.awsdns-01.co.uk

# VÉRIFIER PROPAGATION:
# dig example.com NS
# nslookup -type=NS example.com
# Ou: https://www.whatsmydns.net/

# SUPPRIMER HOSTED ZONE
════════════════════════════════════════════════════════════════════════════════

# [ATTENTION] ATTENTION: Supprimer zone = supprimer tous les records!

# D'abord, lister et supprimer tous les records (sauf NS et SOA)
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABC

# Supprimer hosted zone
aws route53 delete-hosted-zone \
  --id Z1234567890ABC

# ERREUR SI:
# "The specified hosted zone contains non-required resource record sets"
# CAUSE: Records autres que NS/SOA existent
# SOLUTION: Supprimer tous les records d'abord


═══════════════════════════════════════════════════════════════════════════════
[OK] DNS RECORDS - ENTRÉES DNS
═══════════════════════════════════════════════════════════════════════════════

DNS RECORD = "Mapping nom -> valeur"

STRUCTURE RECORD:
- Name: Nom (ex: www.example.com)
- Type: A, AAAA, CNAME, MX, TXT, etc.
- TTL: Durée cache (secondes)
- Value: Valeur (IP, nom, texte)

TTL (Time To Live):
- 300s (5 min) = Standard
- 60s (1 min) = Changements fréquents
- 3600s (1h) = Stable, économise requêtes
- Plus court = Plus flexible mais plus de requêtes DNS

# CRÉER RECORD A (IPv4)
════════════════════════════════════════════════════════════════════════════════

# Préparer change batch JSON
cat > create-a-record.json << 'EOF'
{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "203.0.113.25"
          }
        ]
      }
    }
  ]
}
EOF

# Appliquer changement
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://create-a-record.json

# EXPLICATION DÉTAILLÉE:

# "Action": "CREATE"
#   = Créer nouveau record
#   = Options: CREATE, DELETE, UPSERT
#   = UPSERT = Create ou Update (recommandé)

# "Name": "www.example.com"
#   = Nom complet (FQDN)
#   = Peut omettre domaine: "www" (AWS ajoute .example.com)

# "Type": "A"
#   = Type de record
#   = A = IPv4 address

# "TTL": 300
#   = Time To Live (secondes)
#   = 300s = 5 minutes
#   = Cache DNS gardera cette valeur 5 min

# "ResourceRecords": [{"Value": "203.0.113.25"}]
#   = Liste de valeurs (peut avoir plusieurs IPs)

# RÉSULTAT:
# {
#   "ChangeInfo": {
#     "Id": "/change/C1234567890DEF",
#     "Status": "PENDING",
#     "SubmittedAt": "2024-01-15T10:35:00.000Z"
#   }
# }

# Status: PENDING -> Changement en cours (30-60 secondes)
# Status: INSYNC -> Changement appliqué

# Vérifier statut changement
aws route53 get-change --id C1234567890DEF

# CRÉER RECORD AVEC PLUSIEURS IPs (ROUND-ROBIN)
════════════════════════════════════════════════════════════════════════════════

cat > multi-ip-record.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {"Value": "203.0.113.25"},
          {"Value": "203.0.113.26"},
          {"Value": "203.0.113.27"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://multi-ip-record.json

# COMMENT ÇA MARCHE:
# DNS retourne les 3 IPs en rotation
# Client choisit aléatoirement
# Résultat: Load balancing basique
# [ATTENTION] Pas de health checks!

# CRÉER RECORD CNAME (ALIAS)
════════════════════════════════════════════════════════════════════════════════

cat > cname-record.json << 'EOF'
{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "blog.example.com",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [
          {"Value": "example.wordpress.com"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://cname-record.json

# EXPLICATION CNAME:
# blog.example.com -> example.wordpress.com
# Client résout:
# 1. blog.example.com -> CNAME -> example.wordpress.com
# 2. example.wordpress.com -> A -> IP
# Deux résolutions DNS!

# [ATTENTION] LIMITATIONS CNAME:
# NE PEUT PAS être utilisé pour apex/root domain!
# [X] example.com CNAME -> autre.com (INVALIDE)
# [OK] www.example.com CNAME -> autre.com (VALIDE)
# Solution pour apex: Utiliser ALIAS record

# CRÉER ALIAS RECORD (SPÉCIAL AWS) - RECOMMANDÉ
════════════════════════════════════════════════════════════════════════════════

# ALIAS = Comme CNAME mais:
# [OK] Fonctionne pour apex/root domain
# [OK] Gratuit (pas de frais DNS queries)
# [OK] Health checks intégrés
# [OK] Résolution DNS directe (plus rapide)

# Alias vers Application Load Balancer
cat > alias-to-alb.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "example.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z35SXDOTRQ7X7K",
          "DNSName": "my-alb-1234567890.us-east-1.elb.amazonaws.com",
          "EvaluateTargetHealth": true
        }
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://alias-to-alb.json

# EXPLICATION PARAMÈTRES:

# "Type": "A"
#   = Toujours A ou AAAA pour Alias
#   = Pas de TTL (géré automatiquement)

# "AliasTarget"
#   = Configuration alias

# "HostedZoneId": "Z35SXDOTRQ7X7K"
#   = Hosted Zone ID du service AWS cible
#   = DIFFÉRENT de votre hosted zone!
#   = Chaque région ELB a son propre ID
#   = us-east-1 ALB = Z35SXDOTRQ7X7K
#   = us-west-2 ALB = Z1H1FL5HABSF5

# TROUVER HOSTED ZONE ID ELB:
aws elbv2 describe-load-balancers \
  --names my-alb \
  --query 'LoadBalancers[0].CanonicalHostedZoneId' \
  --output text

# "DNSName": "my-alb-123....elb.amazonaws.com"
#   = DNS name du ALB
#   = Obtenir avec: describe-load-balancers

# "EvaluateTargetHealth": true
#   = Vérifier santé ALB
#   = Si ALB unhealthy -> Route 53 ne route pas vers lui
#   = Recommandé: true

# HOSTED ZONE IDs COMMUNS:
# ALB/NLB us-east-1: Z35SXDOTRQ7X7K
# ALB/NLB us-west-2: Z1H1FL5HABSF5
# CloudFront: Z2FDTNDATAQYW2
# S3 Website us-east-1: Z3AQBSTGFYJSTF
# Liste complète: https://docs.aws.amazon.com/general/latest/gr/elb.html

# Alias vers CloudFront
cat > alias-to-cloudfront.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "cdn.example.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "DNSName": "d123456789.cloudfront.net",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}
EOF

# EXPLICATION:
# HostedZoneId CloudFront = Toujours Z2FDTNDATAQYW2 (global)
# EvaluateTargetHealth = false (CloudFront n'a pas health checks)

# Alias vers S3 Static Website
cat > alias-to-s3.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "static.example.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z3AQBSTGFYJSTF",
          "DNSName": "my-bucket.s3-website-us-east-1.amazonaws.com",
          "EvaluateTargetHealth": false
        }
      }
    }
  ]
}
EOF

# [ATTENTION] IMPORTANT S3:
# Nom bucket DOIT matcher nom DNS!
# Domaine: static.example.com
# Bucket: static.example.com
# Sinon ça ne marche pas!

# CRÉER RECORD MX (MAIL)
════════════════════════════════════════════════════════════════════════════════

cat > mx-record.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "example.com",
        "Type": "MX",
        "TTL": 300,
        "ResourceRecords": [
          {"Value": "10 mail1.example.com"},
          {"Value": "20 mail2.example.com"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://mx-record.json

# EXPLICATION MX:
# "10 mail1.example.com"
#   = 10 = priorité (plus bas = plus prioritaire)
#   = mail1.example.com = serveur mail
# Emails essaient mail1 d'abord, puis mail2 si échec

# Exemple Gmail:
# {"Value": "1 aspmx.l.google.com"},
# {"Value": "5 alt1.aspmx.l.google.com"},
# {"Value": "5 alt2.aspmx.l.google.com"}

# CRÉER RECORD TXT (VERIFICATION, SPF)
════════════════════════════════════════════════════════════════════════════════

cat > txt-record.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "example.com",
        "Type": "TXT",
        "TTL": 300,
        "ResourceRecords": [
          {"Value": "\"v=spf1 include:_spf.google.com ~all\""},
          {"Value": "\"google-site-verification=ABC123DEF456\""}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://txt-record.json

# EXPLICATION TXT:
# Valeur DOIT être entre guillemets doubles échappés
# \"texte\" = correct
# SPF = Autorise serveurs à envoyer emails
# Vérification = Prouver ownership domaine

# LISTER TOUS LES RECORDS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les records d'une zone
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABC

# Format lisible
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --query 'ResourceRecordSets[*].[Name,Type,TTL]' \
  --output table

# RÉSULTAT EXEMPLE:
# ----------------------------------------------------------
# | example.com.           | SOA   | 900  |
# | example.com.           | NS    | 172800 |
# | example.com.           | A     | 300  |
# | www.example.com.       | A     | 300  |
# | blog.example.com.      | CNAME | 300  |
# | mail.example.com.      | A     | 300  |
# ----------------------------------------------------------

# Filtrer par type
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --query "ResourceRecordSets[?Type=='A']"

# Filtrer par nom
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --query "ResourceRecordSets[?Name=='www.example.com.']"

# MODIFIER RECORD EXISTANT
════════════════════════════════════════════════════════════════════════════════

# Utiliser Action: UPSERT (Update or Insert)
cat > update-record.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "203.0.113.100"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://update-record.json

# EXPLICATION:
# UPSERT = Si record existe -> update, sinon -> create
# Recommandé car idempotent

# SUPPRIMER RECORD
════════════════════════════════════════════════════════════════════════════════

# Pour supprimer, doit spécifier EXACT mêmes valeurs
cat > delete-record.json << 'EOF'
{
  "Changes": [
    {
      "Action": "DELETE",
      "ResourceRecordSet": {
        "Name": "blog.example.com",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [
          {"Value": "example.wordpress.com"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://delete-record.json

# [ATTENTION] IMPORTANT:
# Tous les champs doivent matcher exactement!
# Name, Type, TTL, ResourceRecords
# Sinon erreur: "Invalid change batch"

# BATCH OPERATIONS (MULTIPLE CHANGEMENTS)
════════════════════════════════════════════════════════════════════════════════

# Créer/modifier/supprimer plusieurs records en une commande
cat > batch-changes.json << 'EOF'
{
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "api.example.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [{"Value": "203.0.113.50"}]
      }
    },
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "TTL": 60,
        "ResourceRecords": [{"Value": "203.0.113.100"}]
      }
    },
    {
      "Action": "DELETE",
      "ResourceRecordSet": {
        "Name": "old.example.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [{"Value": "203.0.113.99"}]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://batch-changes.json

# EXPLICATION:
# Tous les changements appliqués atomiquement
# Si un échoue -> tous échouent (rollback)
# Max 1000 changes par batch


═══════════════════════════════════════════════════════════════════════════════
[OK] HEALTH CHECKS - SURVEILLER DISPONIBILITÉ
═══════════════════════════════════════════════════════════════════════════════

HEALTH CHECK = "Surveiller si endpoint est accessible"

TYPES:
1. ENDPOINT -> Vérifie URL/IP spécifique
2. CALCULATED -> Combine plusieurs health checks
3. CLOUDWATCH ALARM -> Basé sur métrique CloudWatch

USE CASES:
- Failover automatique
- Load balancing intelligent
- Alertes si service down

# CRÉER HEALTH CHECK ENDPOINT (HTTPS)
════════════════════════════════════════════════════════════════════════════════

aws route53 create-health-check \
  --health-check-config '{
    "Type": "HTTPS",
    "ResourcePath": "/health",
    "FullyQualifiedDomainName": "api.example.com",
    "Port": 443,
    "RequestInterval": 30,
    "FailureThreshold": 3
  }' \
  --caller-reference $(date +%s)

# EXPLICATION PARAMÈTRES:

# "Type": "HTTPS"
#   = Protocole à vérifier
#   = Options: HTTP, HTTPS, TCP, HTTP_STR_MATCH, HTTPS_STR_MATCH

# "ResourcePath": "/health"
#   = Chemin URL à vérifier
#   = GET https://api.example.com/health
#   = Doit retourner 200 OK

# "FullyQualifiedDomainName": "api.example.com"
#   = Domaine ou IP à vérifier

# "Port": 443
#   = Port à vérifier
#   = 443 = HTTPS, 80 = HTTP

# "RequestInterval": 30
#   = Intervalle entre checks (secondes)
#   = Options: 30 (standard, $0.50/mois), 10 (fast, $1/mois)

# "FailureThreshold": 3
#   = Nombre échecs consécutifs avant unhealthy
#   = 3 = Standard (équilibre entre faux positifs et rapidité)
#   = Range: 1-10

# RÉSULTAT:
# {
#   "HealthCheck": {
#     "Id": "12345678-1234-1234-1234-123456789012",
#     "CallerReference": "1705334400",
#     "HealthCheckConfig": {
#       "Type": "HTTPS",
#       "ResourcePath": "/health",
#       "FullyQualifiedDomainName": "api.example.com",
#       "Port": 443,
#       "RequestInterval": 30,
#       "FailureThreshold": 3
#     },
#     "HealthCheckVersion": 1
#   }
# }

# [ATTENTION] Notez HealthCheck.Id: 12345678-1234-1234-1234-123456789012

# COMMENT ÇA MARCHE:
# 1. Route 53 envoie requêtes depuis ~15 emplacements mondiaux
# 2. Toutes les 30 secondes, chaque emplacement vérifie
# 3. Si ≥18% emplacements (3+) échouent -> unhealthy
# 4. Si unhealthy -> failover déclenché (si configuré)

# CRÉER HEALTH CHECK AVEC STRING MATCHING
════════════════════════════════════════════════════════════════════════════════

# Vérifier que réponse contient texte spécifique

aws route53 create-health-check \
  --health-check-config '{
    "Type": "HTTPS_STR_MATCH",
    "ResourcePath": "/status",
    "FullyQualifiedDomainName": "api.example.com",
    "Port": 443,
    "RequestInterval": 30,
    "FailureThreshold": 3,
    "SearchString": "OK"
  }' \
  --caller-reference $(date +%s)

# EXPLICATION:

# "Type": "HTTPS_STR_MATCH"
#   = Vérifier string dans réponse
#   = HTTP_STR_MATCH pour HTTP

# "SearchString": "OK"
#   = Texte à chercher dans réponse
#   = Réponse doit contenir "OK" pour être healthy
#   = Case sensitive
#   = Premiers 5120 bytes seulement

# USE CASE:
# Endpoint /status retourne: {"status": "OK", "db": "connected"}
# Health check cherche "OK" -> Healthy
# Si retourne "ERROR" -> Unhealthy

# CRÉER HEALTH CHECK TCP
════════════════════════════════════════════════════════════════════════════════

# Juste vérifier si port ouvert (pas de HTTP)

aws route53 create-health-check \
  --health-check-config '{
    "Type": "TCP",
    "IPAddress": "203.0.113.25",
    "Port": 3306,
    "RequestInterval": 30,
    "FailureThreshold": 3
  }' \
  --caller-reference $(date +%s)

# EXPLICATION:
# Vérifie seulement connexion TCP
# Parfait pour: Databases, Redis, services non-HTTP
# "IPAddress" = IP directe (pas de DNS)

# CRÉER HEALTH CHECK CALCULATED (COMBINER)
════════════════════════════════════════════════════════════════════════════════

# Combine plusieurs health checks avec logique

aws route53 create-health-check \
  --health-check-config '{
    "Type": "CALCULATED",
    "ChildHealthChecks": [
      "12345678-1234-1234-1234-123456789012",
      "abcdefgh-abcd-abcd-abcd-abcdefghijkl"
    ],
    "HealthThreshold": 1
  }' \
  --caller-reference $(date +%s)

# EXPLICATION:

# "Type": "CALCULATED"
#   = Combiner plusieurs health checks

# "ChildHealthChecks": [...]
#   = Liste de health check IDs à surveiller

# "HealthThreshold": 1
#   = Minimum health checks healthy pour être healthy
#   = 1 = Au moins 1 doit être healthy (OR logic)
#   = 2 = Au moins 2 doivent être healthy (AND logic partiel)

# USE CASE:
# Surveiller API dans 2 régions
# Healthy si au moins 1 région UP

# CRÉER HEALTH CHECK CLOUDWATCH ALARM
════════════════════════════════════════════════════════════════════════════════

# Basé sur métrique CloudWatch (ex: CPU, custom metric)

# 1. Créer CloudWatch Alarm d'abord
aws cloudwatch put-metric-alarm \
  --alarm-name high-error-rate \
  --alarm-description "Error rate above 5%" \
  --metric-name ErrorRate \
  --namespace MyApp \
  --statistic Average \
  --period 60 \
  --evaluation-periods 2 \
  --threshold 5 \
  --comparison-operator GreaterThanThreshold

# 2. Créer Health Check basé sur alarm
aws route53 create-health-check \
  --health-check-config '{
    "Type": "CLOUDWATCH_METRIC",
    "AlarmIdentifier": {
      "Region": "us-east-1",
      "Name": "high-error-rate"
    },
    "InsufficientDataHealthStatus": "Healthy"
  }' \
  --caller-reference $(date +%s)

# EXPLICATION:

# "Type": "CLOUDWATCH_METRIC"
#   = Basé sur CloudWatch

# "AlarmIdentifier"
#   = Quelle alarme surveiller
#   = Region + Name

# "InsufficientDataHealthStatus": "Healthy"
#   = Statut si données insuffisantes
#   = Options: Healthy, Unhealthy, LastKnownStatus

# USE CASE:
# Surveiller métriques applicatives complexes
# Ex: Taux d'erreur, latence p99, queue depth

# AJOUTER TAGS À HEALTH CHECK
════════════════════════════════════════════════════════════════════════════════

aws route53 change-tags-for-resource \
  --resource-type healthcheck \
  --resource-id 12345678-1234-1234-1234-123456789012 \
  --add-tags Key=Environment,Value=Production Key=Owner,Value=DevTeam

# LISTER HEALTH CHECKS
════════════════════════════════════════════════════════════════════════════════

# Lister tous les health checks
aws route53 list-health-checks

# Format lisible
aws route53 list-health-checks \
  --query 'HealthChecks[*].[Id,HealthCheckConfig.Type,HealthCheckConfig.FullyQualifiedDomainName]' \
  --output table

# RÉSULTAT EXEMPLE:
# -------------------------------------------------------------------------
# | 12345678-... | HTTPS     | api.example.com           |
# | abcdefgh-... | TCP       | None (IP: 203.0.113.25)   |
# | ijklmnop-... | CALCULATED| None                      |
# -------------------------------------------------------------------------

# VOIR STATUT HEALTH CHECK
════════════════════════════════════════════════════════════════════════════════

# Obtenir statut actuel
aws route53 get-health-check-status \
  --health-check-id 12345678-1234-1234-1234-123456789012

# RÉSULTAT EXEMPLE:
# {
#   "HealthCheckObservations": [
#     {
#       "Region": "us-east-1",
#       "IPAddress": "54.239.98.1",
#       "StatusReport": {
#         "Status": "Success",
#         "CheckedTime": "2024-01-15T10:40:00.000Z"
#       }
#     },
#     {
#       "Region": "eu-west-1",
#       "IPAddress": "54.239.98.2",
#       "StatusReport": {
#         "Status": "Success",
#         "CheckedTime": "2024-01-15T10:40:00.000Z"
#       }
#     },
#     ...
#   ]
# }

# EXPLICATION:
# ~15 emplacements vérifient indépendamment
# Status pour chaque emplacement
# Healthy global si ≥18% successful

# CONFIGURER ALARMES SNS
════════════════════════════════════════════════════════════════════════════════

# Recevoir notification si unhealthy

# 1. Créer SNS topic
aws sns create-topic --name healthcheck-alerts

# 2. Souscrire email
aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:healthcheck-alerts \
  --protocol email \
  --notification-endpoint ops@example.com

# 3. Configurer health check pour notifier
aws route53 update-health-check \
  --health-check-id 12345678-1234-1234-1234-123456789012 \
  --alarm-identifier Region=us-east-1,Name=healthcheck-alarm

# 4. Créer CloudWatch Alarm pour health check
aws cloudwatch put-metric-alarm \
  --alarm-name healthcheck-alarm \
  --alarm-description "Health check failed" \
  --namespace AWS/Route53 \
  --metric-name HealthCheckStatus \
  --dimensions Name=HealthCheckId,Value=12345678-1234-1234-1234-123456789012 \
  --statistic Minimum \
  --period 60 \
  --evaluation-periods 1 \
  --threshold 1 \
  --comparison-operator LessThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:healthcheck-alerts

# MODIFIER HEALTH CHECK
════════════════════════════════════════════════════════════════════════════════

# Changer configuration existante
aws route53 update-health-check \
  --health-check-id 12345678-1234-1234-1234-123456789012 \
  --failure-threshold 5 \
  --resource-path "/healthz"

# Désactiver health check temporairement
aws route53 update-health-check \
  --health-check-id 12345678-1234-1234-1234-123456789012 \
  --disabled

# Réactiver
aws route53 update-health-check \
  --health-check-id 12345678-1234-1234-1234-123456789012 \
  --no-disabled

# SUPPRIMER HEALTH CHECK
════════════════════════════════════════════════════════════════════════════════

aws route53 delete-health-check \
  --health-check-id 12345678-1234-1234-1234-123456789012

# [ATTENTION] ERREUR SI:
# Health check utilisé par records DNS
# SOLUTION: Supprimer/modifier records d'abord


═══════════════════════════════════════════════════════════════════════════════
[OK] ROUTING POLICIES - STRATEGIES DE ROUTAGE
═══════════════════════════════════════════════════════════════════════════════

ROUTING POLICY = "Comment Route 53 répond aux requêtes DNS"

7 TYPES:
1. SIMPLE -> Une seule ressource ou plusieurs (random)
2. WEIGHTED -> Répartition par pourcentage (A/B testing)
3. LATENCY -> Route vers région la plus proche
4. FAILOVER -> Primary/Secondary (disaster recovery)
5. GEOLOCATION -> Route basé sur localisation utilisateur
6. GEOPROXIMITY -> Route basé sur proximité géographique + bias
7. MULTIVALUE -> Multiple IPs avec health checks

# 1. SIMPLE ROUTING - LE PLUS BASIQUE
════════════════════════════════════════════════════════════════════════════════

# Simple = 1 record, 1+ valeurs
# DNS retourne toutes les valeurs en rotation aléatoire

cat > simple-routing.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [
          {"Value": "203.0.113.25"},
          {"Value": "203.0.113.26"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://simple-routing.json

# COMMENT ÇA MARCHE:
# Client A: Reçoit 203.0.113.25, puis 203.0.113.26
# Client B: Reçoit 203.0.113.26, puis 203.0.113.25
# Ordre aléatoire

# [ATTENTION] LIMITATIONS:
# Pas de health checks
# Si 203.0.113.25 down -> clients peuvent l'obtenir quand même

# USE CASE:
# Petit site, pas besoin complexité
# Ressources toutes équivalentes


# 2. WEIGHTED ROUTING - RÉPARTITION PAR POURCENTAGE
════════════════════════════════════════════════════════════════════════════════

# Weighted = Contrôler % trafic vers chaque ressource
# Parfait pour A/B testing, canary deployments

# Record 1: 70% trafic
cat > weighted-record-1.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Production-Server-1",
        "Weight": 70,
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "203.0.113.25"}
        ]
      }
    }
  ]
}
EOF

# Record 2: 30% trafic
cat > weighted-record-2.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Production-Server-2",
        "Weight": 30,
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "203.0.113.26"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://weighted-record-1.json

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://weighted-record-2.json

# EXPLICATION PARAMÈTRES:

# "SetIdentifier": "Production-Server-1"
#   = ID unique pour ce record
#   = OBLIGATOIRE pour weighted/latency/failover/geolocation
#   = Doit être différent pour chaque record même nom

# "Weight": 70
#   = Poids relatif
#   = 70 + 30 = 100 total
#   = 70/100 = 70% trafic
#   = Peut utiliser n'importe quels nombres (ex: 7 et 3)

# CALCUL POURCENTAGE:
# Poids record / Somme tous poids = %
# 70 / (70+30) = 70%
# 30 / (70+30) = 30%

# COMMENT ÇA MARCHE:
# 100 requêtes DNS:
# ~70 reçoivent 203.0.113.25
# ~30 reçoivent 203.0.113.26

# USE CASES:
# - A/B testing: 90% version A, 10% version B
# - Canary deployment: 95% old, 5% new
# - Load distribution: 50/50 entre 2 datacenters
# - Blue/Green: 100% blue -> 50/50 -> 100% green

# Weighted avec Health Checks
cat > weighted-with-health.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "US-East",
        "Weight": 70,
        "TTL": 60,
        "HealthCheckId": "12345678-1234-1234-1234-123456789012",
        "ResourceRecords": [
          {"Value": "203.0.113.25"}
        ]
      }
    }
  ]
}
EOF

# EXPLICATION:
# Si health check échoue -> record ignoré
# Tout trafic va vers autres records healthy


# 3. LATENCY ROUTING - PLUS PROCHE GÉOGRAPHIQUEMENT
════════════════════════════════════════════════════════════════════════════════

# Latency = Router vers région avec latence la plus faible

# US East (Virginie)
cat > latency-us-east.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "US-East-Servers",
        "Region": "us-east-1",
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "203.0.113.25"}
        ]
      }
    }
  ]
}
EOF

# EU West (Irlande)
cat > latency-eu-west.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "EU-West-Servers",
        "Region": "eu-west-1",
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "198.51.100.50"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://latency-us-east.json

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://latency-eu-west.json

# EXPLICATION:

# "Region": "us-east-1"
#   = Région AWS de cette ressource
#   = Route 53 mesure latence utilisateur vers chaque région
#   = Choisit région avec latence la plus faible

# COMMENT ÇA MARCHE:
# Utilisateur New York -> us-east-1 (latence 5ms)
# Utilisateur Paris -> eu-west-1 (latence 10ms)
# Utilisateur Tokyo -> ap-northeast-1 (si configuré)

# [ATTENTION] IMPORTANT:
# Basé sur latence réseau AWS, pas distance géographique
# Latence mesurée par AWS entre user et région

# Latency avec Alias (vers ALB)
cat > latency-alias-us.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "US-East-ALB",
        "Region": "us-east-1",
        "AliasTarget": {
          "HostedZoneId": "Z35SXDOTRQ7X7K",
          "DNSName": "my-alb-us.us-east-1.elb.amazonaws.com",
          "EvaluateTargetHealth": true
        }
      }
    }
  ]
}
EOF


# 4. FAILOVER ROUTING - PRIMARY/SECONDARY
════════════════════════════════════════════════════════════════════════════════

# Failover = Active/Passive disaster recovery

# Primary (actif)
cat > failover-primary.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Primary-Site",
        "Failover": "PRIMARY",
        "TTL": 60,
        "HealthCheckId": "12345678-1234-1234-1234-123456789012",
        "ResourceRecords": [
          {"Value": "203.0.113.25"}
        ]
      }
    }
  ]
}
EOF

# Secondary (backup)
cat > failover-secondary.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Secondary-Site",
        "Failover": "SECONDARY",
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "198.51.100.50"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://failover-primary.json

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://failover-secondary.json

# EXPLICATION:

# "Failover": "PRIMARY"
#   = Ressource principale
#   = Toujours utilisée si healthy

# "Failover": "SECONDARY"
#   = Ressource backup
#   = Utilisée SEULEMENT si primary unhealthy

# "HealthCheckId"
#   = Health check du primary (OBLIGATOIRE)
#   = Si échoue -> bascule vers secondary

# COMMENT ÇA MARCHE:
# 1. Primary healthy -> Tout trafic vers primary
# 2. Primary unhealthy -> Tout trafic vers secondary
# 3. Primary redevient healthy -> Retour vers primary

# USE CASE:
# - Site principal us-east-1
# - Site backup eu-west-1
# - Si us-east-1 down -> failover automatique vers eu-west-1

# Failover avec Alias (Active-Passive ALBs)
cat > failover-alb-primary.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Primary-ALB-US",
        "Failover": "PRIMARY",
        "AliasTarget": {
          "HostedZoneId": "Z35SXDOTRQ7X7K",
          "DNSName": "primary-alb.us-east-1.elb.amazonaws.com",
          "EvaluateTargetHealth": true
        }
      }
    }
  ]
}
EOF


# 5. GEOLOCATION ROUTING - PAR LOCALISATION
════════════════════════════════════════════════════════════════════════════════

# Geolocation = Router basé sur localisation géographique utilisateur

# Europe
cat > geo-europe.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Europe-Servers",
        "GeoLocation": {
          "ContinentCode": "EU"
        },
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "198.51.100.50"}
        ]
      }
    }
  ]
}
EOF

# Amérique du Nord
cat > geo-north-america.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "North-America-Servers",
        "GeoLocation": {
          "ContinentCode": "NA"
        },
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "203.0.113.25"}
        ]
      }
    }
  ]
}
EOF

# Default (si aucun match)
cat > geo-default.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Default-Servers",
        "GeoLocation": {
          "ContinentCode": "*"
        },
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "203.0.113.100"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://geo-europe.json

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://geo-north-america.json

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://geo-default.json

# EXPLICATION:

# "GeoLocation": {"ContinentCode": "EU"}
#   = Continent Europe
#   = Options: AF, AN, AS, EU, NA, OC, SA

# "GeoLocation": {"ContinentCode": "*"}
#   = Default/fallback
#   = Utilisé si aucun autre match
#   = [ATTENTION] RECOMMANDÉ d'avoir un default!

# GRANULARITÉ GEOLOCATION:
# 1. Continent (le moins spécifique)
# 2. Pays
# 3. État/Province (US seulement)

# Par pays
cat > geo-france.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "France-Servers",
        "GeoLocation": {
          "CountryCode": "FR"
        },
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "198.51.100.75"}
        ]
      }
    }
  ]
}
EOF

# Par état US
cat > geo-california.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "California-Servers",
        "GeoLocation": {
          "CountryCode": "US",
          "SubdivisionCode": "CA"
        },
        "TTL": 60,
        "ResourceRecords": [
          {"Value": "203.0.113.150"}
        ]
      }
    }
  ]
}
EOF

# PRIORITÉ MATCHING:
# 1. État/Province (plus spécifique)
# 2. Pays
# 3. Continent
# 4. Default

# EXEMPLE:
# Utilisateur Californie:
#   1. Cherche CA, US -> Trouve -> 203.0.113.150
# Utilisateur New York:
#   1. Cherche NY, US -> Pas trouvé
#   2. Cherche US -> Pas trouvé
#   3. Cherche NA -> Trouve -> 203.0.113.25

# USE CASES:
# - Conformité légale (données en UE pour users UE)
# - Content localization (langue, currency)
# - Restrictions géographiques (licensing)


# 6. GEOPROXIMITY ROUTING - PROXIMITÉ + BIAS
════════════════════════════════════════════════════════════════════════════════

# Geoproximity = Comme latency mais avec contrôle bias

# [ATTENTION] Nécessite Traffic Flow (interface graphique)
# Pas disponible directement via CLI
# Doit utiliser console ou API Traffic Flow

# CONCEPT:
# Bias = Augmenter/réduire zone d'influence
# Bias +50 = Attirer plus de trafic (zone plus grande)
# Bias -50 = Repousser trafic (zone plus petite)

# USE CASE:
# 2 datacenters:
# - US: Capacité énorme -> Bias +30
# - EU: Capacité limitée -> Bias -20
# Résultat: Plus de trafic vers US même si latence similaire


# 7. MULTIVALUE ROUTING - MULTIPLE IPs + HEALTH CHECKS
════════════════════════════════════════════════════════════════════════════════

# Multivalue = Multiple records avec health checks individuels
# Comme Simple mais avec health checks

# Server 1
cat > multivalue-1.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Server-1",
        "MultiValueAnswer": true,
        "TTL": 60,
        "HealthCheckId": "health-check-1",
        "ResourceRecords": [
          {"Value": "203.0.113.25"}
        ]
      }
    }
  ]
}
EOF

# Server 2
cat > multivalue-2.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Server-2",
        "MultiValueAnswer": true,
        "TTL": 60,
        "HealthCheckId": "health-check-2",
        "ResourceRecords": [
          {"Value": "203.0.113.26"}
        ]
      }
    }
  ]
}
EOF

# Server 3
cat > multivalue-3.json << 'EOF'
{
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "A",
        "SetIdentifier": "Server-3",
        "MultiValueAnswer": true,
        "TTL": 60,
        "HealthCheckId": "health-check-3",
        "ResourceRecords": [
          {"Value": "203.0.113.27"}
        ]
      }
    }
  ]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://multivalue-1.json

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://multivalue-2.json

aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch file://multivalue-3.json

# EXPLICATION:

# "MultiValueAnswer": true
#   = Activer multivalue routing

# "HealthCheckId"
#   = Health check pour ce record spécifique
#   = Si unhealthy -> record exclu des réponses

# COMMENT ÇA MARCHE:
# Route 53 retourne jusqu'à 8 IPs healthy
# Client choisit aléatoirement
# Si Server-2 unhealthy:
#   -> Retourne seulement Server-1 et Server-3

# DIFFÉRENCE vs SIMPLE:
# Simple: Retourne tous, même unhealthy
# Multivalue: Retourne seulement healthy

# USE CASE:
# Load balancing simple avec health checks
# Alternative économique à ELB pour cas simples


═══════════════════════════════════════════════════════════════════════════════
[OK] DOMAIN REGISTRATION - ACHETER DOMAINES
═══════════════════════════════════════════════════════════════════════════════

# Route 53 = Aussi registrar (acheter domaines)

# VÉRIFIER DISPONIBILITÉ DOMAINE
════════════════════════════════════════════════════════════════════════════════

# Vérifier si domaine disponible
aws route53domains check-domain-availability \
  --domain-name example.com

# RÉSULTAT:
# {
#   "Availability": "AVAILABLE"
# }
# ou "UNAVAILABLE", "DONT_KNOW"

# VOIR PRIX DOMAINES
════════════════════════════════════════════════════════════════════════════════

# Obtenir prix pour extension
aws route53domains get-domain-detail \
  --domain-name example.com

# PRIX COMMUNS (USD/an):
# .com: $12-13
# .net: $11-12
# .org: $12-13
# .io: $39
# .ai: $49-99
# .fr: $12
# .co.uk: $9

# ENREGISTRER DOMAINE
════════════════════════════════════════════════════════════════════════════════

# [ATTENTION] Commande complexe, préférer console AWS
# Nécessite informations contact complètes

aws route53domains register-domain \
  --domain-name example.com \
  --duration-in-years 1 \
  --auto-renew \
  --admin-contact '{
    "FirstName": "John",
    "LastName": "Doe",
    "ContactType": "PERSON",
    "AddressLine1": "123 Main St",
    "City": "Seattle",
    "State": "WA",
    "CountryCode": "US",
    "ZipCode": "98101",
    "PhoneNumber": "+1.2065551234",
    "Email": "john@example.com"
  }' \
  --registrant-contact <same-as-admin> \
  --tech-contact <same-as-admin>

# EXPLICATION:
# --duration-in-years: 1-10 ans
# --auto-renew: Renouvellement automatique
# Contacts: Admin, Registrant, Tech (peuvent être identiques)

# LISTER DOMAINES ENREGISTRÉS
════════════════════════════════════════════════════════════════════════════════

aws route53domains list-domains

# TRANSFÉRER DOMAINE VERS ROUTE 53
════════════════════════════════════════════════════════════════════════════════

# 1. Déverrouiller domaine chez registrar actuel
# 2. Obtenir authorization code (EPP code)
# 3. Transférer

aws route53domains transfer-domain \
  --domain-name example.com \
  --duration-in-years 1 \
  --auth-code "ABC123DEF456"

# RENOUVELER DOMAINE
════════════════════════════════════════════════════════════════════════════════

aws route53domains renew-domain \
  --domain-name example.com \
  --duration-in-years 1

# PRIVACY PROTECTION
════════════════════════════════════════════════════════════════════════════════

# Cacher informations contact WHOIS (recommandé)
aws route53domains update-domain-contact-privacy \
  --domain-name example.com \
  --admin-privacy true \
  --registrant-privacy true \
  --tech-privacy true


═══════════════════════════════════════════════════════════════════════════════
[OK] TRAFFIC POLICIES - CONFIGURATIONS COMPLEXES
═══════════════════════════════════════════════════════════════════════════════

# Traffic Policy = Configuration routage complexe réutilisable
# Interface visuelle (console AWS recommandée)

# EXEMPLE COMBINAISON:
# 1. Geolocation (EU vs US)
# 2. Puis Weighted (50/50) dans chaque région
# 3. Puis Failover (Primary/Secondary) pour chaque

# STRUCTURE:
# www.example.com
# ├─ EU users
# │  ├─ 50% -> eu-west-1 (Primary)
# │  │        └─ Failover -> eu-central-1 (Secondary)
# │  └─ 50% -> eu-west-2 (Primary)
# │           └─ Failover -> eu-central-1 (Secondary)
# └─ US users
#    ├─ 50% -> us-east-1 (Primary)
#    │        └─ Failover -> us-west-2 (Secondary)
#    └─ 50% -> us-east-2 (Primary)
#             └─ Failover -> us-west-2 (Secondary)

# Traffic Policy CLI (création version JSON)
aws route53 create-traffic-policy \
  --name complex-routing \
  --document file://traffic-policy.json

# [ATTENTION] Complexe, préférer console AWS Traffic Flow


═══════════════════════════════════════════════════════════════════════════════
[OK] DNSSEC - SÉCURITÉ DNS
═══════════════════════════════════════════════════════════════════════════════

# DNSSEC = Signature cryptographique DNS
# Protège contre DNS spoofing/poisoning

# ACTIVER DNSSEC
════════════════════════════════════════════════════════════════════════════════

# 1. Enable DNSSEC signing
aws route53 enable-hosted-zone-dnssec \
  --hosted-zone-id Z1234567890ABC

# 2. Obtenir Delegation Signer (DS) records
aws route53 get-dnssec \
  --hosted-zone-id Z1234567890ABC

# 3. Ajouter DS records chez registrar
# (Via interface registrar)

# DÉSACTIVER DNSSEC
════════════════════════════════════════════════════════════════════════════════

aws route53 disable-hosted-zone-dnssec \
  --hosted-zone-id Z1234567890ABC

# [ATTENTION] ATTENTION:
# DNSSEC augmente complexité
# Peut causer problèmes si mal configuré
# Recommandé seulement si nécessaire (haute sécurité)


═══════════════════════════════════════════════════════════════════════════════
[OK] QUERY LOGGING - LOGS REQUÊTES DNS
═══════════════════════════════════════════════════════════════════════════════

# Query Logging = Enregistrer toutes les requêtes DNS

# ACTIVER QUERY LOGGING
════════════════════════════════════════════════════════════════════════════════

# 1. Créer CloudWatch Log Group
aws logs create-log-group \
  --log-group-name /aws/route53/example.com

# 2. Créer resource policy pour Route 53
cat > log-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "route53.amazonaws.com"
      },
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/example.com:*"
    }
  ]
}
EOF

aws logs put-resource-policy \
  --policy-name route53-query-logging \
  --policy-document file://log-policy.json

# 3. Créer query logging config
aws route53 create-query-logging-config \
  --hosted-zone-id Z1234567890ABC \
  --cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:/aws/route53/example.com

# LOGS CONTIENNENT:
# - Timestamp
# - Hosted Zone ID
# - Query Name (ex: www.example.com)
# - Query Type (A, AAAA, CNAME, etc.)
# - Response Code (NOERROR, NXDOMAIN, etc.)
# - Query Source IP
# - Edge Location

# EXEMPLE LOG:
# {
#   "version": "1.0",
#   "timestamp": "2024-01-15T10:45:00Z",
#   "query_name": "www.example.com",
#   "query_type": "A",
#   "response_code": "NOERROR",
#   "query_source": "203.0.113.50",
#   "edge_location": "IAD50"
# }

# LISTER QUERY LOGGING CONFIGS
════════════════════════════════════════════════════════════════════════════════

aws route53 list-query-logging-configs

# SUPPRIMER QUERY LOGGING
════════════════════════════════════════════════════════════════════════════════

aws route53 delete-query-logging-config \
  --id qlc-12345678-1234-1234-1234-123456789012

# [ATTENTION] COÛTS:
# Logs CloudWatch = $0.50/GB
# Peut devenir cher pour sites à fort trafic!


═══════════════════════════════════════════════════════════════════════════════
[OK] RESOLVER - DNS PRIVÉ HYBRIDE
═══════════════════════════════════════════════════════════════════════════════

# Resolver = Connecter DNS on-premise <-> AWS VPC

# CONCEPTS:
# - Inbound Endpoint: VPC -> On-premise (requêtes entrantes)
# - Outbound Endpoint: On-premise -> VPC (requêtes sortantes)
# - Forwarding Rules: Quels domaines forwarded

# CRÉER INBOUND ENDPOINT
════════════════════════════════════════════════════════════════════════════════

# Permettre on-premise de résoudre noms privés AWS

aws route53resolver create-resolver-endpoint \
  --name vpc-inbound-endpoint \
  --direction INBOUND \
  --security-group-ids sg-0123456789abcdef0 \
  --ip-addresses SubnetId=subnet-1,Ip=10.0.1.10 SubnetId=subnet-2,Ip=10.0.2.10

# EXPLICATION:
# Direction INBOUND = Recevoir requêtes de l'extérieur
# IPs: Route 53 Resolver endpoints dans VPC
# On-premise DNS forward vers ces IPs

# CRÉER OUTBOUND ENDPOINT
════════════════════════════════════════════════════════════════════════════════

# Permettre VPC de résoudre noms on-premise

aws route53resolver create-resolver-endpoint \
  --name vpc-outbound-endpoint \
  --direction OUTBOUND \
  --security-group-ids sg-0123456789abcdef0 \
  --ip-addresses SubnetId=subnet-1 SubnetId=subnet-2

# CRÉER FORWARDING RULE
════════════════════════════════════════════════════════════════════════════════

# Forward requêtes pour domaine vers serveurs on-premise

aws route53resolver create-resolver-rule \
  --creator-request-id $(date +%s) \
  --name forward-to-onprem \
  --rule-type FORWARD \
  --domain-name internal.company.com \
  --target-ips Ip=192.168.1.10,Port=53 Ip=192.168.1.11,Port=53 \
  --resolver-endpoint-id rslvr-out-abc123

# Associer rule au VPC
aws route53resolver associate-resolver-rule \
  --resolver-rule-id rslvr-rr-abc123 \
  --vpc-id vpc-0123456789abcdef0


═══════════════════════════════════════════════════════════════════════════════
[OK] MONITORING & MÉTRIQUES
═══════════════════════════════════════════════════════════════════════════════

# MÉTRIQUES CLOUDWATCH
════════════════════════════════════════════════════════════════════════════════

# Route 53 publie automatiquement métriques

# Voir nombre de requêtes DNS
aws cloudwatch get-metric-statistics \
  --namespace AWS/Route53 \
  --metric-name QueryCount \
  --dimensions Name=HostedZoneId,Value=Z1234567890ABC \
  --start-time 2024-01-15T00:00:00Z \
  --end-time 2024-01-16T00:00:00Z \
  --period 3600 \
  --statistics Sum

# MÉTRIQUES DISPONIBLES:
# - QueryCount: Nombre requêtes DNS
# - HealthCheckStatus: Statut health checks (0=unhealthy, 1=healthy)
# - HealthCheckPercentageHealthy: % healthy
# - ConnectionTime: Temps connexion (health checks TCP)
# - TimeToFirstByte: TTFB (health checks HTTP/HTTPS)
# - SSLHandshakeTime: Temps SSL handshake

# ALARMES CLOUDWATCH
════════════════════════════════════════════════════════════════════════════════

# Alarme si health check échoue
aws cloudwatch put-metric-alarm \
  --alarm-name route53-healthcheck-failed \
  --alarm-description "Health check unhealthy" \
  --namespace AWS/Route53 \
  --metric-name HealthCheckStatus \
  --dimensions Name=HealthCheckId,Value=12345678-1234-1234-1234-123456789012 \
  --statistic Minimum \
  --period 60 \
  --evaluation-periods 2 \
  --threshold 1 \
  --comparison-operator LessThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:ops-alerts

# Alarme si trop de requêtes DNS (anomalie)
aws cloudwatch put-metric-alarm \
  --alarm-name route53-high-query-count \
  --alarm-description "Unusual DNS query volume" \
  --namespace AWS/Route53 \
  --metric-name QueryCount \
  --dimensions Name=HostedZoneId,Value=Z1234567890ABC \
  --statistic Sum \
  --period 300 \
  --evaluation-periods 1 \
  --threshold 1000000 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:ops-alerts


═══════════════════════════════════════════════════════════════════════════════
[OK] BEST PRACTICES ROUTE 53
═══════════════════════════════════════════════════════════════════════════════

# [OK] TTL (TIME TO LIVE)
════════════════════════════════════════════════════════════════════════════════

1. TTL COURT (60-300s)
   - Changements fréquents
   - Failover rapide
   - Coût: Plus de requêtes DNS

2. TTL LONG (3600-86400s)
   - Configuration stable
   - Économise requêtes DNS ($$$)
   - Changements lents à propager

3. RECOMMANDATION:
   - Production stable: 300-3600s
   - Avant migration: 60s (permet changement rapide)
   - Après migration stable: Augmenter à 3600s

# [OK] ALIAS vs CNAME
════════════════════════════════════════════════════════════════════════════════

TOUJOURS préférer ALIAS pour ressources AWS:

ALIAS:
[OK] Gratuit (pas de frais query)
[OK] Fonctionne pour apex/root (example.com)
[OK] Plus rapide (1 query vs 2)
[OK] Health checks intégrés

CNAME:
[X] Payant ($0.40/million queries)
[X] Ne fonctionne PAS pour apex
[X] Plus lent (2 queries)

# [OK] HEALTH CHECKS
════════════════════════════════════════════════════════════════════════════════

1. TOUJOURS configurer health checks pour:
   - Failover routing
   - Weighted routing (production)
   - Multivalue routing

2. ENDPOINT HEALTH CHECK:
   - Path léger: /health, /ping
   - Pas de DB queries lourdes
   - Retourner 200 OK si healthy

3. FAILURE THRESHOLD:
   - 3 = Standard (bon équilibre)
   - 2 = Plus sensible (failover rapide)
   - 5 = Moins sensible (éviter faux positifs)

4. REQUEST INTERVAL:
   - 30s = Standard ($0.50/mois)
   - 10s = Fast ($1/mois) - Pour failover critique

# [OK] ROUTING POLICIES
════════════════════════════════════════════════════════════════════════════════

CHOISIR SELON USE CASE:

- Simple: Petit site, 1 serveur
- Weighted: A/B testing, canary deployment
- Latency: Multi-région, performance
- Failover: Disaster recovery, HA
- Geolocation: Conformité, localization
- Multivalue: Load balancing simple + health checks

COMBINER pour cas complexes:
Geolocation -> Latency -> Failover

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

1. DOMAIN LOCKING:
   - Activer transfer lock
   - Empêche transfert non autorisé

2. PRIVACY PROTECTION:
   - Cacher infos WHOIS
   - Éviter spam/phishing

3. MFA:
   - Activer MFA sur compte AWS
   - Protection contre hijacking

4. DNSSEC:
   - Si haute sécurité requise
   - Finance, gouvernement, santé

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

OPTIMISER COÛTS:

1. ALIAS vs CNAME:
   - Alias = GRATUIT
   - CNAME = $0.40/million
   - Économie significative!

2. HEALTH CHECKS:
   - Seulement où nécessaire
   - $0.50/mois par check
   - 10 checks = $5/mois

3. QUERY LOGGING:
   - Désactiver si pas utilisé
   - Peut coûter cher (CloudWatch Logs)

4. HOSTED ZONES:
   - Consolider domaines si possible
   - $0.50/mois par zone

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

1. MULTIPLE RÉGIONS:
   - Au moins 2 régions AWS
   - Latency ou Failover routing

2. HEALTH CHECKS:
   - Surveiller TOUS les endpoints
   - Failover automatique

3. TTL APPROPRIÉ:
   - 60-300s pour failover rapide
   - Pas trop court (coût)

4. TESTED REGULARLY:
   - Tester failover mensuellement
   - Simuler pannes


═══════════════════════════════════════════════════════════════════════════════
[OK] TROUBLESHOOTING ROUTE 53
═══════════════════════════════════════════════════════════════════════════════

# PROBLÈME 1: DNS ne résout pas
════════════════════════════════════════════════════════════════════════════════

# Vérifier propagation nameservers
dig example.com NS
nslookup -type=NS example.com

# Vérifier chez registrar:
# Nameservers doivent être ceux de Route 53
# ns-123.awsdns-12.com, etc.

# Délai propagation: 5 min - 48h (généralement < 1h)

# PROBLÈME 2: Record existe mais ne résout pas
════════════════════════════════════════════════════════════════════════════════

# Vérifier record créé
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --query "ResourceRecordSets[?Name=='www.example.com.']"

# Vérifier TTL:
# Si changé récemment, attendre TTL expirer

# Flush DNS cache local:
# Windows: ipconfig /flushdns
# macOS: sudo dscacheutil -flushcache
# Linux: sudo systemd-resolve --flush-caches

# PROBLÈME 3: Failover ne fonctionne pas
════════════════════════════════════════════════════════════════════════════════

# Vérifier health check status
aws route53 get-health-check-status \
  --health-check-id 12345678-1234-1234-1234-123456789012

# Causes communes:
# 1. Health check endpoint bloqué (security group)
# 2. Path /health n'existe pas
# 3. Retourne 500 au lieu de 200
# 4. Timeout trop court

# Solution:
# Tester endpoint manuellement:
curl -I https://api.example.com/health

# PROBLÈME 4: Weighted routing inégal
════════════════════════════════════════════════════════════════════════════════

# Vérifier poids configurés
aws route53 list-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --query "ResourceRecordSets[?Name=='www.example.com.'].[SetIdentifier,Weight]"

# [ATTENTION] IMPORTANT:
# Distribution pas exacte à cause TTL et cache
# Peut prendre plusieurs heures pour stabiliser

# PROBLÈME 5: Coûts élevés
════════════════════════════════════════════════════════════════════════════════

# Vérifier nombre de queries
aws cloudwatch get-metric-statistics \
  --namespace AWS/Route53 \
  --metric-name QueryCount \
  --dimensions Name=HostedZoneId,Value=Z1234567890ABC \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-31T00:00:00Z \
  --period 86400 \
  --statistics Sum

# Solutions:
# 1. Augmenter TTL (réduire queries)
# 2. Utiliser ALIAS au lieu de CNAME
# 3. Désactiver query logging si pas nécessaire


═══════════════════════════════════════════════════════════════════════════════
[OK] EXEMPLES COMPLETS PAR CAS D'USAGE
═══════════════════════════════════════════════════════════════════════════════

# EXEMPLE 1: SITE SIMPLE (1 SERVEUR)
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Configuration DNS pour site simple

ZONE_ID="Z1234567890ABC"

# Apex (example.com) -> Serveur
cat > apex.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "example.com",
      "Type": "A",
      "TTL": 300,
      "ResourceRecords": [{"Value": "203.0.113.25"}]
    }
  }]
}
EOF

# WWW -> Serveur
cat > www.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "TTL": 300,
      "ResourceRecords": [{"Value": "203.0.113.25"}]
    }
  }]
}
EOF

# Mail (Gmail)
cat > mail.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "example.com",
      "Type": "MX",
      "TTL": 3600,
      "ResourceRecords": [
        {"Value": "1 aspmx.l.google.com"},
        {"Value": "5 alt1.aspmx.l.google.com"},
        {"Value": "5 alt2.aspmx.l.google.com"}
      ]
    }
  }]
}
EOF

# SPF record
cat > spf.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "example.com",
      "Type": "TXT",
      "TTL": 3600,
      "ResourceRecords": [
        {"Value": "\"v=spf1 include:_spf.google.com ~all\""}
      ]
    }
  }]
}
EOF

# Appliquer tous
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://apex.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://www.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://mail.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://spf.json


# EXEMPLE 2: SITE AVEC ALB (ALIAS)
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Site avec Application Load Balancer

ZONE_ID="Z1234567890ABC"
ALB_DNS="my-alb-1234567890.us-east-1.elb.amazonaws.com"
ALB_ZONE_ID="Z35SXDOTRQ7X7K"  # us-east-1 ALB

# Apex -> ALB
cat > apex-alb.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "example.com",
      "Type": "A",
      "AliasTarget": {
        "HostedZoneId": "'$ALB_ZONE_ID'",
        "DNSName": "'$ALB_DNS'",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

# WWW -> ALB
cat > www-alb.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "AliasTarget": {
        "HostedZoneId": "'$ALB_ZONE_ID'",
        "DNSName": "'$ALB_DNS'",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://apex-alb.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://www-alb.json


# EXEMPLE 3: MULTI-RÉGION AVEC FAILOVER
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Haute disponibilité multi-région

ZONE_ID="Z1234567890ABC"

# Health checks
HC_US=$(aws route53 create-health-check \
  --health-check-config '{
    "Type": "HTTPS",
    "ResourcePath": "/health",
    "FullyQualifiedDomainName": "us.example.com",
    "Port": 443,
    "RequestInterval": 30,
    "FailureThreshold": 3
  }' \
  --caller-reference $(date +%s) \
  --query 'HealthCheck.Id' \
  --output text)

HC_EU=$(aws route53 create-health-check \
  --health-check-config '{
    "Type": "HTTPS",
    "ResourcePath": "/health",
    "FullyQualifiedDomainName": "eu.example.com",
    "Port": 443,
    "RequestInterval": 30,
    "FailureThreshold": 3
  }' \
  --caller-reference $(date +%s) \
  --query 'HealthCheck.Id' \
  --output text)

# Primary (US)
cat > failover-primary.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "US-Primary",
      "Failover": "PRIMARY",
      "HealthCheckId": "'$HC_US'",
      "AliasTarget": {
        "HostedZoneId": "Z35SXDOTRQ7X7K",
        "DNSName": "us-alb.us-east-1.elb.amazonaws.com",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

# Secondary (EU)
cat > failover-secondary.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "EU-Secondary",
      "Failover": "SECONDARY",
      "HealthCheckId": "'$HC_EU'",
      "AliasTarget": {
        "HostedZoneId": "Z32O12XQLNTSW2",
        "DNSName": "eu-alb.eu-west-1.elb.amazonaws.com",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://failover-secondary.json

echo "Failover configuré:"
echo "- Primary: US (Health Check: $HC_US)"
echo "- Secondary: EU (Health Check: $HC_EU)"


# EXEMPLE 4: GLOBAL AVEC GEOLOCATION
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Routage global par localisation

ZONE_ID="Z1234567890ABC"

# Europe
cat > geo-europe.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "Europe",
      "GeoLocation": {"ContinentCode": "EU"},
      "AliasTarget": {
        "HostedZoneId": "Z32O12XQLNTSW2",
        "DNSName": "eu-alb.eu-west-1.elb.amazonaws.com",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

# Asie
cat > geo-asia.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "Asia",
      "GeoLocation": {"ContinentCode": "AS"},
      "AliasTarget": {
        "HostedZoneId": "Z14GRHDCWA56QT",
        "DNSName": "asia-alb.ap-southeast-1.elb.amazonaws.com",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

# Amérique du Nord
cat > geo-northamerica.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "North-America",
      "GeoLocation": {"ContinentCode": "NA"},
      "AliasTarget": {
        "HostedZoneId": "Z35SXDOTRQ7X7K",
        "DNSName": "us-alb.us-east-1.elb.amazonaws.com",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

# Default (reste du monde)
cat > geo-default.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "Default",
      "GeoLocation": {"ContinentCode": "*"},
      "AliasTarget": {
        "HostedZoneId": "Z35SXDOTRQ7X7K",
        "DNSName": "us-alb.us-east-1.elb.amazonaws.com",
        "EvaluateTargetHealth": true
      }
    }
  }]
}
EOF

aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://geo-europe.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://geo-asia.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://geo-northamerica.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://geo-default.json

echo "Geolocation configuré globalement"


# EXEMPLE 5: A/B TESTING AVEC WEIGHTED
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# A/B Testing: 90% version A, 10% version B

ZONE_ID="Z1234567890ABC"

# Version A (90%)
cat > weighted-a.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "Version-A",
      "Weight": 90,
      "TTL": 60,
      "ResourceRecords": [{"Value": "203.0.113.25"}]
    }
  }]
}
EOF

# Version B (10%)
cat > weighted-b.json << 'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "www.example.com",
      "Type": "A",
      "SetIdentifier": "Version-B",
      "Weight": 10,
      "TTL": 60,
      "ResourceRecords": [{"Value": "203.0.113.26"}]
    }
  }]
}
EOF

aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://weighted-a.json
aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://weighted-b.json

echo "A/B Testing: 90% A, 10% B"

# Après analyse, basculer progressivement:
# 90/10 -> 80/20 -> 70/30 -> 50/50 -> 30/70 -> 10/90 -> 0/100


# EXEMPLE 6: CANARY DEPLOYMENT
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Canary: Déployer nouvelle version progressivement

ZONE_ID="Z1234567890ABC"

function set_weights() {
    OLD_WEIGHT=$1
    NEW_WEIGHT=$2
    
    cat > weighted-old.json << EOF
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "api.example.com",
      "Type": "A",
      "SetIdentifier": "Old-Version",
      "Weight": $OLD_WEIGHT,
      "TTL": 60,
      "ResourceRecords": [{"Value": "203.0.113.25"}]
    }
  }]
}
EOF

    cat > weighted-new.json << EOF
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "api.example.com",
      "Type": "A",
      "SetIdentifier": "New-Version",
      "Weight": $NEW_WEIGHT,
      "TTL": 60,
      "ResourceRecords": [{"Value": "203.0.113.26"}]
    }
  }]
}
EOF

    aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://weighted-old.json
    aws route53 change-resource-record-sets --hosted-zone-id $ZONE_ID --change-batch file://weighted-new.json
    
    echo "Weights updated: Old=$OLD_WEIGHT%, New=$NEW_WEIGHT%"
}

# Phase 1: 100% old
set_weights 100 0
sleep 60

# Phase 2: 95% old, 5% new (canary)
set_weights 95 5
echo "Monitoring canary for 30 minutes..."
sleep 1800

# Phase 3: Si métriques OK, continuer
set_weights 50 50
sleep 600

# Phase 4: Finaliser
set_weights 0 100
echo "Deployment complete: 100% new version"


═══════════════════════════════════════════════════════════════════════════════
[OK] MIGRATION VERS ROUTE 53
═══════════════════════════════════════════════════════════════════════════════

# PROCÉDURE MIGRATION COMPLÈTE
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Migrer domaine vers Route 53 sans downtime

DOMAIN="example.com"

echo "=== MIGRATION ROUTE 53: $DOMAIN ==="

# ÉTAPE 1: RÉDUIRE TTL CHEZ ANCIEN PROVIDER
echo "ÉTAPE 1: Réduire TTL à 60s chez ancien provider"
echo "Attendre propagation (24-48h si TTL était élevé)"
read -p "TTL réduit? (y/n) " -n 1 -r
echo

# ÉTAPE 2: CRÉER HOSTED ZONE ROUTE 53
echo "ÉTAPE 2: Création hosted zone..."
ZONE_ID=$(aws route53 create-hosted-zone \
  --name $DOMAIN \
  --caller-reference $(date +%s) \
  --query 'HostedZone.Id' \
  --output text)

echo "Hosted Zone créée: $ZONE_ID"

# Obtenir nameservers
NAMESERVERS=$(aws route53 get-hosted-zone \
  --id $ZONE_ID \
  --query 'DelegationSet.NameServers' \
  --output text)

echo "Nameservers Route 53:"
echo "$NAMESERVERS"

# ÉTAPE 3: EXPORTER RECORDS ANCIEN PROVIDER
echo "ÉTAPE 3: Exporter tous les records de l'ancien provider"
echo "Format: Name, Type, TTL, Value"
echo "Créer fichier: records-export.csv"
read -p "Export prêt? (y/n) " -n 1 -r
echo

# ÉTAPE 4: IMPORTER RECORDS DANS ROUTE 53
echo "ÉTAPE 4: Import records..."

# Exemple avec CSV (adapter selon format)
while IFS=',' read -r name type ttl value; do
    cat > temp-record.json << EOF
{
  "Changes": [{
    "Action": "CREATE",
    "ResourceRecordSet": {
      "Name": "$name",
      "Type": "$type",
      "TTL": $ttl,
      "ResourceRecords": [{"Value": "$value"}]
    }
  }]
}
EOF
    
    aws route53 change-resource-record-sets \
      --hosted-zone-id $ZONE_ID \
      --change-batch file://temp-record.json
done < records-export.csv

echo "Records importés"

# ÉTAPE 5: VÉRIFIER RECORDS
echo "ÉTAPE 5: Vérification records..."
aws route53 list-resource-record-sets \
  --hosted-zone-id $ZONE_ID \
  --query 'ResourceRecordSets[*].[Name,Type,TTL]' \
  --output table

read -p "Records corrects? (y/n) " -n 1 -r
echo

# ÉTAPE 6: TESTER AVEC NAMESERVERS ROUTE 53
echo "ÉTAPE 6: Test avec nameservers Route 53..."
NS=$(echo "$NAMESERVERS" | head -1)
echo "Test: dig @$NS $DOMAIN"
dig @$NS $DOMAIN

read -p "Tests OK? (y/n) " -n 1 -r
echo

# ÉTAPE 7: CHANGER NAMESERVERS CHEZ REGISTRAR
echo "ÉTAPE 7: CHANGEMENT NAMESERVERS"
echo "Aller chez registrar et configurer:"
echo "$NAMESERVERS"
echo ""
echo "[ATTENTION] ATTENTION: Après ce changement, propagation 5min-48h"
read -p "Nameservers changés chez registrar? (y/n) " -n 1 -r
echo

# ÉTAPE 8: SURVEILLER PROPAGATION
echo "ÉTAPE 8: Surveillance propagation..."
echo "Vérifier avec: https://www.whatsmydns.net/"

# ÉTAPE 9: AUGMENTER TTL APRÈS STABILISATION
echo "ÉTAPE 9: Après 24-48h stabilisation, augmenter TTL à 3600s"

echo "=== MIGRATION TERMINÉE ==="


═══════════════════════════════════════════════════════════════════════════════
[OK] OUTILS UTILES
═══════════════════════════════════════════════════════════════════════════════

# VÉRIFIER DNS
════════════════════════════════════════════════════════════════════════════════

# dig (Linux/macOS)
dig example.com
dig example.com A
dig example.com MX
dig @8.8.8.8 example.com  # Via serveur spécifique

# nslookup (Windows/Linux/macOS)
nslookup example.com
nslookup -type=MX example.com
nslookup example.com 8.8.8.8

# host (Linux/macOS)
host example.com
host -t MX example.com

# VÉRIFIER PROPAGATION GLOBALE
════════════════════════════════════════════════════════════════════════════════

# Online tools:
# https://www.whatsmydns.net/
# https://dnschecker.org/
# https://www.dnswatch.info/

# CLI multiple locations
curl "https://dns.google/resolve?name=example.com&type=A"

# TESTER HEALTH CHECK
════════════════════════════════════════════════════════════════════════════════

# Simuler health check Route 53
curl -I https://api.example.com/health
curl -w "@curl-format.txt" -o /dev/null -s https://api.example.com/health

# curl-format.txt:
# time_namelookup: %{time_namelookup}\n
# time_connect: %{time_connect}\n
# time_appconnect: %{time_appconnect}\n
# time_pretransfer: %{time_pretransfer}\n
# time_starttransfer: %{time_starttransfer}\n
# time_total: %{time_total}\n
# http_code: %{http_code}\n

# SCRIPT MONITORING CONTINU
════════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Monitor DNS resolution continu

DOMAIN="www.example.com"

while true; do
    RESULT=$(dig +short $DOMAIN)
    TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
    
    if [ -z "$RESULT" ]; then
        echo "[$TIMESTAMP] [X] DNS FAILED"
    else
        echo "[$TIMESTAMP] [OK] DNS OK: $RESULT"
    fi
    
    sleep 60
done


═══════════════════════════════════════════════════════════════════════════════
[OK] CALCULATEUR COÛTS ROUTE 53
═══════════════════════════════════════════════════════════════════════════════

#!/bin/bash
# Calculateur coûts Route 53

# INPUTS
HOSTED_ZONES=2
DNS_QUERIES_MILLION=10  # Millions de queries/mois
HEALTH_CHECKS=5
ALIAS_QUERIES_MILLION=5  # Alias = gratuit

# PRICING
HOSTED_ZONE_COST=0.50
QUERY_COST_FIRST_BILLION=0.40  # Per million
HEALTH_CHECK_COST=0.50

# CALCUL
HOSTED_ZONES_TOTAL=$(echo "$HOSTED_ZONES * $HOSTED_ZONE_COST" | bc)

# Queries (premiers milliard)
if [ $DNS_QUERIES_MILLION -le 1000 ]; then
    QUERIES_TOTAL=$(echo "$DNS_QUERIES_MILLION * $QUERY_COST_FIRST_BILLION" | bc)
else
    FIRST_BILLION=$(echo "1000 * $QUERY_COST_FIRST_BILLION" | bc)
    REMAINING=$(echo "($DNS_QUERIES_MILLION - 1000) * 0.20" | bc)
    QUERIES_TOTAL=$(echo "$FIRST_BILLION + $REMAINING" | bc)
fi

HEALTH_CHECKS_TOTAL=$(echo "$HEALTH_CHECKS * $HEALTH_CHECK_COST" | bc)

TOTAL=$(echo "$HOSTED_ZONES_TOTAL + $QUERIES_TOTAL + $HEALTH_CHECKS_TOTAL" | bc)

echo "=== COÛTS ROUTE 53 MENSUELS ==="
echo ""
echo "Hosted Zones: $HOSTED_ZONES × \$$HOSTED_ZONE_COST = \$$HOSTED_ZONES_TOTAL"
echo "DNS Queries: $DNS_QUERIES_MILLION million × \$$QUERY_COST_FIRST_BILLION = \$$QUERIES_TOTAL"
echo "Alias Queries: $ALIAS_QUERIES_MILLION million × \$0.00 = \$0.00 (GRATUIT)"
echo "Health Checks: $HEALTH_CHECKS × \$$HEALTH_CHECK_COST = \$$HEALTH_CHECKS_TOTAL"
echo ""
echo "TOTAL: \$$TOTAL/mois"
echo ""
echo "[IDEE] OPTIMISATIONS:"
echo "- Utiliser ALIAS au lieu de CNAME (gratuit)"
echo "- Augmenter TTL (réduire queries)"
echo "- Health checks seulement où nécessaire"


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

# Hosted Zones
aws route53 create-hosted-zone --name example.com --caller-reference $(date +%s)
aws route53 list-hosted-zones
aws route53 get-hosted-zone --id Z1234567890ABC
aws route53 delete-hosted-zone --id Z1234567890ABC

# Records
aws route53 change-resource-record-sets --hosted-zone-id Z1234567890ABC --change-batch file://record.json
aws route53 list-resource-record-sets --hosted-zone-id Z1234567890ABC

# Health Checks
aws route53 create-health-check --health-check-config '{...}' --caller-reference $(date +%s)
aws route53 list-health-checks
aws route53 get-health-check-status --health-check-id 12345678-1234-1234-1234-123456789012
aws route53 delete-health-check --health-check-id 12345678-1234-1234-1234-123456789012

# Domain Registration
aws route53domains check-domain-availability --domain-name example.com
aws route53domains list-domains
aws route53domains register-domain --domain-name example.com --duration-in-years 1 ...

# Query Logging
aws route53 create-query-logging-config --hosted-zone-id Z1234567890ABC \
  --cloud-watch-logs-log-group-arn arn:aws:logs:...
aws route53 list-query-logging-configs
aws route53 delete-query-logging-config --id qlc-...


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

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

# Routing Policies Guide
https://docs.aws.amazon.com/route53/latest/DeveloperGuide/routing-policy.html

# Health Checks
https://docs.aws.amazon.com/route53/latest/DeveloperGuide/health-checks.html

# Pricing
https://aws.amazon.com/route53/pricing/

# Hosted Zone IDs (ALB, CloudFront, etc.)
https://docs.aws.amazon.com/general/latest/gr/elb.html

# DNS Checkers
https://www.whatsmydns.net/
https://dnschecker.org/
https://mxtoolbox.com/

# WHOIS Lookup
https://www.whois.com/

# DNS Propagation
https://www.dnswatch.info/

# AWS Service Limits
https://docs.aws.amazon.com/route53/latest/DeveloperGuide/DNSLimitations.html


═══════════════════════════════════════════════════════════════════════════════
[OK] GLOSSARY
═══════════════════════════════════════════════════════════════════════════════

A RECORD: Maps domain name to IPv4 address
AAAA RECORD: Maps domain name to IPv6 address
ALIAS: AWS special record (like CNAME but better)
APEX/ROOT: Domain without subdomain (example.com vs www.example.com)
CNAME: Canonical name (alias to another domain)
DNS: Domain Name System
DNSSEC: DNS Security Extensions
FQDN: Fully Qualified Domain Name (with trailing dot)
HOSTED ZONE: Container for DNS records
MX RECORD: Mail exchange servers
NAMESERVER: Server that holds DNS records
NS RECORD: Nameserver record
REGISTRAR: Company that sells domain names
SOA: Start of Authority record
TXT RECORD: Text record (verification, SPF, etc.)
TTL: Time To Live (cache duration)
WHOIS: Database of domain ownership


═══════════════════════════════════════════════════════════════════════════════
[OK] CHECKLIST DÉPLOIEMENT PRODUCTION
═══════════════════════════════════════════════════════════════════════════════

AVANT MISE EN PRODUCTION:
[ ] Hosted zone créée
[ ] Tous les records importés (A, CNAME, MX, TXT)
[ ] TTL configurés (300-3600s)
[ ] ALIAS utilisés pour ressources AWS
[ ] Health checks configurés
[ ] Routing policies testées
[ ] Nameservers notés
[ ] SPF/DMARC records ajoutés (email)
[ ] SSL certificates validés (if using TXT validation)
[ ] Tests DNS avec dig/nslookup
[ ] Documentation mise à jour

CHANGEMENT NAMESERVERS:
[ ] TTL réduit à 60s (24-48h avant)
[ ] Backup configuration actuelle
[ ] Nameservers changés chez registrar
[ ] Propagation surveillée (whatsmydns.net)
[ ] Tests depuis multiple locations
[ ] Email fonctionnel vérifié
[ ] Applications testées
[ ] TTL augmenté après stabilisation (24-48h)

APRÈS MISE EN PRODUCTION:
[ ] Monitoring actif (CloudWatch)
[ ] Health checks surveillés
[ ] Query logging analysé (si activé)
[ ] Coûts suivis
[ ] Documentation finalisée
[ ] Équipe formée sur failover
[ ] Procédure rollback documentée
[ ] Tests disaster recovery planifiés