# TP Terraform : Architecture modulaire 3-tiers sur GCP

## Introduction

Dans ce TP, nous allons déployer une architecture trois tiers sur Google Cloud Platform (GCP) en utilisant une approche modulaire avec Terraform.

Cette architecture comprendra :

* Une couche frontend exposée sur Internet
* Une couche backend pour la logique métier
* Une couche base de données
* Une gestion des accès via IAM

## Prérequis

* Un compte Google Cloud Platform (GCP)
* Terraform installé (v1.0.0 ou supérieure)
* Google Cloud SDK installé et configuré
* Un éditeur de texte (VSCode recommandé)
* Une clé SSH (créée avec `ssh-keygen -t ed25519`)

## Structure du Projet

Créez la structure de répertoires suivante :

```text
tp-cloud/
└── terraform
    ├── environments/
    │   └── dev/
    │       ├── main.tf
    │       ├── variables.tf
    │       └── outputs.tf
    ├── modules/
    │   ├── network/
    │   │   ├── main.tf
    │   │   ├── variables.tf
    │   │   └── outputs.tf
    │   ├── compute/
    │   │   ├── main.tf
    │   │   ├── variables.tf
    │   │   └── outputs.tf
    │   └── iam/
    │       ├── main.tf
    │       ├── variables.tf
    │       └── outputs.tf
    └── templates/
        └── ansible.cfg.tpl
```

-----

## Partie 1 : Module Network

### Step 1 : Variables du Module

Dans `modules/network/variables.tf`, définissez les variables :

```terraform
# À vous de définir les variables pour :
# - project_name (string)
# - region (string)
# - frontend_cidr (string)
# - backend_cidr (string)
# - database_cidr (string)
# - ssh_source_ranges (string)
```

### Step 2 : Ressources Réseau

Dans `modules/network/main.tf`, créez :

```terraform
# À vous de créer :
# 1. Un VPC personnalisé avec auto_create_subnetworks = false
# 2. Trois sous-réseaux (frontend, backend, database)
# 3. Règles de firewall :
#    - HTTP/HTTPS vers frontend
#    - SSH vers toutes les instances
#    - Port 8000 de frontend vers backend
#    - Port 3306 de backend vers database
```

### Step 3 : Outputs du Module

Dans `modules/network/outputs.tf`, exposez :

```terraform
# À vous d'exposer :
# 1. L'ID du VPC
# 2. Les IDs des sous-réseaux sous forme de map
```

-----

## Partie 2 : Module Compute

### Step 1 : Variables du Module

Dans `modules/compute/variables.tf`, définissez :

```terraform
# À vous de définir les variables pour :
# - instance_type
# - zone
# - frontend_subnet_id
# - backend_subnet_id
# - database_subnet_id
```

### Step 2 : Instances

Dans `modules/compute/main.tf`, créez :

```terraform
# À vous de créer :

# 1. Instance frontend :
#    - Image : debian-11
#    - Disque : 10GB
#    - IP publique
#    - Tags : frontend, ssh
#    - OS Login enabled

# 2. Instance backend :
#    - Image : debian-11
#    - Disque : 10GB
#    - Pas d'IP publique (interne seulement)
#    - Tags : backend, ssh
#    - OS Login enabled

# 3. Instance database :
#    - Image : debian-11
#    - Disque : 20GB
#    - Pas d'IP publique
#    - Tags : database, ssh
#    - OS Login enabled
```

### Step 3 : Outputs du Module

Dans `modules/compute/outputs.tf`, exposez :

```terraform
# À vous d'exposer :
# 1. Les IPs internes de toutes les instances
# 2. L'IP publique du frontend
# 3. Les noms des instances
```

-----

## Partie 3 : Module IAM

### Step 1 : Variables du Module

Dans `modules/iam/variables.tf`, définissez :

```terraform
# À vous de définir :
# - project_id (string)
```

### Step 2 : Configuration IAM

Dans `modules/iam/main.tf`, créez :

```terraform
# À vous de créer :
# 1. Un compte de service pour Terraform
# 2. Une clé pour ce compte de service
# 3. Les rôles IAM nécessaires
# 4. La configuration OS Login avec votre clé SSH
```

### Step 3 : Outputs du Module

Dans `modules/iam/outputs.tf`, exposez :

```terraform
# À vous d'exposer :
# 1. L'email du compte de service
# 2. La clé du compte de service (sensitive = true)
```

-----

## Partie 4 : Configuration de l'Environnement

### Step 1 : Variables d'Environnement

Dans `environments/dev/variables.tf`, définissez toutes les variables nécessaires avec des valeurs par défaut appropriées.

### Step 2 : Configuration Principale

Dans `environments/dev/main.tf`, configurez :

```terraform
# À vous de :
# 1. Configurer le provider google
# 2. Appeler les trois modules avec les bonnes variables
# 3. Créer le fichier de configuration Ansible (template)
```

### Step 3 : Outputs

Dans `environments/dev/outputs.tf`, exposez les informations utiles des trois modules.

-----

## Validation et Tests

À chaque étape du développement :

1.  **Initialisation :**
    `terraform init`
2.  **Validation :**
    `terraform fmt`
    `terraform validate`
3.  **Déploiement :**
    `terraform plan`
    `terraform apply`

### Critères de Validation

Votre implémentation sera validée sur :

1.  **Structure Modulaire**
    * Séparation claire des responsabilités
    * Réutilisabilité des modules
    * Gestion appropriée des dépendances
2.  **Configuration Réseau**
    * Segmentation appropriée
    * Règles de firewall cohérentes
    * Communication inter-tiers sécurisée
3.  **Sécurité**
    * OS Login correctement configuré
    * Accès SSH restreint
    * Principe du moindre privilège
4.  **Qualité du Code**
    * Nommage cohérent
    * Variables bien typées
    * Outputs pertinents

-----

## Bonus

Améliorations possibles :

1.  **Réseau**
    * Cloud NAT pour les instances privées
    * VPC Service Controls
    * Cloud Armor pour le frontend
2.  **Compute**
    * Custom metadata
    * Instance groups
    * Load balancer
3.  **IAM**
    * Custom roles
    * Workload Identity
    * Secret Manager

## Nettoyage

À la fin du TP, n'oubliez pas de détruire les ressources :
`terraform destroy`

## Documentation Utile

* Terraform GCP Provider
* GCP Networking
* GCP Compute Engine
* GCP IAM

## Conseils

* Développez et testez chaque module individuellement.
* Utilisez `terraform console` pour tester les expressions.
* Documentez vos choix d'implémentation.
* Utilisez des noms de ressources cohérents.