# 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