Create Azure Connection API with Connection Runtime Url - azure

I have a logic App (a standard logic app) that make a call to cosmos DB.
I need to store the "Connection Runtime Url" under the configuration of the logic App.
When I create the connection from the logic app designer, the connection have this property. However, when I deploy the same connection using an ARM template, the connection don't have this property.
Anyone knows how can get this property or generate it? And if possible, how to call it later in an ARM template
Thanks

Only API connection of kind: 'V2' can return a connectionRuntimeUrl.
You can create a cosmos db connector with the below script (bicep):
param location string = resourceGroup().location
param cosmosDbAccountName string
param connectorName string = '${cosmosDbAccountName}-connector'
// get a reference to the cosmos db account
resource cosmosDbAccount 'Microsoft.DocumentDB/databaseAccounts#2021-06-15' existing = {
name: cosmosDbAccountName
}
// create the related connection api
resource cosmosDbConnector 'Microsoft.Web/connections#2016-06-01' = {
name: connectorName
location: location
kind: 'V2'
properties: {
displayName: connectorName
parameterValues: {
databaseAccount: cosmosDbAccount.name
accessKey: listKeys(cosmosDbAccount.id, cosmosDbAccount.apiVersion).primaryMasterKey
}
api: {
id: 'subscriptions/${subscription().subscriptionId}/providers/Microsoft.Web/locations/${location}/managedApis/documentdb'
}
}
}
output connectionRuntimeUrl string = reference(cosmosDbConnector.id, cosmosDbConnector.apiVersion, 'full').properties.connectionRuntimeUrl
The url will be an output of the generated ARM
You can then set this url as an appsetting in the workflow app:
COSMOS_CONNECTION_RUNTIMEURL: <connectionRuntimeUrl>
Then in the connections.json file, you can reference this app setting:
{
"managedApiConnections": {
"documentdb": {
...
"connectionRuntimeUrl": "#appsetting('COSMOS_CONNECTION_RUNTIMEURL')"
}
}
}
Using appsettings and parameters should make thing easier to deploy

According to this discussion, a simple API connection (V1) may not have "connectionRuntimeUrl". So, to be able to see it I need to add
"kind": "V2",
in my connection Template, also as #Thomas wrote in his answer

Related

How to link my workbook resource with another resource

I have created a simple workbook template via Bicep without any settings.
I'd like to integrate/link it with another resource, for example application insights using Bicep and deploy it to Azure with my pipeline.
However, I do not know how I can link them together. If it is not possible, how can I link the workbook template to an App Service resource or another resource instance?
This is my workbook Bicep:
#description('The unique guid for this workbook instance.')
param workbookId string
#description('The location of the resource.')
param location string
#description('The friendly name for the workbook that is used in the Gallery or Saved List. Needs to be unique in the scope of the resource group and source.')
param workbookName string
#description('The gallery that the workbook will been shown under. Supported values include workbook, `tsg`, Azure Monitor, etc.')
param workbookType string = 'tsg'
#description('The id of resource instance to which the workbook will be associated.')
param workbookSourceId string = '<insert-your-resource-id-here>'
resource workbook 'Microsoft.Insights/workbooks#2022-04-01' = {
name: workbookId
location: location
kind: 'shared'
properties: {
displayName: workbookName
serializedData: '{"version":"Notebook/1.0","items":[{"type":1,"content":"{\\"json\\":\\"Hello World!\\"}","conditionalVisibility":null}],"isLocked":false}'
version: '1.0'
sourceId: workbookSourceId
category: workbookType
}
}
output workbookId string = workbook.id
And this is my Application Insights:
#description('Name of Application Insights resource.')
param appName string
#description('Type of app you are deploying. This field is for legacy reasons and will not impact the type of App Insights resource you deploy.')
param type string = 'web'
#description('Which Azure Region to deploy the resource to. This must be a valid Azure regionId.')
param regionId string
#description('Source of Azure Resource Manager deployment.')
param requestSource string
#description('Log Analytics workspace ID to associate with your Application Insights resource.')
param workspaceResourceId string
//param deployWorkspaceDiagnosticSettings bool = true
// #description('See documentation on tags: https://learn.microsoft.com/azure/azure-resource-manager/management/tag-resources.')
// param tagsArray object
resource applicationInsights 'Microsoft.Insights/components#2020-02-02' = {
name: appName
location: regionId
// tags: tagsArray
kind: 'other'
properties: {
Application_Type: type
Flow_Type: 'Bluefield'
Request_Source: requestSource
WorkspaceResourceId: workspaceResourceId
}
}
#description('Get Application Insights ID.')
output appIdOutput string = applicationInsights.id
#description('Get Application Type.')
output appTypeOutput string = applicationInsights.properties.Application_Type
#description('Get Instrumentation Key.')
output appInstrumentationKeyOutput string = applicationInsights.properties.InstrumentationKey
#description('The id of resource instance to which the workbook will be associated.')
param workbookSourceId string = '<insert-your-resource-id-here>'
This is what links the workbook to a resource. that workbookSourceId would be the resource id of the application insights resource, which you'd create first (if you want to link it to the app insights resource)
how you actually do that in bicep specifically i do not know, but it appears you already do similar with workspaceResourceId?

Can someone share datasets in PowerBI across different service principle profiles?

We would like to expose some datasets that are common for all customers and could be imported into their powerbi reports across different workspaces.
We have a design where we use one service principle profile per customer. This in provides securoty around isolating the data of each customer. Is there any way (using service principle profiles) to be able to support the sharing of some common data across workspaces?
Is there any way (using service principal profiles) to be able to support the sharing of some common data across workspaces?
Yes, you can create a security group in Azure AD and add all the service principals that are modelled to your customers in that group and then provide that security group access to your workspace by adding the group as with required permissions on the workspace where the shared dataset exists. If you want to give access to individual service principals, you can do that too.
Your customers can then use the SP’s client ID, Tenant ID and Secret to access the dataset via their app in the browser or even by calling the data via PowerShell. You can directly share your dataset with the security group containing your Service principals.
Created a security group in Azure AD and added my service principal to the group: -
Power BI settings:-
Go to app.powerbi.com Log in to your Power BI workspace > click on Settings > Admin Portal > Tenant Settings > Developer Settings > Allow service principals to use Power BI API’s Enable > and then provide access to your security group
There are 2 ways you can share your data with the Service principal
1. Sharing directly
By directly sharing the workspace dataset with the Security group where the service principals exist.
2. Access permissions on workspace
Provide Access to the workspace so the sp’s can access data set directly via their app or call the workspace via Power shell.
Go to your workspace > Select your data and click on … dots > Manage permissions > Grant people access > Select your Power BI Embed group
You can change the read write permissions later >
Calling Dataset via Application -
Now, We can call this Dataset from our application by adding the Authentication to Service principal and adding the SP’s Client ID, Tenant ID, Client Secret etc. You can refer this document :-
https://learn.microsoft.com/en-us/power-bi/developer/embedded/embed-organization-app
Authentication Code :
This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices (IServiceCollection services) {
services
.AddMicrosoftIdentityWebAppAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi(PowerBiServiceApi.RequiredScopes)
.AddInMemoryTokenCaches();
services.AddScoped (typeof (PowerBiServiceApi));
var mvcBuilder = services.AddControllersWithViews (options => {
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add (new AuthorizeFilter (policy));
});
mvcBuilder.AddMicrosoftIdentityUI();
services.AddRazorPages();
}
app.settings:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxx.onmicrosoft.com",
"TenantId": "xxxxxxxxxxxxx",
"ClientId": "xxxxxxxxxxxxx",
"ClientSecret": "xxxxxxxx",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath": "/signout-callback-oidc"
},
"PowerBi": {
"ServiceRootUrl": "https://api.powerbi.com"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Controller.cs
private PowerBiServiceApi powerBiServiceApi;
public HomeController (PowerBiServiceApi powerBiServiceApi) {
this.powerBiServiceApi = powerBiServiceApi;
}
[AllowAnonymous]
public IActionResult Index() {
return View();
}
public async Task<IActionResult> Embed() {
Guid workspaceId = new Guid("11111111-1111-1111-1111-111111111111");
Guid reportId = new Guid("22222222-2222-2222-2222-222222222222");
var viewModel = await powerBiServiceApi.GetReport(workspaceId, reportId);
return View(viewModel);
}
[AllowAnonymous]
[ResponseCache (Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error() {
return View (new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
Embed your powerbi data set with JS
$(function(){
// 1 - Get DOM object for div that is report container
let reportContainer = document.getElementById("embed-container");
// 2 - Get report embedding data from view model
let reportId = window.viewModel.reportId;
let embedUrl = window.viewModel.embedUrl;
let token = window.viewModel.token
// 3 - Embed report using the Power BI JavaScript API.
let models = window['powerbi-client'].models;
let config = {
type: 'report',
id: reportId,
embedUrl: embedUrl,
accessToken: token,
permissions: models.Permissions.All,
tokenType: models.TokenType.Aad,
viewMode: models.ViewMode.View,
settings: {
panes: {
filters: { expanded: false, visible: true },
pageNavigation: { visible: false }
}
}
};
// Embed the report and display it within the div container.
let report = powerbi.embed(reportContainer, config);
Add such codes depending on the framework of your customer’s App and run the app to access the Power BI data.
Accessing PowerBI workspace with Powershell -
Refer the document here :- https://learn.microsoft.com/en-us/powershell/module/microsoftpowerbimgmt.profile/connect-powerbiserviceaccount?view=powerbi-ps
Powershell commands :-
Install PowerBI Powershell module -
Install-Module -Name MicrosoftPowerBIMgmt
Connect to PowerBI SP -
Connect-PowerBIServiceAccount -ServicePrincipal -Credential (Get-Credential) -Tenant 83331f4e-7f45-4ce4-99ed-af9038592395
In the User name enter the App Id of the SP and in Password add the secret that was created for the SP during app registration.
connected to PowerBI successfully :-
Get the workspace -
Get-PowerBIWorkspace
Reference :-
https://learn.microsoft.com/en-us/power-bi/developer/embedded/embed-service-principal
https://learn.microsoft.com/en-us/power-bi/developer/embedded/embed-organization-app

Configuring encryption protection in Azure SQL server using ARM/Bicep

I'm trying to build both ARM and Bicep templates for enabling BYOK/CMK/TDE on Azure SQL server (and databases).
The challenge I'm having is that templates expect KeyVault Key Version to be passed in as an input. I'd really like to avoid that, as version could eventually change and it's not a value I'd like to maintain as an input parameter.
what I've tried so far is to create these 2 resources for SQL:
Microsoft.Sql/servers/keys#2022-05-01-preview
Microsoft.Sql/servers/encryptionProtector#2022-05-01-preview
encryptionProtector seems pretty straighforward, which just uses servers/keys resource. And that's where I'm stuck.
It requires KV key version for 'name' field, which I expected to be able to get from Microsoft.KeyVault/vaults/keys existing resource. However it only has this property:
keyVaultKey.properties.keyUriWithVersion
My next option was to parse the value, like:
var sqlServerKeyName = '${keyVaultName}_${keyVaultKeyName}_${last(split(keyVaultKey.properties.keyUriWithVersion, '/'))}'
but this results in warning:
his expression is being used in an assignment to the "name" property of the "Microsoft.Sql/servers/keys" type, which requires a value that can be calculated at the start of the deployment. You are referencing a variable which cannot be calculated at the start ("keyVaultKeyName" -> "keyVaultKey"). Properties of keyVaultKey which can be calculated at the start include "apiVersion", "id", "name", "type"
So my question is: is it possible to get KV Key Version from Bicep/ARM template and if yes - how? Or is it generally not recommended to do that (especially in the context of transparent data encryption)?
lastly, if there are no ARM/Bicep based solutions, I guess next best solution could be to try to retrieve latest version via powershell and then pass it as input. any suggestions/examples on this approach maybe?
note: KeyVault and Keys are created in separate deployment so I cannot use KV deployment output for this
The error is just about the name of the resource: the value has to be calculated when the deployment starts which is not possible in your case because the name is generated from another resource.
You would need to invoke it through another module:
// sqlserver-keyvault-encryption.bicep
param sqlServerName string
param keyVaultName string
param keyName string
param keyVersion string
param keyUri string
resource sqlServer 'Microsoft.Sql/servers#2022-05-01-preview' existing = {
name: sqlServerName
}
// Create sql server key from key vault
resource sqlServerKey 'Microsoft.Sql/servers/keys#2022-05-01-preview' = {
name: '${keyVaultName}_${keyName}_${keyVersion}'
parent: sqlServer
properties: {
serverKeyType: 'AzureKeyVault'
uri: keyUri
}
}
// Create the encryption protector
resource propector 'Microsoft.Sql/servers/encryptionProtector#2022-05-01-preview' = {
name: 'current'
parent: sqlServer
properties: {
serverKeyType: 'AzureKeyVault'
serverKeyName: sqlServerKey.name
}
}
Then you can invoke it from a parent module:
param sqlServerName string
param keyVaultName string
param keyName string
resource keyVault 'Microsoft.KeyVault/vaults#2022-07-01' existing = {
name: keyVaultName
}
resource keyVaultKey 'Microsoft.KeyVault/vaults/keys#2022-07-01' existing = {
name: keyName
parent: keyVault
}
module encryption 'sqlserver-keyvault-encryption.bicep' = {
name: 'sqlserver-keyvault-encryption'
params: {
sqlServerName: sqlServerName
keyVaultName: keyVault.name
keyName: keyVaultKey.name
keyVersion: last(split(keyVaultKey.properties.keyUriWithVersion, '/'))
keyUri: keyVaultKey.properties.keyUriWithVersion
}
}

Pulumi: Missing PrimaryAccessKey for EventGrid Topic

I'm using Pulumi 1.16 with dotnet/C# and the AzureNative stack. I try to create an EventGridTopic. To access the created resource's properties later I pull some output values.
Example code:
var topic = new Topic("eventgrid-topic-status", new TopicArgs
{
TopicName = "egt-status-dev",
ResourceGroupName = "rg-testapp-dev",
Location = "westeurope"
});
var endPointOutput = topic.Endpoint;
var endPointAccessKey = ""; // missing output property
The resource is being created. I found no way to get the access key properties:
PrimaryAccessKey
SecondaryAccessKey
In the former (elder) Azure stack the properties exist. But in Azure Native stack not. Is that on purpose, just work in progress, has been forgotten or is there some other way to retrieve these properties on this object?
This is output on Azure (old stack):
This is Azure Native, clearly the keys are missing:
I doubt that this happens accidentally and would like to understand what to do.
Azure API (and therefore Azure Native resources) return no sensitive information in their outputs automatically to minimize security risks. You have to make an explicit call to retrieve those.
In this case, you likely need to invoke the function listTopicSharedAccessKeys.
You will want to call the function from within an Apply to make sure that it's triggered only after the topic is created (e.g., not during preview):
var keys = topic.Name.Apply(topicName => ListTopicSharedAccessKeys.InvokeAsync(
new ListTopicSharedAccessKeysArgs
{
ResourceGroupName = "rg-testapp-dev",
TopicName = topicName
}));
If you don't want to hardcode the resource group name:
let keys = pulumi.all([rg.name, topic.name]).apply(arr =>
azn.eventgrid.listTopicSharedAccessKeys(
{
resourceGroupName: arr[0],
topicName: arr[1]
}
)
);
keys.apply(x => pulumi.log.info(x.key1 ?? ""));

[Azure Deployments]: Can we filter Azure Resource Group Deployments by name using c#?

I am trying to fetch the Azure Resource Group Deployments by using filter where name starting with "Deploy" but can't find any documentation on the $filter.
I tried to do something like below:
try
{
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var resourceClient = new ResourcesManagementClient(subscriptionId, credentials);
var deployments = resourceClient.Deployments;
AsyncPageable<DeploymentExtended> rgDeployments = deployments.ListByResourceGroupAsync("myRG", "name eq 'Deploy-20210412184314'");
await foreach (DeploymentExtended deploymentProperties in rgDeployments)
{
Trace.WriteLine(deploymentProperties.Name);
}
}
catch(Exception e)
{
Trace.WriteLine(e.Message);
}
But it gives error saying -
{"error":{"code":"InvalidProvisioningStateFilter","message":"Invalid $filter 'name eq 'Deploy-20210412184314'' specified in the query string."}}
So can we only use filter like provisioningState eq '{state}' not for name?
I am using Azure Resources Management client library for .NET.
Please refer this documentation.
I am afraid you could not use the filter with name eq 'Deploy-20210412184314', in this case, if you already knew the name of the deployment and want to get it at the resource group scope, no need to use ListByResourceGroupAsync, just use this method DeploymentsOperations.GetAsync(String, String, CancellationToken), pass the resourceGroupName and deploymentName, you can simply get it.

Resources