commit 368cfd1ef68f40de2f66d99fd12fd8656820deba Author: Maxime Pierront Date: Wed Dec 3 11:30:40 2025 +0100 chore: Add initial project scaffolding for Terraform-based GCP IaC diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml new file mode 100644 index 0000000..2aa056d --- /dev/null +++ b/.idea/google-java-format.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4a93fc7 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2839e6f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f947b08 --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +# IaC_BUT3 + +## Activer les API suivantes + +activer api : Identity and Access Management (IAM) API +activer api : Cloud Resource Manager API + +## Créer la VM + +**Créer une VM small comme les tp précédents** + +## Installation sur la VM + +sudo apt install git +git clone https://github.com/MaximePIERRONT/IaC_BUT3.git + +### Génération de la clé privée +`ssh-keygen -t rsa -f ~/.ssh/id_ed25519 -C ` + +**replace "." & "@" with "_"** +```bash +eval `ssh-agent` +ssh-add ~/.ssh/id_ed25519 +``` + +### Installation terraform + +Source : +[https://www.hashicorp.com/official-packaging-guide?product_intent=terraform](https://www.hashicorp.com/official-packaging-guide?product_intent=terraform) + +Ajouter terraform dans votre list de package disponible +```bash +sudo apt update && sudo apt install gpg + +wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg + +gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint + +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list + +``` +Installer terraform et ansible +```bash +sudo apt update +sudo apt install terraform` + +sudo apt install ansible +ansible-galaxy collection install community.mysql +sudo apt install -y python3-google-auth python3-requests python3-google-auth-httplib2 python3-googleapi +``` + +### Connection avec google + +Faire les étapes suivantes pour la connexion à Google sur votre VM + +![img.png](img.png) + +![img_1.png](img_1.png) + +![img_2.png](img_2.png) + +![img_3.png](img_3.png) \ No newline at end of file diff --git a/but3-iac.iml b/but3-iac.iml new file mode 100644 index 0000000..9a5cfce --- /dev/null +++ b/but3-iac.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/cheat-sheet-terraform.md b/cheat-sheet-terraform.md new file mode 100644 index 0000000..4ecc277 --- /dev/null +++ b/cheat-sheet-terraform.md @@ -0,0 +1,352 @@ +# Terraform GCP Cheatsheet + +## 1\. Commandes Terraform de Base + +### Initialisation et Configuration + +| Commande | Description | +| :--- | :--- | +| `terraform init` | Initialise un projet Terraform | +| `terraform fmt` | Formate les fichiers `.tf` | +| `terraform validate` | Vérifie la syntaxe | +| `terraform plan` | Montre les changements prévus | +| `terraform apply` | Applique les changements | +| `terraform destroy` | Détruit l'infrastructure | +| `terraform output` | Affiche les outputs | +| `terraform show` | Montre l'état actuel | + +----- + +## 2\. Blocs de Base Terraform + +### Provider Configuration + +```terraform +terraform { + required_providers { + google = { + source = "hashicorp/google" + version = "~> 6.0" + } + } +} + +provider "google" { + project = var.project_id + region = var.region +} +``` + +### Variables et Outputs + +**Déclaration de variable :** + +```terraform +variable "project_id" { + description = "ID du projet GCP" + type = string + default = "mon-projet" +} +``` + +**Output :** + +```terraform +output "instance_ip" { + value = google_compute_instance.main.network_interface[0].access_config[0].nat_ip +} +``` + +----- + +## 3\. Ressources GCP Communes + +### Réseau VPC + +```terraform +# VPC +resource "google_compute_network" "vpc" { + name = "mon-vpc" + auto_create_subnetworks = false +} + +# Sous-réseau +resource "google_compute_subnetwork" "subnet" { + name = "mon-subnet" + network = google_compute_network.vpc.id + ip_cidr_range = "10.0.1.0/24" + region = "europe-west1" +} +``` + +### Règles de Pare-feu + +```terraform +resource "google_compute_firewall" "allow_http" { + name = "allow-http" + network = google_compute_network.vpc.id + + allow { + protocol = "tcp" + ports = ["80", "443"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["web"] +} +``` + +### Instances de Calcul + +```terraform +resource "google_compute_instance" "vm" { + name = "ma-vm" + machine_type = "e2-medium" + zone = "europe-west1-b" + + boot_disk { + initialize_params { + image = "debian-cloud/debian-11" + size = 10 + } + } + + network_interface { + access_config {} # IP publique + subnetwork = google_compute_subnetwork.subnet.id + } + + tags = ["web", "app"] + + metadata = { + enable-oslogin = "TRUE" + } +} +``` + +----- + +## 4\. Types de Données et Expressions + +### Types de Variables + +```terraform +# String +variable "machine_type" { + type = string +} + +# Number +variable "disk_size" { + type = number +} + +# Boolean +variable "enable_public_ip" { + type = bool +} + +# List +variable "allowed_ports" { + type = list(number) +} + +# Map +variable "labels" { + type = map(string) +} + +# Object +variable "disk_config" { + type = object({ + size = number + type = string + image = string + }) +} +``` + +### Expressions Courantes + +```terraform +# Interpolation +name = "${var.project_name}-instance" + +# Condition +count = var.environment == "prod" ? 2 : 1 + +# For expression +dynamic "allowed_ports" { + for_each = var.ports + content { + port = allowed_ports.value + } +} +``` + +----- + +## 5\. Fonctions Utiles + +### Fonctions de String + +* `lower(string)` : Convertit en minuscules +* `upper(string)` : Convertit en majuscules +* `format("vm-%s", name)` : Formate une chaîne + +### Fonctions de Collection + +* `length(list)` : Longueur d'une liste +* `concat(list1, list2)` : Concatène des listes +* `merge(map1, map2)` : Fusionne des maps + +### Fonctions de Fichier + +* `file("path/to/file")` : Lit un fichier +* `fileexists("path")` : Vérifie l'existence +* `templatefile("tpl", {})` : Traite un template + +----- + +## 6\. Modules + +### Structure de Base d'un Module + +* `main.tf` : Ressources principales +* `variables.tf` : Variables d'entrée +* `outputs.tf` : Valeurs exposées + +### Déclaration d'un Module + +```terraform +module "network" { + source = "./modules/network" + + # Variables d'entrée + project_name = var.project_name + region = var.region + + # Autres variables spécifiques au module + cidr_range = "10.0.0.0/16" +} +``` + +### Référence des Outputs + +```terraform +# Utilisation d'un output de module +resource "google_compute_instance" "vm" { + network = module.network.vpc_id +} + +# Output d'un module +output "vpc_id" { + value = module.network.vpc_id +} +``` + +### Sources de Modules + +**Module local :** + +```terraform +module "vpc" { + source = "./modules/vpc" +} +``` + +**Module du registry :** + +```terraform +module "bucket" { + source = "terraform-google-modules/cloud-storage/google" + version = "3.4.0" +} +``` + +**Module Git :** + +```terraform +module "network" { + source = "git::https://example.com/network.git?ref=v1.2.0" +} +``` + +### Dépendances Entre Modules + +```terraform +module "database" { + source = "./modules/database" + + # Dépendance explicite + depends_on = [module.network] + + # Utilisation des outputs d'autres modules + subnet_id = module.network.private_subnet_id + vpc_id = module.network.vpc_id +} +``` + +----- + +## 7\. Bonnes Pratiques + +### Organisation du Code + +Structure recommandée `project/` : + +* `main.tf` : Ressources principales +* `variables.tf` : Définitions des variables +* `outputs.tf` : Définitions des outputs +* `versions.tf` : Configuration des providers +* `terraform.tfvars` : Valeurs des variables + +### Conventions de Nommage + +* Utilisez des tirets (`-`) pour les ressources +* Utilisez des underscores (`_`) pour les variables +* Préfixez les ressources avec leur type + +### Tags à Utiliser + +* `environment`: prod, dev, staging +* `project`: nom du projet +* `role`: web, app, db +* `managed-by`: terraform + +----- + +## 8\. Debugging + +### Logging et Debug + +```bash +# Active les logs détaillés +export TF_LOG=DEBUG +export TF_LOG_PATH=terraform.log + +# Vérifie l'état d'une ressource spécifique +terraform state show google_compute_instance.vm +``` + +### Gestion d'État + +| Commande | Action | +| :--- | :--- | +| `terraform state list` | Liste les ressources | +| `terraform state rm ADDR` | Supprime de l'état | +| `terraform import ADDR ID` | Importe une ressource | +| `terraform state mv SRC DEST` | Déplace une ressource | + +----- + +## 9\. Messages d'Erreur Communs + +* **"Error: Provider configuration not present"** + * *Solution :* Exécutez `terraform init` +* **"Error: No valid credential sources found"** + * *Solution :* Configurez l'authentification GCP +* **"Error: Resource already exists"** + * *Solution :* Importez la ressource ou changez son nom +* **"Error: Configuration directory not empty"** + * *Solution :* Initialisez dans un nouveau répertoire \ No newline at end of file diff --git a/global-architecture.png b/global-architecture.png new file mode 100644 index 0000000..144d37f Binary files /dev/null and b/global-architecture.png differ diff --git a/img.png b/img.png new file mode 100644 index 0000000..bf9f77d Binary files /dev/null and b/img.png differ diff --git a/img_1.png b/img_1.png new file mode 100644 index 0000000..8b72435 Binary files /dev/null and b/img_1.png differ diff --git a/img_2.png b/img_2.png new file mode 100644 index 0000000..6afc2de Binary files /dev/null and b/img_2.png differ diff --git a/img_3.png b/img_3.png new file mode 100644 index 0000000..99fd978 Binary files /dev/null and b/img_3.png differ diff --git a/terraform/templates/ansible.cfg.tpl b/terraform/templates/ansible.cfg.tpl new file mode 100644 index 0000000..f0a8d1f --- /dev/null +++ b/terraform/templates/ansible.cfg.tpl @@ -0,0 +1,8 @@ +[defaults] +host_key_checking = False +inventory = gcp_compute.yml +interpreter_python = auto_silent +remote_user = ${replace(replace(remote_user, ".", "_"), "@", "_")} + +[inventory] +enable_plugins = gcp_compute, auto, host_list, yaml, ini, toml, script \ No newline at end of file diff --git a/tp-terraform.md b/tp-terraform.md new file mode 100644 index 0000000..325d2a8 --- /dev/null +++ b/tp-terraform.md @@ -0,0 +1,281 @@ +# 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. \ No newline at end of file