Compare commits

22 Commits
main ... main

Author SHA1 Message Date
e0260e91c0 Tout marche (normalement) 2025-12-04 11:33:11 +01:00
d4fc544fd6 bonus nat 2025-12-04 11:03:27 +01:00
16187ed9f6 2eme quick fix main dev 2025-12-04 10:51:13 +01:00
9326dffa63 je sais pas ecrir ansible 2025-12-04 10:49:07 +01:00
05696d7841 quick fix main dev 2025-12-04 10:48:18 +01:00
249504829a presque fini (je pense) 2025-12-04 10:46:51 +01:00
5746077039 encore iam 2025-12-04 10:27:10 +01:00
ad464191fe iam suite 2025-12-04 10:21:50 +01:00
5527d753c0 iam debut 2025-12-04 10:15:25 +01:00
40d03d2b5a e2-small 2025-12-04 09:50:16 +01:00
432b0106e6 encore une autre correction 2025-12-04 09:47:48 +01:00
19e323e130 correction main compute 2 2025-12-04 09:42:09 +01:00
c2fd824f28 correction main compute 2025-12-04 09:41:19 +01:00
abcbb6a6f3 correction main 2025-12-04 09:38:38 +01:00
6bc635c038 ajout module compute 2025-12-04 09:33:36 +01:00
7d80805e60 debut compute 2025-12-04 09:02:57 +01:00
6dbffb5a10 variable region correct 2025-12-03 17:02:13 +01:00
28e1d8e179 variables mauvais caracter 2025-12-03 16:59:10 +01:00
a5183330fb output correction 2025-12-03 16:57:14 +01:00
bb380bb780 modif main 2025-12-03 16:53:20 +01:00
1e6d1192c3 variables nom projet 2025-12-03 16:43:11 +01:00
d82eced501 arborenscence + fichier modifier 2025-12-03 16:33:17 +01:00
14 changed files with 1190 additions and 0 deletions

90
iam-step.md Normal file
View File

@@ -0,0 +1,90 @@
# TP : Gestion des Identités (IAM) et Accès SSH
Dans cette partie, vous allez configurer les accès pour que Terraform puisse interagir avec le projet et pour que vous puissiez vous connecter aux futures machines virtuelles.
## Objectifs
1. Créer une identité machine (Service Account).
2. Lui donner des droits sur le projet.
3. Configurer votre propre clé SSH via le service **OS Login** de GCP.
---
## Étape 1 : Créer l'identité machine
**Objectif :** Créer un compte de service (Service Account) qui sera utilisé par nos scripts d'automatisation.
* **Ressource à utiliser :** `google_service_account`
* **Consignes :**
* Donnez-lui l'ID `terraform`.
* Ajoutez un `display_name` explicite pour qu'on le reconnaisse dans la console GCP.
## Étape 2 : Générer une clé d'accès
**Objectif :** Pour utiliser ce compte de service depuis l'extérieur (ou via Terraform), nous avons besoin d'une clé.
* **Ressource à utiliser :** `google_service_account_key`
* **Consignes :**
* Vous devez lier cette ressource au compte de service créé à l'étape 1 via son attribut `name` (ex: `google_service_account.votre_nom.name`).
* Définissez le type de clé publique sur `"TYPE_X509_PEM_FILE"`.
## Étape 3 : Donner des droits (IAM)
**Objectif :** Un compte de service naît sans aucun droit. Vous devez lui donner le rôle de "Viewer" sur le projet pour qu'il puisse lire les ressources.
* **Ressource à utiliser :** `google_project_iam_binding`
* **Consignes :**
* **Project :** Utilisez votre variable `var.project_id`.
* **Role :** Le rôle cible est `"roles/viewer"`.
* **Members :** C'est une liste. Attention à la syntaxe spécifique GCP pour désigner un membre : `"serviceAccount:..."`. Vous devez concaténer ce préfixe avec l'email du service account créé à l'étape 1 (`.email`).
## Étape 4 : Récupérer votre identité
**Objectif :** Terraform doit savoir "qui" lance le script actuellement pour associer la clé SSH à la bonne personne.
* **Data Source à utiliser :** `data "google_client_openid_userinfo"`
* **Consignes :**
* Déclarez simplement ce bloc `data` avec le nom `me`. Il n'a pas besoin d'arguments à l'intérieur. Il servira juste à récupérer votre email dynamiquement.
## Étape 5 : Ajouter votre clé SSH (OS Login)
**Objectif :** Uploader votre clé publique SSH locale vers GCP pour permettre la connexion aux VMs sans gestion manuelle.
* **Ressource à utiliser :** `google_os_login_ssh_public_key`
* **Consignes :**
* **User :** Utilisez l'email récupéré grâce au data source de l'étape 4 (`.email`).
* **Key :** Vous devez lire le contenu de votre fichier de clé publique locale.
* **Fonction Terraform :** Utilisez la fonction `file("chemin/vers/la/clé")`.
* **Chemin recommandé :** `~/.ssh/id_ed25519.pub`.
> **Attention :** Vérifiez impérativement que vous avez bien généré une clé SSH sur votre poste local avant de lancer le `terraform apply`. Sinon, Terraform ne trouvera pas le fichier et plantera.
---
### Résumé des liens entre ressources
Assurez-vous que vos ressources se référencent correctement :
* La **Clé** référencie le **Service Account**.
* L'**IAM Binding** référencie le **Service Account**.
* L'**OS Login** référencie le **Data User Info**.
Voici la suite du document Markdown (MD) à ajouter à la suite de l'étape 5.
---
## Étape 6 : Exposer les résultats (Outputs)
**Objectif :** Une fois le déploiement terminé, Terraform masque par défaut certaines informations. Nous devons définir explicitement quelles valeurs nous voulons voir ou récupérer (notamment pour les utiliser dans d'autres scripts).
* **Fichier à utiliser :** `outputs.tf` (c'est une bonne pratique de séparer les outputs du `main.tf`).
### Consigne A : L'email du Service Account
Nous aurons besoin de connaître l'adresse email complète générée par Google pour ce compte.
* Créez un output nommé `service_account_email`.
* Dans la valeur (`value`), référencez l'attribut `.email` de la ressource créée à l'**Étape 1**.
### Consigne B : La Clé Privée (Attention Sécurité)
Nous devons récupérer la clé privée générée pour pouvoir authentifier des applications externes.
* Créez un output nommé `service_account_key`.
* Dans la valeur, référencez l'attribut `.private_key` de la ressource créée à l'**Étape 2**.
* **Important :** Terraform refusera d'afficher cette valeur ou l'affichera en clair dans vos logs si vous ne faites pas attention. Vous **devez** ajouter l'argument suivant dans ce bloc output pour masquer la valeur dans le terminal :
```hcl
sensitive = true
```

653
terraform-show.txt Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 6.12.0"
}
local = {
source = "hashicorp/local"
version = "~> 2.5.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}
module "network" {
source = "../../modules/network"
project_name = var.project_name
region = var.region
frontend_cidr = var.frontend_cidr
backend_cidr = var.backend_cidr
database_cidr = var.database_cidr
ssh_source_ranges = var.ssh_source_ranges
}
module "compute" {
source = "../../modules/compute"
project_name = var.project_name
zone = var.zone
instance_type = var.instance_type
frontend_subnet_id = module.network.subnet_ids["frontend"]
backend_subnet_id = module.network.subnet_ids["backend"]
database_subnet_id = module.network.subnet_ids["database"]
}
module "iam" {
source = "../../modules/iam"
project_id = var.project_id
ssh_public_key_path = "/home/adriendick18/.ssh/id_ed25519.pub"
}
data "google_client_openid_userinfo" "me" {}
resource "local_file" "ansible_cfg" {
filename = "${path.module}/ansible.cfg"
content = templatefile(
"${path.module}/../../templates/ansible.cfg.tpl",
{
remote_user = data.google_client_openid_userinfo.me.email
}
)
}

View File

@@ -0,0 +1,32 @@
output "ip_internes" {
value = module.compute.ip_internes
}
output "ip_public_frontend" {
value = module.compute.ip_public_frontend
}
output "nom_instances" {
value = module.compute.nom_instances
}
output "service_account_email" {
description = "Service account email"
value = module.iam.service_account_email
}
output "service_account_key" {
description = "Service key"
value = module.iam.service_account_key
sensitive = true
}
output "vpc_terraform" {
description = "ID du VPC créé"
value = module.network.vpc_id
}
output "subnet_ids" {
description = "Map des IDs des sous-réseaux"
value = module.network.subnet_ids
}

View File

@@ -0,0 +1,53 @@
variable "project_name" {
type = string
description = "Nom logique du projet"
default = "projet-virtualisation"
}
variable "region" {
type = string
description = "Région dans laquelle déployer les ressources"
default = "europe-west9"
}
variable "zone" {
description = "Zone dans laquelle déployer les instances compute"
type = string
default = "europe-west9-b"
}
variable "frontend_cidr" {
description = "CIDR for frontend subnet"
type = string
default = "10.0.1.0/24"
}
variable "backend_cidr" {
description = "CIDR for backend subnet"
type = string
default = "10.0.2.0/24"
}
variable "database_cidr" {
description = "CIDR for database subnet"
type = string
default = "10.0.3.0/24"
}
variable "ssh_source_ranges" {
type = string
description = "Plages dadresses autorisées à se connecter en SSH"
default = "0.0.0.0/0"
}
variable "project_id" {
description = "ID du projet GCP"
type = string
default = "projet-virtualisation-478713"
}
variable "instance_type" {
description = "Type de machine pour les VM"
type = string
default = "e2-small"
}

View File

@@ -0,0 +1,69 @@
resource "google_compute_instance" "frontend" {
name = "${var.project_name}-frontend-vm"
machine_type = var.instance_type
zone = var.zone
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
size = 10
}
}
network_interface {
subnetwork = var.frontend_subnet_id
access_config {}
}
tags = ["frontend", "ssh"]
metadata = {
enable-oslogin = "TRUE"
}
}
resource "google_compute_instance" "backend" {
name = "${var.project_name}-backend-vm"
machine_type = var.instance_type
zone = var.zone
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
size = 10
}
}
network_interface {
subnetwork = var.backend_subnet_id
}
tags = ["backend", "ssh"]
metadata = {
enable-oslogin = "TRUE"
}
}
resource "google_compute_instance" "database" {
name = "${var.project_name}-database-vm"
machine_type = var.instance_type
zone = var.zone
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
size = 20
}
}
network_interface {
subnetwork = var.database_subnet_id
}
tags = ["database", "ssh"]
metadata = {
enable-oslogin = "TRUE"
}
}

View File

@@ -0,0 +1,19 @@
output "ip_internes" {
value = {
frontend = google_compute_instance.frontend.network_interface[0].network_ip
backend = google_compute_instance.backend.network_interface[0].network_ip
database = google_compute_instance.database.network_interface[0].network_ip
}
}
output "ip_public_frontend" {
value = google_compute_instance.frontend.network_interface[0].access_config[0].nat_ip
}
output "nom_instances" {
value = {
frontend = google_compute_instance.frontend.name
backend = google_compute_instance.backend.name
database = google_compute_instance.database.name
}
}

View File

@@ -0,0 +1,29 @@
variable "project_name" {
description = "Nom du projet / préfixe pour les VMs"
type = string
}
variable "instance_type" {
description = "Type de machine à utiliser pour les instances"
type = string
}
variable "zone" {
description = "Zone où déployer les instances"
type = string
}
variable "frontend_subnet_id" {
description = "ID du sous-réseau frontend"
type = string
}
variable "backend_subnet_id" {
description = "ID du sous-réseau backend"
type = string
}
variable "database_subnet_id" {
description = "ID du sous-réseau database"
type = string
}

View File

@@ -0,0 +1,26 @@
resource "google_service_account" "terraform_sa" {
account_id = "terraform"
display_name = "Service Account Terraform"
}
resource "google_service_account_key" "terraform_sa_key" {
service_account_id = google_service_account.terraform_sa.name
public_key_type = "TYPE_X509_PEM_FILE"
}
resource "google_project_iam_binding" "terraform_sa_viewer" {
project = var.project_id
role = "roles/viewer"
members = [
"serviceAccount:${google_service_account.terraform_sa.email}"
]
}
data "google_client_openid_userinfo" "me" {}
resource "google_os_login_ssh_public_key" "me_ssh_key" {
project = var.project_id
user = data.google_client_openid_userinfo.me.email
key = file(var.ssh_public_key_path)
}

View File

@@ -0,0 +1,10 @@
output "service_account_email" {
description = "Service account email"
value = google_service_account.terraform_sa.email
}
output "service_account_key" {
description = "Service key"
value = google_service_account_key.terraform_sa_key.private_key
sensitive = true
}

View File

@@ -0,0 +1,9 @@
variable "project_id" {
description = "ID du projet GCP"
type = string
}
variable "ssh_public_key_path" {
description = "Chemin vers la clé publique SSH"
type = string
}

View File

@@ -0,0 +1,101 @@
resource "google_compute_network" "vpc" {
name = "${var.project_name}-vpc"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "frontend_network" {
name = "${var.project_name}-frontend-subnet"
network = google_compute_network.vpc.id
ip_cidr_range = var.frontend_cidr
region = var.region
}
resource "google_compute_subnetwork" "backend_network" {
name = "${var.project_name}-backend-subnet"
network = google_compute_network.vpc.id
ip_cidr_range = var.backend_cidr
region = var.region
}
resource "google_compute_subnetwork" "database_network" {
name = "${var.project_name}-database-subnet"
network = google_compute_network.vpc.id
ip_cidr_range = var.database_cidr
region = var.region
}
resource "google_compute_firewall" "ssh_firewall" {
name = "${var.project_name}-ssh"
network = google_compute_network.vpc.name
direction = "INGRESS"
priority = 1000
target_tags = ["ssh"]
source_ranges = [var.ssh_source_ranges]
allow {
protocol = "tcp"
ports = ["22"]
}
}
resource "google_compute_firewall" "frontend_firewall" {
name = "${var.project_name}-frontend-http-https"
network = google_compute_network.vpc.name
direction = "INGRESS"
priority = 1000
target_tags = ["frontend"]
source_ranges = ["0.0.0.0/0"]
allow {
protocol = "tcp"
ports = ["80", "443"]
}
}
resource "google_compute_firewall" "backend_firewall" {
name = "${var.project_name}-frontend-to-backend-8000"
network = google_compute_network.vpc.name
direction = "INGRESS"
priority = 1000
target_tags = ["backend"]
source_tags = ["frontend"]
allow {
protocol = "tcp"
ports = ["8000"]
}
}
resource "google_compute_firewall" "database_firewall" {
name = "${var.project_name}-backend-to-database-3306"
network = google_compute_network.vpc.name
direction = "INGRESS"
priority = 1000
target_tags = ["database"]
source_tags = ["backend"]
allow {
protocol = "tcp"
ports = ["3306"]
}
}
resource "google_compute_router" "nat_router" {
name = "${var.project_name}-nat-router"
region = var.region
network = google_compute_network.vpc.id
}
resource "google_compute_router_nat" "nat_config" {
name = "${var.project_name}-cloud-nat"
router = google_compute_router.nat_router.name
region = var.region
nat_ip_allocate_option = "AUTO_ONLY"
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
log_config {
enable = true
filter = "ALL"
}
}

View File

@@ -0,0 +1,13 @@
output "vpc_id" {
description = "ID du VPC créé"
value = google_compute_network.vpc.id
}
output "subnet_ids" {
description = "Map des IDs des sous-réseaux"
value = {
frontend = google_compute_subnetwork.frontend_network.id
backend = google_compute_subnetwork.backend_network.id
database = google_compute_subnetwork.database_network.id
}
}

View File

@@ -0,0 +1,29 @@
variable "project_name" {
description = "Nom du projet / préfixe des ressources réseau"
type = string
}
variable "region" {
description = "Région GCP"
type = string
}
variable "frontend_cidr" {
description = "CIDR pour le subnet frontend"
type = string
}
variable "backend_cidr" {
description = "CIDR pour le subnet backend"
type = string
}
variable "database_cidr" {
description = "CIDR pour le subnet database"
type = string
}
variable "ssh_source_ranges" {
description = "Plage IP autorisée pour le SSH"
type = string
}