Un module Terraform est un ensemble de fichiers de configuration Terraform qui décrivent une configuration spécifique.
Les modules peuvent être utilisés pour organiser la configuration Terraform en composants réutilisables, de sorte que les mêmes ressources ou configurations puissent être utilisées à plusieurs endroits dans un plan de déploiement.
Les modules Terraform peuvent également être utilisés pour partager des configurations avec d'autres utilisateurs de Terraform.
Utilisation d'un module :
module "monmodule" {
source = "./rep_module"
}
Structure d'un module recommandé par Hashicorp :
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
Ou plus poussé :
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
├── ...
├── modules/
│ ├── nestedA/
│ │ ├── README.md
│ │ ├── variables.tf
│ │ ├── main.tf
│ │ ├── outputs.tf
│ ├── nestedB/
│ ├── .../
├── examples/
│ ├── exampleA/
│ │ ├── main.tf
│ ├── exampleB/
│ ├── .../
terraform get
terraform init
terraform apply -target=module.docker
terraform apply -target=module.postgres
Voici l'architecture recherché pour installer docker via un module :
.
├── main.tf
├── modules
│ └── docker_install
│ ├── main.tf
│ ├── startup-options.conf
│ └── variables.tf
└── terraform.tfvars
3 directories, 5 files
En détails :
main.tf
:variable "ssh_host" {}
variable "ssh_user" {}
variable "ssh_key" {}
module "docker_install" {
source = "./modules/docker_install" # On appelle le module
ssh_host = var.ssh_host # On passe les variables au main.tf du module docker_install
ssh_key = var.ssh_key # on pourrait changer le nom de la variable si on le souhaitait
ssh_user = var.ssh_user
}
terraform.tfvars
:ssh_host = "192.168.1.10"
ssh_user = "antoine"
ssh_key = "/Users/antoine/.ssh/id_rsa"
modules/docker_install/main.tf
:resource "null_resource" "ssh_target" {
connection {
type = "ssh"
user = var.ssh_user
host = var.ssh_host
private_key = file(var.ssh_key)
}
provisioner "remote-exec" {
inline = [
"sudo apt update -qq >/dev/null",
"curl -fsSL https://get.docker.com -o get-docker.sh",
"sudo chmod 755 get-docker.sh",
"sudo ./get-docker.sh >/dev/null"
]
}
provisioner "file" {
source = "${path.module}/startup-options.conf" # Récupère le path du module actuel
destination = "/tmp/startup-options.conf"
}
provisioner "remote-exec" {
inline = [
"sudo mkdir -p /etc/systemd/system/docker.service.d/",
"sudo cp /tmp/startup-options.conf /etc/systemd/system/docker.service.d/startup_options.conf",
"sudo systemctl daemon-reload",
"sudo systemctl restart docker",
"sudo usermod -aG docker ubuntu"
]
}
}
modules/docker_install/startup-options.conf
:[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://192.168.1.10:2375 -H unix:///var/run/docker.sock
modules/docker_install/variables.tf
:variable "ssh_host" {}
variable "ssh_user" {}
variable "ssh_key" {}
On va maintenant lancer les commandes terraform :
❯ tf get
❯ tf init
Initializing modules...
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/null...
- Installing hashicorp/null v3.2.1...
- Installed hashicorp/null v3.2.1 (signed by HashiCorp)
...
❯ tf plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.install.null_resource.ssh_target will be created
+ resource "null_resource" "ssh_target" {
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.❯ tf plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# module.install.null_resource.ssh_target will be created
+ resource "null_resource" "ssh_target" {
+ id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
❯ tf apply
Architecture souhaitée :
.
├── main.tf
├── modules
│ ├── docker_install
│ │ ├── main.tf
│ │ ├── startup-options.conf
│ │ └── variables.tf
│ └── docker_run
│ ├── main.tf
│ └── variables.tf
└── terraform.tfvars
4 directories, 7 files
main.tf
modifié :variable "ssh_host" {}
variable "ssh_user" {}
variable "ssh_key" {}
module "docker_install" {
source = "./modules/docker_install"
ssh_host = var.ssh_host
ssh_key = var.ssh_key
ssh_user = var.ssh_user
}
module "docker_run" {
source = "./modules/docker_run"
ssh_host = var.ssh_host
}
modules/docker_run/main.tf
:terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "2.25.0"
}
}
}
provider "docker" {
host = "tcp://${var.ssh_host}:2375"
}
resource "docker_image" "nginx" {
name = "nginx:latest"
}
resource "docker_container" "nginx" {
image = docker_image.nginx.image_id
name = "nginx-wiki"
ports {
internal = 80
external = 80
}
}
Si on fait un terraform apply, nous aurons une erreur car docker n'est pas installé sur notre machine distante :
❯ tf apply
╷
│ Error: Error pinging Docker server: Cannot connect to the Docker daemon at tcp://192.168.1.10:2375. Is the docker daemon running?
│
│ with module.docker_run.provider["registry.terraform.io/kreuzwerker/docker"],
│ on modules/docker_run/main.tf line 10, in provider "docker":
│ 10: provider "docker" {
│
Afin de lancer l'installation avant le lancement d'un container, nous faisons appel au paramètre -target
:
❯ tf apply -target modules.docker_install