How to link my workbook resource with another resource - azure

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?

Related

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
}
}

Create Azure Connection API with Connection Runtime Url

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

How to specify 4 connection strings in azurerm_app_service resource block

I have a module defined in our enterprise for creating App Service Plan along with Azure Web Apps. But now i would like to use the "azurerm_app_service" resource block as mentioned in the link : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/app_service
In our module the connection strings are defined under the argument :
app_settings = {
AzureAd__ClientSecret = <Connection String of the App SP stored in Azure KV>
DbConnection__ConnectionString = <Azure SQL DB Connection String stored in Azure KV>
CosmosDb__Account = <Connection String of the Cosmos DB Account stored in Azure KV>
CosmosDb__Key = <Connection String of the Cosmos DB Account Key stored in Azure KV>
}
Now in the resource block for "azurerm_app_service" as per the URL above there is an argument called connection_string as shown in the URL :
connection_string {
name = "Database"
type = "SQLServer"
value = "Server=some-server.mydomain.com;Integrated Security=SSPI"
}
So i would like to know as to how i can define my 4 connection strings in the resource block against the "connection_string" argument and what are the types i should choose for each of my connection strings?
Will it be ok if i continue to define my connection strings as they are in the module now under "app_settings", or that will be a problem if i do that in the new resource block structure?
Looking for some help on this
For your requirement, you can use the dynamic block to define the multiple connection_string in the azurerm_app_service resource block. The example code here for you:
resource "azurerm_app_service" "webapp" {
...
dynamic "connection_string" {
for_each = var.connection_strings
content {
name = each.value.name
type = each.value.type
value = each.value.value
}
}
...
}
So you see, you'd better use a variable to configure all the necessary things of the connection_strings, and then use it in the dynamic block.

COS access policies interface vs terraform

In interface I can go to COS Bucket Access Policies and easily assign policy that then looks more or less like:
Cloud Object Storage service
serviceInstance string equals foo-bar, resource string equals foo-bar-pcaps, resourceType string equals bucket
I'm struggling to find a way to do the same via terraform because whenever I try with the proper TF code like:
resource "ibm_iam_service_policy" "policy_pcaps" {
iam_service_id = ibm_iam_service_id.serviceID_pcaps.id
roles = ["Writer"]
resources {
service = "cloud-object-storage"
resource = ibm_cos_bucket.pcaps.id
}
}
I'm ending up with
Cloud Object Storage service
resource string equals crn:v1:bluemix:public:cloud-object-storage:global:a/27beaaea79a<redacted>34dd871b:8b124bc6-147c-47ba-bd47-<redacted>:bucket:foo-bar-pcaps:meta:rl:us-east
The problem is that the Writer policy that is required here does not work properly with that policy details.
How to achieve something similar to the first policy with Terraform?
Thanks
You can achieve this similar to this example Service Policy by using attributes.
I created a policy through the UI for Cloud Object Storage and specified the policy to contain a bucket name. Then I used:
ibmcloud iam access-group-policy GROUP_NAME POLICY_ID --output JSON
to get a better understanding of the policy.
With that I created this sample terraform snippet and tested it. It is creating the IAM access group + policy:
resource "ibm_iam_access_group" "accgrp_cos" {
name = "test_cos"
}
resource "ibm_iam_access_group_policy" "policy" {
access_group_id = ibm_iam_access_group.accgrp_cos.id
roles = ["Writer"]
resources {
service = "cloud-object-storage"
attributes = {
resourceType = "bucket"
resource = "tf-test-cos"
}
}
}

Pulumi is creating an azure resource group with a different name

Why Pulumi is not creating a resource group with the name I gave?
Here is my small script
const azure = require("#pulumi/azure")
const resourceGroupName = new azure.core.ResourceGroup("test-pulumi", {
location: "francecentral",
});
The name of the resource group is: test-pulumi83d54581
The name parameter that you give is your component's name, not the full name of the resource to be created. By default, Pulumi appends a suffix to all names to avoid name collision e.g. across multiple stacks.
To specify the name explicitly, pass it as options parameter:
const resourceGroupName = new azure.core.ResourceGroup("test-pulumi", {
name: "test-pulumi",
location: "francecentral",
});
That's a bit verbose, and we might get an option to disable name suffixes - see this issue for progress.

Resources