Get Log Analytics Workspace key from Bicep - azure

In a bicep file for an App Service, I want to grab the id and key from an existing Log Analytic Workbench, created in another repo/bicep file.
I see this is possible in Terraform, but cannot find any docs on how to achieve this with Bicep, which seems a bit odd.
What I thought should be possible would be something like this;
// Refer to existing Log Analytics Workbench
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces#2022-10-01' existing = {
name: logAnalyticsWorkspaceName
}
and then doing something like;
logAnalyticsWorkspace.properties.keys.primary_shared_key
Any tips?

you would need to use the listKeys function:
// Get a reference to the existing log analytics workspace
resource logAnalyticWorkspace 'Microsoft.OperationalInsights/workspaces#2021-06-01' existing = {
name: logAnalyticWorkspaceName
}
var primaryKey = listKeys(logAnalyticWorkspace.id, logAnalyticWorkspace.apiVersion).primarySharedKey

Related

Bicep - create credentials for Managed Identity for use in LinkedService

I am attempting to re-create an Azure Data Factory using Bicep, and specifically i am trying to user a User Assigned Managed Identity for a linked service to an Azure SQL Database.
I am able to create the ua MI by doing the following -
resource uami 'Microsoft.ManagedIdentity/userAssignedIdentities#2018-11-30' = {
name: uamiName
location: location
}
This gets successfully attached to the data factory upon build.
Next i am trying to associate that UA MI to the database connection i am making in the Linked Services section. In the front end its like selected 'User Assigned Managed Identity' and selecting the creds ( or create new). I am trying to do this via Bicep and In order to do this, i first needs credentials - I can't find anywhere in Bicep to create these credentials.
I see lots of old references to Microsoft.DataFactory/factories/credentials - but i can't seem to find that.
Appreciate any help that anyone can offer.
I haven't found much documentation neither.
I've created a credential from data factory studio then export the ARM template. The bicep equivalent looks like that:
param location string
param uamiName string
param dataFactoryName string
// Create the managed identity
resource uami 'Microsoft.ManagedIdentity/userAssignedIdentities#2022-01-31-preview' = {
name: uamiName
location: location
}
// assuming the data factory already exists
resource dataFactory 'Microsoft.DataFactory/factories#2018-06-01' existing = {
name: dataFactoryName
}
// Create the credentials
resource credentials 'Microsoft.DataFactory/factories/credentials#2018-06-01' = {
name: uami.name
parent: dataFactory
properties: {
type: 'ManagedIdentity'
typeProperties: {
resourceId: uami.id
}
}
}

How to get Azure App Configuration feature flag value list in bicep template

I would like to get list of already created feature flags from Azure App Configuration in bicep template. I want to pass it to separate bicep file that will use union function on existing and new feature flags to not override already existing ones.
Simillar thing I'm already using for Web App and list() function get existing app settings:
module appConfig './webappsettings.bicep' = {
name: '${deployment().name}-appSettings'
params: {
webAppName: webapp.name
currentAppSettings: list('${webapp.id}/config/appsettings', '2021-03-01').properties
appSettings: allSettings
}
}
How can I achieve something similar for Azure App Configuration to get key values of feature flags?
I tried with below solution but I only got key values of App Configuration
resource configurationStore 'Microsoft.AppConfiguration/configurationStores#2021-10-01-preview' existing = {
name: 'appcfg'
}
module configStoreKeyValues 'inner.bicep' = {
name: 'config-store'
params: {
existingKeyValues: configurationStore.listKeys().value
keyValues: keyValues
contentType: contentType
}
}
using same list() function or listKeys()
list('${configurationStore.id}/keyValues','2021-10-01-preview').properties
I'm getting an error:
Status Message: The resource namespace 'subscriptions' is invalid. (Code:InvalidResourceNamespace)
The "List" operation of key-values is not supported by the control-plane REST API in App Configuration. The listKeys API you used above returns the "Access keys", not the key-value configuration data you are looking for. You can create/update/read individual key-value, feature flag, Key Vault reference as KeyValues resource using Bicep. Feature flag is a special key-value with certain key prefix and content type. Below is an example of feature flag using the ARM template, but it should give you an idea of how to do the same in Bicep.
https://azure.microsoft.com/resources/templates/app-configuration-store-ff/
Note that the "List" operation of key-values is supported in the data-plane REST API of App Configuration. Besides the REST API, it's also accessible via Azure CLI, Azure portal, and App Configuration SDKs programmatically.

How can I adapt an existing resource with Azure Bicep?

I'm currently porting some infrastructure as code scripts from Azure CLI to Azure Bicep. Among many other things, the Bicep files should create a subnet and allow access from this subnet to an existing Azure SQL Server and an existing Storage Account.
For the SQL Server, this is simple - I can reference the existing server resource and declare a child resource representing the VNET rule:
resource azureSqlServer 'Microsoft.Sql/servers#2021-05-01-preview' existing = {
name: azureSqlServerName
resource vnetRule 'virtualNetworkRules' = {
name: azureSqlServerVnetRuleName
properties: {
virtualNetworkSubnetId: subnetId
}
}
}
However, with the Storage Account, the network rules are not child resources, but a property of the Storage Account resource (properties.networkAcls.virtualNetworkRules). I cannot declare all the details of the Storage Account in my Bicep file because that resource is way out of scope from the deployment I'm currently working on. In essence, I want to adapt the existing resource, just ensuring a single rule is present.
The following does not work because existing cannot be combined with properties:
resource storageAccount 'Microsoft.Storage/storageAccounts#2021-06-01' existing = {
name: storageAccountName
properties: {
networkAcls: {
virtualNetworkRules: [
{
id: subnetId
action: 'Allow'
}
]
}
}
}
Is there any way I can adapt just a tiny bit of an existing resource using Bicep?
UPDATE: I just realized you came from Azure CLI and was trying to find a way in bicep - sorry for not answering your actual question - anyway your post made me think about this in another way other than bicep, so my "answer" is what I came up with...
...sounds like we thought about this in the same manner; using bicep to pimp an existing Storage Account, granting a new subnet access. However I ended up using AzureCLI az storage account network-rule add
e.g.
newSubnet='/subscriptions/<subscr-guid>/resourceGroups/<rg-name-where-vnet-resides>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<subnet-name>'
az storage account network-rule add -g <rg-name-where-sa-resides> --account-name <storage-account-name> --subnet $newSubnet
run this from a terminal or put it in an AzureCLI task in a devops pipeline (which is what I needed)
The existing keyword in bicep is used to tell bicep that the resource already exists and you just want a symbolic reference to that resource in the code. If the resource doesn't exist it's likely that the the deployment will fail in some way.
Your first snippet is equivalent to:
resource vnetRule 'Microsoft.Sql/servers/virtualNetworkRules#2021-05-01-preview' = {
name: '${azureSqlServerName}/${azureSqlServerVnetRuleName}'
properties: {
virtualNetworkSubnetId: subnetId
}
}
In your second snippet since you want to update properties you have to provide the complete declaration of the resource, IOW you have to define and deploy the storageAccount. This isn't unique to bicep, it's the way the declarative model in Azure works.
That said, if you want to deploy to another scope in bicep, you can use a module with the scope property. E.g.
module updateStorage 'storage.bicep' = {
scope: resourceGroup(storageResourceGroupName)
name: 'updateStorage'
}
The downside is that you need to make sure you define/declare all the properties need for that storageAccount which is not ideal. There are some ways you can author around that, but if the storageAccount doesn't exist, the deployment is guaranteed to fail. For example, you could assert the storageAccount exists, fetch its properties and then union or modify the properties in the module. You might be able to make that work (depending on the extent of your changes) but it's a bit of an anti-pattern in a declarative model.
That help?

Access Azure Function App system keys in Terraform

I want to create Azure EventGrid subscription using Terraform.
resource "azurerm_eventgrid_system_topic_event_subscription" "function_app" {
name = "RunOnBlobUploaded"
system_topic = azurerm_eventgrid_system_topic.function_app.name
resource_group_name = azurerm_resource_group.rg.name
included_event_types = [
"Microsoft.Storage.BlobCreated"
]
subject_filter {
subject_begins_with = "/blobServices/default/containers/input"
}
webhook_endpoint {
url = "https://thumbnail-generator-function-app.azurewebsites.net/runtime/webhooks/blobs?functionName=Create-Thumbnail&code=<BLOB-EXTENSION-KEY>"
}
}
By following this doc, I successfully deployed it and it works. However, the webhook_endpoint URL needs <BLOB-EXTENSION-KEY> which is hardcoded right now and found from the following place in the portal:
In order to not commit a secret to GitHub, I want to get this value by reference, ideally using Terraform.
According to my research, it seems there is no way in Terraform to reference that value.
The closest one is this data source azurerm_function_app_host_keys in Terraform. However, it doesn't cover the blobs_extension key!
Is there any good way to reference blobs_extension in Terraform without a hardcoded value?
Thanks in advance!
If TF does not support it yet, you can create your own External Data Source which is going to use azure cli or sdk to get the value you want, and return it to your TF for further use.

Initialization logic of a Azure ARM solution template without VM resource

Is it possible to have an ARM solution template (createUiDefinition.json, azuredeploy.json, etc) published to Azure Marketplace, which have an App Service and a CosmosDB account resources but does not has any VM resources to have initialization logic (e.g. creation of CosmosDB database, collections) which executes once solution template is deployed.
In case if solution template contained VM, then it would be possible to use a Custom Script Extension, but is there a way without VMs?
I'm not sure what are you exactly after, but we are using Azure Function as a part of an arm template to configure cosmosDb. here is how it works:
"uri": "[concat('https://functionUrl?param1=', parameters('cosmosName'), '&param2=', listKeys(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('cosmosName')), '2016-03-31').primaryMasterKey, '&code=', parameters('functionKey'))]"
this will call Azure Function and give it the cosmosDb name and key and you can use that in your Azure Function to connect to cosmosDb and configure it. the only caveat is your function should return empty template (or not empty, just parseable by the engine).
var template = #"{'$schema': 'https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#', 'contentVersion': '1.0.0.0', 'parameters': {}, 'variables': {}, 'resources': []}";
HttpResponseMessage myResponse = req.CreateResponse(HttpStatusCode.OK);
myResponse.Content = new StringContent(template, System.Text.Encoding.UTF8, "application/json");
return myResponse;

Resources