chore: Add initial project scaffolding for Terraform-based GCP IaC

This commit is contained in:
Maxime Pierront
2025-12-03 11:30:40 +01:00
commit b90b2d8105
15 changed files with 753 additions and 0 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@@ -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

6
.idea/google-java-format.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GoogleJavaFormatSettings">
<option name="enabled" value="false" />
</component>
</project>

14
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AnalysisProjectProfileManager">
<option name="PROJECT_PROFILE" />
<option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
<list size="0" />
</component>
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="SuppressionsComponent">
<option name="suppComments" value="[]" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/but3-iac.iml" filepath="$PROJECT_DIR$/but3-iac.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

62
README.md Normal file
View File

@@ -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://grond.iut-fbleau.fr/pierront/but3-iac.git
### Génération de la clé privée
`ssh-keygen -t rsa -f ~/.ssh/id_ed25519 -C <john_doe_gmail_com>`
**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)

8
but3-iac.iml Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="GENERAL_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

352
cheat-sheet-terraform.md Normal file
View File

@@ -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

BIN
global-architecture.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

BIN
img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
img_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
img_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
img_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -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

281
tp-terraform.md Normal file
View File

@@ -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.