Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
💥 Les 22 & 23 novembre : Accès 100% GRATUIT
à la Bibliothèque Numérique ENI. Je m'inscris !
  1. Livres et vidéos
  2. L’infrastructure as Code avec Terraform
  3. Dans la pratique
Extrait - L’infrastructure as Code avec Terraform Déployez votre infrastructure sur le Cloud
Extraits du livre
L’infrastructure as Code avec Terraform Déployez votre infrastructure sur le Cloud Revenir à la page d'achat du livre

Dans la pratique

Des exemples variés d’infrastructure

Ce chapitre, un peu spécial, a pour but d’illustrer quelques cas d’usage intéressants de Terraform avec des exemples de code concrets.

Ces exemples de code (comme d’autres de cet ouvrage) sont disponibles sur le repository GitHub disponible à cette adresse : https://github.com/eni-terraform-samples, ainsi que sur GitLab : https://gitlab.com/eni-terraform-samples/.

Les exemples sont entièrement fonctionnels. Ils contiennent chacun un fichier README.md, qui décrit quelles sont les variables Terraform demandées, les outputs en sortie et les variables d’environnement nécessaires à la configuration du provider (clés d’API, tokens, etc.). Ils peuvent servir de point de départ à l’écriture de code pour une infrastructure de production, ou à l’écriture d’un module (cf. chapitre Utiliser et développer des modules).

N’hésitez pas à les télécharger, les tester et les modifier !

Un cluster k8s sur Scaleway

La création d’un cluster Kubernetes sur Scaleway consiste à créer deux ressources : le cluster en lui-même, ainsi qu’un node pool, qui contiendra les machines virtuelles du cluster.

Pour être créé, un cluster a également besoin d’un réseau privé.

Voici un exemple de code simple, mais complet, qui crée un cluster Kubernetes sur le cloud Scaleway :

# scaleway cluster needs a private network 
resource "scaleway_vpc_private_network" "network" {} 
 
# getting lastest supported k8s version 
data "scaleway_k8s_version" "latest" { 
  name = "latest" 
  region = "fr-par" 
} 
 
resource "scaleway_k8s_cluster" "cluster" { 
  name = "cluster" 
 
  # versions have the form region/version 
  version = split( "/",  
    data.scaleway_k8s_version.latest.id)[1] 
  cni = "cilium" 
 
  region = "fr-par" 
 
  # referencing the created network 
  private_network_id = scaleway_vpc_private_network.network.id 
 
  # delete all that wes created when destroying the cluster 
  delete_additional_resources = true 
} 
 
resource "scaleway_k8s_pool" "pool" { 
  # referencing the created cluster id 
  cluster_id = scaleway_k8s_cluster.cluster.id 
 
  name...

Une zone DNS chez OVH

La gestion d’une zone DNS chez OVH peut se faire avec leur provider Terraform. 

La data ovh_domain_zone permet de récupérer des informations sur un nom de domaine et sa zone existante chez OVH. La ressource ovh_domain_zone_record permet de créer de nouveaux enregistrements dans une zone DNS existante.

data "ovh_domain_zone" "zone" { 
  name = "star-wars.ovh" 
} 
 
resource "ovh_domain_zone_record" "dagobah" { 
  zone = data.ovh_domain_zone.zone.name 
  subdomain = "dagobah" 
  fieldtype = "A" 
  ttl = 60 
  target = "47.41.108.60" 
} 
 
resource "ovh_domain_zone_record" "tatooine" { 
  zone = data.ovh_domain_zone.zone.name 
  subdomain = "tatooine" 
  fieldtype = "A" 
  ttl = 60 
  target = "242.105.108.11" 
} 

Dans cet exemple de code, la zone DNS star-wars.ovh est accédée à l’aide d’un bloc data.

Deux records DNS sont ajoutés à cette zone : dagobah.star-wars.ovh et tatooine.star-wars.ovh, avec leurs adresses IP respectives.

L’exécution de ce code avec terraform apply donne les logs suivants :...

Un groupe GitLab avec des repositories

Il est possible d’initialiser des repositories GitLab avec Terraform.

Le code suivant initialise les repositories de cet ouvrage en utilisant le provider GitLab :

resource "gitlab_group" "terraform_code_examples" { 
  name = "ENI Terraform Book Samples" 
  path = "eni-terraform-samples" 
  description = "A GitLab group for Terraform code samples" 
 
  avatar = "logo-eni.png" 
} 
 
resource "gitlab_project" "ovh_dns_zone" { 
  name = "ovh-dns-zone" 
  description = "sample Terraform project which manages an OVH DNS zone" 
 
  namespace_id = gitlab_group.terraform_code_examples.id 
 
  avatar = "logo-ovhcloud.png" 
} 
 
resource "gitlab_project" "scaleway_k8s_cluster" { 
  name = "scaleway-k8s-cluster" 
  description = "sample Terraform project which creates a k8s cluster 
on Scaleway Cloud" 
 
  namespace_id = gitlab_group.terraform_code_examples.id 
 
  avatar = "logo-scaleway.png" 
} 
 
resource "gitlab_project" "aws_intances" { 
  name = "aws-instances" ...

Des repositories sur GitHub

Comme c’est le cas pour GitLab, il est possible d’utiliser Terraform pour créer des repositories GitHub.

Le code suivant initialise les repositories de cet ouvrage en utilisant le provider GitHub :

locals { 
  projects = { 
    "ovh-dns-zone" : "sample Terraform project which manages 
an OVH DNS zone" 
    "scaleway-k8s-cluster" : "sample Terraform project which 
creates a k8s cluster on Scaleway Cloud" 
    "aws-instances" : "sample Terraform project which manages 
EC2 instances exposed by a load-balancer" 
  } 
} 
 
resource "github_repository" "repository" { 
  for_each = local.projects 
 
  name = each.key 
  description = each.value 
 
  visibility = "public" 
} 

La ressource github_repository permet de créer un repository GitHub.

Un for_each est utilisé pour créer plusieurs repositories à partir du même bloc ressource. La syntaxe et le fonctionnement de l’argument for_each sont expliqués dans le chapitre Concepts avancés de Terraform.

Les repositories sont créés dans l’organisation définie au niveau du provider :...

Une base de données PostgreSQL sur Google Cloud

Cet exemple est un peu plus compliqué que les exemples précédents. Ici, une base de données PostgreSQL est créée sur Google Cloud, ainsi qu’un utilisateur pour s’y connecter. Les informations d’accès à l’utilisateur sont alors stockées à deux endroits : dans un secret sur Google Secret Manager, ainsi que dans un secret dans un Vault.

Le code suivant, présent dans le fichier main.tf crée un serveur de base de données PostgreSQL sur Google Cloud, avec une base de données star-wars :

# create a database server instance 
resource "google_sql_database_instance" "this" { 
  name = "star-wars-database" 
  database_version = "POSTGRES_15" 
 
  # use "Paris" region 
  region = "europe-west9" 
 
  settings { 
    tier = "db-f1-micro" 
    disk_size = 20 
    disk_autoresize = true 
    backup_configuration { 
      enabled = true 
  } 
  } 
} 
 
# create a database inside the instance 
resource "google_sql_database" "this"...

Des serveurs EC2 et un load-balancer sur AWS

Cette infrastructure est plus compliquée que les infrastructures précédentes :

images/04EI08.png

Cette infrastructure contient la déclaration de trois sous-réseaux publics dans un VPC (Virtual Private Cloud, un réseau privé virtuel). Une Internet Gateway permet d’ouvrir l’accès à Internet (sortant) et rend possible l’association d’adresses IP publiques. Chaque sous-réseau contient une machine virtuelle. Les machines virtuelles sont exposées par un load-balancer HTTP qui répartit les requêtes entrantes sur les trois machines.

Les réseaux sont déclarés par le fichier networks.tf :

locals { 
  vpc_cidr_block = "10.200.0.0/16" 
  networks = { 
    "eu-west-3a" = "10.200.1.0/24" 
    "eu-west-3b" = "10.200.2.0/24" 
    "eu-west-3c" = "10.200.3.0/24" 
  } 
} 
 
# Définition du VPC et des sous-réseaux 
resource "aws_vpc" "main" { 
  cidr_block = local.vpc_cidr_block 
 
  tags = { 
    Name = "vpc-eu-west-3" 
  } 
} 
 
resource "aws_subnet" "public_subnet" { 
  for_each = local.networks 
 
  availability_zone = each.key 
  cidr_block = each.value 
 
  vpc_id = aws_vpc.main.id 
 
  tags = { 
    Name = "subnet-${each.key}" 
  } 
} 
 
resource "aws_internet_gateway" "internet" { 
  vpc_id = aws_vpc.main.id 
} 

Une variable locale contient le bloc réseau à associer au VPC, ainsi que le nom des trois zones à utiliser associées aux plages réseau souhaitées.

Le réseau est créé avec un bloc aws_vpc. Les sous-réseaux...

Une base de données MongoDB sur Atlas

Le code de cet exemple utilise quatre variables en entrée :

variable "organization_id" { 
  type = string 
  description = "the organization in which to create the cluster" 
} 
 
variable "environment" { 
  type = string 
  description = "the name of the environment for the cluster" 
} 
 
variable "cluster_name" { 
  type = string 
  description = "the name of the cluster" 
} 
 
variable "database_user" { 
  type = object({ 
    username = string 
    database_name = string 
  }) 
} 

La variable organization_id permet de saisir l’identifiant de l’organisation dans laquelle déployer le cluster.

La variable environment est utilisée pour créer un projet dans l’organisation MongoDB Atlas. La notion de projet dans MongoDB Atlas permet d’isoler différents clusters.

La variable cluster_name permet de nommer le cluster.

La variable database_user permet de déclarer un utilisateur dans le cluster, qui aura des droits d’écriture sur une base de données.

Le fichier cluster.tf définit la création du projet MongoDB Atlas, ainsi que le cluster :

resource "mongodbatlas_project" "this" { 
  org_id = var.organization_id 
 
  name = var.environment 
} 
 
resource "mongodbatlas_cluster" "this" { 
  project_id = mongodbatlas_project.this.id 
  name = var.cluster_name ...

Conclusion

Ce chapitre a présenté des cas d’usages les plus variés possible de Terraform.

Les cas les plus simples sont les utilisations des services GitHub et GitLab, pour créer des repositories. Ces cas sont simplistes, mais montrent un usage relativement original de Terraform. Il est possible d’aller plus loin sur ces deux exemples : création de variables de CI/CD ou secrets, ajout de membres d’équipes en contributeur sur les repositories, etc.

Les cas plus compliqués sont la base de données avec l’intégration de Vault, ou l’infrastructure EC2 sur AWS. Le cas de la base de données montre un usage intéressant d’intégration de plusieurs providers dans le même code. Il n’est pas rare d’utiliser le provider Vault pour écrire des secrets lorsque des ressources sont créées sur un service cloud (utilisateur ou service account, par exemple).

Les cas de l’infrastructure EC2 sur AWS montrent un usage des fonctions avancées de Terraform, en particulier le for_each en teasing, qui est expliqué en détail dans le chapitre Concepts avancés de Terraform.

Vous arrivez à l’issue du premier tiers de ce livre ! Les chapitres suivants introduisent les notions plus avancées : modules, constructions de code avancées, gestion du state, écriture de tests...