Azure Lifecycle setting in BICEP delete/replace all the existing rules - azure

So I create following bicep based on https://learn.microsoft.com/en-us/azure/templates/microsoft.storage/2022-05-01/storageaccounts/managementpolicies?pivots=deployment-language-bicep.
It works fine and creates rule, however it deletes all the existing rules. Even they are more than one rule (all different names of course), it delete all the existing rules and replace it with one rule in the bicep script. What am I missing?
resource storage_lifecycle 'Microsoft.Storage/storageAccounts/managementPolicies#2022-05-01' = {
name: 'default'
parent:storageAccount
properties: {
policy: {
rules: [
{
name: 'lifeCycleRule'
enabled: true
type: 'Lifecycle'
definition: {
filters: {
blobTypes: [
'blockBlob'
]
}
actions: {
baseBlob: {
tierToCool: {
daysAfterModificationGreaterThan: 30
}
tierToArchive: {
daysAfterModificationGreaterThan: 30
}
delete: {
daysAfterModificationGreaterThan: 30
}
}
}
}
}
]
}
}
}

Based on this stack answer: Unable to add new rule in Storage Management Policy on Azure, and my experience with Azure API Gateway, you will need to add the existing rules to the new policy.

Related

Bicep - Unable to Create VM Snapshot Backup Policy for Azure Recovery Services Vault

I am trying to deploy a Recovery Services Vault as part of an infrastructure release using Bicep. I am having trouble deploying one backup policy in particular, a VM Snapshot backup policy (AzureIaaSVM).
I have followed the Bicep reference page for creating the template but it fails validation when trying to deploy.
I am using VSCode to develop and when I build an ARM template from the Bicep file, it fails validation with the following message:
If I have understood the documentation correctly, there should be more than just 'AzureStorage' being allowed here.
My question is, is this a tooling/API problem or have I misunderstood the documentation? If so, what would I have to alter to get this working?
The template:
resource vmSnapshotBackupPolicy 'Microsoft.RecoveryServices/vaults/backupPolicies#2022-03-01' = {
name: 'vm-snapshot-policy'
location: resourceLocation
parent: recoveryServicesVault
properties: {
protectedItemsCount: 0
backupManagementType: 'AzureIaasVM'
instantRPDetails: {
azureBackupRGNamePrefix: 'vmsnapshot'
}
instantRpRetentionRangeInDays: 2
policyType: 'V1'
retentionPolicy: {
retentionPolicyType: 'LongTermRetentionPolicy'
dailySchedule: {
retentionDuration: {
count: 7
durationType: 'Days'
}
retentionTimes: [
'2022-10-21T02:00:00Z'
]
}
monthlySchedule: {
retentionDuration: {
count: 6
durationType: 'Months'
}
retentionScheduleDaily: {
daysOfTheMonth: [
{
date: 1
isLast: false
}
]
}
retentionScheduleFormatType: 'Daily'
retentionTimes: [
'2022-10-21T02:00:00Z'
]
}
weeklySchedule: {
daysOfTheWeek: [
'Sunday'
]
retentionDuration: {
count: 4
durationType: 'Weeks'
}
retentionTimes: [
'2022-10-21T02:00:00Z'
]
}
yearlySchedule: {
monthsOfYear: [
'July'
]
retentionDuration: {
count: 2
durationType: 'Years'
}
retentionScheduleDaily: {
daysOfTheMonth: [
{
date: 1
isLast: false
}
]
}
retentionScheduleFormatType: 'Daily'
retentionTimes: [
'2022-10-21T02:00:00Z'
]
}
}
schedulePolicy: {
schedulePolicyType: 'SimpleSchedulePolicy'
scheduleRunFrequency: 'Daily'
scheduleRunTimes: [
'2022-10-21T02:00:00Z'
]
scheduleWeeklyFrequency: 0
}
timeZone: 'UTC'
}
}
It's a tooling problem, see: https://github.com/Azure/azure-quickstart-templates/blob/master/quickstarts/microsoft.recoveryservices/recovery-services-backup-vms/main.bicep for another example.
You can also add a comment here: https://github.com/Azure/bicep/issues/784 for the tooling issue.

Deploying ARM Template for an API Connection that uses OnPrem Data Gateway succeeds but the authType and gateway parameters are missing

I've been banging my head against a brick wall on this.
I'm trying to deploy via Azure DevOps pipeline, a bicep/ARM Template an API Connection that uses a Custom Connector that is linked to an On-prem API via a Data Gateway.
Here is my bicep file...
param connectionName string
param displayName string
param gatewayResourceGroup string
param gatewayName string
param connectorName string
param location string = resourceGroup().location
resource connector 'Microsoft.Web/customApis#2016-06-01' existing = {
name: connectorName
}
resource gatewayApi 'Microsoft.Web/connectionGateways#2016-06-01' existing = {
name: gatewayName
scope: resourceGroup(gatewayResourceGroup)
}
resource apiConnection 'Microsoft.Web/connections#2016-06-01' = {
name: connectionName
location: location
properties: {
displayName: displayName
nonSecretParameterValues: {
authType: 'anonymous'
#disable-next-line BCP036
gateway: {
name: gatewayName
id: gatewayApi.id
type: 'Microsoft.Web/connectionGateways'
}
}
api: {
name: connector.name
displayName: 'CONNECTOR ${connectorName}'
id: connector.id
type: 'Microsoft.Web/customApis'
}
}
}
I issue is the nonSecretParameterValues.
They don't go anywhere.
The API Connection is deployed like...
What makes this a little worse is the deployment is successful...
But if I drill into the Operation details I can see there were two issues...
"overallStatus": "Error",
"statuses": [
{
"status": "Error",
"target": "authType",
"error": {
"code": "ConfigurationNeeded",
"message": "Parameter value missing."
}
},
{
"status": "Error",
"target": "gateway",
"error": {
"code": "ConfigurationNeeded",
"message": "Parameter value missing."
}
}
],
Very frustrating.
Now I can manually add the values I intended to be there for the authType and gateway parameters after the deployment is "successful". Then my logic app that uses this API Connection and Custom Connector to Onprem Gateway works as expected.
But the exported template for the API Connection does not change between the connection having missing parameters (in the UI) or after I manually enter the values.
I have also tried added some Powershell after the deployment to pick up the connection and to try settings the "missing" values and updating the resource from there.
I can see another API Connection via Powershell which is correctly set with the authType and gateway parameters.
But when I try, to set these on the resource I need to "fix" it also complains...
I would really like to have the API Connection deployment fully via Azure DevOps pipeline.
NOTE: I find it very odd to have to use the #disable-next-line BCP036 to disable the warning in VSCode. And even opening the built ARM Template will give a warning on the "gateway" property name. I even tried replacing the "object" with just the resource id and that didn't help.
The parameters should be in a parameterValues property object:
resource apiConnection 'Microsoft.Web/connections#2016-06-01' = {
name: connectionName
location: location
properties: {
displayName: displayName
parameterValues: {
authType: 'anonymous'
gateway: {
id: gatewayApi.id
}
}
...
}
}
Suggestion:
The nonSecretParameterValues object must be in the format of a dictionary. I cannot find any hard documentation about this as a data structure, but it's mentioned several times.
nonSecretParameterValues: {
authType: 'anonymous'
gateway-name: gatewayName
gateway-id: gatewayApi.id
gateway-type: 'Microsoft.Web/connectionGateways'
}
Hope this helps.

Creating an Azure Queue action in a Logic App with bicep results in 'Connector not Found'

I try to create a Logic App with a Azure Queues Operation. I want to use a API connection resource to connect to the storage account. However
The API Connection resource and the Logic App itself are deployed without errors but after deployment the operation cannot find the API connection and the operation does not work.
When I manually create the operation in the portal after deployment it works.
Part of bicep for the action in logic app:
'Put_a_message_on_a_queue_(V2)' : {
runafter: {}
type: 'ApiConnection'
inputs: {
body: 'start'
host: {
connection: {
name: azureQueueConnectionId
}
}
method: 'post'
path: '/v2/storageAccounts/${storageAccountName}/queues/dailymaintenance/messages'
}
}
The API connection:
resource logicAppConnection 'Microsoft.Web/connections#2016-06-01' = {
name: name
location: resourceLocation
properties: {
displayName: 'connect-to-${externalResourceName}'
parameterValues: {
storageaccount: storageAccountReference.name
sharedkey: storageAccountReference.listKeys().keys[0].value
}
api: {
name: 'azurequeues'
displayName: 'Azure Queues'
description: 'Azure Queue storage provides cloud messaging between application components. Queue storage also supports managing asynchronous tasks and building process work flows.'
iconUri: 'https://connectoricons-prod.azureedge.net/releases/v1.0.1546/1.0.1546.2665/azurequeues/icon.png'
brandColor: '#0072C6'
id: '${subscription().id}/providers/Microsoft.Web/locations/${resourceLocation}/managedApis/azurequeues'
type: 'Microsoft.Web/locations/managedApis'
}
testLinks: [
{
requestUri: '${environment().resourceManager}/subscriptions/${subscription().id}/resourceGroups/${resourceGroup().name}/providers/Microsoft.Web/connections/${name}/extensions/proxy/testConnection?api-version=2016-06-01'
method: 'get'
}
]
}
}
output id string = logicAppConnection.id
This is de error I get in the Logic App Designer: "Connector not found"
I am wondering why this is not working as expected and if someone already managed to do this with bicep?
Thanks in advance
AFAIK, It is believed that if you deploy the Template, both API Connections will be created, but you will have to manually update the connection inside logic apps by adding your service credentials. This is because, in order to complete the API connection, you must provide consent, which is not available in the template.
This script will retrieve a consent link for an OAuth Logic Apps connector connection. The consent link will then be opened, and authorization will be completed to allow a connection to be established.
For more inforation please refer this blog|BICEP-Create API connections for Logic Apps & Deploy Logic Apps & API Connection with ARM
It turned out the API connection name must be set as follows to make this work
actions: {
'Put_a_message_on_a_queue_(V2)' : {
runafter: {}
type: 'ApiConnection'
inputs: {
body: 'start'
host: {
connection: {
name: '#parameters(\'$connections\')[\'azurequeues\'][\'connectionId\']'
}
}
method: 'post'
path: '/v2/storageAccounts/${storageAccountName}/queues/dailymaintenance/messages'
}
}
}
}
parameters: {
'$connections': {
value: {
azurequeues: {
connectionId: logicAppConnection.id
connectionName: 'LogicAppConnection'
id: '/subscriptions/xxxxxxxxxxx/providers/Microsoft.Web/locations/westeurope/managedApis/azurequeues'
}
}
}
}
After I deployed this, it worked!

Azure generate URL for a standard Logic app with connection to CosmosDB

I have a workflow in a standard logic app, that have HTTP trigger. When the workflow is trigged, the workflow, retrieve some data from a CosmosDB. Something like:
The previous method will require to have an API connection. I have already created and deployed a 'V2' API connection. Let's call it myCosmosCon
Also in the ARM template for my logic app I have already added a connectionRuntimeUrl of my connection API (to myCosmosCon) to appSettings (configuration):
....
"siteConfig": {
"appSettings": [
{
"name": "subscriptionId",
"value": "[subscription().subscriptionId]"
},
{
"name": "resourceGroup_name",
"value": "[resourceGroup().name]"
},
{
"name": "location_name",
"value": "[resourceGroup().location]"
},
{
"name": "connectionRuntimeUrl",
"value": "[reference(resourceId('Microsoft.Web/connections', parameters('connection_name')),'2016-06-01', 'full').properties.connectionRuntimeUrl]"
},
.....
]
},
Then I wrote the following in the connections.json:
{
"managedApiConnections": {
"documentdb": {
"api": {
"id": "/subscriptions/#appsetting('subscriptionId')/providers/Microsoft.Web/locations/#appsetting('location_name')/managedApis/documentdb"
},
"connection": {
"id": "/subscriptions/#appsetting('subscriptionId')/resourceGroups/#appsetting('resourceGroup_name')/providers/Microsoft.Web/connections/myCosmosCon"
},
"connectionRuntimeUrl": "#appsetting('connection_runtimeUrl')",
"authentication": {
"type": "ManagedServiceIdentity"
}
}
}
}
Now, when I deploy the ARM template of my Logic app, workflow, ... etc. I see no errors, the workflow looks also good. The only problem is the URL link to the HTTP trigger is not generated, I can't run the program.
However, if I change the connection_runtimeUrl in the connections.json file to have the actual value; to look something like:
"connectionRuntimeUrl": "https://xxxxxxxxxxxxx.xx.common.logic-norwayeast.azure-apihub.net/apim/myCosmosCon/xxxxxxxxxxxxxxxxxxxxxxxx/",
The URL is generated directly and I can simply run the workflow. AFTER that, if I return the connection_runtimeUrl as it was (a call to appsettings()), it still working!! the link also stay there.
It looks like the when I deploy the Logic app and the workflow that the connections.json, do not compile or make the call, so Azure think that there is an error and do not generate the link.
Any idea about how to solve the problem??
Thanks!
Not sure but could be the issue:
When you create a connection api for a logic app standard, you also need to create an access policy at the connection api level for the system assigned identity running the logic app standard.
param location string = resourceGroup().location
param cosmosDbAccountName string
param connectorName string = '${cosmosDbAccountName}-connector'
// The principalid of the logic app standard system assigned identity
param principalId string
// 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'
}
}
}
// Grant permission to the logic app standard to access the connection api
resource cosmosDbConnectorAccessPolicy 'Microsoft.Web/connections/accessPolicies#2016-06-01' = {
name: '${cosmosDbConnector.name}/${principalId}'
location: location
properties: {
principal: {
type: 'ActiveDirectory'
identity: {
tenantId: subscription().tenantId
objectId: principalId
}
}
}
}
output connectionRuntimeUrl string = reference(cosmosDbConnector.id, cosmosDbConnector.apiVersion, 'full').properties.connectionRuntimeUrl
I'm having trouble with the exact same issue/bug. The only work around as I see it is to deploy the workflow twice. First time with an actual URL pointing to a dummy connection and the second time with the appsetting reference.

Sync'ing ACL permissions in a NodeJS application using MongoDB

Currently using the Node ACL module from:
https://github.com/OptimalBits/node_acl
This is working a treat but now the requirement is have to reflect any changes to our security config in our ACL layer.
What Im looking for is a clean way to iterate over the roles defined in our security config, decide whether the permissions/resources have changed and if they have update or remove them.
Here is a sample security config file, take the scenario where 'put' is removed from the resource /projectId.
"roles":{
"itemRole":[
{
"roles":"owner-projectId",
"allows":[
{
"resources":"/projectId",
"permissions": ["put", "post", "patch","get","delete"]
},
{
"resources":"/projectId/settings",
"permissions": ["put"]
}
]
},
{
"roles":"collaborator-projectId",
"allows":[
{
"resources":"/itemId",
"permissions":["put","post", "patch","get"]
},
{
"resources":"/api/resource/itemId",
"permissions":["put", "post", "patch","get"]
}
]
},
{
"roles":"spectator-newId",
"allows":[ ]
},
{
"roles":"admin-newId",
"allows":[
{
"resources":"/api/resource/itemId/update",
"permissions":[ "put"]
}
]
}
]
}
The following query will allow me iterate over the different roles and return all the allows for that resources, these allow_* should match what is currently in the security.config:
db.getCollection('authACLresources').find( { _bucketname: {"$regex":"allows_*"}, key: { '$in': [ 'spectator-2bc240c6ffa988260b501922' ] }})
I can then look at the different permissions and compare - just wondering if there is a better way to do this? I know the node ACL module has a method called whatResources but doesn't give you the permissions just the resources.

Resources