Thursday, September 14, 2023
Resolve Azure Data Explorer error - Principal 'aaduser=xxx' is not authorized to perform operation 'VersionShowCommand'
Tuesday, September 5, 2023
Designing an active/passive solution using Azure Front Door with priority based traffic routing
Tuesday, August 15, 2023
Secure Azure app services behind Azure Front Door using private link
When an Azure App Service is exposed through Azure Front Door, it utilizes the public address and directs the traffic over the public network. However, we can leverage Azure Front Door as the gateway and restrict all public traffic to our origin (Azure App Service app) by utilizing the Private Link integration feature available in Azure Front Door Premium.
Private Link integration enables Front Door to connect with your origin using the Private Link service. This approach eliminates the necessity for your origin to be accessed over the public internet. Instead, it permits Front Door to access the origin using Microsoft's backbone network.
This process establishes the Private Link connection for the origin and necessitates your approval at the origin.
Tuesday, August 1, 2023
Configure SonarQube in Azure Container Instances and connect with Azure DevOps pipelines for Static Application Security Testing (SAST)
- Configure SonarQube community edition as a container in Azure Container Instances (ACI) with backend as Azure SQL instance
- Configure SonarQube in Azure DevOps
# Login to Azure environment and select the subscription
az login
az account set --subscription "My Demos"
# Create SQL instance and firewall rules
az sql server create --name srv-sql-sonarqube --resource-group rg-sonarqube --location australiaeast --admin-user sonar --admin-password [Password]
az sql server firewall-rule create --resource-group rg-sonarqube --server srv-sql-sonarqube -n AzureServices --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
# Create the database in SQL instance
az sql db create --resource-group rg-sonarqube --server srv-sql-sonarqube --name sonarqubeDb --service-objective S0 --collation SQL_Latin1_General_CP1_CS_AS
# Create a container instance with offical SonarQube image
az container create --resource-group rg-sonarqube --location australiaeast --name sonarqube --cpu 2 --memory 3.5 --image sonarqube:7.7-community --os-type Linux --ip-address Public --environment-variables 'SONARQUBE_JDBC_USERNAME'='sonar' 'SONARQUBE_JDBC_PASSWORD'='[Password]' 'SONARQUBE_JDBC_URL'='jdbc:sqlserver://srv-sql-sonarqube.database.windows.net:1433;database=sonarqubeDb;user=sonar@srv-sql-sonarqube;password=[Password];encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30' --ports 9000 --protocol TCP
Wednesday, July 12, 2023
Send email with exchange email using Azure service principal
Following is a generic method to send email with attachments using Azure service principle with Mail.Send permission.
This approach is more secure than classic SmtpClient.SendEmail method. Service principal approach allows you to authenticate using Azure Active Directory, which provides a more secure way of authenticating than using a username and password.
You need to supply Client ID, Tenant ID and Client Secret as parameters.
public async Task<bool> SendGraphEmailAsync(Email email,string clientId, string tenantId, string clientSecret)
{
bool result = false;
var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
BlobService blobService = new BlobService();
SharePointRepository sharePointRepository = new SharePointRepository();
//method to get email template from blob storage template container
var emailTemplate = await blobService.ReadFileFromBlob("Email-Template.html", "template");
//method to get attachment from sharepoint
var csvAttachment = await sharePointRepository.GetAttachmentFromSharePointAsBiyes(email.CSVName);
var message = new Message
{
Subject = email.Subject,
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = emailTemplate.ToString()
},
From = new Recipient
{
EmailAddress = new EmailAddress
{
Address = email.From
}
},
CcRecipients = new List<recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = email.SingleCC
}
}
},
ToRecipients = new List<recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = email.SingleTo
}
}
},
Attachments = new List<microsoft .graph.models.attachment="">
{
new FileAttachment
{
OdataType = "#microsoft.graph.fileAttachment",
Name = email.CSVName.Split('/').Last(),
ContentType = "text/csv",
ContentBytes = csvAttachment,
}
},
};
Microsoft.Graph.Users.Item.SendMail
.SendMailPostRequestBody requestbody = new()
{
Message = message,
SaveToSentItems = false
};
var scopes = new[] { "https://graph.microsoft.com/.default" };
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
try
{
await graphClient.Users[email.From]
.SendMail
.PostAsync(requestbody);
return result;
}
catch (Microsoft.Graph.ServiceException)
{
throw;
}
}
Hope that helps
Wednesday, June 21, 2023
Apply Azure DevOps variable groups to Azure App Service deployment slot scope
Friday, June 9, 2023
Queue triggered Azure Function - Take only one message from queue at a time
I encountered a situation where my queue-triggered function didn't consistently behave as expected. The issue stemmed from the function's execution order not aligning with my expectations.
The root cause of this problem lies in the unpredictability of message ingestion order within a storage queue when executing queue-triggered functions. While storage queues are designed to process messages in a first-in, first-out (FIFO) fashion, several factors can influence the actual order of message ingestion. For instance, when multiple instances of the function run concurrently, messages may be processed out of sequence. Furthermore, delays in message processing or variations in message priorities can also disrupt the expected order of ingestion.
If your objective is to maintain a strict order of message ingestion and you are utilizing a storage queue, you'll need to address this concern within your code. Alternatively, you can consider migrating to a more dependable solution, such as Azure Service Bus Queue, which offers greater control over message ordering.
However, if your problem can be resolved by dequeuing one message at a time, you can implement the following adjustments to your host.json file within your Azure Function App.
"extensions": {
"queues": {
"batchSize": 1,
"newBatchThreshold": 0,
"maxDequeueCount": 1
}
}
This helped my application to function as expected.