Deploy Ubuntu VM with Prometheus and Grafana using Bicep Language

Leverage Infrastructure-As-Code to deploy an Ubuntu VM with Prometheus and Grafana.

Deploy Ubuntu VM with Prometheus and Grafana using Bicep Language

This article intends to show how you can leverage Infrastructure-As-Code using Bicep Language to deploy an Ubuntu virtual machine with Prometheus and Grafana installed.

The Grafana and Prometheus instance is installed on a virtual machine image with Ubuntu 20.04 LTS Server.

Prerequisites

Solution Overview

We will author a Bicep template that creates an Ubuntu VM and includes Prometheus and Grafana pre-installed.

The solution will include the following files:

  • 📄 main.bicep: This is the Bicep template
  • 📄 azuredeploy.parameters.json: This parameter file contains the values to use for deploying your Bicep template.

This Bicep file also provisions a storage account, virtual network, a public IP address, and a network interface required by the installation.

Let’s get started!

1. Azure Bicep Template — parameters

First, we will create a file named ‘main.bicep’ and define the following parameters:

param location string = resourceGroup().location
param networkInterfaceName string
param networkSecurityGroupName string
param networkSecurityGroupRules array
param subnetName string
param virtualNetworkName string
param addressPrefixes array
param subnets array
param publicIpAddressName string
param publicIpAddressType string
param publicIpAddressSku string
param virtualMachineName string
param virtualMachineComputerName string
param osDiskType string
param virtualMachineSize string
param adminUsername string
@secure()
param adminPassword string
param zone string

2. Azure Bicep Template — variables

We will define the following variables:

var nsgId = resourceId(resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', networkSecurityGroupName)
var vnetId = resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks', virtualNetworkName)
var subnetRef = '${vnetId}/subnets/${subnetName}'

3. Azure Bicep Template — resources

We will define the following resources:

resource networkInterfaceName_resource 'Microsoft.Network/networkInterfaces@2021-03-01' = {
name: networkInterfaceName
location: location
properties: {
ipConfigurations: [
{
name: 'ipconfig1'
properties: {
subnet: {
id: subnetRef
}
privateIPAllocationMethod: 'Dynamic'
publicIPAddress: {
id: resourceId(resourceGroup().name, 'Microsoft.Network/publicIpAddresses', publicIpAddressName)
}
}
}
]
networkSecurityGroup: {
id: nsgId
}
}
dependsOn: [
networkSecurityGroupName_resource
virtualNetworkName_resource
publicIpAddressName_resource
]
}
resource networkSecurityGroupName_resource 'Microsoft.Network/networkSecurityGroups@2019-02-01' = {
name: networkSecurityGroupName
location: location
properties: {
securityRules: networkSecurityGroupRules
}
}
resource virtualNetworkName_resource 'Microsoft.Network/virtualNetworks@2020-11-01' = {
name: virtualNetworkName
location: location
properties: {
addressSpace: {
addressPrefixes: addressPrefixes
}
subnets: subnets
}
}
resource publicIpAddressName_resource 'Microsoft.Network/publicIpAddresses@2019-02-01' = {
name: publicIpAddressName
location: location
properties: {
publicIPAllocationMethod: publicIpAddressType
}
sku: {
name: publicIpAddressSku
}
zones: [
zone
]
}
resource virtualMachineName_resource 'Microsoft.Compute/virtualMachines@2021-07-01' = {
name: virtualMachineName
location: location
properties: {
hardwareProfile: {
vmSize: virtualMachineSize
}
storageProfile: {
osDisk: {
createOption: 'FromImage'
managedDisk: {
storageAccountType: osDiskType
}
}
imageReference: {
publisher: 'readymind'
offer: 'ubuntults20__prometheus_grafana'
sku: 'prometheus_grafana_ubuntu20lts1'
version: 'latest'
}
}
networkProfile: {
networkInterfaces: [
{
id: networkInterfaceName_resource.id
}
]
}
osProfile: {
computerName: virtualMachineComputerName
adminUsername: adminUsername
adminPassword: adminPassword
linuxConfiguration: {
patchSettings: {
patchMode: 'ImageDefault'
}
}
}
diagnosticsProfile: {
bootDiagnostics: {
enabled: true
}
}
}
plan: {
name: 'prometheus_grafana_ubuntu20lts1'
publisher: 'readymind'
product: 'ubuntults20__prometheus_grafana'
}
zones: [
zone
]
}

We will also define an output as follows:

output adminUsername string = adminUsername

4. Parameters file

Create a new file named ‘azuredeploy.parameters.json’. The code below shows the definition of the parameters file:

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"networkInterfaceName": {
"value": "ubuntu-prometheus-gr653"
},
"networkSecurityGroupName": {
"value": "ubuntu-prometheus-grafana-nsg"
},
"networkSecurityGroupRules": {
"value": [
{
"name": "SSH",
"properties": {
"priority": 300,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "22"
}
},
{
"name": "Prometheus",
"properties": {
"priority": 310,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "9090"
}
},
{
"name": "Grafana",
"properties": {
"priority": 320,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "3000"
}
}
]
},
"subnetName": {
"value": "default"
},
"virtualNetworkName": {
"value": "azinsider_demo-vnet"
},
"addressPrefixes": {
"value": [
"10.0.0.0/16"
]
},
"subnets": {
"value": [
{
"name": "default",
"properties": {
"addressPrefix": "10.0.0.0/24"
}
}
]
},
"publicIpAddressName": {
"value": "ubuntu-prometheus-grafana-ip"
},
"publicIpAddressType": {
"value": "Static"
},
"publicIpAddressSku": {
"value": "Standard"
},
"virtualMachineName": {
"value": "ubuntu-prometheus-grafana"
},
"virtualMachineComputerName": {
"value": "ubuntu-prometheus-grafana"
},
"osDiskType": {
"value": "StandardSSD_LRS"
},
"virtualMachineSize": {
"value": "Standard_B4ms"
},
"adminUsername": {
"value": "Your-VM-username"
},
"adminPassword": {
"value": "Your-password-or-SSH-key"
},
"zone": {
"value": "1"
}
}
}

Modify the above parameters as needed.

5. Azure Bicep Template — Deployment

We will use the command below to deploy our Bicep template:

$date = Get-Date -Format "MM-dd-yyyy"
$deploymentName = "AzInsiderDeployment"+"$date"
New-AzResourceGroupDeployment -Name $deploymentName -ResourceGroupName azinsider_demo -TemplateFile .\main.bicep -TemplateParameterFile .\azuredeploy.parameters.json -c

The image below shows the preview of the deployment:

Deploy Ubuntu VM with Prometheus and Grafana using Bicep Language

Then we will execute the deployment. The image below shows the deployment output:

Ubuntu VM with Prometheus and Grafana using Bicep Language — Deployment Output

We can verify that Prometheus and Grafana are up and running by accessing the IP of the VM and ports 3000, 9090.

The image below shows Grafana running on the Ubuntu VM:

Grafana

The image below shows Prometheus up:

Prometheus

You can find the code of this solution in the following URL, feel free to contribute!

👉 Join the AzInsider email list here.

-Dave R.

--

--