Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cdc0c92
provision Azure Managed Grafana workspace
Oct 8, 2025
fb7997d
put variables in the right position
Oct 8, 2025
e13fb60
remove conditional statement
Oct 9, 2025
03b5d4f
update windows to use 1es-windows-2022
Oct 9, 2025
4a5ed6d
remove bicep installation task
Oct 9, 2025
ec7b956
remove parameters that are not needed
Oct 9, 2025
28e0eda
changed parameters file format for bicep
Oct 9, 2025
a5805d6
changed parameters file format for bicep
Oct 9, 2025
5424b0c
remove role assignment from bicep
Oct 9, 2025
e0004fc
remove role assignment from bicep
Oct 9, 2025
0ef9267
changed parameters file format for bicep
Oct 9, 2025
0382325
changed parameters file format for bicep
Oct 9, 2025
e8a9e30
add task to install amg extension
Oct 9, 2025
aa6018d
remove allow-preview-versions flag
Oct 9, 2025
ac429bd
assign grafana admin role to .net eng services
Oct 9, 2025
5683982
assign grafana admin role to .net eng services
Oct 9, 2025
340831d
assign grafana admin role to .net eng services
Oct 9, 2025
c76bcc4
remove grafana admin role assignment
Oct 9, 2025
eed1aed
add release job type
Oct 9, 2025
90cdefc
remove release job type
Oct 9, 2025
f533797
provision azure managed grafana workspace
Oct 13, 2025
a074e78
fix bicep file path
Oct 13, 2025
7fc2c34
add provsion grafana stage to the deployment
Oct 13, 2025
2273352
Merge branch 'main' into haruna/managed-grafana-new
haruna99 Oct 13, 2025
b5ea9ca
add deploy azure managed grafana script
Oct 14, 2025
ccc335f
Merge updates for Azure Managed Grafana provisioning pipeline
Oct 14, 2025
6ff2dba
remove test pipeline
Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,23 @@ extends:
GrafanaKeyVault: dotnet-grafana
GrafanaVariableGroup: Dotnet-Grafana-Production
ServiceConnectionClientId: fc1eb341-aea4-4a11-8f80-d14b8775b2ba
ServiceConnectionId: 4a511f6f-b538-48e6-a389-207e430634d1
ServiceConnectionId: 4a511f6f-b538-48e6-a389-207e430634d1

- template: /eng/deploy-managed-grafana.yml@self
parameters:
${{ if ne(variables['Build.SourceBranch'], 'refs/heads/production') }}:
DeploymentEnvironment: Staging
ServiceConnectionName: dnceng-managed-grafana-staging
GrafanaWorkspaceName: dnceng-grafana-staging
GrafanaKeyVault: dnceng-grafana-int-kv
GrafanaVariableGroup: Dnceng-Managed-Grafana-Staging-Vg
ServiceConnectionClientId: 4ad9ae35-2d42-4245-a954-9003b7e31349
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these service connections? Tell me more about them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GrafanaWorkspaceName is the name of the Grafana instance in azure.
The GrafanaKeyVault, GrafanaVariableGroup and ServiceConnectionClientId are not in use and can be deleted.

ServiceConnectionId: f955b932-c7e3-48f7-9d67-4e6542b3568a
${{ else }}:
DeploymentEnvironment: Production
ServiceConnectionName: dnceng-managed-grafana
GrafanaWorkspaceName: dnceng-grafana
GrafanaKeyVault: dnceng-grafana-prod-kv
GrafanaVariableGroup: Dnceng-Managed-Grafana-Vg
ServiceConnectionClientId: 0ceeca1a-31e7-49ee-9bf4-15f14ed28fa4
ServiceConnectionId: 332b249e-769b-49a9-9dc9-d82afe28ec0a
32 changes: 32 additions & 0 deletions eng/deploy-managed-grafana.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
parameters:
- name: ServiceConnectionName
type: string
- name: ServiceConnectionClientId
type: string
- name: ServiceConnectionId
type: string
- name: DeploymentEnvironment
type: string
- name: GrafanaWorkspaceName
type: string
- name: GrafanaKeyVault
type: string
- name: GrafanaVariableGroup
type: string

stages:
- stage: ProvisionGrafana
displayName: 'Provision Grafana Infrastructure'
dependsOn:
- predeploy
- approval
jobs:
- template: /eng/provision-grafana.yaml@self
parameters:
DeploymentEnvironment: ${{ parameters.DeploymentEnvironment }}
ServiceConnectionName: ${{ parameters.ServiceConnectionName }}
GrafanaResourceGroup: 'monitoring-managed'
GrafanaWorkspaceName: ${{ parameters.GrafanaWorkspaceName }}
GrafanaLocation: 'westus2'
GrafanaKeyVault: ${{ parameters.GrafanaKeyVault }}
GrafanaVariableGroup: ${{ parameters.GrafanaVariableGroup }}
2 changes: 2 additions & 0 deletions eng/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ stages:
demands: ImageOverride -equals 1es-windows-2019
dependsOn:
- deploy
- ProvisionGrafana
variables:
- group: ${{ parameters.StatusVariableGroup }}
- group: ${{ parameters.GrafanaVariableGroup }}
Expand Down Expand Up @@ -201,6 +202,7 @@ stages:
demands: ImageOverride -equals 1es-windows-2019
dependsOn:
- deploy
- ProvisionGrafana
jobs:
- job: scenario
displayName: Scenario tests
Expand Down
43 changes: 43 additions & 0 deletions eng/deployment/azure-managed-grafana.bicep
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts about using this file (or at least this pattern) to also deploy all the things necessary for Grafana? Like the keyvaults, identities and their permissions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None currently. I can start working on this

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Azure Managed Grafana Workspace Bicep Template
@description('The Azure region where the Grafana workspace will be deployed')
param location string

@description('The name of the Grafana workspace')
param grafanaWorkspaceName string

@description('The pricing tier for the Grafana workspace')
@allowed([
'Standard'
'Essential'
])
param skuName string = 'Standard'

// Azure Managed Grafana Workspace
resource grafanaWorkspace 'Microsoft.Dashboard/grafana@2023-09-01' = {
name: grafanaWorkspaceName
location: location
sku: {
name: skuName
}
identity: {
type: 'SystemAssigned'
}
properties: {
deterministicOutboundIP: 'Enabled'
apiKey: 'Enabled'
autoGeneratedDomainNameLabelScope: 'TenantReuse'
zoneRedundancy: 'Disabled'
publicNetworkAccess: 'Enabled'
grafanaIntegrations: {
azureMonitorWorkspaceIntegrations: []
}
}
}

// Output the Grafana workspace details
output grafanaWorkspaceId string = grafanaWorkspace.id
output grafanaWorkspaceName string = grafanaWorkspace.name
output grafanaWorkspaceUrl string = grafanaWorkspace.properties.endpoint
output grafanaPrincipalId string = grafanaWorkspace.identity.principalId
output grafanaTenantId string = grafanaWorkspace.identity.tenantId
output grafanaWorkspaceLocation string = grafanaWorkspace.location
141 changes: 141 additions & 0 deletions eng/deployment/deploy-grafana.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Azure Managed Grafana Deployment Script
# This script deploys an Azure Managed Grafana workspace using Bicep

param(
[Parameter(Mandatory = $true)]
[string]$SubscriptionId,

[Parameter(Mandatory = $true)]
[string]$ResourceGroupName,

[Parameter(Mandatory = $true)]
[string]$Location,

[Parameter(Mandatory = $true)]
[string]$GrafanaWorkspaceName,

[Parameter(Mandatory = $false)]
[string]$DeploymentName = "grafana-deployment-$(Get-Date -Format 'yyyyMMdd-HHmmss')",

[Parameter(Mandatory = $false)]
[switch]$WhatIf = $false
)

# Set error action preference
$ErrorActionPreference = "Stop"

Write-Host "=======================================" -ForegroundColor Cyan
Write-Host "Azure Managed Grafana Deployment Script" -ForegroundColor Cyan
Write-Host "=======================================" -ForegroundColor Cyan

try {
# Check if Azure CLI is installed
Write-Host "Checking Azure CLI installation..." -ForegroundColor Yellow
az version 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
throw "Azure CLI is not installed or not in PATH. Please install Azure CLI first."
}
Write-Host "✓ Azure CLI is installed" -ForegroundColor Green

# Check if user is logged in
Write-Host "Checking Azure authentication..." -ForegroundColor Yellow
$account = az account show 2>$null | ConvertFrom-Json
if ($LASTEXITCODE -ne 0) {
Write-Host "Not logged in to Azure. Please login..." -ForegroundColor Yellow
az login
if ($LASTEXITCODE -ne 0) {
throw "Failed to login to Azure"
}
}
Write-Host "✓ Authenticated as: $($account.user.name)" -ForegroundColor Green

# Set the subscription
Write-Host "Setting subscription to: $SubscriptionId" -ForegroundColor Yellow
az account set --subscription $SubscriptionId
if ($LASTEXITCODE -ne 0) {
throw "Failed to set subscription. Please check if the subscription ID is correct and you have access."
}
Write-Host "✓ Subscription set successfully" -ForegroundColor Green

# Check if resource group exists, create if it doesn't
Write-Host "Checking if resource group '$ResourceGroupName' exists..." -ForegroundColor Yellow
az group show --name $ResourceGroupName 2>$null | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Host "Resource group doesn't exist. Creating..." -ForegroundColor Yellow
az group create --name $ResourceGroupName --location $Location
if ($LASTEXITCODE -ne 0) {
throw "Failed to create resource group"
}
Write-Host "✓ Resource group created successfully" -ForegroundColor Green
} else {
Write-Host "✓ Resource group already exists" -ForegroundColor Green
}

# Get the Bicep file path
$bicepFile = Join-Path $PSScriptRoot "azure-managed-grafana.bicep"
if (!(Test-Path $bicepFile)) {
throw "Bicep file not found at: $bicepFile"
}
Write-Host "✓ Bicep file found: $bicepFile" -ForegroundColor Green

# Prepare deployment parameters
$parameters = @{
location = $Location
grafanaWorkspaceName = $GrafanaWorkspaceName
skuName = "Standard"
}

# Convert parameters to string format for Azure CLI
$paramString = ($parameters.GetEnumerator() | ForEach-Object { "$($_.Key)=`"$($_.Value)`"" }) -join " "

# Run deployment
if ($WhatIf) {
Write-Host "Running what-if deployment..." -ForegroundColor Yellow
$cmd = "az deployment group what-if --resource-group $ResourceGroupName --template-file `"$bicepFile`" --parameters $paramString"
Write-Host "Command: $cmd" -ForegroundColor Gray
Invoke-Expression $cmd
} else {
Write-Host "Starting deployment..." -ForegroundColor Yellow
Write-Host "Deployment name: $DeploymentName" -ForegroundColor Gray
Write-Host "Resource group: $ResourceGroupName" -ForegroundColor Gray
Write-Host "Grafana workspace name: $GrafanaWorkspaceName" -ForegroundColor Gray

$cmd = "az deployment group create --resource-group $ResourceGroupName --name $DeploymentName --template-file `"$bicepFile`" --parameters $paramString"
Write-Host "Command: $cmd" -ForegroundColor Gray

$result = Invoke-Expression $cmd | ConvertFrom-Json

if ($LASTEXITCODE -eq 0) {
Write-Host "=======================================" -ForegroundColor Green
Write-Host "✓ Deployment completed successfully!" -ForegroundColor Green
Write-Host "=======================================" -ForegroundColor Green

# Display outputs
if ($result.properties.outputs) {
Write-Host "Deployment Outputs:" -ForegroundColor Cyan
$result.properties.outputs | ConvertTo-Json -Depth 3 | Write-Host
}

# Get the Grafana workspace details
Write-Host "`nGrafana Workspace Details:" -ForegroundColor Cyan
$grafana = az grafana show --name $GrafanaWorkspaceName --resource-group $ResourceGroupName | ConvertFrom-Json
Write-Host "Workspace Name: $($grafana.name)" -ForegroundColor White
Write-Host "Workspace URL: $($grafana.properties.endpoint)" -ForegroundColor White
Write-Host "Location: $($grafana.location)" -ForegroundColor White
Write-Host "SKU: $($grafana.sku.name)" -ForegroundColor White
Write-Host "System Managed Identity: $($grafana.identity.principalId)" -ForegroundColor White
} else {
throw "Deployment failed"
}
}
}
catch {
Write-Host "=======================================" -ForegroundColor Red
Write-Host "❌ Error occurred during deployment:" -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
Write-Host "=======================================" -ForegroundColor Red
exit 1
}

Write-Host "`n🎉 Script completed successfully!" -ForegroundColor Green
Write-Host "You can now access your Grafana workspace and configure it as needed." -ForegroundColor Yellow
Loading