DEV Community

Axel
Axel

Posted on • Updated on

Azure API Management: Harnessing Bicep for Effortless User and Subscription Creation

Introduction

In the realm of cloud computing, the management of users and subscriptions is a fundamental task that can quickly become a bottleneck in operational efficiency. Clicking through interfaces to create each user and subscription individually is not only tedious but also prone to errors.

Fortunately, there's a better way: automation. By harnessing the power of scripting, we can streamline this process, making it both clickless and error-free. In this brief guide, we'll explore how to achieve this using a combination of Bicep and PowerShell.

By creating a single Bicep file and accompanying PowerShell script, we can automate the creation of multiple users and subscriptions effortlessly.

Prerequisites

Scripts

main.bicep
The bicep file to create user and subscription.

@description('Name of Api Management')
param apimName string

@description('Name of the product')
param apimProductId string

@description('Array of users to create')
param users array

// Resource to add users to API Management
resource apimUser 'Microsoft.ApiManagement/service/users@2019-12-01' = [
  for user in users: {
    name: '${apimName}/${user}'
    properties: {
      firstName: '${user}'
      lastName: '${user}'
      email: '${user}@mail.be'
      password: 'myUserPassword'
      state: 'active'
    }
  }
]

// Resource to add subscriptions to API Management
resource apimSubscription 'Microsoft.ApiManagement/service/subscriptions@2019-12-01' = [
   for user in users: {
    name: '${apimName}/ProductAPIService'
    properties: {
      displayName: 'Product API Service' 
      state: 'active'
      scope: '/products/${apimProductId}'
      allowTracing: false
      ownerId: '/users/${user}'  
    }
  dependsOn: [
      apimUser
    ]
  }
]

// Output the name of the API Management instance
output addInApiName string = apimName

// Output the ID of the product in API Management
output addInProduct string = apimProductId

// Output the subscription keys for the created users
output souscriptionKey array = [for i in range(0, length(users)):  {
  user: last(split(apimSubscription[i].properties.ownerId, '/'))
  key: apimSubscription[i].listSecrets().primaryKey
}]
Enter fullscreen mode Exit fullscreen mode

main.dev.bicepparam
The bicepparam to configure the apimName, apimProductId and users.

using 'main.bicep'

param apimName = 'myApimName'
param apimProductId = 'myProductID'
param users = [
  'user1'
  'user2'
]
Enter fullscreen mode Exit fullscreen mode

createUsersAndSubscriptions.ps1
The powershell to launch the bicep file and returns the credential in text file.

param(
    # Azure APIM Environment to deploy
    [string]$env
)

$date = Get-Date -Format "dd/MM/yyyy"
$logFolderPath = Join-Path -Path $PSScriptRoot -ChildPath "$env\logs"
$credentialsFolderPath = Join-Path -Path $PSScriptRoot -ChildPath "$env\$date\credentials"

# Function to create a directory if it doesn't exist
function Ensure-DirectoryExists {
    param (
        [string]$path
    )
    if (!(Test-Path -Path $path)) {
        New-Item -ItemType Directory -Path $path | Out-Null
        Write-Host "New folder $path created successfully!" -ForegroundColor Green
    } else {
        Write-Host "Folder $path already exists!"
    }
}

# Ensure necessary directories exist
Ensure-DirectoryExists -path $logFolderPath
Ensure-DirectoryExists -path $credentialsFolderPath

# Function to format validation output
function Format-ValidationOutput {
    param (
        $ValidationOutput, 
        [int]$Depth = 0
    )
    Set-StrictMode -Off
    $ValidationOutput | Where-Object { $_ -ne $null } | ForEach-Object {
        @('  ' * $Depth + ': ' + $_.Message) + @(Format-ValidationOutput -ValidationOutput $_.Details -Depth ($Depth + 1))
    }
}

# Function to return full environment name
function Return-FullEnvironmentName {
    param (
        [string]$environment
    )

    switch ($environment) {
        'dev' { 'Development' }
        'acc' { 'Acceptance' }
        'prd' { 'Production' }
        default { 'Unknown' }
    }
}

# Test Deployment
$ErrorMessages = Format-ValidationOutput (Test-AzResourceGroupDeployment -Verbose -ResourceGroupName "apim-$env-rg" -TemplateFile "main.bicep" -TemplateParameterFile "main.$env.bicepparam")

if ($ErrorMessages) {
    $errorMessage = 'Validation returned the following errors:' + [System.Environment]::NewLine + ($ErrorMessages -join [System.Environment]::NewLine) + [System.Environment]::NewLine + 'Template is invalid.'
    Write-Host $errorMessage
    Write-Output $errorMessage >> "$logFolderPath/logs.txt"
} else { 
    Write-Host "Start users and subscriptions creation on $env environment"

    $deploymentResult = New-AzResourceGroupDeployment `
        -Name "apiUserAndSubscriptionDeployment" `
        -Verbose `
        -ResourceGroupName "apim-$env-rg" `
        -TemplateFile "main.bicep" `
        -TemplateParameterFile "main.$env.bicepparam"

    $deploymentResult | Out-File -FilePath "$logFolderPath/logs.txt" -Append

    $apimName = $deploymentResult.Outputs.addInApiName.Value
    Add-Content -Path "$credentialsFolderPath/credentials.txt" -Value "Api Management : $apimName"

    $environmentFullName = Return-FullEnvironmentName -environment $env
    Add-Content -Path "$credentialsFolderPath/credentials.txt" -Value "Environment : $environmentFullName"

    $productName = $deploymentResult.Outputs.addInProduct.Value
    Add-Content -Path "$credentialsFolderPath/credentials.txt" -Value "Product : $productName"

    $subscriptionKeys = $deploymentResult.Outputs.subscriptionKey[0].Value | Select-Object
    Add-Content -Path "$credentialsFolderPath/credentials.txt" -Value "Subscriptions : $subscriptionKeys"
}
Enter fullscreen mode Exit fullscreen mode

After creating those files, you can launch this command :
createUsersAndSubscriptions.ps1 -env dev

Clean up the resources

You can clean up your resource using this command :
Remove-AzResourceGroup -Name "apiUserAndSubscriptionDeploypment"

Go further

If you want to automate the creation you can add it to a pipeline following this link :
https://learn.microsoft.com/en-us/training/modules/build-first-bicep-deployment-pipeline-using-azure-pipelines/

Thank for reading

If you have any questions, feedback, or suggestions, please feel free to leave them in the comments below. I'm eager to hear from you and respond to your thoughts!

Top comments (0)