I had the privilege of conducting a session at the Global Security BootCamp (Perth 2025)
Following is the presentation I conducted.
Following are few snaps from the event
Following is the official site of the event
I had the privilege of conducting a session at the Global Security BootCamp (Perth 2025)
Following is the presentation I conducted.
Following are few snaps from the event
Following is the official site of the event
I had the privilege of delivering a session at the Perth Global AI Bootcamp at Microsoft. My topic was Designing AI-Powered APIs on Azure: Best Practices& Considerations
We explored various aspects of the AI solution design, aligning closely with the principles of the Azure Well-Architected Framework.
Following is the presentation I conducted
Following are few snaps from the event
#URL
https://login.microsoftonline.com/{Tenant ID}/oauth2/v2.0/token
#METHOD
POST
#X-WWW-FORM-URLENCODED
#X-WWW-FORM-URLENCODED
grant_type=client_credentials
&client_id={Client ID}
&client_secret={Client Secret}
&scope=https://management.azure.com/.default
Application Insights plays a crucial role in applications hosted on Microsoft Azure. It is important to periodically review the associated Log Analytics Workspace instances to ensure they are properly governed and optimized.
The following areas should be examined for these resources in alignment with the Azure Well-Architected Framework.
It is evident that AppTraces have increased recently, which may negatively impact overall query performance.
My Log Analytics Workspace is set to the default 90-day data retention period, which I prefer to keep unchanged to achieve cost optimization.
Since the outlier is only in the AppTraces table, I want to reduce the retention period specifically for that table. The expectation is to maintain a lower data volume in that container while keeping the overall workspace retention unchanged.
Following was the approach I used.
Navigate to Tables in the Log Analytics Workspace and select the AppTraces table.
Click on Manage Table to access the table settings.
Change the retention period to 60 days, which overrides the default retention setting for this table only.
That's it! The AppTraces table will now retain data for 60 days, reducing log volume while keeping the overall workspace retention unchanged.
Let's consider the opposite approach: How can you increase data retention while still optimizing costs?
You can also use this approach to optimize costs. For example, if you need to increase the retention period from 90 to 120 days, instead of applying the change to all tables, you can selectively extend retention only for the tables that truly require it. This helps balance cost efficiency and data availability.
Additional retention will incur costs based on the amount of storage consumed.
#URL
https://management.azure.com/subscriptions/{Tenant ID}/resourceGroups/{Resource Group}/providers/Microsoft.CostManagement/query?api-version=2024-08-01
#METHOD
POST
#AUTHORIZATION
Bearer Token
#BODY
{
"type": "Usage",
"timeframe": "MonthToDate",
"dataset": {
"granularity": "None",
"aggregation": {
"totalCost": {
"name": "PreTaxCost",
"function": "Sum"
}
},
"grouping": [
{
"type": "Dimension",
"name": "ResourceType"
},
{
"type": "Dimension",
"name": "MeterCategory"
}
]
}
}
You can use this approach to generate an access token{
"id": "subscriptions/{Tenant ID}/resourcegroups/{Resource Group}/providers/Microsoft.CostManagement/query/5c25de9e-06aa-4839-81b4-64273e0bc86f",
"name": "5c25de9e-06aa-4839-81b4-64273e0bc86f",
"type": "Microsoft.CostManagement/query",
"location": null,
"sku": null,
"eTag": null,
"properties": {
"nextLink": null,
"columns": [
{
"name": "PreTaxCost",
"type": "Number"
},
{
"name": "ResourceType",
"type": "String"
},
{
"name": "MeterCategory",
"type": "String"
},
{
"name": "Currency",
"type": "String"
}
],
"rows": [
[
34.957915,
"microsoft.apimanagement/service",
"API Management",
"AUD"
],
[
0.0016342144,
"microsoft.keyvault/vaults",
"Key Vault",
"AUD"
],
[
0.036166705555556,
"microsoft.loadtestservice/loadtests",
"Azure Load Testing",
"AUD"
],
[
0.034666562722667,
"microsoft.operationalinsights/workspaces",
"Log Analytics",
"AUD"
],
[
0.000007542612,
"microsoft.storage/storageaccounts",
"Bandwidth",
"AUD"
],
[
0.0001935796,
"microsoft.storage/storageaccounts",
"Storage",
"AUD"
],
[
0.0,
"microsoft.web/sites",
"Azure App Service",
"AUD"
],
[
0.000000359172,
"microsoft.web/sites",
"Bandwidth",
"AUD"
]
]
}
}
This article is the third part of a multi-part series. In this section, I will explain how to render custom mock responses from JSON files stored in a storage container. Below are the different parts of this article series.
{
"id": 1,
"name": "Introduction to Azure",
"category": "Cloud Computing",
"description": "A beginner-friendly course covering the fundamentals of Microsoft Azure.",
"duration": "4 weeks",
"instructor": "John Doe"
}
<inbound>
<base />
<choose>
<when condition="@(context.Request.Url.Query.GetValueOrDefault("id") == "1")">
<send-request mode="new" response-variable-name="response" timeout="10" ignore-error="false">
<set-url>@($"https://rgstoragefedora001.blob.core.windows.net/data/Subject/1.json?sp=r&st=2024-03-08T12:01:42Z&se=2024-03-08T20:01:42Z&spr=https&sv=2022-11-02&sr=b&sig=DrqWZJxGP38PNJYFKCoMgIqn6AjNC71nw0x%2FjITu4aM%3D")</set-url>
<set-method>GET</set-method>
</send-request>
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>@(new JObject(((IResponse)context.Variables["response"]).Body.As<JObject>()).ToString())</set-body>
</return-response>
</when>
<when condition="@(context.Request.Url.Query.GetValueOrDefault("id") == "2")">
<send-request mode="new" response-variable-name="response" timeout="10" ignore-error="false">
<set-url>@($"https://rgstoragefedora001.blob.core.windows.net/data/Subject/2.json?sp=r&st=2024-03-08T12:34:15Z&se=2024-03-08T20:34:15Z&spr=https&sv=2022-11-02&sr=b&sig=OVhf3uGIASMHWHtg8F%2BypQzLatI9DeEzqoFns2iGOUk%3D")</set-url>
<set-method>GET</set-method>
</send-request>
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>@(new JObject(((IResponse)context.Variables["response"]).Body.As<JObject>()).ToString())</set-body>
</return-response>
</when>
<otherwise>
<return-response>
<set-status code="404" reason="Not Found" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>{
"error": "Student ID not found"
}</set-body>
</return-response>
</otherwise>
</choose>
</inbound>
This article is the second part of a three-part series. We will discuss how to render custom mock responses using APIM policy. Below are the different parts of this article series.
Custom mock responses
Often, we need more than just a 200 OK response without a body. Instead, we require comprehensive responses formatted as JSON messages. Adding to the complexity, the response often needs to vary based on specific query string parameters.
Here’s the approach I used to generate custom mock responses in Azure API Management based on varying query string parameters.
Navigate to your API Management instance and select the specific API operation you want to configure.
Click on the Inbound Processing section and open the Policy Code Editor.
We will modify the inbound section of the policy. We will add a policy segment to dynamically generate the response body based on a specified query string parameter.
Here is the code I used
<inbound>
<base />
<choose>
<when condition="@(context.Request.Url.Query.GetValueOrDefault("id") == "1")">
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>{
"studentId": "1",
"name": "Jane Smith",
"grade": "B"
}</set-body>
</return-response>
</when>
<when condition="@(context.Request.Url.Query.GetValueOrDefault("id") == "2")">
<return-response>
<set-status code="200" reason="OK" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>{
"studentId": "2",
"name": "Jane Smith",
"grade": "B",
}</set-body>
</return-response>
</when>
<otherwise>
<return-response>
<set-status code="404" reason="Not Found" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>{
"error": "Student ID not found"
}</set-body>
</return-response>
</otherwise>
</choose>
</inbound>
You can test the outcome by navigating to the Test console and specifying the appropriate query string parameter, as shown below.
Then, submit the request to verify that the appropriate response is returned based on the specified query string parameter.
[ApiController]
[Route("api/[controller]")]
public class GatewayTestController : ControllerBase
{
private readonly HttpClient _httpClient;
public GatewayTestController(HttpClient httpClient)
{
_httpClient = httpClient;
}
[HttpGet]
public async Task GetOutboundIp()
{
// Call external API over internet
var response = await _httpClient.GetAsync("https://httpbin.org/ip");
if (!response.IsSuccessStatusCode)
{
return StatusCode((int)response.StatusCode, "Failed to get outbound IP");
}
var callerIP = await response.Content.ReadAsStringAsync();
return Ok(callerIP);
}
}