A
u
Belaid Youba Hadj Arab, Etienne Deneuve
Oct 25, 2023 · 6 min read

Déployer une machine virtuelle avec Terraform et Ansible

Side view worker wearing gloves

Dans cette deuxième partie nous allons enfin passer aux choses sérieuses : le déploiement de la vm. Vérifiez que vous avez bien suivi les étapes de l’article précédent, et nous sommes partis!

1. Azure

  1. La première chose à faire est de se connecter à Azure, pour y déployer nos ressources :

Terminal window
az login --tenant VOTRE-TENANT

Notez qu’il existe plusieurs façons de se connecter à Azure, ici on le fait avec un tenant, mais ça peut être aussi sans. Faite un az login -h pour choisir celle qui vous convient

2. Terraform

2.1. Création des fichiers .tf

  1. Créer un dossier pour y mettre notre code Terraform :

Terminal window
mkdir terraform-vm-tuto
cd terraform-vm-tuto
# et si vous utiliez vscode
code .
  1. Dans ce dossier, nous allons créer 5 fichiers : main.tf, variables.tf,providers.tf, network.tf et outputs.tf.

  2. Commençons par providers.tf. Son rôle est de déclarer les fournisseurs qui seront utilisés pour déployer les ressources :

    terraform {
    required_providers {
    azurerm = {
    source = "hashicorp/azurerm"
    version = "@>2.0"
    }
    tls = {
    source = "hashicorp/tls"
    version = "@>4.0"
    }
    }
    }
    provider "azurerm" {
    features {}
    }
  3. Puis main.tf. C’est ici que seront déclarées les dites ressources qui seront déployées, comme le resource group et la virtual machine par exemple, ainsi que leurs configurations :

    resource "azurerm_resource_group" "tf_rg" {
    location = var.resource_group_location
    name = var.resource_group_name
    }
    resource "azurerm_linux_virtual_machine" "tf_my_terraform_vm" {
    name = "myVM"
    location = azurerm_resource_group.tf_rg.location
    resource_group_name = azurerm_resource_group.tf_rg.name
    network_interface_ids = [azurerm_network_interface.tf_my_terraform_nic.id]
    size = "Standard_DS1_v2"
    os_disk {
    name = "myOsDisk"
    caching = "ReadWrite"
    storage_account_type = "Premium_LRS"
    }
    source_image_reference {
    publisher = "Canonical"
    offer = "0001-com-ubuntu-server-jammy"
    sku = "22_04-lts-gen2"
    version = "latest"
    }
    computer_name = var.computer_name
    admin_username = var.admin_username
    disable_password_authentication = true
    admin_ssh_key {
    username = var.admin_username
    public_key = tls_private_key.tf_public_ssh.public_key_openssh
    }
    }
  4. Ensuite vientnetwork.tf. Ici on déclare les vnet, subnet et autres ressources en rapport avec le networking :

Terminal window
resource "azurerm_virtual_network" "tf_my_terraform_network" {
name = "myVnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.tf_rg.location
resource_group_name = azurerm_resource_group.tf_rg.name
}
resource "azurerm_subnet" "tf_my_terraform_subnet" {
name = "mySubnet"
resource_group_name = azurerm_resource_group.tf_rg.name
virtual_network_name = azurerm_virtual_network.tf_my_terraform_network.name
address_prefixes = ["10.0.1.0/24"]
}
resource "azurerm_public_ip" "tf_my_terraform_public_ip" {
name = "myPublicIP"
location = azurerm_resource_group.tf_rg.location
resource_group_name = azurerm_resource_group.tf_rg.name
allocation_method = "Dynamic"
}
resource "azurerm_network_security_group" "tf_my_terraform_nsg" {
name = "myNetworkSecurityGroup"
location = azurerm_resource_group.tf_rg.location
resource_group_name = azurerm_resource_group.tf_rg.name
security_rule {
name = "SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
resource "azurerm_network_interface" "tf_my_terraform_nic" {
name = "myNIC"
location = azurerm_resource_group.tf_rg.location
resource_group_name = azurerm_resource_group.tf_rg.name
ip_configuration {
name = "my_nic_configuration"
subnet_id = azurerm_subnet.tf_my_terraform_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.tf_my_terraform_public_ip.id
}
}
resource "azurerm_network_interface_security_group_association" "example" {
network_interface_id = azurerm_network_interface.tf_my_terraform_nic.id
network_security_group_id = azurerm_network_security_group.tf_my_terraform_nsg.id
}
resource "tls_private_key" "tf_public_ssh" {
algorithm = "RSA"
rsa_bits = 4096
}
  1. Le fichier variables.tf contiendra toutes les variables utilisées pour configurer les ressources. il est toujours utile de les configurer via des variables, car il sera plus facile de les modifier après au gré de vos besoins :

    variable "resource_group_name" {
    type = string
    default = "rg-terraform-ansible-tuto"
    description = "nom du ressource groupe"
    }
    variable "resource_group_location" {
    type = string
    default = "westeurope"
    description = "localisation du ressource groupe"
    }
    variable "computer_name" {
    type = string
    default = "myvm"
    description = "nom de la machine virtual"
    }
    variable "admin_username" {
    type = string
    default = "azureadmin"
    description = "nom de l'utilisateur admin"
    }
    variable "vnet_address_space" {
    type = list(string)
    default = ["10.0.0.0/16"]
    description = "plage ip du virtual network"
    }
    variable "subnet_address_space" {
    type = list(string)
    default = ["10.0.1.0/24"]
    description = "plage ip du sub-network"
    }
  2. Et enfin outputs.tf :

    output "public_ip_address" {
    value = azurerm_linux_virtual_machine.tf_my_terraform_vm.public_ip_address
    }
    output "tls_private_key" {
    value = tls_private_key.tf_public_ssh.private_key_pem
    sensitive = true
    }

2.1.1. Déployer plusieurs vm

  1. Dans le code plus haut, on ne déploie qu’une seule machine virtuelle, si on veut en déployer 2 ou 3, il nous suffira de créer d’autres bloc. On peut aussi utiliser le meta-argument: count

  2. Pour ça, dans le fichier main.tf on rajoute :

    resource "azurerm_linux_virtual_machine" "tf_my_terraform_vm" {
    count = 3 # le nombre de vm qui sera déployé est de 3, par exemple
    name = var.vm_names[count.index]
    location = azurerm_resource_group.tf_rg.location
    resource_group_name = azurerm_resource_group.tf_rg.name
    network_interface_ids = [azurerm_network_interface.tf_my_terraform_nic.id]
    size = "Standard_DS1_v2"
    os_disk {
    name = var.vm_os_disk_names[count.index]
    caching = "ReadWrite"
    storage_account_type = "Premium_LRS"
    }
    source_image_reference {
    publisher = "Canonical"
    offer = "0001-com-ubuntu-server-jammy"
    sku = "22_04-lts-gen2"
    version = "latest"
    }
    computer_name = var.computer_names[count.index]
    admin_username = var.admin_username[count.index]
    disable_password_authentication = true
    admin_ssh_key {
    username = var.admin_username[count.index]
    public_key = tls_private_key.tf_public_ssh.public_key_openssh
    }
    }
  3. On modifie quelques variables dans le fichier variables.tf :

    variable "computer_name" {
    type = list(string)
    default = ["myvm","myvm2","myvm3"]
    description = "nom de la machine virtual"
    }
    variable "admin_username" {
    type = list(string)
    default = ["azureadmin","azureadmin2","azureadmin3"]
    description = "nom de l'utilisateur admin"
    }

2.2. Initialisation et déploiement

  1. Maintenant que les fichiers sont créés, nous allons faire l’initialisation de Terraform. Pour ça, il faut se mettre à la racine du dossier créé plus haut :

Terminal window
terraform init
  1. Une fois l’initialisation terminée, on peut lancer une commande optionnelle pour vérifier la syntaxe de notre code :

Terminal window
terraform validate
  1. Une fois notre code vérifié, nous allons générer le plan via la commande :

Terminal window
terraform plan -out main.tfplan

Notez que vous pouvez nommer votre plan comme vous souhaitez, ici on a choisi main.tfplan.

  1. Voilà le moment tant attendu ! avec cette commande, nous allons enfin déployer notre vm :

Terminal window
terraform apply "main.tfplan"

Notez qu’il est possible de faire un terraform apply sans passer par un terraform plan, mais il est toujours recommandé de générer un plan, car il est fort utile pour avoir un déploiement cohérent et stable.

  1. Grâce aux outputs nous allons récupérer l’adresse ip de notre vm ainsi que la clé ssh privée :

Terminal window
# récupération de l'ip
terraform output public_ip_address
# récupération de la clé ssh privé
terraform output -raw tls_private_key > @/.ssh/vm_id_rsa
  1. Avant de se connecter à la vm, nous devons d’abord restreindre l’accès à la clé privée :

Terminal window
chmod 600 @/.ssh/vm_id_rsa
  1. On peut essayer de se connecter à la vm maintenant :

Terminal window
ssh -i @/.ssh/vm_id_rsa azureadmin@<public_ip_address>
  • Et voilà, nous avons notre machine virtuelle de déployée, il ne nous reste plus qu’à la configurer en utilisant Ansible
Ansible Terraform Azure

Articles relatifs