ARM KeyVault Access Policies Conditional Add - azure-keyvault

Is it possible to add an access policy via a conditional statement? Basically, if environment == production I don't want to add the registration.
I have the following in my template however I don't want the application called foobarApplicationId to be added if the environment is production. Can I do this inline or do I need a seperate template? Will setting foobarApplicationId to be an empty string work?
{
"name": "[variables('keyVault-name')]",
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2016-10-01",
"location": "[resourceGroup().location]",
"properties": {
"tenantId": "[subscription().tenantId]",
"sku": {
"family": "A",
"name": "standard"
},
"accessPolicies": [
{
"tenantId": "[subscription().tenantId]",
"objectId": "[parameters('keyVaultOwner')]",
"permissions": {
"keys": [
"all"
],
"secrets": [
"all"
],
"certificates": [
"all"
],
"storage": [
]
}
},
{
"tenantId": "[subscription().tenantId]",
"objectId": "[parameters('foobarApplicationId')]",
"permissions": {
"keys": [
"get",
"wrapKey",
"unwrapKey",
"sign",
"verify",
"list"
],
"secrets": [
"get",
"list"
],
"certificates": [
"get",
"list"
],
"storage": [
]
}
},

"condition" within "accessPolicies" doesn't seem to have any effect for me. It doesn't cause any validation or deployment error, but the access policies got added even when the condition evaluated to false.
I found the following trick works better: Use an if clause for your "objectId" and "permissions", such that if the condition is false, you would assign an empty set of permissions to the empty GUID, effectively becoming a no-op.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"variables": {
"keyVaultNoPermissions": { },
"keyVaultAppReadPermissions": {
"keys": [ "get", "wrapKey", "unwrapKey", "sign", "verify", "list" ],
"secrets": [ "get", "list" ],
"certificates": [ "get", "list" ]
}
},
"resources": [
// ...
{
"type": "Microsoft.KeyVault/vaults/accessPolicies",
"apiVersion": "2016-10-01",
"name": "[concat(parameters('keyVaultName'), '/add')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[parameters('keyVaultName')]"
],
"properties": {
"accessPolicies": [
{
"tenantId": "[subscription().tenantId]",
"objectId": "[if(not(equals(parameters('environment'), 'PROD')), parameters('foobarApplicationId'), '00000000-0000-0000-0000-000000000000')]",
"permissions": "[if(not(equals(parameters('environment'), 'PROD')), variables('keyVaultAppReadPermissions'), variables('keyVaultNoPermissions'))]"
}
]
}
}
]
}

It would be in the individual access policy adding a condition section that will take an environment parameter like:
{
"condition": "[not(equals(parameters('environment'),'PROD'))]"
"tenantId": "[subscription().tenantId]",
"objectId": "[parameters('foobarApplicationId')]",
"permissions": {
"keys": [
"get",
"wrapKey",
"unwrapKey",
"sign",
"verify",
"list"
],
"secrets": [
"get",
"list"
],
"certificates": [
"get",
"list"
],
"storage": [
]
}
}

Add the access policies separately, conditionally. You can see an explanation here.
{
"resources": [{
"name": "[variables('keyVault-name')]",
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2016-10-01",
"location": "[resourceGroup().location]",
"properties": {
"tenantId": "[subscription().tenantId]",
"sku": {
"family": "A",
"name": "standard"
},
"accessPolicies": [{
"tenantId": "[subscription().tenantId]",
"objectId": "[parameters('keyVaultOwner')]",
"permissions": {
"keys": [
"all"
],
"secrets": [
"all"
],
"certificates": [
"all"
],
"storage": [
]
}
}
]
}
}, {
"name": "[concat(variables('keyVault-name'), '/add')]",
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2016-10-01",
"condition": "[not(startsWith(parameters('environmentName'), 'PROD'))]",
"location": "[resourceGroup().location]",
"properties": {
"tenantId": "[subscription().tenantId]",
"sku": {
"family": "A",
"name": "standard"
},
"accessPolicies": [{
"tenantId": "[subscription().tenantId]",
"objectId": "[parameters('foobarApplicationId')]",
"permissions": {
"keys": [
"get",
"wrapKey",
"unwrapKey",
"sign",
"verify",
"list"
],
"secrets": [
"get",
"list"
],
"certificates": [
"get",
"list"
],
"storage": [
]
}
}
]
}
}
]
}

Related

Add multiple access policy in Key Vault for different resource group object id

I am trying to add multiple access policy in key vault for 2 object ids. One of them which belongs to same resource group as key vault and another belongs to a different resource group.
"resources": [
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2021-11-01-preview",
"name": "[parameters('vaultName')]",
"location": "[resourcegroup().location]",
"properties": {
"sku": {
"family": "A",
"name": "standard"
},
"tenantId": "[subscription().tenantId]",
"accessPolicies": [
{
"tenantId": "[reference(concat('Microsoft.Web/sites/', variables('functionName'), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').tenantId]",
"objectId": "[reference(concat('Microsoft.Web/sites/', variables('functionName'), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId]",
"permissions": {
"secrets": [
"get",
"list"
]
}
},
{
"tenantId": "[reference(concat('Microsoft.Web/sites/', variables('functionNameAnotherRg'), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').tenantId]",
"objectId": "[reference(concat('Microsoft.Web/sites/', variables('functionNameAnotherRg'), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId]",
"permissions": {
"secrets": [
"get",
"list"
]
}
}
],
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": true,
"enableSoftDelete": true,
"softDeleteRetentionInDays": 90
}
}
]
I am getting error as application does not found in resource group. Can someone please help
Found the solution. We need to specify resource group name in order to grant access to another application belongs to another resource group.
{
"tenantId": "[reference(resourceId(parameters('AnotherResourceGroup'),'Microsoft.Web/sites', parameters('FunName')), '2021-03-01', 'Full').identity.tenantId]",
"objectId": "[reference(resourceId(parameters('AnotherResourceGroup'),'Microsoft.Web/sites', parameters('FunName')), '2021-03-01', 'Full').identity.principalId]",
"permissions": { "secrets": [ "Get", "list" ] }
}

how can JAVA_OPTIONS added in deployconfig in OpenshiftContainer

I am trying to add below JAVA_OPTIONS in deployconfig in OpenshiftContainer but is throwing syntax error .Could anyone help me how to add parameters in OpenshiftContainer please
JAVA_OPTIONS
-Djavax.net.ssl.trustStore={KEYSTORE_PATH}/cacerts.ts,
-Djavax.net.ssl.trustStorePassword=changeit,
Djavax.net.ssl.keyStore=${KEYSTORE_PATH}/keystore.pkcs12-Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASS}
-Djava.awt.headless=true,
deploymentConfig as json:
{
"apiVersion": "apps.openshift.io/v1",
"kind": "DeploymentConfig",
"metadata": {
"labels": {
"app": "${APP_NAME}"
},
"name": "${APP_NAME}"
},
"spec": {
"replicas": 1,
"selector": {
"app": "${APP_NAME}",
"deploymentconfig": "${APP_NAME}"
},
"strategy": null,
"template": {
"metadata": {
"labels": {
"app": "${APP_NAME}",
"deploymentconfig": "${APP_NAME}"
}
},
"spec": {
"containers": [
{
"env": [
{
"name": "SPRING_PROFILE",
"value": "migration"
},
{
"name": "JAVA_MAIN_CLASS",
"value": "com.agcs.Application"
},
{
"name": "JAVA_OPTIONS",
"value":"-Djavax.net.ssl.trustStore={KEYSTORE_PATH}/cacerts.ts",
"-Djavax.net.ssl.trustStorePassword=changeit",
-Djavax.net.ssl.keyStore=${KEYSTORE_PATH}/keystore.pkcs12
-Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASS}
-Djava.awt.headless=true,
},
{
"name": "MONGO_AUTH_DB",
"valueFrom": {
"secretKeyRef": {
"key": "spring.data.mongodb.authentication-database",
"name": "mongodb-secret"
}
}
},
],
"image": "${IMAGE_NAME}",
"imagePullPolicy": "Always",
"name": "${APP_NAME}",
"ports": [
{
"containerPort": 8103,
"protocol": "TCP"
}
],
"resources": {
"limits": {
"cpu": "500m",
"memory": "1Gi"
},
"requests": {
"cpu": "500m",
"memory": "500Mi"
}
},
"volumeMounts":[
{
"name": "secret-volume",
"mountPath": "/mnt/secrets",
"readOnly": true
}
]
}
],
"volumes": [
{
"name": "secret-volume",
"secret": {
"secretName": "keystore-new"
}
}
]
}
}
}
}
{
"name": "JAVA_OPTIONS",
"value":"-Djavax.net.ssl.trustStore={KEYSTORE_PATH}/cacerts.ts",
"-Djavax.net.ssl.trustStorePassword=changeit",
-Djavax.net.ssl.keyStore=${KEYSTORE_PATH}/keystore.pkcs12
-Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASS}
-Djava.awt.headless=true,
},
This is invalid json, as the key value can only have one value, while you have provided multiple comma separated strings.
JAVA_OPTIONS isn't a standard environment variable, so we don't know how it's processed but maybe this will work?
{
"name": "JAVA_OPTIONS",
"value":"-Djavax.net.ssl.trustStore={KEYSTORE_PATH}/cacerts.ts -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.keyStore=${KEYSTORE_PATH}/keystore.pkcs12 -Djavax.net.ssl.keyStorePassword=${KEYSTORE_PASS} -Djava.awt.headless=true"
},
But there's still probably an issue, because it seems like {KEYSTORE_PATH} is supposed to be a variable. That's not defined or expanded in this file. For a first attempt, probably just hardcode the values of all these variables.
For secrets (such as passwords) you can hardcode some value for initial testing, but please use OpenShift Secrets for formal testing and the actual deployment.

ARM Template for Importing Azure Key Vault Certificate in Function App

I have a function app which calls another API with a certificate. This certificate (.pfx) file is already present in the key vault. I am using below ARM template to import the certificate to SSL settings of the function app.
Note: the function app gets deployed fine when I remove section "hostNameSslStates". But after adding it, I get -
"Code": "Conflict",
"Message": "The certificate with thumbprint 'XXXXXXXX' does not match the hostname
'blobcreate-eventgridtrigger-functionapp.azurewebsites.net'."
ARM Template resources section-
`
"resources": [
//StorageAccount
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[parameters('storageAccounts_name')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "[parameters('storageSKU')]",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [],
"ipRules": [],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true
},
"blob": {
"keyType": "Account",
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "Hot"
}
},
//BlobService
{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-06-01",
"name": "[variables('blobServiceName')]",
"dependsOn": ["[variables('storageAccountResourceId')]"],
"sku": {
"name": "[parameters('storageSKU')]"//,
// "tier": "Standard"
},
"properties": {
"cors": {
"corsRules": []
},
"deleteRetentionPolicy": {
"enabled": false
}
}
},
//function app with server farm
//cert store access policies update-
{
"type": "Microsoft.KeyVault/vaults",
"name": "testARMTemplateKeyVault",
"apiVersion": "2016-10-01",
"location": "[resourceGroup().location]",
"properties": {
"sku": {
"family": "A",
"name": "standard"
},
"tenantId": "c29678d0-eceb-4df2-a225-79cf795a6b64",
"accessPolicies": [
{
"tenantId": "tenantIdOfSubscription", //obtained from Get-AzTenant
"objectId": "objectid of Microsoft Azure App Service", //obtained from Get-AzADServicePrincipal
"permissions": {
"keys": [
"Get",
"List",
"Update",
"Create",
"Import",
"Delete",
"Recover",
"Backup",
"Restore"
],
"secrets": [
"Get",
"List",
"Set",
"Delete",
"Recover",
"Backup",
"Restore"
],
"certificates": [
"Get",
"List",
"Update",
"Create",
"Import",
"Delete",
"Recover",
"ManageContacts",
"ManageIssuers",
"GetIssuers",
"ListIssuers",
"DeleteIssuers"
],
"storage": []
}
}
],
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": true,
"enableSoftDelete": true
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('azurefunction_hostingPlanName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Y1",
"tier": "Dynamic"
},
"properties": {
"name": "[variables('azurefunction_hostingPlanName')]",
"computeMode": "Dynamic"
}
},
{
"type": "Microsoft.Web/certificates",
"name": "testingcert",
"apiVersion": "2016-03-01",
"location": "[resourceGroup().location]",
"properties": {
"keyVaultId": "[resourceId('Microsoft.KeyVault/vaults', 'testARMTemplateKeyVault')]",
"keyVaultSecretName": "testingcert",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('azurefunction_hostingPlanName'))]"
}
},
{
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/sites",
"name": "[parameters('functionAppName')]",
"location": "[resourceGroup().location]",
"kind": "functionapp",
"dependsOn": [
"[variables('azureFunction_serverFarmResourceId')]",
"[variables('storageAccountResourceId')]",
"[resourceId('Microsoft.Web/certificates', 'testingcert')]"
],
"properties": {
"serverFarmId": "[variables('azureFunction_serverFarmResourceId')]",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccounts_name'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),variables('storageAccountApiVersion')).keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', parameters('storageAccounts_name'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),variables('storageAccountApiVersion')).keys[0].value)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(parameters('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~10"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components/', parameters('functionApp_applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "dotnet"
},
{
"name": "WEBSITE_LOAD_CERTIFICATES",
"value": "required certificate thumprint"
}
]
},
"hostNameSslStates": [
{
"name": "blobcreate-eventgridtrigger-functionapp.azurewebsites.net",//obtained from custom domains flatform features of the function app
"sslState": "SniEnabled",
"thumbprint": "[reference(resourceId('Microsoft.Web/certificates', 'testingcert')).Thumbprint]",
"toUpdate": true
}
]
}
}
]`
add certificates section in template -
{
"type": "Microsoft.Web/certificates",
"name": "[parameters('CertificateName')]",
"apiVersion": "2019-08-01",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Web/serverFarms/', variables('azurefunction_hostingPlanName'))]"
],
"properties": {
"keyVaultId": "[parameters('keyvaultResourceId')]",
"keyVaultSecretName": "[parameters('invoiceApiCertificateKeyVaultSecretName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('azurefunction_hostingPlanName'))]"
}
}
and then add dependsOn for this certificate in the function app-
[resourceId('Microsoft.Web/certificates', parameters('CertificateName'))]
well, the error is quite obvious, you are trying to add a certificate for blobcreate-eventgridtrigger-functionapp.azurewebsites.net but the dns name on the certificate doesnt match that, hence the error. that is probably not the right way to add a certificate unless its going to be used for SSL termination

500 Internal Server Error when uploading GeoJSON to Azure Maps Data Service

I always receive 500 Internal Service Error
POST: https://atlas.microsoft.com/mapData/upload?subscription-key=&api-version=1.0&dataFormat=geojson
Sample data:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-122.13393688201903,
47.63829579223815
],
[
-122.13389128446579,
47.63782047131512
],
[
-122.13240802288054,
47.63783312249837
],
[
-122.13238388299942,
47.63829037035086
],
[
-122.13393688201903,
47.63829579223815
]
]
]
},
"properties": {
"geometryId": "1"
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-122.13374376296996,
47.63784758098976
],
[
-122.13277012109755,
47.63784577367854
],
[
-122.13314831256866,
47.6382813338708
],
[
-122.1334782242775,
47.63827591198201
],
[
-122.13374376296996,
47.63784758098976
]
]
]
},
"properties": {
"geometryId": "2",
"validityTime": {
"expiredTime": "2019-01-15T00:00:00",
"validityPeriod": [
{
"startTime": "2019-01-08T01:00:00",
"endTime": "2019-01-08T17:00:00",
"recurrenceType": "Daily",
"recurrenceFrequency": 1,
"businessDayOnly": true
}
]
}
}
}
]
}
Need help

How do I pass output of one node as an input parameter to another node in Argo workflow DAG

I am trying to construct a ML pipeline DAG using Argo. And I am running into an issue where I need a value from one node in the DAG to be sent as a parameter to its subsequent node. Say the ARGO DAG structure looks like the following:
{
"apiVersion": "argoproj.io/v1alpha1",
"kind": "Workflow",
"metadata": {
"generateName": "workflow01-"
},
"spec": {
"entrypoint": "workflow01",
"arguments": {
"parameters": [
{
"name": "log-level",
"value": "INFO"
}
]
},
"templates": [
{
"name": "workflow01",
"dag": {
"tasks": [
{
"name": "A",
"template": "task-container",
"arguments": {
"parameters": [
{
"name": "model-type",
"value": "INTENT-TRAIN"
}
]
}
},
{
"name": "B",
"template": "task-container",
"dependencies": ["A"],
"arguments": {
"parameters": [
{
"name": "model-type",
"value": "INTENT-EVALUATE"
}
]
}
}
]
}
},
{
"name": "task-container",
"inputs": {
"parameters": [
{
"name": "model-type",
"value": "NIL"
}
]
},
"container": {
"env": [
{
"name": "LOG_LEVEL",
"value": "{{workflow.parameters.log-level}}"
},
{
"name": "MODEL_TYPE",
"value": "{{inputs.parameters.model-type}}"
}
]
}
}
]
}
}
A -> B
The computation happening in B depends on the value that has been computed in A.
How will I be able to pass the value computed in A into B?
You can use Argo's "artifacts" for this - see the examples at https://github.com/argoproj/argo-workflows/tree/master/examples#artifacts
Another way is to set up a shared volume: https://github.com/argoproj/argo-workflows/tree/master/examples#volumes

Resources