Cargando...

Bicep: Crear máquina virtual en Azure

Crear máquina virtual en Azure con plantillas en Bicep

Si vas a trabajar con soluciones en Azure, necesitarás crear máquinas virtuales. Crear una máquina virtual en Azure desde el portal es muy sencillo, sin embargo, cuando tienes que crear múltiples máquinas y replicar en diferentes entornos, se vuelve una tarea más compleja y repetitiva, y todo lo que es repetitivo se puede y debe automatizar. También, es posible que necesites crear y desechar entornos continuamente. Por supuesto, además de máquinas virtuales, se puede crear cualquier recurso usando plantillas. En esta ocasión te compartiré un ejemplo básico de cómo crear una máquina virtual Linux en Azure utilizando una plantilla escrita en Bicep. De forma resumida, Bicep es un nuevo leguaje para definir plantillas ARM con una sintaxis más sencilla y fácil de entender que JSON. Además, introduce otras características como los módulos para separar el código para implementaciones más complejos.

Inicialmente necesitas instalar Bicep, para ello, la forma más fácil es instalar la versión más reciente de Azure CLI. También, si utilizas Visual Studio Code, te sugiero instalar la extensión de Bicep. En ese sentido, te recomiendo el artículo de OpenWebinars Azure Bicep, el nuevo lenguaje para definir plantillas ARM, donde aprenderás los conceptos, ventajas que ofrece y cómo dar los primeros pasos con este lenguaje, incluyendo la instalación.

Crear plantilla ARM en Bicep

Comencemos, crea un archivo con la extensión .bicep. Para el ejemplo, usaré el nombre vm-linux.bicep

En este primer bloque he definido cuatro parámetros. El primer parámetro es un prefijo para el nombre que se les dará a los recursos. El segundo recibirá la región donde se crearán los recursos, en este caso el valor corresponde a la región del grupo de recursos. El tercero es para ingresar el nombre de usuario para la máquina virtual y el último para escribir la contraseña.

param resourceName string = 'crashell'
param location string = resourceGroup().location
param adminUsername string
param adminPassword string

En este segundo he definido algunas variables para los nombres de los recursos. Como puedes apreciar, en el valor estoy usando el parámetro resourceName. También, he considerado guardar en variables el prefijo de direcciones para la red virtual y subred, el tamaño de la máquina y una etiqueta que será proporcional en todos los recursos.

var vmSize            = 'Standard_B1s'
var vnetName          = '${resourceName}-vnet'
var vnetAddress       = '10.0.0.0/16'
var vnetSubnetName    = 'public'
var vnetSubnetAddress = '10.0.0.0/24'
var vmName            = '${resourceName}-vm'
var pipName           = '${resourceName}-ip'
var nicName           = '${resourceName}-nic'
var nsgName           = '${resourceName}-nsg'
var envTag            = 'dev'

Lo siguiente es crear los recursos que necesita una máquina virtual.

Crear dirección IP pública en Azure

resource pip 'Microsoft.Network/publicIPAddresses@2021-02-01' = { 
  name: pipName
  location: location
  properties: {
    publicIPAllocationMethod: 'Dynamic'
  }
  sku: {
    name: 'Basic'
  }
  tags: {
    env: envTag
  }
}

Crear grupo de seguridad de red en Azure. En este caso contiene una única regla para permitir el acceso por SSH a la máquina virtual. Los grupos de seguridad se pueden asociar a subredes e interfaces de red, en esta plantilla se asociará directamente a la interfaz de red de la máquina virtual.

resource nsg 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
  name: nsgName
  location: location
  properties: {
    securityRules: [
      {
        name: 'default-allow-ssh'
        properties: {
          priority: 100
          access: 'Allow'
          direction: 'Inbound'
          destinationPortRange: '22'
          protocol: 'Tcp'
          sourceAddressPrefix: '*'
          sourcePortRange: '*'
          destinationAddressPrefix: '*'
        }
      }
    ]
  }
  tags: {
    env: envTag
  }
}

Crear red virtual en Azure con Bicep. Para este ejemplo solo se necesita una subred.

resource vnet 'Microsoft.Network/virtualNetworks@2021-02-01' = {
  name: vnetName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        vnetAddress
      ]
    }
    subnets: [
      {
        name: vnetSubnetName
        properties: {
          addressPrefix: vnetSubnetAddress
        }
      }
    ]
  }
  tags: {
    env: envTag
  }
}

Crea una interfaz de red para la máquina virtual.

resource nic 'Microsoft.Network/networkInterfaces@2021-02-01' = {
  name: nicName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: pip.id
          }
          subnet: {
            id: resourceId('Microsoft.Network/virtualNetworks/subnets', vnetName, vnetSubnetName)
          }
        }
      }
    ]
  }
  tags: {
    env: envTag
  }
  dependsOn: [
    vnet
    nsg
  ]
}

Crear máquina virtual. En este bloque está la definición para crear una máquina virtual con sistema operativo Ubuntu 21.04. Se hace uso de algunas variables definidadas previamente como el tamaño de la máquina, el usuario, contraseña, etc.

resource vm 'Microsoft.Compute/virtualMachines@2021-04-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPassword
    }
    storageProfile: {
      imageReference: {
        publisher: 'canonical'
        offer: '0001-com-ubuntu-server-hirsute'
        sku: '21_04-gen2'
        version: 'latest'
      }
      osDisk: {
        createOption: 'FromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: nic.id
        }
      ]
    }
  }
  tags: {
    env: envTag
  }
}

También, es importante saber como conectarse a una máquina virtual en Azure. En este ejemplo es una máquina con GNU/Linux, sería por medio de SSH y se necesita la dirección IP pública de la máquina. En esta última línea se usa un Output para mostrar la dirección IP pública que recibe la máquina virtual.

output ip string = pip.properties.ipAddress

A continuación, la plantilla completa y posteriormente las instrucciones para hacer la implementación desde la CLI.

param resourceName string = 'crashell'
param location string = resourceGroup().location
param adminUsername string
param adminPassword string

var vmSize            = 'Standard_B1s'
var vnetName          = '${resourceName}-vnet'
var vnetAddress       = '10.0.0.0/16'
var vnetSubnetName    = 'public'
var vnetSubnetAddress = '10.0.0.0/24'
var vmName            = '${resourceName}-vm'
var pipName           = '${resourceName}-ip'
var nicName           = '${resourceName}-nic'
var nsgName           = '${resourceName}-nsg'
var envTag            = 'dev'

resource pip 'Microsoft.Network/publicIPAddresses@2021-02-01' = { 
  name: pipName
  location: location
  properties: {
    publicIPAllocationMethod: 'Dynamic'
  }
  sku: {
    name: 'Basic'
  }
  tags: {
    env: envTag
  }
}

resource nsg 'Microsoft.Network/networkSecurityGroups@2021-02-01' = {
  name: nsgName
  location: location
  properties: {
    securityRules: [
      {
        name: 'default-allow-ssh'
        properties: {
          priority: 100
          access: 'Allow'
          direction: 'Inbound'
          destinationPortRange: '22'
          protocol: 'Tcp'
          sourceAddressPrefix: '*'
          sourcePortRange: '*'
          destinationAddressPrefix: '*'
        }
      }
    ]
  }
  tags: {
    env: envTag
  }
}

resource vnet 'Microsoft.Network/virtualNetworks@2021-02-01' = {
  name: vnetName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        vnetAddress
      ]
    }
    subnets: [
      {
        name: vnetSubnetName
        properties: {
          addressPrefix: vnetSubnetAddress
        }
      }
    ]
  }
  tags: {
    env: envTag
  }
}

resource nic 'Microsoft.Network/networkInterfaces@2021-02-01' = {
  name: nicName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: pip.id
          }
          subnet: {
            id: resourceId('Microsoft.Network/virtualNetworks/subnets', vnetName, vnetSubnetName)
          }
        }
      }
    ]
  }
  tags: {
    env: envTag
  }
  dependsOn: [
    vnet
    nsg
  ]
}

resource vm 'Microsoft.Compute/virtualMachines@2021-04-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPassword
    }
    storageProfile: {
      imageReference: {
        publisher: 'canonical'
        offer: '0001-com-ubuntu-server-hirsute'
        sku: '21_04-gen2'
        version: 'latest'
      }
      osDisk: {
        createOption: 'FromImage'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: nic.id
        }
      ]
    }
  }
  tags: {
    env: envTag
  }
}

output ip string = pip.properties.ipAddress

Implementar plantilla ARM desde la CLI

Primero, es ideal hacer una comprobación y obtener una vista previa de los cambios que se realizarán antes de hacer la implementación. También, sirve para encontrar errores que el editor no puede detectar.

az deployment group create --resource-group NombreRG --template-file vm-linux.bicep --what-if

Para hacer la implementación ejecuta la siguiente instrucción:

az deployment group create --resource-group CrashellRG --template-file vm-linux.bicep

Cambia CrashellRG por tu grupo de recursos.

¡Listo, ahora podrás implementar una máquina virtual en cuestión de segundos! Es una plantilla sencilla. Seguiremos compartiendo más contenido, poco a poco la complejidad irá aumentando. Considero que este es punto de partida importante.

Puedes visitar el repositorio Infraestructura como código en Azure con Bicep para encontrar para encontrar la plantilla completa.

  • John Doe
    43 Sales$156,24 Totals
    62%
  • Rosy O'Dowell
    12 Leads$56,24 Totals
    32%

With supporting text below as a natural lead-in to additional content.

Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled.