Tuesday, July 30, 2024

Azure Container Apps: Scaling Rule based on Azure Service Bus Subscription

In this post, let's see how to set a scaling rule for Azure Container App to scale based on # of messages in an Azure Service Bus Subscription.

I am deploying an Azure Function App with a ServiceBusTrigger as a Container App.

# Windows PowerShell
az containerapp create `
--name <CONTAINER_APP_NAME> `
--resource-group <CONTAINER_APP_RESOURCE_GROUP>` --environment <CONTAINER_APP_ENVIRONMENT>
--image <CONTAINER_APP_IMAGE> `
--set-env-vars "AzureWebJobsServiceBus=<SERVICE_BUS_CONNECTION_STRING>" `
--min-replicas 0 `
--max-replicas 5 ` --secrets "service-bus-connectionstring=<SERVICE_BUS_CONNECTION_STRING>"
--scale-rule-name some-subsciption-name-rule `
--scale-rule-type azure-servicebus `
--scale-rule-metadata `
    "subscriptionName=some-subsciption-name" `
    "topicName=some-topic-name" `
    "messageCount=10" `
--scale-rule-auth "connection=service-bus-connectionstring"

Here I am creating a container app with a scale rule of type azure-servicebus. An important thing to notice is, I am creating a secret service-bus-connectionstring and using it for scale-rule-auth, so KEDA scaler can communicate with the Service Bus namespace.

Metrics: Replica Count

More reading:
   Set scaling rules in Azure Container Apps

Hope this helps.

Happy Coding.

Regards,
Jaliya

Wednesday, July 17, 2024

EF Core 8.0: Numeric Rowversion for Azure SQL/Microsoft SQL Server

In this post, let's have a look at this small yet handy EF Core 8.0 feature for troubleshooting concurrency issues.

Before EF Core 8.0, the rowversion property in C# classes needs to be of type byte[].
public record Post
{
    public int Id { getset}

    public string Title { getset}

    public byte[] Timestamp { getset}
}
And when debugging, it looks like the following.
Timestamp as byte[]
Now with EF Core 8.0, we can map the rowversion to long or ulong.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Post>()
        .Property(e => e.Timestamp)
        .HasConversion<byte[]>()
        .IsRowVersion();
}
public record Post
{
    public int Id { getset}

    public string Title { getset}

    public long Timestamp { getset}
}
When debugging it's more readable now.
Timestamp as long
Happy Coding.

Regards,
Jaliya

Monday, July 15, 2024

Introducing dotnet nuget why

With .NET SDK 8.0.4xx and later versions, we will have access to a   new dotnet nuget command: dotnet nuget why. You can try this now with the latest .NET 9 SDK Preview: 9.0.100-preview.6 (thanks @ErikEJ for pointing it out).
dotnet nuget why --help
dotnet nuget why --help
For an example,
dotnet nuget why <PROJECT|SOLUTION> System.Text.Json
dotnet nuget why
I can see the dependency graph for the given package and if it references an old package.

Read more:

Happy Coding.

Regards,
Jaliya

Thursday, July 11, 2024

Received Microsoft MVP Award in Developer Technologies

I am humbled and honored once again to receive the precious Microsoft Most Valuable Professional (MVP) Award for the 11th consecutive year.

As always looking forward to another great year on top of Microsoft Development Stack.
Microsoft Most Valuable Professional (MVP)
Thank you Microsoft for your appreciation and Thank you everyone for your continuous support.

Happy Coding.

Regards,
Jaliya

Tuesday, July 2, 2024

Azure DevOps Pipeline: Build and Deploy Azure Container App

In this post, let's see how we can build and deploy an Azure Container App from an Azure DevOps Pipeline.

Here for deployment, I am using az containerapp update.

trigger:
  branches:
    include:
      - main

pool:
  vmImage: ubuntu-latest

variables:
  acrServiceConnection: <ACR_SERVICE_CONNECTION>
  acrName: myacr.azurecr.io
  imageRepositoryName: '<ACR_REPOSITORY_NAME>'
  containerAppServiceConnection: '<CONTAINER_APP_SERVICE_CONNECTION>'
  containerAppResourceGroup: '<CONTAINER_APP_RESOURCE_GROUP>'
  containerAppName: '<CONTAINER_APP_NAME>'

name: $(Build.BuildId)

stages:
stage: Build
  displayName: Build
  jobs:  
  - job: Build
    displayName: Build Docker Image
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        containerRegistry: '$(acrServiceConnection)'
        repository: '$(imageRepositoryName)'
        command: 'buildAndPush'
        Dockerfile: '**/Dockerfile'
        buildContext: './'
        tags: '$(Build.BuildId)'

stage: Deploy
  displayName: Deploy
  dependsOn:
  - Build
  condition: succeeded('Build')
  jobs:  
  - deployment: Deployment
    displayName: Deploy to Container App
    # Requires an environment named 'Development'
    environment: Development
    strategy:
      runOnce:
        deploy:
          steps:
           - task: AzureCLI@2
             displayName: Update Container App
             inputs:
               azureSubscription: '$(containerAppServiceConnection)'
               scriptType: 'bash'
               scriptLocation: 'inlineScript'
               inlineScript: |
                 az containerapp update \
                 --name $(containerAppName) \
                 --resource-group $(containerAppResourceGroup) \
                 --image '$(acrName)/$(imageRepositoryName):$(Build.BuildId)' \
                 --set-env-vars \
                   'MongoDB__ConnectionString=<VALUE>' \
                   'ServiceBus__ConnectionString=<VALUE>' \
                 --min-replicas 1 \
                 --max-replicas 1

Azure DevOps already has an Azure Container Apps Deployment Task AzureContainerApps@1, which I haven't used, but do check it out.

Hope this helps.

Happy Coding.

Regards,
Jaliya