Aprovisionamiento de una máquina virtual Linux mediante Bicep

Completado

El elemento principal de una plantilla de Bicep es un recurso, que designa un recurso de Azure. Cada recurso contiene un conjunto de propiedades genéricas y específicas de recursos. Por ejemplo, la plantilla usada en el ejemplo siguiente describe una red virtual de Azure. Aunque las propiedades de nombre y ubicación son genéricas, addressPrefix es específica del recurso. La cadena Microsoft.Network/virtualNetworks@2021-05-01 junto al recurso designa su versión de API, y la entrada virtualNetwork representa su nombre simbólico, que proporciona una manera de hacer referencia al recurso dentro de la plantilla.

Además del elemento resource, la siguiente plantilla de ejemplo también incluye un elemento parameter que permite asignar un nombre a la red virtual durante la implementación. Si no asigna un nombre en ese momento, el valor predeterminado de lnx-bcp-vnet se aplica en su lugar. El elemento description es un ejemplo de decorador, como se indica con el carácter @ inicial. Su propósito es describir el rol del parámetro y su salida aparece junto al cuadro de texto del parámetro cuando se usa Azure Portal para revisar o implementar la plantilla de Azure Resource Manager correspondiente. Use el ejemplo de código siguiente para aprovisionar una máquina virtual Linux mediante 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
      ]
    }
  }
}

Implementación de una máquina virtual Linux mediante plantillas de Bicep

Trabajar con Bicep implica la creación e implementación de plantillas. Para simplificar y mejorar la experiencia de creación, use Visual Studio Code con la extensión de Bicep. La misma extensión también admite implementaciones basadas en Bicep. Si prefiere desencadenar una implementación desde una línea de comandos o como parte de una tarea con scripts, puede instalar y usar la CLI de Bicep como una utilidad independiente o usarla directamente desde una sesión de la CLI de Azure. La CLI de Azure instala la CLI de Bicep automáticamente durante la primera invocación de cualquier comando az bicep. Sin embargo, para realizar una instalación manual de Bicep, ejecute az bicep install.

Efectivamente, el proceso de aprovisionamiento de una máquina virtual de Azure que ejecuta Linux mediante Bicep normalmente implica la siguiente secuencia de pasos de alto nivel:

  • Identifique una imagen de máquina virtual adecuada.
  • Identifique el tamaño de máquina virtual adecuado.
  • Cree una plantilla de Bicep.
  • Inicie la implementación de la plantilla de Bicep.

Al implementar plantillas de Bicep, una tarea denominada transpilación las convierte automáticamente en plantillas equivalentes de Azure Resource Manager. También puede realizar una conversión entre los formatos de Bicep y Azure Resource Manager mediante la ejecución de los comandos bicep build y bicep decompile, respectivamente.

Para identificar la imagen y el tamaño adecuados de la máquina virtual, siga los pasos descritos en las unidades anteriores de este módulo. Esta unidad se centra en tareas específicas de Bicep.

Creación de una plantilla de Bicep

Para crear una plantilla de Bicep, comience iniciando una sesión de Visual Studio Code con la extensión de Bicep instalada. A continuación, cree un archivo denominado main.bicep. Agregue el siguiente contenido al archivo y luego guarde los cambios:

Nota

Los nombres de archivo que elija para los archivos de Bicep son arbitrarios, aunque es recomendable elegir un nombre que refleje el contenido o el propósito del archivo, y debe usar ".bicep" como extensión del archivo.

@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}'

Nota

Esta plantilla se basa en el contenido del repositorio de GitHub Plantillas de inicio rápido de Azure.

Inicio de la implementación de la plantilla de Bicep

Después de guardar el archivo main.bicep, puede continuar con una implementación basada en plantillas. En primer lugar, inicie una sesión de la CLI de Azure en el equipo local y ejecute az login para autenticarse. Deberá proporcionar las credenciales de un usuario con privilegios suficientes para aprovisionar recursos en la suscripción de Azure. A continuación, cambie el directorio actual por el que reside el archivo main.bicep. Como alternativa, puede iniciar una sesión de Bash en Azure Cloud Shell y cargar ese archivo en el directorio principal dentro del entorno de Azure Cloud Shell.

A continuación, ejecute el siguiente comando desde una sesión de la CLI de Azure autenticada para crear un grupo de recursos, que contendrá todos los recursos que forman parte de la implementación posterior:

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

Antes de continuar, es posible que desee asegurarse de que usa la versión más reciente de la CLI de Bicep mediante la ejecución del siguiente comando:

az bicep upgrade

Por último, inicie la implementación mediante la ejecución del siguiente comando:

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

Nota

Este comando incluye el modificador --parameters, que en este caso establece el nombre del administrador local para la máquina virtual de Azure que va a implementar. La CLI de Azure le pide que proporcione la contraseña correspondiente porque no se ha establecido el valor predeterminado del parámetro adminPasswordOrKey.

La máquina virtual de Azure debería empezar a funcionar en breve, normalmente en unos minutos. Para conectarse a ella, identifique el nombre de dominio completo (FQDN) asociado a su interfaz de red revisando la salida que genera la implementación. Como alternativa, puede usar el valor shCommand. Cuando se le solicite, proporcione la contraseña recién establecida para autenticarse al establecer una conexión SSH.

En caso de que no haya registrado los valores de salida de la implementación de Bicep, puede volver a mostrarlos ejecutando el siguiente comando:

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

La salida con formato JSON debería parecerse al siguiente contenido:

{
  "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"
  }
}