Comment sauvegarder l'état de Terraform sur Google Cloud Storage
S'il existe un truc indispensable et très important en travaillant avec Terraform c'est l'état (state). Pour faire simple ,l'état permet de sauvegarder les configurations et les ressources créées. Cet état est normalement enregistré dans un fichier local appelé terraform.tfstate
, mais il peut également être enregistré dans un service de stockage, ce qui est préférable dans un environnement d'équipe et pour de vrais projets.Nous allons voir comment sauvegarder nos états sur Google Cloud Storage.
L'approche pour sauvegarder les états dans un service de stockage n'est pas nouvelle. Elle est directement intégrée dans Terraform grâce aux backend
Il existe deux types de backend :
Nous allons utiliser un backend distant dans notre cas.
Les backends
distants de Terraform nous permettent de stocker le fichier d'état dans un service de stockage .
Il existe bien sur plusieurs backend disponible comme :
Pour utiliser le backend gcs
, la première chose a noté est que votre bucket doit exister avant que n'ajoutiez la configuration du backend dans votre configuration Terraform. Pour cela, vous pouvez creer le bucket manuellement ou le créer avec Terraform en utilisant le backend local puis changer le backend vers gcs
.
Dans ce tuto, je vais utiliser la deuxième approche. La première approche est quand même interressante car elle vous permet de garder vos états même si vous détruisez votre infrastructure avec Terraform.
Pour cette démonstration, nous allons lancer une instance sur Google Cloud et sauvegarder l'etat sur Google Cloud Storage.
Nos fichiers Terraform ressembleront à ceci
variable "project_id" {
description = "Google Cloud Platform (GCP) Project ID"
type = string
default = "loopbin"
}
variable "region" {
description = "GCP region"
type = string
default = "europe-west1"
}
variable "zone" {
description = "GCP zone."
type = string
default = "europe-west1-b"
}
variable "name" {
description = "Nom du server web "
type = string
default = "nginx-server"
}
variable "machine_type" {
description = "type de machie sur GCE"
type = string
default = "n1-highcpu-2"
}
variable "state_bucket_name" {
description = "Nom du bucket ou sont enregister les etats"
type = string
default = "loopbin-terraform-state-bucket"
}
resource "google_compute_instance" "vm" {
name = var.name
machine_type = var.machine_type
zone = var.zone
tags = ["http-server"]
boot_disk {
initialize_params {
image = "debian-cloud/debian-10"
}
}
network_interface {
network = "default"
access_config {
}
}
metadata_startup_script = "sudo apt-get update; sudo apt-get install -yq nginx"
}
resource "google_compute_firewall" "nginx_server_firewall" {
name = "nginx-server-firewall"
network = "default"
target_tags = [ "http-server" ]
allow {
protocol = "tcp"
ports = ["80"]
}
}
output "server_ip" {
value = google_compute_instance.vm.network_interface.0.access_config.0.nat_ip
}
resource "google_storage_bucket" "terraform_state_bucket" {
name = var.state_bucket_name
location = upper(var.region)
uniform_bucket_level_access = true
force_destroy = true
}
provider "google" {
project = var.project_id
region = var.region
}
terraform {
backend "local" {
path = "state/terraform.tfstate"
}
}
Comme spécifié dans le fichier main.tf, nous allons au début garder notre état localement dans l'emplacement state/terraform.tfstate
.
Ce code exécutera les actions suivantes :
loopbin-terraform-state-bucket
dans la zone EUROPE-WESTnginx-server
et y installera nginx à la créationC'est le moment de deployer
terraform init
terraform plan
terraform apply
Si tout va bien, le déploiement sera un succès. Nous pouvons vérifier notre déploiement avec les commandes suivantes.
$ gcloud compute instances list
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
nginx-server europe-west1-b n1-highcpu-2 10.132.0.4 35.195.174.19 RUNNING
$ gcloud compute firewall-rules list
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
default-allow-icmp default INGRESS 65534 icmp False
default-allow-internal default INGRESS 65534 tcp:0-65535,udp:0-65535,icmp False
default-allow-rdp default INGRESS 65534 tcp:3389 False
default-allow-ssh default INGRESS 65534 tcp:22 False
nginx-server-firewall default INGRESS 1000 tcp:80 False
$ gsutil list
gs://loopbin-terraform-state-bucket/
Et bien sur, l'adresse IP de notre instance nous montrera la page d'accueil par défaut de NGINX.
À ce niveau, nous avons notre bucket, mais nous ne l'utilisons pas encore comme backend. Tout ce qu'il nous faut, c'est quelque ligne de code dans notre ficher main.tf
provider "google" {
project = var.project_id
region = var.region
}
terraform {
backend "gcs" {
bucket = "loopbin-terraform-state-bucket"
prefix = "state"
}
}
Dans le code si dessus, nous avons changé notre backend local pour le backend gcs.
Le backend gcs prend une valeur de configuration obligatoire, c'est bucket
le nom du bucket ou sera stocker nos états. l'option préfix nous permet de spécifier un préfixe qui sera utiliser comme emplacement dans le bucket (nom de dossier).
Tout ce qu'il nous faut maintent, c'est faire les commandes de déploiement terraform init
, terraform plan
et terraform apply
$ gsutil ls -r gs://loopbin-terraform-state-bucket/**
gs://loopbin-terraform-state-bucket/state/default.tfstate
La commande gsutil nous montre que notre fichier tfstate est maintenant dans notre bucket sur Google Cloud
Attention n'oubliez pas de ramener le backend vers
local
avant de lancer une infrastructure. Si vous ne le faites pas, terraform supprimera le bucket puis ne sera plus en mesure d'avoir accès à l'état bloqué pour continuer.
Bravo