Votre blog sur Google Cloud sans rien débourser ? Possible !

Votre blog sur Google Cloud sans rien débourser ? Possible !

Avant de commencer, je dois vous dire quelque chose...

Je dois vous avouer que cet article est arrivé un peu par hasard. Vous connaissez mes goûts en matière d'hébergement, je suis plutôt adepte de raspberry mais surtout de maîtriser localement l'infrastructure que j'expose sur Internet.

J'ai réalisé dans le passé, plusieurs articles sur des services comme Gitea, qui sont très légers et rapides à mettre en place sur ce type de matériel.

Seulement parfois, la vie réserve des situations inattendues...

Vers la fin du mois de novembre, un grand opérateur français est venu fibrer mes voisins (j'habite dans une résidence). Le jour même, je perds la connexion au niveau de la box. Le boitier qui me relie à la fibre clignote en rouge.

Dans un premier temps, je me dis que ce genre de situation peut malheureusement parfois arriver, je prends donc rendez-vous avec un technicien pour réparer la situation.

Le lendemain, celui-ci m'apprend que j'ai été débranché car plus aucune prise fibre au niveau du palier n'était disponible et que le technicien qui a réalisé l'intervention d'hier n'a pas pris la peine de chercher une solution : il a coupé une personne au hasard, en l'occurrence moi.

Résultat : Plus d'accès à internet, étant quelques jours par semaine en télétravail, c'est assez embêtant. Mais surtout, plus d'accès depuis l'extérieur à mon NAS, à mes services et surtout mon blog qui est indisponible...

Une situation très embarrassante où j'ai dû attendre au final plusieurs semaines pour que l'opérateur d'immeuble ajoute l'équipement nécessaire au niveau du palier pour me raccorder à nouveau.

J'avais deux solutions : soit attendre, sans vraiment savoir quand je pourrai de nouveau bénéficier de la fibre optique, soit migrer mes services sur le Cloud pour éviter une interruption trop longue.

Devinez quelle situation j'ai choisie ?

LE CLOUD !! :)

AWS, Azure et Google Cloud sont dans un bateau...

Migrer sur le Cloud oui, mais lequel ?

En matière de connaissances pures, je suis à l'aise avec AWS et Google Cloud, un petit peu moins avec Azure.

Le but était de trouver une solution temporaire dans un premier temps, mais qui resterait un moyen de secours si jamais la situation venait à se reproduire.

Quand on parle Cloud, on parle aussi facturation. J'ai voulu me lancer un défi, prendre le Cloud qui me reviendrait le moins cher pour mon utilisation.

Ces trois grands fournisseurs de Cloud proposent des offres d'essai avec des produits gratuits, mais qui sont limités à 12 mois pour AWS et Azure concernant le Compute, c'est à dire, tout ce qui se réfère au calcul. Seul Google Cloud ne définit pas de limite de temps pour détenir une machine virtuelle associée aux conditions du niveau gratuit.

De plus, Google Cloud définit un certain nombre de services qui sont éligibles à cette offre sans frais additionnels : vous pouvez les retrouver cette page ici.

C'est donc vers ce dernier que je me suis orienté.

Attention tout de même, la liste des services et des limites de la version gratuite peuvent évoluer dans le temps, il faut donc être attentif à cela.

Le temps étant compté, il me fallait plusieurs services et fonctionnalités :

  • Une machine virtuelle proche de la capacité d'un raspberry : une machine virtuelle e2-micro (2 vCPUs et 1 Go de RAM) fera amplement l'affaire ;
  • Un espace de stockage pour la sauvegarde de données : Cloud Storage permet de stocker jusqu'à 5 Go de stockage régional ;
  • Une adresse IP externe pour accéder à mes services : la version gratuite ne facture pas l'utilisation d'une adresse IP externe pour Compute Engine ;
  • Une solution pour superviser les services que j'expose : la version gratuite de Cloud Logging et Cloud Monitoring proposent des fonctionnalités suffisantes dans mon cas d'utilisation ;
  • Sans oublier la possibilité de créer une ou plusieurs alertes sur la facturation en cas de dépassement, si un ou plusieurs services changent leurs limites pour la version gratuite, par exemple.

Enfin, la plupart des services associés à cette version impliquent d'être dans des régions spécifiques des États-Unis : us-west1 (Oregon), us-central1 (Iowa) ou us-east1 (Caroline du Sud). Cette dernière étant la plus "proche" du continent européen, je l'ai donc utilisée pour déployer mes services.

Petite remarque : la version standard d'App Engine dispose d'une offre gratuite si vous préférez héberger votre application à travers ce service plutôt que d'utiliser une machine virtuelle.

Mon choix étant fait, il est maintenant temps de se concentrer sur l'initialisation de Google Cloud et de réaliser les premières étapes avant de créer mon infrastructure.

Initialiser son organisation sur Google Cloud

Avant de commencer à créer quoi que ce soit en termes de code, il est nécessaire de disposer d'un espace au sein de Google Cloud pour déployer mon projet ainsi que les ressources qui le composent.

Je vous recommande, plutôt que de créer un seul projet avec la version gratuite, de venir créer une organisation. Cela permettra d'organiser vos projets si jamais vous voulez utiliser Google Cloud au-delà de la version gratuite et profiter des 300 $ à la suite de votre inscription pour tester différents services comme Google Kubernetes Engine (GKE) ou Cloud Run par exemple.

Pour créer une organisation, il faut disposer d'un nom de domaine, dans mon cas : filador.fr et se créer un compte sur le service Cloud Identity qui permet de gérer les utilisateurs de celle-ci. Là encore, Cloud Identity dispose d'une version gratuite, limité à 50 utilisateurs.

Cette page vous permet de créer votre utilisateur sur Cloud Identity et de rattacher votre nom de domaine. Une fois ces étapes terminées, tout est bon, on peut commencer à initialiser un premier projet.

L'histoire de l'oeuf et de la poule

Pour déployer avec Terraform, je dois disposer d'un compte de service et lui donner les droits nécessaires pour créer un projet et les ressources qui vont bien.

Oui mais... pour créer un compte de service sur Google Cloud, je dois disposer d'un projet.

Je vous conseille donc d'initialiser votre premier projet manuellement qui servira de bootstrap à la création du compte de service et de lui attribuer les rôles associés au niveau de l'organisation.

Ces rôles dépendent de ce que vous allez créer comme ressources avec Terraform. Dans le code qui sera présenté plus bas, certains rôles sont nécessaires :

  • Project Creator (roles/resourcemanager.projectCreator) pour créer des projets ;
  • Folder Viewer (roles/resourcemanager.folderViewer) pour lire le dossier dans lequel on crée le projet ;
  • Organisation Viewer (roles/resourcemanager.organizationViewer) pour lire l'organisation à laquelle on rattache le projet ;
  • Billing Account Administrator (roles/billing.admin) pour associer le projet avec les données de facturation et créer des alertes de budget ;
  • Compute Instance Admin (v1) (roles/compute.instanceAdmin.v1) pour gérer les ressources Compute comme une machine virtuelle, par exemple ;
  • Compute Network Admin (roles/compute.networkAdmin) pour gérer la partie réseau sauf les règles de pare-feu et de certificats ;
  • Compute Security Admin (roles/compute.securityAdmin) pour configurer les règles de pare-feu et sécuriser les machines virtuelles ;
  • Storage Admin (roles/storage.admin) pour créer un bucket Cloud Storage et stocker les sauvegardes.

Pour ma part, j'ai supprimé les projets créés automatiquement à la suite de l'initialisation de l'organisation. Vous pouvez faire la même chose, si vous le souhaitez en utilisant Cloud Resource Manager.

Si ces notions sont floues, je vous recommande de consulter la documentation officielle sur le compte de service et sur la gestion d'une organisation.

Pour créer mes ressources Terraform avec mon compte de service, je vais recourir au principe d'usurpation d'identité qui permet à mon utilisateur de tirer parti des rôles du compte de service sans télécharger ou exposer inutilement une clé au format JSON. C'est aussi une bonne pratique en matière de sécurité.

Votre utilisateur (autre que le super administrateur de votre organisation) doit disposer des rôles ci-dessous pour réaliser l'usurpation d'identité d'un compte de service :

  • Service Account User (roles/iam.serviceAccountUser)
  • Service Account Token Creator (Service Account Token Creator)

Il est temps de s'attaquer à l'infrastructure et au code Terraform !

Il était une fois, Terraform

Terraform, l'outil que l'on ne présente plus pour déployer de l'infrastructure. Il va permettre de mettre en place l'ensemble des ressources dont on a besoin et ainsi, créer une machine virtuelle.

Le code Terraform que j'ai utilisé est disponible via le lien suivant :

https://github.com/axinorm/google-cloud-free-tier

C'est mon petit cadeau de Noël en retard.

Les ressources utilisées

Il est temps de regarder plus en détail le code !

Le fichier terraform.auto.tfvars regroupe l'ensemble des variables à initialiser pour créer le projet et les ressources correspondantes. Vous trouverez la plupart des informations dont vous avez besoin dans le menu IAM and admin > Manage resources et Billing.

Dans le fichier compute.tf, il y a la ressource google_compute_instance avec les valeurs par défaut à us-east1-c pour la zone et e2-micro pour le type de machine. Ce qui permet d'avoir une machine virtuelle éligible à la version gratuite.

Plusieurs paramètres sont ajoutés, comme un disque dur de 30 Go, lui aussi, fait partie de la version gratuite.

Le transfert d'IP est désactivé par mesure de sécurité : can_ip_forward = "false".

On vient protéger l'intégrité de la machine virtuelle avec plusieurs paramètres :

  shielded_instance_config {
    enable_secure_boot          = true
    enable_vtpm                 = true
    enable_integrity_monitoring = true
  }

Pour plus de renseignements sur ces différents paramètres, je vous recommande de consulter la documentation correspondante.

Un peu plus haut, une adresse IP externe sera réservée :

resource "google_compute_address" "external_services" {
  project = module.external_services.project_id
  region  = var.region

  name         = "external-services-ip"
  address_type = "EXTERNAL"
}

Et ajoutée à l'instance avec le bloc access_config :

  network_interface {
    subnetwork = lookup(module.network_subnets.subnets, "${var.region}/${var.subnet_name}").self_link
    access_config {
      nat_ip = google_compute_address.external_services.address
    }
  }

Enfin, on associe un compte de service à ma machine virtuelle pour qu'elle ait le droit de déposer les sauvegardes dans un bucket Cloud Storage :

  service_account {
    email  = google_service_account.external_services.email
    scopes = ["cloud-platform"]
  }

Pour ce qui est du fichier firewall.tf, on utilise le module firewall-rules pour créer une règle qui autorise les flux HTTP et HTTPS. Si vous avez besoin d'administrer la machine virtuelle, une deuxième règle permet de se connecter en SSH via un tunnel IAP (Identity-Aware Proxy) permettant d'activer un niveau de sécurité supplémentaire.

Ensuite, dans iam.tf, le compte de service pour la machine virtuelle est relié avec le rôle roles/storage.objectAdmin permettant de stocker mes sauvegardes.

Tout ce qui concerne les alertes, que ce soit au niveau du CPU de l'instance ou ce qui permet de vérifier que le service est toujours en ligne se trouve dans monitoring.tf. Faites attention à renseigner votre email dans la variable notification_email pour le fichier terraform.auto.tfvars pour être alerté en cas de problème.

Dans le fichier network.tf, on retrouve les modules vpc et subnets pour créer le sous-réseau dans lequel l'instance sera placée.

La création du projet se trouve dans le fichier project.tf, plusieurs caractéristiques sont à noter :

  • auto_create_network = false permet de désactiver le VPC par défaut, ce qui évite d'avoir un réseau avec un sous-réseau par région ;
  • On active la surveillance de la facturation, ce qui est très utile si jamais un service de la version gratuite change de caractéristique, afin d'être alerté au plus tôt avec ce bloc de code :

  budget_amount            = var.billing_amount
  budget_alert_spend_basis = "CURRENT_SPEND"
  budget_alert_spent_percents = [
    0.1,
    0.25,
    0.5,
    0.75,
    1
  ]
  • On supprime les comptes de service par défaut default_service_account = "disable" qui ont des permissions beaucoup trop larges à des fins de sécurité.

Dans le fichier providers.tf, on retrouve le compte de service Terraform que l'on va usurper, comme expliqué un peu plus haut.

Ensuite, le fichier storage.tf permet de créer le bucket dans lequel on peut stocker des fichiers depuis la machine virtuelle.

Comme la version gratuite est limitée à 5 Go, il peut être utile d'ajouter une condition permettant de supprimer les anciennes sauvegardes afin de ne pas dépasser ce seuil :

  lifecycle_rule {
    condition {
      age = 10
    }
    action {
      type = "Delete"
    }
  }

Vous pouvez ajuster le paramètre age en fonction de vos besoins.

Plusieurs sécurités ont été mises en place sur ce bucket :

  public_access_prevention = "enforced"
  force_destroy            = false

Le paramètre public_access_prevention permet d'empêcher les accès publics à un ou plusieurs éléments du bucket, et, force_destroy de rendre impossible la suppression de celui-ci s'il y a des éléments à l'intérieur.

Enfin, les deux derniers fichiers variables.tf et outputs.tf permettent, pour le premier, de définir l'ensemble des variables à renseigner dans le fichier terraform.auto.tfvars. Le second, quant à lui, affiche en fin d'exécution de Terraform l'identifiant du projet nouvellement créé et l'adresse IP externe de la machine virtuelle.

Tout est bon ! Le code est prêt, il est temps de créer les différentes ressources !

Création des ressources

Une fois le terraform.auto.tfvars renseigné, plusieurs commandes sont à réaliser pour déployer l'infrastructure.

Tout d'abord, via le terminal et à l'endroit où se trouve le code, il est nécessaire de se connecter avec le compte Google qui réalisera l'usurpation d'identité sur le compte de service utilisé par Terraform :

gcloud auth login --update-adc

Par la suite, on retrouve les commandes Terraform classiques : init, plan et apply.

# Initialisation des providers et des modules
terraform init

# Génération du plan
terraform plan

# Génération du plan et création des ressources
terraform apply

Bien joué ! Votre infrastructure, mais surtout votre machine virtuelle, est correctement déployée !

À noter que quelques erreurs peuvent survenir au moment de l'apply si une ou plusieurs API n'ont pas été activées.

Pour aller plus loin

Comme dit précédemment, pour se connecter en SSH sur la machine virtuelle, il est important de décommenter cette partie dans le fichier firewall.tf sans oublier le terraform apply :

    ...
    {
      name                    = "frw-allow-ssh-from-iap"
      description             = null
      direction               = "INGRESS"
      priority                = null
      ranges                  = ["35.235.240.0/20"]
      source_tags             = null
      source_service_accounts = null
      target_tags             = ["external-services"]
      target_service_accounts = null
      allow = [{
        protocol = "tcp"
        ports    = ["22"]
      }]
      deny       = []
      log_config = null
    }
    ...

Avec cette action, vous êtes en mesure d'utiliser la ligne de commande ci-dessous pour vous connecter à la machine virtuelle :

gcloud compute ssh --zone "us-east1-c" <Nom de la machine virtuelle>  --project <ID du projet> --tunnel-through-iap

Vous pouvez aussi exécuter des scripts de durcissement pour renforcer la sécurité de votre instance. Si, comme moi, vous aimez Ansible, je vous recommande cette collection de rôles.

Il peut être recommandé de protéger votre machine virtuelle contre les attaques par déni de service (DDoS) et pourquoi pas, de disposer d'un cache pour améliorer les temps de réponse si vous exposez des services comme un blog par exemple.

Cloudflare dispose d'une offre gratuite pour les projets personnels.

Il peut être intéressant d'utiliser l'infrastructure de Cloudflare à travers cette offre pour bénéficier de plusieurs fonctionnalités très intéressantes :

  • Gestion centralisée du DNS pour vos noms de domaine ;
  • Protection anti-DDoS ;
  • Gestion du cache avec le réseau de diffusion de contenu (CDN) ;
  • Génération de certificats.

En utilisant le proxy de Cloudflare, il peut être intéressant de restreindre la communication des flux HTTP et HTTPS de votre machine virtuelle, uniquement avec celui-ci.

Pour cela, rien de compliqué, un provider Terraform existe avec une datasource permettant de récupérer les plages IP de Cloudflare.

Vous êtes maintenant prêt à exposer vos services en toute sécurité !

Conclusion

Cette mésaventure aura eu le mérite de me faire réfléchir à l'utilisation de plusieurs produits de l'offre gratuite de Google Cloud pour migrer mes services et par conséquent, rédiger un article pour les partager avec vous.

On parle ici d'une infrastructure très simple pour des services personnels qui ne sont pas critiques. Il est évidemment possible de muscler la disponibilité des machines virtuelles pour quelques euros de plus en utilisant les services Google Cloud correspondant. À vous de décider en fonction de vos besoins.

Ce projet peut être vu comme une base pour celles et ceux qui souhaitent commencer à déployer des applications à moindre coût.

N'oubliez pas de garder un œil sur la facturation et sur ce que vous consommez. :)