Passing credentials to DSC script from arm template - azure

I am trying to deploy a VM with a DSC extension from an ARM template. According to various sources, and even this SO question, I am following the correct way to pass a credential object to my script:
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.19",
"autoUpgradeMinorVersion": true,
"settings": {
"modulesUrl": "[concat(parameters('_artifactsLocation'), '/', variables('ConfigureRSArchiveFolder'), '/', variables('ConfigureRSArchiveFileName'), '/', parameters('_artifactsLocationSasToken'))]",
"configurationFunction": "[variables('rsConfigurationConfigurationFunction')]",
"properties": {
"SQLSAAdminAuthCreds": {
"UserName": "[parameters('SSRSvmAdminUsername')]",
"Password": "PrivateSettingsRef:SAPassword"
}
}
},
"protectedSettings": {
"Items": {
"SAPassword": "[parameters('SSRSvmAdminPassword')]"
}
}
}
However, when I deploy it, I get this error message:
Error message: "The DSC Extension received an incorrect input: The password element of
argument 'SQLSAAdminAuthCreds' to configuration 'PrepareSSRSServer' does not
match the required format. It should be as follows
{
"UserName" : "MyUserName",
"Password" : "PrivateSettingsRef:MyPassword"
}.
Please correct the input and retry executing the extension.".
As far as I can see, my format is correct. What am I missing? Thanks

It seems that function try to use the paramters that cause the issue. So please have try a check the function in the ps1 file where use the SQLSAAdminAuthCreds. I can't repro the issue that your mentioned. I do a demo for it, the following is my detail steps.
1.Prepare a ps1 file, I get the demo code from article
configuration Main
{
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[PSCredential]
$SQLSAAdminAuthCreds
)
Node localhost {
User LocalUserAccount
{
Username = $SQLSAAdminAuthCreds.UserName
Password = $SQLSAAdminAuthCreds
Disabled = $false
Ensure = "Present"
FullName = "Local User Account"
Description = "Local User Account"
PasswordNeverExpires = $true
}
}
}
2.Zip the ps1 file
3.Download the ARM template and parameters from the Azure portal.
4.Edit the template and parameter file
Try to deploy the ARM template with VS or Powershell
Check it from the Azure portal or output.

Related

Get properties for an object returned by Get-AzResource on Azure

I am trying get the properties of an Azure Disk Resource. When I run the command in my subscription
$R=Get-AzResource -Name <ResourceName>
It provides a list of properties given here I am specifically interested getting the Properties PSobject. However running the following command:
$R.Properties -eq $null
does returns true. When I look at this resource from Azure Portal (Same user principal as in Powershell command) in Json format I am given a selection of schemas to choose from and lots of properties are provided. Below is a sample:
"properties": {
"osType": "Linux",
"hyperVGeneration": "V2",
"supportsHibernation": true,
"supportedCapabilities": {
"acceleratedNetwork": true,
"architecture": "x64"
},
"creationData": {
"createOption": "FromImage",
"imageReference": {
"id": "xxx"
}
},
"diskSizeGB": 30,
"diskIOPSReadWrite": 500,
"diskMBpsReadWrite": 60,
"encryption": {
"type": "EncryptionAtRestWithPlatformKey"
},
"networkAccessPolicy": "AllowAll",
"publicNetworkAccess": "Enabled",
"timeCreated": "2023-01-09T13:38:24.500223+00:00",
"provisioningState": "Succeeded",
"diskState": "Attached",
"diskSizeBytes": 32213303296,
"uniqueId": "xxx"
What is the proper command to get this information using PowerShell?
You should set the ExpandProperties switch
https://learn.microsoft.com/en-us/powershell/module/az.resources/get-azresource?view=azps-9.3.0#-expandproperties
$resourceWithProperties = Get-AzResource -Name <ResourceName> -ExpandProperties
You can the access the properties with
$resourceWithProperties.Properties
You can get all properties using -ExapandProperties command and Alternative way of getting all properties is by using below commands:
Connect-AzAccount
$disk = Get-AzResource -ResourceId "/subscriptions/<subscriptionId>/resourceGroups/<Rg name>/providers/Microsoft.Compute/disks/<Diskname>"
$disk.Properties | Format-List *
Output:

Terraform issue creating the resource "azurerm_synapse_linked_service" specifically with the "type_properties_json" field

I am trying to create a Synapse Workspace Linked Service using Terraform and am running into a constant snag with the "type_properties_json" field that is (required).
When I try to establish a Linked Service to an SFTP resource type, I can do so through the portal no problem, however trying to do so with Terraform is constantly providing me with errors. I am using the JSON code format referenced here, but the "type_properties_json" field keeps erroring out as I believe it is expecting a "String" and I am instead providing a Map[string] type.
The error I keep receiving during the terraform apply is json: cannot unmarshal string into Go value of type map[string]interface {}
My specific code looks like the following:
resource "azurerm_synapse_linked_service" "linked-service" {
synapse_workspace_id = azurerm_synapse_workspace.synapse.id
name = "name"
type = "Sftp"
type_properties_json = <<JSON
{
"host": "x.x.com",
"port": 22,
"skipHostKeyValidation": false,
"hostKeyFingerprint": "ssh-rsa 2048 xx:00:00:00:xx:00:x0:0x:0x:0x:0x:00:00:x0:x0:00",
"authenticationType": "Basic",
"userName": "whatever_name,
"password": "randompassw"
}
JSON
depends_on = [azurerm_synapse_firewall_rule.allow]
}
Running out of hope here and am now looking to crowd source to see if anyone else has ever ran into this problem!!
This is because of the password parameter you are passing. As per this Microsoft documentation, it should be passed as below:
"password": {
"type": "SecureString",
"value": "<value>"
}
Instead of
"password": <value>
I tested the same in my environment using your code where I faced the exact same issue:
So, I used the below code, applying the solution mentioned above:
resource "azurerm_synapse_linked_service" "example" {
name = "SftpLinkedService"
synapse_workspace_id = azurerm_synapse_workspace.example.id
type = "Sftp"
type_properties_json = <<TYPE
{
"host": "xxx.xx.x.x",
"port": 22,
"skipHostKeyValidation": false,
"hostKeyFingerprint": "<SSH-publicKey>",
"authenticationType": "Basic",
"userName": "adminuser",
"password": {
"type": "SecureString",
"value": "<Value>"
}
}
TYPE
depends_on = [
azurerm_synapse_firewall_rule.example,
azurerm_synapse_firewall_rule.example1
]
}
Output:

Azure ARM template for Automation Account Variable - cant use paramets as value

I am trying to create an ARM template for my runbook with additional variables ab packages.
I want to have the values of Automation Account Variables as parameters of ARM template.
When I am using the documentation syntax I am getting the variables value as "[parameters(parameterName)] instead the value of the parameter
when I am not using the syntax code I just get this error:
Invalid JSON - Kindly check the value of the variable
This is the ARM template resource code:
{
"apiVersion": "2020-01-13-preview",
"type": "Microsoft.Automation/automationAccounts/variables",
"name": "[concat(parameters('AutomationAccount'), '/blobContainerName')]",
"location": "[parameters('automationRegion')]",
"properties": {
"description": "output container name",
"isEncrypted": false,
"value": "\"[parameters('blobContainerName')]\""
}
}
how its looks like in the variables after deployment:
Try the following:
"properties": {
"value": "[concat('\"', parameters('blobContainerName'), '\"')]"
},
You need to use concat to join the strings

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.

Unable to use Resource Functions for Azure Resource Manager Templates

My parameters file looks as follows:
{
"$schema":"http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion":"1.0.0.0",
"parameters":{
"siteName":{
"value":"my-api-application"
},
"appServicePlanName":{
"value":"MyServicePlan"
},
"siteLocation":{
"value":"West US"
},
"vaultResourceGroup": {
"value":"my-vault-res-group"
},
"vaultName": {
"value":"my-keyvault"
},
"nodeEnv": {
"value":"development"
},
"adminPassword": {
"reference": {
"keyVault": {
"id": "/subscriptions/yyyyyyyy-xxxx-xxxx-xxxx-yyyyyyyy/resourceGroups/my-vault-res-group/providers/Microsoft.KeyVault/vaults/my-keyvault"
},
"secretName": "adminPassword"
}
}
}
}
The adminPassword value will be picked up from the specified KeyVault, with the particular id. However, I have to hard code the "id" value.
According to this link, I could specify the id using some thing like this:
resourceId(subscription().subscriptionId, parameters('vaultResourceGroup'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]
However, when using the above syntax/Resource Functions, I receive an error while releasing and deploying my App Service using the VSTS (I used Azure Resource Group Deployment task for APP deployment). The error is some what like this:
The id must be of the following format:
/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}
Not sure what am I doing wrong?
You're not doing anything wrong, that's intentional. You must use a literal resourceId in the parameters file (parameters files don't allow for function use).
If you have a scenario for a dynamic KeyVault id you can use a nested deployment:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-keyvault-parameter#reference-a-secret-with-dynamic-id

Resources