Сегодня мы создадим шаблон Azure Bicep для предоставления виртуальной машины на базе Linux.

Основная цель этой статьи — показать вам, как можно использовать Azure Bicep для развертывания виртуальной машины на базе Linux. В этом случае мы создадим шаблон Bicep для развертывания Kemp Flowmon в Azure.

Обзор

Что мы можем ожидать после развертывания этой виртуальной машины на базе Linux в Azure? Мы развернем устройство Kemp Flowmon Collector, которое является хорошим примером, так как это машина на базе Linux, и оно предоставит вам прогнозный мониторинг производительности сети и возможности сетевого обнаружения и реагирования.

В этой статье основное внимание будет уделено тому, как можно использовать шаблоны Azure Bicep для упрощения развертывания этой виртуальной машины на базе Linux в Azure.

Предпосылки.

  • Активная подписка Azure.
  • Пользователь с ролями владельца/участника
  • Группа ресурсов

Давайте начнем!

Создание виртуальной машины на базе Linux в Azure включает несколько шагов:

  • Создать группу ресурсов
  • Создайте виртуальную машину и связанные с ней компоненты (виртуальную сеть, подсеть, сетевые интерфейсы, DNS, правила безопасности).

Обратите внимание, что эта конкретная машина — Kemp Flowmon — разрешает только аутентификацию SSH. Поэтому мы включим возможность аутентификации с помощью SSH вместо использования пароля в шаблоне Bicep.

1. Создайте пару ключей SSH

Первый шаг — создать пару ключей SSH; вы можете прочитать следующую статью о том, как создать пару ключей SSH для виртуальных машин Linux в Azure — https://docs.microsoft.com/en-us/azure/virtual-machines/linux/mac-create-ssh-keys »

В этом случае мы создадим пару ключей SSH с помощью консоли Azure Bash. На портале Azure запросите новую консоль, как показано на изображении ниже.

Затем мы сгенерируем SSH-ключ, используя следующую команду:

ssh-keygen \
    -m PEM \
    -t rsa \
    -b 4096 \
    -C "flowmon" \
    -f ~/.ssh/flowmon-priv-key \
    -N yourpasshphrase

Это сгенерирует ключ в каталоге SSH в вашем файловом ресурсе:

Если вы не знакомы с форматом открытого ключа SSH, вы можете отобразить свой открытый ключ с помощью следующей команды cat, заменив «~/.ssh/id_rsa.pub» на путь и имя файла. вашего собственного файла открытого ключа, если необходимо:

cat ~/.ssh/flowmon-priv-key.pub

Приведенная выше команда покажет открытый ключ SSH в консоли. Он понадобится нам во время развертывания, так что держите его под рукой.

Прохладный! Теперь у нас есть пара ключей SSH.

Вы должны принять условия лицензии от Kemp Flowmon Collector. Поскольку это виртуальная машина, развернутая из магазина, мы должны принять условия перед развертыванием этого устройства.

Мы можем использовать PowerShell, чтобы принять условия с помощью командлета ниже:

Get-AzMarketplaceTerms `
-Publisher 'flowmon' `
-Product 'flowmon_collector' `
-Name 'v1101-byol' |
Set-AzMarketplaceTerms -Accept

Теперь, когда мы приняли условия маркетплейса, теперь давайте начнем работать над нашим шаблоном Bicep.

2. Шаблон Azure Bicep — параметры

Мы определим запуск, определив параметры виртуальной машины.

В приведенном ниже коде показаны параметры, которые будут использоваться для этого развертывания:

// The name of your Virtual Machine.
param vmName string = 'flowmonVm'
// Username for the Virtual Machine.
param adminUsername string
// Type of authentication to use on the Virtual Machine. SSH key is recommended.
param authenticationType string = 'sshPublicKey'
// SSH Key or password for the Virtual Machine. SSH key is recommended.
@secure()
param adminPasswordOrKey string
// Unique DNS Name for the Public IP used to access the Virtual Machine.
param dnsLabelPrefix string = toLower('flowmon-${uniqueString(resourceGroup().id)}')
// Location for all resources.
param location string = resourceGroup().location
// The size of the VM.
param vmSize string = 'Standard_B4ms'
// Name of the VNET.
param virtualNetworkName string = 'vNet'
// Name of the subnet in the virtual network.
param subnetName string = 'Subnet'
// Name of the Network Security Group.
param networkSecurityGroupName string = 'SecGroupNet'

Обратите внимание, что мы используем декоратор “@secure()” для безопасной передачи ключа SSH. Я рекомендую вам прочитать эту статью о том, как использовать декоратор @secure() для безопасной передачи секретов в параметрах.

3. Шаблон Azure Bicep — переменные

Далее мы определим несколько переменных:

var publicIPAddressName = '${vmName}PublicIP'
var networkInterfaceName = '${vmName}Nic'
var subnetRef = '${vnet.id}/subnets/${subnetName}'
var osDiskType = 'Standard_LRS'
var subnetAddressPrefix = '10.5.0.0/24'
var addressPrefix = '10.5.0.0/16'
var linuxConfiguration = {
  disablePasswordAuthentication: true
  ssh: {
    publicKeys: [
      {
        path: '/home/${adminUsername}/.ssh/authorized_keys'
        keyData: adminPasswordOrKey
      }
    ]
  }
}

Обратите внимание, что в переменной «linuxConfiguration» мы отключаем аутентификацию по паролю, передаем путь SSH-ключей и ссылаемся на значение ключа.

4. Шаблон Azure Bicep — сеть

Следующим шагом является определение сетевых интерфейсов. При необходимости вы можете создать больше интерфейсов.

resource nic 'Microsoft.Network/networkInterfaces@2020-06-01' = {
  name: networkInterfaceName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          subnet: {
            id: subnetRef
          }
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: publicIP.id
          }
        }
      }
    ]
    networkSecurityGroup: {
      id: nsg.id
    }
  }
}

Затем мы определим правила безопасности, чтобы разрешить или запретить доступ к этой виртуальной машине. Сборщику Kemp Flowmon требуется несколько правил для получения трафика из разных источников:

resource nsg 'Microsoft.Network/networkSecurityGroups@2020-06-01' = {
  name: networkSecurityGroupName
  location: location
  properties: {
    securityRules: [
      {
           name: 'SSH'
           properties : {
               protocol : 'Tcp' 
               sourcePortRange :  '*'
               destinationPortRange :  '22'
               sourceAddressPrefix :  '*'
               destinationAddressPrefix: '*'
               access:  'Allow'
               priority : 1010
               direction : 'Inbound'
               sourcePortRanges : []
               destinationPortRanges : []
               sourceAddressPrefixes : []
               destinationAddressPrefixes : []
          }
      }
      {
           name : 'HTTPS'
           properties : {
               protocol :  'Tcp'
               sourcePortRange :  '*'
               destinationPortRange :  '443'
               sourceAddressPrefix :  '*'
               destinationAddressPrefix :  '*'
               access :  'Allow'
               priority : 1020
               direction :  'Inbound'
               sourcePortRanges : []
               destinationPortRanges : []
               sourceAddressPrefixes : []
               destinationAddressPrefixes : []
          }
      }
      {
           name :  'Collector'
           properties : {
               protocol :  'Udp'
               sourcePortRange :  '*'
               destinationPortRange :  '3000'
               sourceAddressPrefix :  '*'
               destinationAddressPrefix :  '*'
               access :  'Allow'
               priority : 103
               direction :  'Inbound'
               sourcePortRanges : []
               destinationPortRanges : []
               sourceAddressPrefixes : []
               destinationAddressPrefixes : []
          }
      }
    ]
  }
}

Когда у нас будут правила безопасности, мы приступим к определению виртуальной сети:

resource vnet 'Microsoft.Network/virtualNetworks@2020-06-01' = {
  name: virtualNetworkName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        addressPrefix
      ]
    }
    subnets: [
      {
        name: subnetName
        properties: {
          addressPrefix: subnetAddressPrefix
          privateEndpointNetworkPolicies: 'Enabled'
          privateLinkServiceNetworkPolicies: 'Enabled'
        }
      }
    ]
  }
}

Следующим шагом является определение общедоступного IP-адреса. В зависимости от вашей среды вы можете включить только частные IP-адреса; для этого примера мы определим общедоступный IP-адрес

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

Как только мы определили предыдущие ресурсы, последний ресурс, который нужно определить, — это виртуальная машина.

5. Шаблон Azure Bicep — виртуальная машина

В приведенном ниже коде показано определение виртуальной машины.

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    storageProfile: {
      osDisk: {
        createOption: 'FromImage'
        managedDisk: {
          storageAccountType: osDiskType
        }
      }
      imageReference: {
        publisher: 'flowmon'
        offer: 'flowmon_collector'
        sku: 'v1101-byol'
        version: 'latest'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: nic.id
        }
      ]
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPasswordOrKey
      linuxConfiguration: any(authenticationType == 'password' ? null : linuxConfiguration)
    }
    diagnosticsProfile: {
      bootDiagnostics: {
        enabled: true
      }
    }
  }
  plan: {
    name: 'v1101-byol'
    publisher: 'flowmon'
    product: 'flowmon_collector'
  }
}

Обратите внимание, что виртуальная машина Kemp Flowmon должна включать определение плана и включать: имя, издатель и продукт.

Наконец, мы включим вывод для имени пользователя администратора, как показано ниже:

output administratorUsername string = adminUsername

6. Развертывание Azure Bicep

В качестве наилучшей практики я рекомендую предварительно просмотреть развертывание с помощью флага -C. Мы будем использовать приведенную ниже команду, чтобы включить предварительный просмотр развертывания:

New-AzResourceGroupDeployment -Name $deploymentName -ResourceGroupName flowmon -TemplateFile main.bicep -c

Обратите внимание, что мы добавляем флаг -c в конце команды; это активирует проверку What-IF. Таким образом, вы можете предварительно просмотреть операцию развертывания, прежде чем выполнять фактическое развертывание.

Во время развертывания вам будет предложено ввести имя пользователя-администратора. Это значение должно быть «flowmon». Это особая конфигурация для устройства Kemp Flowmon.

Затем мы предоставим открытый ключ SSH. Это значение передается как безопасный параметр.

На изображении ниже показан предварительный просмотр развертывания:

Как только все будет правильно настроено, мы приступим к развертыванию. На рисунке ниже показан результат развертывания:

Доступ к виртуальной машине теперь возможен через https://Ваш-IP-адрес.

После развертывания я рекомендую вам получить доступ к устройству через SSH и изменить пароль пользователя GUI для доступа к веб-интерфейсу пользователя.

Полный шаблон бицепса показан ниже:

// The name of your Virtual Machine.
param vmName string = 'flowmonVm'
// Username for the Virtual Machine.
param adminUsername string
// Type of authentication to use on the Virtual Machine. SSH key is recommended.
param authenticationType string = 'sshPublicKey'
// SSH Key or password for the Virtual Machine. SSH key is recommended.
@secure()
param adminPasswordOrKey string
// Unique DNS Name for the Public IP used to access the Virtual Machine.
param dnsLabelPrefix string = toLower('flowmon-${uniqueString(resourceGroup().id)}')
// Location for all resources.
param location string = resourceGroup().location
// The size of the VM.
param vmSize string = 'Standard_B4ms'
// Name of the VNET.
param virtualNetworkName string = 'vNet'
// Name of the subnet in the virtual network.
param subnetName string = 'Subnet'
// Name of the Network Security Group.
param networkSecurityGroupName string = 'SecGroupNet'
var publicIPAddressName = '${vmName}PublicIP'
var networkInterfaceName = '${vmName}Nic'
var subnetRef = '${vnet.id}/subnets/${subnetName}'
var osDiskType = 'Standard_LRS'
var subnetAddressPrefix = '10.5.0.0/24'
var addressPrefix = '10.5.0.0/16'
var linuxConfiguration = {
  disablePasswordAuthentication: true
  ssh: {
    publicKeys: [
      {
        path: '/home/${adminUsername}/.ssh/authorized_keys'
        keyData: adminPasswordOrKey
      }
    ]
  }
}
resource nic 'Microsoft.Network/networkInterfaces@2020-06-01' = {
  name: networkInterfaceName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          subnet: {
            id: subnetRef
          }
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: publicIP.id
          }
        }
      }
    ]
    networkSecurityGroup: {
      id: nsg.id
    }
  }
}
resource nsg 'Microsoft.Network/networkSecurityGroups@2020-06-01' = {
  name: networkSecurityGroupName
  location: location
  properties: {
    securityRules: [
      {
           name: 'SSH'
           properties : {
               protocol : 'Tcp' 
               sourcePortRange :  '*'
               destinationPortRange :  '22'
               sourceAddressPrefix :  '*'
               destinationAddressPrefix: '*'
               access:  'Allow'
               priority : 1010
               direction : 'Inbound'
               sourcePortRanges : []
               destinationPortRanges : []
               sourceAddressPrefixes : []
               destinationAddressPrefixes : []
          }
      }
      {
           name : 'HTTPS'
           properties : {
               protocol :  'Tcp'
               sourcePortRange :  '*'
               destinationPortRange :  '443'
               sourceAddressPrefix :  '*'
               destinationAddressPrefix :  '*'
               access :  'Allow'
               priority : 1020
               direction :  'Inbound'
               sourcePortRanges : []
               destinationPortRanges : []
               sourceAddressPrefixes : []
               destinationAddressPrefixes : []
          }
      }
      {
           name :  'Collector'
           properties : {
               protocol :  'Udp'
               sourcePortRange :  '*'
               destinationPortRange :  '3000'
               sourceAddressPrefix :  '*'
               destinationAddressPrefix :  '*'
               access :  'Allow'
               priority : 103
               direction :  'Inbound'
               sourcePortRanges : []
               destinationPortRanges : []
               sourceAddressPrefixes : []
               destinationAddressPrefixes : []
          }
      }
   ]
  }
}
resource vnet 'Microsoft.Network/virtualNetworks@2020-06-01' = {
  name: virtualNetworkName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        addressPrefix
      ]
    }
    subnets: [
      {
        name: subnetName
        properties: {
          addressPrefix: subnetAddressPrefix
          privateEndpointNetworkPolicies: 'Enabled'
          privateLinkServiceNetworkPolicies: 'Enabled'
        }
      }
    ]
  }
}
resource publicIP 'Microsoft.Network/publicIPAddresses@2020-06-01' = {
  name: publicIPAddressName
  location: location
  properties: {
    publicIPAllocationMethod: 'Dynamic'
    publicIPAddressVersion: 'IPv4'
    dnsSettings: {
      domainNameLabel: dnsLabelPrefix
    }
    idleTimeoutInMinutes: 4
  }
  sku: {
    name: 'Basic'
  }
}
resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    storageProfile: {
      osDisk: {
        createOption: 'FromImage'
        managedDisk: {
          storageAccountType: osDiskType
        }
      }
      imageReference: {
        publisher: 'flowmon'
        offer: 'flowmon_collector'
        sku: 'v1101-byol'
        version: 'latest'
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: nic.id
        }
      ]
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPasswordOrKey
      linuxConfiguration: any(authenticationType == 'password' ? null : linuxConfiguration)
    }
    diagnosticsProfile: {
      bootDiagnostics: {
        enabled: true
      }
    }
  }
  plan: {
    name: 'v1101-byol'
    publisher: 'flowmon'
    product: 'flowmon_collector'
  }
}
output administratorUsername string = adminUsername

Я надеюсь, что эта статья поможет вам в вашем путешествии по Bicep и в том, как вы можете использовать Bicep для развертывания виртуальных машин на базе Linux в Azure.

Присоединяйтесь к списку рассылки AzInsider здесь.

-Дэйв Р.