Provisionner une machine virtuelle Linux en utilisant Bicep

Effectué

L’élément principal d’un modèle Bicep est la ressource, qui désigne une ressource Azure. Chaque ressource contient un ensemble de propriétés génériques et spécifiques à la ressource. Par exemple, le modèle utilisé dans l’exemple suivant décrit un réseau virtuel Azure. Les propriétés nom et emplacement sont génériques, mais addressPrefix est spécifique à la ressource. La chaîne Microsoft.Network/virtualNetworks@2021-05-01 après la ressource désigne la version de son API, et l’entrée virtualNetwork représente son nom symbolique qui permet de référencer la ressource dans le modèle.

En plus de l’élément resource, l’exemple de modèle suivant inclut également un élément de paramètre qui vous permet d’attribuer un nom au réseau virtuel lors du déploiement. Si vous n’attribuez pas de nom à ce moment-là, la valeur par défaut lnx-bcp-vnet s’applique à la place. L’élément description est un exemple de décorateur, comme indiqué par le caractère de début @. Son objectif est de décrire le rôle du paramètre, et sa sortie apparaît à côté de la zone de texte du paramètre lorsque vous utilisez le portail Azure pour examiner ou déployer le modèle Azure Resource Manager correspondant. Utilisez l’exemple de code suivant pour provisionner une machine virtuelle Linux en utilisant Bicep :

@description('Name of the virtual network')
param virtualNetworkName string = 'lnx-bcp-vnet'

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-05-01' = {
  name: virtualNetworkName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        addressPrefix
      ]
    }
  }
}

Déployer une machine virtuelle Linux en utilisant des modèles Bicep

L’utilisation de Bicep implique la création et le déploiement de modèles. Pour simplifier et améliorer l’expérience de création, utilisez Visual Studio Code avec l’extension Bicep. La même extension prend également en charge les déploiements basés sur Bicep. Si vous préférez déclencher un déploiement à partir d’une ligne de commande ou dans le cadre d’une tâche scriptée, vous pouvez installer et utiliser l’interface CLI Bicep en tant qu’utilitaire autonome ou l’utiliser directement depuis une session Azure CLI. L’interface Azure CLI installe automatiquement l’interface CLI Bicep lors du premier appel d’une commande az bicep. Cependant, pour effectuer une installation manuelle de Bicep, exécutez az bicep install.

En effet, le processus de provisionnement d’une machine virtuelle Azure exécutant Linux en utilisant Bicep implique généralement la séquence des grandes étapes suivantes :

  • Identifier une image de machine virtuelle appropriée.
  • Identifier la taille de machine virtuelle appropriée.
  • Créer un modèle Bicep.
  • Lancer le déploiement du modèle Bicep.

Quand vous déployez des modèles Bicep, une tâche appelée transpilation les convertit automatiquement en modèles Azure Resource Manager équivalents. Vous pouvez aussi effectuer une conversion entre les formats Bicep et Azure Resource Manager en exécutant les commandes bicep build et bicep decompile, respectivement.

Pour identifier l’image et la taille de machine virtuelle appropriées, suivez les étapes décrites dans les unités précédentes de ce module. Cette unité se concentre sur les tâches spécifiques à Bicep.

Créer un modèle Bicep

Pour créer un modèle Bicep, commencez par lancer une session Visual Studio Code avec l’extension Bicep installée. Créez ensuite un fichier nommé main.bicep. Ajoutez le contenu suivant au fichier, puis enregistrez la modification :

Notes

Les noms de fichiers que vous choisissez pour vos fichiers Bicep sont arbitraires, mais c’est une bonne pratique que de choisir un nom qui reflète le contenu ou l’objectif du fichier, et vous devez utiliser « .bicep » pour l’extension de fichier.

@description('The name of your virtual machine')
param vmName string = 'lnx-bcp-vm'

@description('Username for the virtual machine')
param adminUsername string

@description('Type of authentication to use on the virtual machine')
@allowed([
  'sshPublicKey'
  'password'
])
param authenticationType string = 'password'

@description('SSH Key or password for the virtual machine')
@secure()
param adminPasswordOrKey string

@description('Unique DNS Name for the Public IP used to access the virtual machine')
param dnsLabelPrefix string = toLower('${vmName}-${uniqueString(resourceGroup().id)}')

@description('The allowed Linux distribution and version for the VM')
@allowed([
  'Ubuntu-2204'
])
param ubuntuOSVersion string = 'Ubuntu-2204'

@description('Location for all resources')
param location string = resourceGroup().location

@description('The size of the VM')
param vmSize string = 'Standard_F4s'

@description('Name of the virtual network')
param virtualNetworkName string = 'lnx-bcp-vnet'

@description('Name of the subnet in the virtual network')
param subnetName string = 'subnet0'

@description('Name of the network security group')
param networkSecurityGroupName string = 'lnx-bcp-nsg'

var imageReference = {
  'Ubuntu-2204': {
    publisher: 'Canonical'
    offer: '0001-com-ubuntu-server-jammy'
    sku: '22_04-lts-gen2'
    version: 'latest'
  }
}
var publicIPAddressName = '${vmName}-pip'
var networkInterfaceName = '${vmName}-nic'
var osDiskType = 'Standard_LRS'
var subnetAddressPrefix = '10.3.0.0/24'
var addressPrefix = '10.3.0.0/16'
var linuxConfiguration = {
  disablePasswordAuthentication: true
  ssh: {
    publicKeys: [
      {
        path: '/home/${adminUsername}/.ssh/authorized_keys'
        keyData: adminPasswordOrKey
      }
    ]
  }
}

resource networkInterface 'Microsoft.Network/networkInterfaces@2021-05-01' = {
  name: networkInterfaceName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          subnet: {
            id: subnet.id
          }
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: publicIPAddress.id
          }
        }
      }
    ]
    networkSecurityGroup: {
      id: networkSecurityGroup.id
    }
  }
}

resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2021-05-01' = {
  name: networkSecurityGroupName
  location: location
  properties: {
    securityRules: [
      {
        name: 'ssh'
        properties: {
          priority: 1000
          protocol: 'Tcp'
          access: 'Allow'
          direction: 'Inbound'
          sourceAddressPrefix: '*'
          sourcePortRange: '*'
          destinationAddressPrefix: '*'
          destinationPortRange: '22'
        }
      }
    ]
  }
}

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-05-01' = {
  name: virtualNetworkName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        addressPrefix
      ]
    }
  }
}

resource subnet 'Microsoft.Network/virtualNetworks/subnets@2021-05-01' = {
  parent: virtualNetwork
  name: subnetName
  properties: {
    addressPrefix: subnetAddressPrefix
    privateEndpointNetworkPolicies: 'Enabled'
    privateLinkServiceNetworkPolicies: 'Enabled'
  }
}

resource publicIPAddress 'Microsoft.Network/publicIPAddresses@2021-05-01' = {
  name: publicIPAddressName
  location: location
  sku: {
    name: 'Basic'
  }
  properties: {
    publicIPAllocationMethod: 'Dynamic'
    publicIPAddressVersion: 'IPv4'
    dnsSettings: {
      domainNameLabel: dnsLabelPrefix
    }
    idleTimeoutInMinutes: 4
  }
}

resource vm 'Microsoft.Compute/virtualMachines@2021-11-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    storageProfile: {
      osDisk: {
        createOption: 'FromImage'
        managedDisk: {
          storageAccountType: osDiskType
        }
      }
      imageReference: imageReference[ubuntuOSVersion]
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: networkInterface.id
        }
      ]
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPasswordOrKey
      linuxConfiguration: ((authenticationType == 'password') ? null : linuxConfiguration)
    }
    securityProfile: json('null')
  }
}

output adminUsername string = adminUsername
output fqdn string = publicIPAddress.properties.dnsSettings.fqdn
output sshCommand string = 'ssh ${adminUsername}@${publicIPAddress.properties.dnsSettings.fqdn}'

Notes

Ce modèle est basé sur le contenu du dépôt GitHub Azure Quickstart Templates (Modèles de démarrage rapide Azure).

Lancer le déploiement du modèle Bicep

Après avoir enregistré le fichier main.bicep, vous pouvez procéder à un déploiement basé sur un modèle. Tout d’abord, lancez une session Azure CLI sur votre ordinateur local, puis exécutez az login pour vous authentifier. Vous devez fournir les informations d’identification d’un utilisateur avec des privilèges suffisants pour provisionner des ressources dans votre abonnement Azure. Ensuite, remplacez le répertoire actif par celui où se trouve le fichier main.bicep. Vous pouvez aussi démarrer une session Bash d’Azure Cloud Shell et charger ce fichier dans votre répertoire de base dans l’environnement Azure Cloud Shell.

Ensuite, exécutez la commande suivante à partir d’une session Azure CLI authentifiée pour créer un groupe de ressources, qui va contenir toutes les ressources qui font partie du déploiement à venir :

az group create --name rg-lnx-bcp --location eastus

Avant d’aller plus loin, vous pouvez vérifier que vous utilisez la version la plus récente de l’interface CLI Bicep en exécutant la commande suivante :

az bicep upgrade

Enfin, lancez le déploiement en exécutant la commande suivante :

az deployment group create --resource-group rg-lnx-bcp --template-file main.bicep --parameters adminUsername=azureuser

Notes

Cette commande inclut le commutateur --parameters, qui dans ce cas définit le nom de l’administrateur local pour la machine virtuelle Azure que vous déployez. Azure CLI vous invite à fournir le mot de passe correspondant, car la valeur par défaut du paramètre adminPasswordOrKey n’est pas définie.

La machine virtuelle Azure doit commencer à s’exécuter sous peu, généralement au bout de quelques minutes. Pour vous y connecter, identifiez le nom de domaine complet (FQDN) associé à son interface réseau en examinant la sortie générée par le déploiement. Vous pouvez aussi utiliser la valeur shCommand. Quand vous y êtes invité, fournissez le mot de passe nouvellement défini pour l’authentification lors de l’établissement d’une connexion SSH.

Si vous n’avez pas pris note des valeurs de la sortie du déploiement Bicep, vous pouvez les afficher à nouveau en exécutant la commande suivante :

az deployment group show \
  --resource-group rg-lnx-bcp \
  --name main \
  --query properties.outputs

La sortie au format JSON doit ressembler au contenu suivant :

{
  "adminUsername": {
    "type": "String",
    "value": "azureuser"
  },
  "fqdn": {
    "type": "String",
    "value": "lnx-bcp-vm-example.eastus.cloudapp.azure.com"
  },
  "sshCommand": {
    "type": "String",
    "value": "ssh azureuser@lnx-bcp-vm-example.eastus.cloudapp.azure.com"
  }
}