How to "dependsOn" all copies of a resource? - azure-resource-manager

How can I set up a dependsOn to depend on all copies of a certain resource? Hypothetically, I deploy 0..N number of websites and I need them all to complete before I deploy my traffic manager because the TM needs resource IDs.
Currently I'm only deploying 2 and so I'm just enumerating two items in the dependsOn array, but if I decide I want to deploy more copies (as determined by
[variables('tdfConfiguration')] array), it would be nice for dependsOn to dynamically figure this out.
"apiVersion": "[variables('apiVersion')]",
"type": "Microsoft.Resources/deployments",
"name": "[concat(resourceGroup().name, '-', variables('tdfConfiguration')[0]['roleName'], '-tmprofile')]",
"dependsOn": [
"[concat(resourceGroup().Name, '-', variables('tdfConfiguration')[0]['roleName'], '-website')]",
"[concat(resourceGroup().Name, '-', variables('tdfConfiguration')[1]['roleName'], '-website')]"
],

fairly easy, use copy name. suppose you have a resource like so:
"name": xxx,
"type": zzz,
...
"copy": {
"name": "myCopy",
"count": 0..N
}
you can use the followin dependsOn to depend on all copies:
"dependsOn": [ "myCopy" ]
Reading: https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-multiple#depend-on-resources-in-a-loop

Related

Airflow ECS Register Task Operator, error when passing env. variables

when I am trying to pass env. variables to my ECSRegisterTaskOperator, I get the following error:
Unknown parameter in input: "environment", must be one of: family, taskRoleArn, executionRoleArn, networkMode, containerDefinitions, volumes, placementConstraints, requiresCompatibilities, cpu, memory, tags, pidMode, ipcMode
However according to the documentation for boto3 with Ecs, one has to pass env variables via the environment dictionary.
[reference: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.register_task_definition ]
The part of my task looks like this:
register_task_kwargs={
"cpu": "256",
"memory": "512",
"networkMode": "awsvpc",
"environment": [
{
"name": "REDSHIFT_HOST",
"value": redshift_cluster_test_connection.host
},
{
"name": "REDSHIFT_USER",
"value": "redshift_cluster_test_connection.user"
},
{ "name": "REDSHIFT_PW",
"value": redshift_cluster_test_connection.password}
]
The environment settings go inside the containerDefinitions. You have them at the top level, instead of inside the containerDefinitions.

Can't get the desired properties via JsonPath evaluate method

I have a json schema that marks special properties in need of processing and I want to query those via JsonPath.Evaluate.
Here's a part of the schema to illustrate the issue
{
"type": "object",
"properties": {
"period": {
"description": "The period in which the rule applies",
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time"
},
"end": {
"type": "string",
"format": "date-time"
}
},
"required": [
"start"
],
"x-updateIndicatorProperties": [
"start"
]
},
"productType": {
"type": "string"
},
"x-updateIndicatorProperties": [
"productType"
]
}
}
I want to get the the JsonPath of the "x-updateIndicatorProperties" properties, so that I can then query the actual properties to process.
For this example, the expected result would be
[
"$['properties']['x-updateIndicatorProperties']",
"$['properties']['period']['x-updateIndicatorProperties']"
]
I've been trying for a while to get a JsonPath expression that would query these properties.
Currently I'm just iterating all properties and filter them manually :
"$..*"
I've also tried using :
$..['x-updateIndicatorProperties']
This works. But it returns a lot of duplicates. For the example above, I get 5 results instead of the expected 2. Can be demonstrated here : https://json-everything.net/json-path
Assuming I can't influence the schema itself, only the code that traverses it,
can anybody help with an expression to get the expected results or any other way to achieve the same outcome?
The stack is JsonPath 0.2.0, .net 6 and system.text.json.
This was a bug in the library when parsing paths that use a recursive descent (..) into a quoted-property-name selector (['foo']). So it would happen for any path in the form $..['foo'].
I've fixed the issue and released version 0.2.1.

Apply an Azure Policy to a management group using ARM

Goal: Deploy an Azure Policy to a management group so when certain tags are missing from a resource within its remit, apply the specified Tag from the resource group
Problem: Deploying this template to the management group results in "'The template function 'RESOURCEGROUP' is not expected at this location."
There is a fairly plain structure similar to:
<Management Group> - <Subscription 1> - <Resource Group 1> - <Resource A>
- <Resource Group 2> - <Resource B>
- <Subscription 2> - <Resource Group 3> - <Resource C>
- <Resource D>
There is a fairly simple template using a nested policy definition:
......
"resources": [
{
"type": "Microsoft.Authorization/policyDefinitions",
"apiVersion": "2019-09-01",
"name": ".",
"properties": {
"policyType": "Custom",
"mode": "Indexed",
"displayName": ".",
"description": ".",
"metadata": {
"category": "Tags"
},
"policyRule": {
"if": {
"anyOf": [
{
"field": "tags['costCenter']",
"exists": "false"
},
{
"field": "tags['CostCenter']",
"notin": "[parameters('allowedCostCenter')]"
}
]
},
"then": {
"effect": "modify",
"details": {
"roleDefinitionIds": [
"/providers/Microsoft.Authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f"
],
"operations": [
{
"operation": "add",
"field": "tags['CostCenter']",
"value": "[resourcegroup().tags['CostCenter']]"
}
]
}
}
}
}
}
]
I realise that you can not use "resourcegroup()" on items that are not within a resource group, but the guides suggested using this within the nested template and on "indexed" resources should work.
I'm fairly sure the pipeline is correct as I already have several audit policies deploying
From experimenting in the portal, this looks like it should be possible
There is a decent amount of reading around, but I have not read (or at least understood) that seems to help with this
Is what I am trying to achieve possible? If so, can you see what I am doing wrong?
Thanks for your help!
You need to add escape character if you want resourcegroup() function to be executed as a part of the Azure Policy, not the MG-scope ARM template:
"value": "[[resourcegroup().tags['CostCenter']]"

How to I prevent Microsoft.Automation/automationAccounts/Compilationjobs to always run in ARM deployment?

My ARM template is below which is nested template in bigger ARM template. For some reason DSC Compilation job always run on each deployment. I expected it not be run if it was already run before. How do I control this behavior? I tried using "incrementNodeConfigurationBuild": "false" but it did not do the trick.
{
"name": "WorkerNodeDscConfiguration",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"resourceGroup": "[parameters('automationAccountRGName')]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"resources": [
{
"apiversion": "2015-10-31",
"location": "[reference(variables('automationAccountResourceId'), '2018-01-15','Full').location]",
"name": "[parameters('automationAccountName')]",
"type": "Microsoft.Automation/automationAccounts",
"properties": {
"sku": {
"name": "Basic"
}
},
"tags": {},
"resources": [
{
"name": "workernode",
"type": "configurations",
"apiVersion": "2018-01-15",
"location": "[reference(variables('automationAccountResourceId'), '2018-01-15','Full').location]",
"dependsOn": [
"[concat('Microsoft.Automation/automationAccounts/', parameters('AutomationAccountName'))]"
],
"properties": {
"state": "Published",
"overwrite": "false",
"incrementNodeConfigurationBuild": "false",
"Source": {
"Version": "1.2",
"type": "uri",
"value": "[parameters('WorkerNodeDSCConfigURL')]"
}
}
},
{
"name": "[guid(resourceGroup().id, deployment().name)]",
"type": "Compilationjobs",
"apiVersion": "2018-01-15",
"tags": {},
"dependsOn": [
"[concat('Microsoft.Automation/automationAccounts/', parameters('AutomationAccountName'))]",
"[concat('Microsoft.Automation/automationAccounts/', parameters('AutomationAccountName'),'/Configurations/workernode')]"
],
"properties": {
"configuration": {
"name": "workernode"
},
"incrementNodeConfigurationBuild": "false",
"parameters": {
"WebServerContentURL": "[parameters('WebServerContentURL')]"
}
}
}
]
}
]
}
}
}
In short, AFAIK you should be able to control this behaviour with 'condition'.
To explain it in detail, the DSC compilation jobs resource always run on each deployment because when we use the DSC compilation jobs resource (i.e., Microsoft.Automation/automationAccounts/compilationjobs) in the ARM template, IMHO what it does in the behind is, basically clicks on 'Compile' button of the DSC configuration.
If you click on that 'Compile' button, the compilation of job happens for sure even if it already compiled the job. You may check the same part manually as well.
So AFAIK that was the reason for compilation job always running on each deployment.
What you could do is, update your ARM template with 'condition' (For more information, refer https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-templates-resources#condition and https://learn.microsoft.com/en-us/azure/architecture/building-blocks/extending-templates/conditional-deploy) and then wrap your template with below sample piece of PowerShell code that would determine if the Compilation of job for particular DSC configuration is done already and then deploy the template by passing inline parameter value or by updating condition parameter in parameters template file with new or existing value accordingly. (For more information, refer https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-deploy#pass-parameter-values)
$DscCompilationJob = Get-AzAutomationDscCompilationJob -AutomationAccountName AUTOMATIONACCOUNTNAME -ResourceGroupName RESOURCEGROUPNAME|Sort-Object -Descending -Property CreationTime|Select -First 1| Select Status
$DscCompilationJobStatus = $DscCompilationJob.Status
if ($DscCompilationJobStatus -ne "Completed"){
$DscCompilationJobStatusInlineParameter = "new"
New-AzResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName testgroup -TemplateFile TEMPLATEFILEPATH\demotemplate.json -exampleString $DscCompilationJobStatusInlineParameter
#or update condition parameter in parameters template file with new value accordingly and use below command to deploy the template
New-AzResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName ExampleResourceGroup -TemplateFile TEMPLATEFILEPATH\demotemplate.json -TemplateParameterFile TEMPLATEFILEPATH\demotemplate.parameters.json
}else{
$DscCompilationJobStatusInlineParameter = "existing"
New-AzResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName testgroup -TemplateFile TEMPLATEFILEPATH\demotemplate.json -exampleString $DscCompilationJobStatusInlineParameter
#or update condition parameter in parameters template file with existing value accordingly and use below command to deploy the template
New-AzResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName ExampleResourceGroup -TemplateFile TEMPLATEFILEPATH\demotemplate.json -TemplateParameterFile TEMPLATEFILEPATH\demotemplate.parameters.json
}
And regarding incrementNodeConfigurationBuild property, IMHO this property is just with regards to creation of a new build version of Node Configuration is required or not i.e., when incremental node configuration build is set to false, it does not override the earlier existing Node Configuration by creating a new Node Configuration with the name CONFIGNAME[<2>] (the version number is incremented based on the existing version number already present).
Hope this helps!! Cheers!! :)

Query regarding Artifactory APIs

I am trying to integrate with Artifactory using rest APIs and to do that need to be able to do the following:
Give a filter list of repositories based on tool type e.g I will like to only get repositories which are either nuget or npm based. I tried using https://user.jfrog.io/user/api/repositories but it doesn't return the type of repository so i cannot filter the list. I see that https://user.jfrog.io/user/api/storageinfo returns repositoriesSummaryList which includes the package type of repositories. Is it ok to use this APIs for getting the list of repositories and filtering?
Given a repository I want to get list of packages in that repository. The only way i could find out for this was making a POST call to https://user.jfrog.io/user/api/search/aql with the body
items.find(
{
"repo":{"$eq":"myawesome-remotenugetrepo-cache"}
}
)
Is there any way to get this information using a GET call instead of POST?
In Artifactory different versions of same package are treated as different packages For Example: For the Query in 2 the result is something like this:
[
{
"repo": "myawesome-remotenugetrepo-cache",
"path": ".",
"name": "bootstrap.3.3.2.nupkg",
"type": "file",
"size": 264693,
"created": "2016-05-27T16:07:12.138Z",
"created_by": "admin",
"modified": "2015-12-03T12:57:47.000Z",
"modified_by": "admin",
"updated": "2016-05-27T16:07:12.166Z"
},
{
"repo": "myawesome-remotenugetrepo-cache",
"path": ".",
"name": "bootstrap.3.3.6.nupkg",
"type": "file",
"size": 290372,
"created": "2016-05-27T10:55:47.576Z",
"created_by": "admin",
"modified": "2015-12-03T12:57:48.000Z",
"modified_by": "admin",
"updated": "2016-05-27T10:55:47.613Z"
},
{
"repo": "myawesome-remotenugetrepo-cache",
"path": ".",
"name": "jQuery.1.9.1.nupkg",
"type": "file",
"size": 240271,
"created": "2016-05-27T10:55:43.895Z",
"created_by": "admin",
"modified": "2015-12-07T15:58:51.000Z",
"modified_by": "admin",
"updated": "2016-05-27T10:55:43.930Z"
}
]
As you can see the result includes entries for both versions of bootstrap 3.3.2 and 3.3.6. What I hoped was that the list of packages will just include bootstrap and jQuery, Is there anyway to get this list?
Also give the package bootstrap is there any way to query for different versions of it?
Yes.
You can use the Folder Info GET request.
There are two questions there :)
Not really. You'll probably have to write a simple script to group by the common part of the artifact name.
You can get information about the version of the artifact once you have a repository layout set up. Then you can use queries like Artifact Version Search.

Resources