Déployer une machine virtuelle avec Terraform et Ansible
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
La première chose à faire est de se connecter à Azure, pour y déployer nos ressources :
cspell:disable >
az login --tenant VOTRE-TENANTNotez 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 -hpour choisir celle qui vous convient
2. Terraform
2.1. Création des fichiers .tf
Créer un dossier pour y mettre notre code Terraform :
cspell:disable >
mkdir terraform-vm-tuto cd terraform-vm-tuto # et si vous utiliez vscode code .Dans ce dossier, nous allons créer 5 fichiers :
main.tf,variables.tf,providers.tf,network.tfetoutputs.tf.Commençons par
cspell:disable >providers.tf. Son rôle est de déclarer les fournisseurs qui seront utilisés pour déployer les ressources :cspell:enable >terraform {required_providers {azurerm = {source = "hashicorp/azurerm"version = "@>2.0"}tls = {source = "hashicorp/tls"version = "@>4.0"}}}provider "azurerm" {features {}}Puis
main.tf. C’est ici que seront déclarées les dites ressources qui seront déployées, comme leresource groupet lavirtual machinepar exemple, ainsi que leurs configurations :cspell:enable >resource "azurerm_resource_group" "tf_rg" {location = var.resource_group_locationname = var.resource_group_name}resource "azurerm_linux_virtual_machine" "tf_my_terraform_vm" {name = "myVM"location = azurerm_resource_group.tf_rg.locationresource_group_name = azurerm_resource_group.tf_rg.namenetwork_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_nameadmin_username = var.admin_usernamedisable_password_authentication = trueadmin_ssh_key {username = var.admin_usernamepublic_key = tls_private_key.tf_public_ssh.public_key_openssh}}Ensuite vient
cspell:disable >network.tf. Ici on déclare lesvnet,subnetet autres ressources en rapport avec lenetworking:
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 }Le fichier
variables.tfcontiendra 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 :cspell:enable >variable "resource_group_name" {type = stringdefault = "rg-terraform-ansible-tuto"description = "nom du ressource groupe"}variable "resource_group_location" {type = stringdefault = "westeurope"description = "localisation du ressource groupe"}variable "computer_name" {type = stringdefault = "myvm"description = "nom de la machine virtual"}variable "admin_username" {type = stringdefault = "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"}Et enfin
outputs.tf:cspell:enable >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_pemsensitive = true}
2.1.1. Déployer plusieurs vm
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 lemeta-argument:countPour ça, dans le fichier
main.tfon rajoute :cspell:enable >resource "azurerm_linux_virtual_machine" "tf_my_terraform_vm" {count = 3 # le nombre de vm qui sera déployé est de 3, par exemplename = var.vm_names[count.index]location = azurerm_resource_group.tf_rg.locationresource_group_name = azurerm_resource_group.tf_rg.namenetwork_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 = trueadmin_ssh_key {username = var.admin_username[count.index]public_key = tls_private_key.tf_public_ssh.public_key_openssh}}On modifie quelques variables dans le fichier
variables.tf:cspell:enable >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
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 :
cspell:disable >
terraform initUne fois l’initialisation terminée, on peut lancer une commande optionnelle pour vérifier la syntaxe de notre code :
cspell:disable >
terraform validateUne fois notre code vérifié, nous allons générer le
cspell:disable >planvia la commande :
terraform plan -out main.tfplanNotez que vous pouvez nommer votre
plancomme vous souhaitez, ici on a choisimain.tfplan.
Voilà le moment tant attendu ! avec cette commande, nous allons enfin déployer notre vm :
cspell:disable >
terraform apply "main.tfplan"Notez qu’il est possible de faire un
terraform applysans passer par unterraform plan, mais il est toujours recommandé de générer unplan, car il est fort utile pour avoir un déploiement cohérent et stable.
Grâce aux
cspell:disable >outputsnous allons récupérer l’adresse ipde notre vm ainsi que laclé sshprivée :
# 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_rsaAvant de se connecter à la vm, nous devons d’abord restreindre l’accès à la clé privée :
cspell:disable >
chmod 600 @/.ssh/vm_id_rsaOn peut essayer de se connecter à la vm maintenant :
cspell:disable >
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