Monday, December 15, 2025

Avoid Gemini AI Cost Spikes! Apply Rate Limits to Gemini AI via Azure API Management

In previous video we saw step by step process on integrating Gemini AI in Azure API Management. In this video we will see how Gemini AI can be rate limited in terms of token consumption using api management. This way it can help us to limit AI cost spikes also.

1. Common limit per client

      example 200 TPM per client, applicable for all clients

2. Separate limit per client

      example, Client1 – 200TPM, Client2- 500TPM etc.





Part 1 – Integrate Gemini AI in API Management – 

https://youtu.be/HNuOF09vq_I


Rate limit Gemini AI using API Management Code Base 

https://github.com/kunalchandratre1/azure-gen-ai-gateway 



#AzureBeyondDemos #AzureAPIManagement #GeminiAI #GenAIGateway #AzureIntegration #GoogleGemini #AzureBeyondDemos #APIM #GenerativeAI #AzureTutorial #CloudArchitecture #AIIntegration #AzureForAI #GeminiOnAzure #APIMGateway #AzureAI #Microsoft #MicrosoftAzure #Msftadvocate 

Wednesday, November 26, 2025

Integrate Google Gemini AI with Azure API Management | Multi Cloud Gen AI Gateway

 Multi cloud and Multi AI is reality of today’s world. Because of this concept of Gen AI Gateway is becoming really popular where you can do AI governance implementation using API Gateway. Azure API Management has come up as really strong Gen AI Gateway solution.




#AzureBeyondDemos #AzureAPIManagement #GeminiAI #GenAIGateway #AzureIntegration #GoogleGemini #AzureBeyondDemos #APIM #GenerativeAI #AzureTutorial #CloudArchitecture #AIIntegration #AzureForAI #GeminiOnAzure #APIMGateway #AzureAI

Thursday, November 20, 2025

Google Gemini AI - OpenAPI Specification File

Make sure that you copy paste below code in a file with extension as .yaml. 
#google #gemini #openapi


   


openapi: 3.0.3
info:
  title: Gemini AI API
  description: |
    The Gemini API allows developers to build generative AI applications using Gemini models.
    Gemini is multimodal and can understand text, images, audio, video, and code.
  version: v1beta
  contact:
    name: Google AI
    url: https://ai.google.dev
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0

servers:
  - url: https://generativelanguage.googleapis.com/v1beta
    description: Gemini API Production Server

security:
  - ApiKeyQuery: []
  - ApiKeyHeader: []

tags:
  - name: Models
    description: Operations for listing and retrieving model information
  - name: Content Generation
    description: Generate content using Gemini models
  - name: Embeddings
    description: Generate text embeddings
  - name: Token Counting
    description: Count tokens in prompts

paths:
  /models:
    get:
      tags: [Models]
      operationId: listModels
      summary: List available models
      description: Lists the Gemini models available through the API
      parameters:
        - $ref: '#/components/parameters/PageSize'
        - $ref: '#/components/parameters/PageToken'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListModelsResponse'

  /models/{model}:
    get:
      tags: [Models]
      operationId: getModel
      summary: Get model information
      description: Gets information about a specific model
      parameters:
        - name: model
          in: path
          required: true
          schema:
            type: string
          example: gemini-1.5-pro
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Model'

  /models/{model}:generateContent:
    post:
      tags: [Content Generation]
      operationId: generateContent
      summary: Generate content
      description: Generates a model response given an input GenerateContentRequest
      parameters:
        - name: model
          in: path
          required: true
          schema:
            type: string
          description: 'Model name (e.g., models/gemini-1.5-pro)'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateContentRequest'
            examples:
              simpleText:
                summary: Simple text generation
                value:
                  contents:
                    - role: user
                      parts:
                        - text: "Explain quantum computing in simple terms"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateContentResponse'

  /models/{model}:streamGenerateContent:
    post:
      tags: [Content Generation]
      operationId: streamGenerateContent
      summary: Stream generate content
      description: Generates a streamed response from the model
      parameters:
        - name: model
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GenerateContentRequest'
      responses:
        '200':
          description: Successful response (server-sent events)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateContentResponse'

  /models/{model}:countTokens:
    post:
      tags: [Token Counting]
      operationId: countTokens
      summary: Count tokens
      description: Counts the number of tokens in a prompt
      parameters:
        - name: model
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CountTokensRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CountTokensResponse'

  /models/{model}:embedContent:
    post:
      tags: [Embeddings]
      operationId: embedContent
      summary: Generate embedding
      description: Generates a text embedding vector from the input content
      parameters:
        - name: model
          in: path
          required: true
          schema:
            type: string
          description: 'Model name (e.g., models/text-embedding-004)'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmbedContentRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedContentResponse'

  /models/{model}:batchEmbedContents:
    post:
      tags: [Embeddings]
      operationId: batchEmbedContents
      summary: Batch generate embeddings
      description: Generates multiple embedding vectors from a batch of inputs
      parameters:
        - name: model
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchEmbedContentsRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchEmbedContentsResponse'

components:
  securitySchemes:
    ApiKeyQuery:
      type: apiKey
      in: query
      name: key
      description: API key for authentication
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-goog-api-key
      description: API key for authentication (preferred)

  parameters:
    PageSize:
      name: pageSize
      in: query
      schema:
        type: integer
        maximum: 1000
      description: Maximum number of results to return
    
    PageToken:
      name: pageToken
      in: query
      schema:
        type: string
      description: Token for pagination

  schemas:
    Model:
      type: object
      properties:
        name:
          type: string
          description: 'Model resource name (e.g., models/gemini-1.5-pro)'
        displayName:
          type: string
        description:
          type: string
        inputTokenLimit:
          type: integer
          format: int32
        outputTokenLimit:
          type: integer
          format: int32
        supportedGenerationMethods:
          type: array
          items:
            type: string
          example: ["generateContent", "countTokens"]

    ListModelsResponse:
      type: object
      properties:
        models:
          type: array
          items:
            $ref: '#/components/schemas/Model'
        nextPageToken:
          type: string

    GenerateContentRequest:
      type: object
      required:
        - contents
      properties:
        contents:
          type: array
          items:
            $ref: '#/components/schemas/Content'
          description: The content of the conversation with the model
        systemInstruction:
          $ref: '#/components/schemas/Content'
          description: Developer set system instructions
        generationConfig:
          $ref: '#/components/schemas/GenerationConfig'
        safetySettings:
          type: array
          items:
            $ref: '#/components/schemas/SafetySetting'

    GenerateContentResponse:
      type: object
      properties:
        candidates:
          type: array
          items:
            $ref: '#/components/schemas/Candidate'
        usageMetadata:
          $ref: '#/components/schemas/UsageMetadata'

    Content:
      type: object
      properties:
        role:
          type: string
          enum: [user, model]
          description: The producer of the content
        parts:
          type: array
          items:
            $ref: '#/components/schemas/Part'

    Part:
      type: object
      description: A part of multi-part content
      properties:
        text:
          type: string
          description: Inline text content
        inlineData:
          $ref: '#/components/schemas/Blob'
        fileData:
          $ref: '#/components/schemas/FileData'

    Blob:
      type: object
      required:
        - mimeType
        - data
      properties:
        mimeType:
          type: string
          example: "image/jpeg"
        data:
          type: string
          format: byte
          description: Base64 encoded data

    FileData:
      type: object
      required:
        - fileUri
      properties:
        mimeType:
          type: string
        fileUri:
          type: string
          description: URI of the file

    Candidate:
      type: object
      properties:
        content:
          $ref: '#/components/schemas/Content'
        finishReason:
          type: string
          enum: [STOP, MAX_TOKENS, SAFETY, RECITATION, OTHER]
        safetyRatings:
          type: array
          items:
            $ref: '#/components/schemas/SafetyRating'

    GenerationConfig:
      type: object
      properties:
        temperature:
          type: number
          format: float
          minimum: 0
          maximum: 2
          description: Controls randomness
        topP:
          type: number
          format: float
        topK:
          type: integer
          format: int32
        maxOutputTokens:
          type: integer
          format: int32
        stopSequences:
          type: array
          items:
            type: string

    SafetySetting:
      type: object
      required:
        - category
        - threshold
      properties:
        category:
          type: string
          enum:
            - HARM_CATEGORY_HARASSMENT
            - HARM_CATEGORY_HATE_SPEECH
            - HARM_CATEGORY_SEXUALLY_EXPLICIT
            - HARM_CATEGORY_DANGEROUS_CONTENT
        threshold:
          type: string
          enum:
            - BLOCK_NONE
            - BLOCK_ONLY_HIGH
            - BLOCK_MEDIUM_AND_ABOVE
            - BLOCK_LOW_AND_ABOVE

    SafetyRating:
      type: object
      properties:
        category:
          type: string
        probability:
          type: string
          enum: [NEGLIGIBLE, LOW, MEDIUM, HIGH]

    UsageMetadata:
      type: object
      properties:
        promptTokenCount:
          type: integer
        candidatesTokenCount:
          type: integer
        totalTokenCount:
          type: integer

    CountTokensRequest:
      type: object
      properties:
        contents:
          type: array
          items:
            $ref: '#/components/schemas/Content'

    CountTokensResponse:
      type: object
      properties:
        totalTokens:
          type: integer

    EmbedContentRequest:
      type: object
      required:
        - content
      properties:
        content:
          $ref: '#/components/schemas/Content'
        taskType:
          type: string
          enum:
            - RETRIEVAL_QUERY
            - RETRIEVAL_DOCUMENT
            - SEMANTIC_SIMILARITY
            - CLASSIFICATION
            - CLUSTERING

    EmbedContentResponse:
      type: object
      properties:
        embedding:
          $ref: '#/components/schemas/ContentEmbedding'

    ContentEmbedding:
      type: object
      properties:
        values:
          type: array
          items:
            type: number
            format: float

    BatchEmbedContentsRequest:
      type: object
      required:
        - requests
      properties:
        requests:
          type: array
          items:
            $ref: '#/components/schemas/EmbedContentRequest'

    BatchEmbedContentsResponse:
      type: object
      properties:
        embeddings:
          type: array
          items:
            $ref: '#/components/schemas/ContentEmbedding'


Wednesday, October 22, 2025

Azure App Service vs Azure Kubernetes (AKS) | The Practical Comparison

App service vs AKS. I will give you few advantages of using App service over AKS. I specifically got inputs on my linkedin asking for choices which makes it easy for adoption of app service against AKS. So will be covering imp points related to app services which makes them easy to adopt. 

Comparison done  on - 

1. Scale

2. Networking

3. Ease of operations

4. Ease of deployment and configurations

5. Multi cloud portability

5.and Real world queries 




#AzureBeyondDemos #Azure #AzureAppService #AzureAKS #AzureKubernetesService

#MicrosoftAzure #CloudComputing #Kubernetes #AppService #AzureContainers

#AKSvsAppService #AzureComparison #Microsoft #MicrosoftAzure #Msftadvocate 

Saturday, August 9, 2025

Azure Container Apps Networking Deep Dive | VNET, Ingress & Private Access Scenarios

 In this video I have addressed - Azure Container Apps “Real World” Networking Scenarios - 


  1. Content-web UI Application accessible over internet, content-api accessible only inside container app environment.
  2. Content-web UI Application accessible over private network only (from other VNETs), content-api accessible only inside container app environment.
  3. Content-web UI Application accessible over private network only (from other VNETs), content-api accessible outside of container app environment, and over private network (from other VNETs).
  4. Content-web UI Application accessible over internet, content-api accessible outside of container app environment, and over private network (from other VNETs).
  5. Content-web UI and Content-api both accessible over internet.

#AzureBeyondDemos #AzureContainerApps #AzureNetworking #AzureVNET #AzureIngress
#AzurePaaS #AzureCloud #AzureDeepDive







If you receive below error - 

Failed to provision IP address: Subscription is not registered for feature Microsoft.Network/AllowBringYourOwnPublicIpAddress required to carry out the requested operation

Solution run below command  in azure cli on portal - 
az feature register --name AllowBringYourOwnPublicIpAddress --namespace Microsoft.Network



Monday, July 14, 2025

How to Make Azure API Management Inbound Public IP Static (No More IP Surprises!)

Recently one of my customer had to go through painful journey of API Management inbound public IP change. This public IP was whitelisted to all client apps, external WAF services, xternal partner application and so on. This overall change of whitelisting of public IP was required at 350+ locations. While the best way is to use domain whitelisting not all firewalls or devices support domain based whitelisting. Or some org still work on public ip whitelisting only. In this scenarios, keeping api management public IP static becomes extremely important. 

I am going to show you the way of azure api management provisioning by which you can always get the static public IP address for inbound traffic. 


In this video I will talk about – 

- Which network option should be used for API Management provisioning

- How you can attach public IP of your choice to Azure api management. 

#AzureBeyondDemos #AzureAPIManagement #StaticIP #AzureAPIM #AzureTips #APISecurity #AzureNetworking #PublicIP #CloudSecurity #AzureBestPractices #AzureVNET #VirtualNetwork





Monday, June 23, 2025

Export Azure Resources to Excel or CSV in Seconds | Azure Portal (No Code)

 In this vide we will talk about below features – 

  1. Export to CSV azure resources
  2. Customize default Virtual Machines view and then export to CSV
  3. Customize default IP address, NSF, UDR view and then export to CSV
  4. Create your own view with app services and export to CSV






Sunday, June 8, 2025

Never Miss a Secret or key Expiry! Azure Key Vault Secret and Key Expiration Alerts Demo (No Code)

Manually tracking Key Vault secret or key expiration dates? That’s outdated.

In my latest YouTube video, I walk you through a No-Code solution using Azure Logic Apps to set up automated email alerts for Azure Key Vault secret and key expiration — all powered by Event Grid.

📌 Use this in real-world production to improve your cloud security posture and automate compliance and governance.

✅ What you'll learn:

  • How Azure Key Vault emits expiration events

  • How to handle SubscriptionValidationEvent correctly

  • Setting up Logic Apps to send email alerts — with zero code

  • Limitations of near-expiry events and custom alert workarounds

🔍 Perfect for:
Cloud engineers | Azure architects | DevOps teams | Security admins

Let’s simplify cloud automation — the secure way! 💡
👇 Let me know how you handle secret expiry today.





Sunday, May 4, 2025

Azure CAF vs Azure Well-Architected Framework (WAF) | Which One Do You Need First?

In this video I spoke about #Azure Cloud Adoption Framework (CAF) and Well Architected Framework (WAF) differences. 

I have answered few real world questions about CAF and WAF like - 

  1. Which one should be use in what context?
  2. Is CAF designed only for large enterprises?
  3. Is CAF provide high level guidance and it is not technical guidance?
  4. Is CAF mainly about documentation and should be done in linear way?
  5. Is CAF useful only for “green field” or new projects?
  6. CAF enterprise scale guidance is too much complex for me. What should I do?
  7. Is WAF intended only for certain workloads?
  8. Is WAF to be used only after deployment of application on azure?
  9. From CAF ESLZ blueprints/ templates/ arm scripts/ bicep scripts I want to use only firewall deployment, can I do that?
  10. From CAF ESLZ deployment I don’t want to create so many subscriptions for identity, networking and so on. Is it ok?
  11. Can I evaluate my application architecture for WAF pillars even before deployment of my azure resources and application? 

Please let me know if you have any feedback. Thanks. 









Sunday, April 13, 2025

Azure API Management Logger Setup for Event Hub | REST API Walkthrough

In this video I will talk about – 

  1. Why to log api management traffic to event hub? Benefits of it.
  2. I will explain it with the help of real world Use cases
  3. Setup logger in api management using rest api.

#azure #apimanagement #apigateway #AzureBeyondDemos

Request Body Sample - 

{

  "properties": {

"loggerType": "azureEventHub",

        "description": "adding a new logger",

         "credentials": {

             "endpointAddress":"YourEHNamespace.servicebus.windows.net",

             "identityClientId":"SystemAssigned",

             "name":"YourEventHub"   

          }

   }

}

For below error solution is discussed in the video - 

{

  "error": {

    "code": "NoRegisteredProviderFound",

    "message": "No registered resource provider found for location 'southindia' and API version 'SupportedVersion' for type 'service'. The supported api-versions are '2014-02-14, 2015-09-15, 2016-07-07, 2016-10-10, 2017-03-01, 2018-01-01, 2018-06-01-preview, 2019-01-01, 2019-12-01-preview, 2019-12-01, 2020-06-01-preview, 2020-12-01, 2021-01-01-preview, 2021-04-01-preview, 2021-08-01, 2021-12-01-preview, 2022-04-01-preview, 2022-08-01, 2022-09-01-preview, 2023-03-01-preview, 2023-05-01-preview, 2023-09-01-preview, 2024-05-01, 2024-06-01-preview'. The supported locations are 'centralindia, uaenorth, australiacentral, germanywestcentral, westcentralus, norwayeast, switzerlandnorth, koreasouth, westindia, koreacentral, southafricanorth, ukwest, brazilsouth, eastasia, southindia, canadacentral, canadaeast, australiasoutheast, japaneast, northcentralus, southeastasia, westus2, centralus, uksouth, australiaeast, japanwest, westus, francecentral, southcentralus, eastus2, eastus, northeurope, westeurope, westus3, jioindiacentral, jioindiawest, swedencentral, qatarcentral, polandcentral, italynorth, spaincentral, mexicocentral, israelcentral, newzealandnorth'."

  }

}


Sunday, April 6, 2025

Upgrading Azure Basic Public IP address to Standard sku - part 2

 In this video I will try to answer few important and crucial queries I received on LinkedIn, youTube video comments and so on.


  1. Can I upgrade the ip addresses attached to a VM NIC one by one?
  2. Can I create new NIC, disassociate all existing basic public ips from old nic, perform the upgrade to standard and then attach to new NIC?
  3. Can I disassociate all existing basic public ips from current nic, perform the upgrade to standard and then attach to same existing NIC?
  4. What if I have my public IP basic, static and not attached to anything, can I upgrade?
  5. Does this upgrade involve downtime? If yes, how much? Or how can I calculate?
  6. Is there a way to rollback upgrade in case of failure?
  7. Whom I should involve during the activity?
#azure #azurevm #publicIP





Thursday, March 27, 2025

Upgrading a basic public IP address to standard sku - part 1

 Azure Basic SKU Public IP is retiring on Sep 2025. 

In this video I will talk about – 

1. Why to upgrade basic public Ips to standard, what is the need?

2. Important information about basic IP retirement

3. Understand scenarios in which you will need an upgrade from basic to standard

4. I will demo about Azure VM having NIC with multiple basic public IP upgrade

5. I will also demo about VMs in Av set and are having basic sku public IP then how do you upgrade them.

6. Then we will close. Rest of the upgrade scenarios I will cover in next part of this. 


Feel free to reach out in case of any questions. 



Friday, August 18, 2023

Secure Azure Open AI using Azure Front Door WAF

 8 min to read.

Abstract

Azure Open AI adoption for application innovation is in full speed. With the same speed security teams are analyzing and doing VAPT on Azure Open AI endpoints. Recently a customer’s security team gave big list of 30+ vulnerabilities for their Azure Open AI endpoint.

So obvious question from application team “what can we do for security of Azure Open AI?”

This article step by step guide is for using Azure Front Door Web Application Firewall (WAF) with Azure Open AI.

The Challenge

In my opinion performing VAPT on direct open AI endpoint and calling it unsecure is incorrect approach. If an application team develops and host APIs on say Azure App Service/ AKS/ ARO/ Container Apps; it will also have similar vulnerabilities. Because these are plain APIs and not security appliances. We need to use Security appliances in front of APIs to secure them.

This is similar type of scenario when you create Azure Open AI service in your Azure subscription. Therefore we need to address below security aspects for Azure Open AI endpoint –

       1.      OWASP common vulnerabilities protection
2.      Azure Open AI endpoint should not be hit directly from end client applications like web app/ mobile app.
3.      If possible, remove public access to Open AI endpoint completely.

Solution

The standard approach to protect Azure Open AI APIs will be to use Web Application Firewall (WAF).

WAF on Azure Native technology offering is either Application Gateway or Azure Front Door. I will use Azure Front Door in this article.

Lets start.

Create Azure Open AI Service

Please don’t ask “how do I get access to Open AI in my Azure subscription?”. It is not in my control and I can’t even influence it. Follow the general procedure mentioned here.

Once you have access to Azure Open AI follow the below procedure to create it.

How-to:Create and deploy an Azure OpenAI Service resource - Azure OpenAI | MicrosoftLearn

From this link make sure that you choose “option 1: Allow all networks”. Don’t follow “specific networks only” and “disable network access” scenario for now.

Now Azure Open AI service instance is created. Next step will be to create deployment. Click on “Create New Deployment -> Add details as shown with model selected as gpt-35-turbo. Click on Create to complete model deployment.



Once model is created, select it and click on “Open in Playground”. Then click on “View Code” under “Chat Session” section. A pop up will appear showing Azure Open AI endpoint, and an access key as shown below –

Lets try Azure Open AI endpoint in Postman and get the output. To run in postman I used below details –

Body added in postman is as follows –

{

    "messages": [

        {

            "role""system",

            "content""You are an AI assistant that helps people find information."

        },

        {

            "role""user",

            "content""What is Azure OpenAI?"

        }

    ]

}

Rest of the setting with header in Postman as below. As you can see the outcome is 200 successful response.

Here we have used Azure Open AI endpoint directly in postman. As a next step lets create Azure Front Door and configure Azure Open AI as a backend to Azure Front Door.

Create Azure Front Door Service

On Azure portal click on Create -> In Search box type FrontDoor and Select FrontDoor Service creation option. Then on offerings page select options “Azure Front Door” and “Custom Create” as shown below – [click on image to get better view].


On Profile page under Basic tab select tier as “premium” and Resource group, service name as per your choice. Refer details as below. I could have chosen Standard tier however later in the future I am going to show AFD + Azure OpenAI with private endpoint which will be supported in Premium tier of AFD. [click on image to get better view].


Keep Secrets tab empty for now. On “Endpoint” tab click on “ Add an endpoint” button. Provide name as you wish. The click on Add. Refer to below screenshot – [click on image to get better view].


Then click on “Add a route” option in “Endpoint” tab. Add name as “myRoute”. Then click on “Add a new Origin Group”. Name it as “myOriginGroup”. Then click on “Add a Origin” button as shown below –


On the add Origin screen, I selected origin type as “custom” as Azure OpenAI does not appear inside the Azure front door origin types list. As of now I have not enabled the private endpoint for Azure Open AI. Refer to the screenshot below for rest of the inputs. Then click on “add” to finalize on Origin creation.


You will be redirected back to Origin group screen. Here the screen asks about enabling health probe. In Azure Front Door Health Probes can’t work with Authentication, however Azure Open AI endpoint API need API Key header for authentication. Also my intent is to show how we can WAF protection for Open AI. There are other ways by which you can check Azure Open AI endpoint health status. Therefore here I will disable the Health Probe. Click on Add button to finish Origin group creation.




This will bring back to add route screen. Keep Origin Path blank, Forwarding protocol to “match incoming requests”, Caching option is unchecked. Then click on add to finish route adding.

On the same page click on “Add Policy” button. Provide the name as “myPolicy”, select Azure OpenAI domain listed under “Domains” dropdown. Under WAF Policy option, click on Create New and name it as MyWAFPolicy. Check the option “add bot protection”. Finally click on Save to complete WAF policy creation.


Then click on “review and Create” button to finish Azure front door service creation process.

Output

Now we have Azure Front Door WAF ready with Azure Open AI endpoint as backend. Lets try to access Open AI endpoint using Azure Front Door URL via Postman.

My original Azure Open AI Endpoint is  - https://kunalgenai.openai.azure.com/openai/deployments/kunaldeploy1/chat/completions?api-version=2023-03-15-preview  

With Azure Front Door it will be - https://kunalopenaiafdep-hgc2ecbybxeranac.z01.azurefd.net/openai/deployments/kunaldeploy1/chat/completions?api-version=2023-03-15-preview

Try the Azure Front Door URL in postman, with same body, same headers, same api key and I see that result is successful. Refer below screenshot –


I have not tested with Azure Open AI with private endpoint. Please test it and add your experience in comments.

Conclusion

Hope this article helped you to secure Azure Open AI endpoint using Azure Front Door (AFD) (WAF).

Happy Generative AI..ing!!

A humble request!

Internet is creating a lot of digital garbage. If you feel this a quality blog and someone will definitely get benefited, don't hesitate to hit share button present below. Your one share will save many precious hours of a developer. Thank you.

Next Related Posts

AzureVirtual Machines should be connected to allowed multiple virtual networks.

Start stop multiple Azure VMs on schedule and save cost!

Export Azure VMs to CSV!

Azure Migration frequently asked questions, not easily answered!

Azure VM disk encryption, what should be my approach!

Sunday, July 30, 2023

Azure Virtual machines should be connected to an approved MULTIPLE virtual networks

 8 min to read.

Abstract

Virtual machines should be connected to an approved virtual network - This default Azure policy is fantastic. This policy checks if a VM is part of approved VNET; else it shows compliance message.

However it only offers VMs to be checked against single VNET name. In reality, we have flood of Azure VNETs across multiple Azure subscriptions.

So we need a policy that can check all Azure VMs against “multiple azure Virtual Networks”.

This article talks about creating a policy that allows to provision Azure VMs inside only allowed list of VNETs.

 

The Challenge

This policy will be built as custom. I want to do below –

Evaluate every NIC against the VNET names present in input parameter. Refer yellow and green highlight below. I need to –

1.       Loop using for or for-each

2.       Dynamically get values of all items present in a parameter after performing “split” on the input string.

 

  "mode""All",

  "policyRule": {

    "if": {

      "allOf": [

        {

          "field""type",

          "equals""Microsoft.Network/networkInterfaces"

        },

        {

          "not": {

            "field""Microsoft.Network/networkInterfaces/ipconfigurations[*].subnet.id",

            "contains""[parameters('virtualNetworkIds')]"

          }

        }

      ]

    },

    "then": {

      "effect""[parameters('effect')]"

    }

  },

  "parameters": {

    "effect": {

      "type""String",

      "metadata": {

        "displayName""Effect",

        "description""The effect determines what happens when the policy rule is evaluated to match"

      },

      "allowedValues": [

        "Audit",

        "Deny",

        "Disabled"

      ],

      "defaultValue""Audit"

    },

    "virtualNetworkIds": {

      "type""String",

      "metadata": {

        "displayName""Virtual network Names",

        "description""Resource name of the virtual network. Example: Add , separated multiple values."

      }

    }

  }

}

The input parameter to this policy will be more than one names of VNETs. Unfortunately in Azure policy I could not find a way to iterate over input parameters by using for-each loop construct.

There is a Current function available however it can be used only when we are using Count and Where function. Also these functions are used over Field property, used as an array. These functions cant be used when input parameter is not an array.

Therefore we need a way to iterate over input parameters array and comparing every parameter value with one subnet id Field highlighted as green above.

Solution

If we see the outcome of below line  - "Microsoft.Network/networkInterfaces/ipconfigurations[*].subnet.id",

It will be resolved to id format of subnet similar to below - "/subscriptions/SubId/resourceGroups/rg--net/providers/Microsoft.Network/virtualNetworks/vnet-01/subnets/default"

So we just need to use expertise string functions lie split, combine, concat etc. in a such a way that we take out only VENT name from above string. Therefore lets write code to covert to string and then split so as to get VNET name. Final code is as below –

"[split(string(field('Microsoft.Network/networkInterfaces/ipconfigurations[*].subnet.id')),'/')[8]]"

Creating Custom Policy

Login to Azure portal -> In middle top search box type “Policies” -> Select Definitions -> Create New. Then add values as shown below. The name of the policy I have given as “Azure Resources should be connected to an approved virtual networks”. Code of policy to be added under section “POLICY RULE” can be taken from github link shared below.

Also whenever we create custom policy always get it added in new Category as “My Custom Policies”. Do not add any Role Assignment. Then save to finish policy creation wizard. [click to get better view.]





Open the newly created policy and click on Assign. [click to get better view].





On the Basics tab, make “policy enforcement” option as disabled. We want to just view the report of azure resources not deployed in approved VNET. If we enforce policy means it will not allow to provision new resources in any of the VNET other  than listed in parameters tab below. For testing purpose I disabled policy enforcement.

Under “Remediation” tab uncheck the option “create a managed identity”.

On Parameters tab, make sure that you add names of all VNETs against which you want to evaluate azure resources is added in below shown format only. Then Click on “Save” button for VNET names added and click on “Review and Create” to complete assignment process.



Output

Virtual Machines

I could see that Virtual Machines not listed under the VNETs I added as parameter. Refer screenshots [click to get better view] –





Same policy will also be automatically applied on Azure App Service configured with private endpoint. Refer below output –



Full and final working policy is present at this Github link –

kunalchandratre1/NicVnetPolicy:This repo has code related to Azure policy to identify Azure resources whichare not deployed in approved VNETs. (github.com)

Important –

This policy will not work for Azure Kubernetes Service, VM Scale Sets as their NIC resource provider format is different. However this policy should work as is for all types of private endpoints where NIC is create with resource provider format of Microsoft.Network/networkInterfaces/.

I have not tested with other types of private endpoint. Please test it and add your experience in comments.

Conclusion

Hope this article helped you to build custom policy and helped to achieve your compliance and governance. Let me know your views in comments section below to improve and what are your thoughts on this approach.

Happy Azure Governance!!

A humble request!

Internet is creating a lot of digital garbage. If you feel this a quality blog and someone will definitely get benefited, don't hesitate to hit share button present below. Your one share will save many precious hours of a developer. Thank you.

Next Related Posts

Azure Virtual Machines – real world frequently asked questions – not easily answered.

Start stop multiple Azure VMs on schedule and save cost!

Export Azure VMs to CSV!

Azure Migration frequently asked questions, not easily answered!

Azure VM disk encryption, what should be my approach!