Securing credentials in Desired State Configuration deployed via ARM - azure

How to use Desired State Configuration in combinition with ARM.
Scope:
- We have an Azure virtual machine that is deployed via an ARM template.
- The VM has an extension resource in the ARM template, for the Desired State Configuration
- We need to pass sensitive parameters (in a secure way!) into the Desired State Configuration (we want to create an additional local windows account with the DSC)
- Configuration file is used to know what public key to use for encryption, and to let the VM know which certificate it has to use for decryption (by thumbprint)
- When using ARM, you need to define the configuration data file in a separate property
- I noticed that the DSC service, automically adds an certificate for document encryption to the VM.
Question:
If I want to get this working out of the box, I will need to create the configurationDataFile upfront, and store it somewhere (like blob or something).
However, the 'out-of-the-box' certificate on the VM is only known after the ARM template has been deployed.
I was wondering if there is a way to get the encryption/decryption in DSC working, using the out of the box DSC Certificate on the VM, without using different incremental DSC templates.
So how can I know the out of the box certificate thumbprint at deployment time? (In the arm template?)
Do I actually need to transform the ConfigurationData file for every deployment (and finding the correct thumbprint of the VM), or is there an out of the box way to tell DSC via ARM to use the out of the box created certificate for this?

Because the target VM is also the authoring machine, the passwords can be passed as plain text, as they never leave the Virtual Machine.
This has been verified by Microsoft support.

Related

Azure resource manager template deployments - Using _artifactsLocation and _artifactsLocationSasToken

Where and how to use artifactsLocation and _artifactsLocationSasToken in Arm template deployments. Are these used only for nested deployments.
Can we use these for custom VM extension of the Virtual machine as part of post provisioning activity, after VM is built or should the extension be added as part of the VM build deployment template only.
VM Custom script extension - (Initialize and format data drives, Mount file shares for instance)
Azure quick start templates, have the parameter values for these as default for artifactsLocation and type securestring for _artifactsLocationSasToken. How these values are populated in the ARM deployment runtime.
It would be great if someone can provide documentation around the same / step by step process or share an existing working custom script extension template.
There's nothing inherent in the platform that makes _artifactsLocation and _artifactsLocationSasToken special... it's just a pattern (well used) that has developed for staging artifacts needed for a deployment. The pattern is to stage all artifacts together and then use the uri of the main template as a relative location. The defaultValue generally used for _artifactsLocation is:
"defaultValue": "[deployment().properties.templateLink.uri]"
The deployment() function is inherent and contains the uri passed in for the main template.
That said, you can use those values anyway you see fit and the primary use case is for retrieving any artifact needed by any resource. For example:
Custom Script Extension
https://github.com/Azure/azure-quickstart-templates/blob/master/demos/vm-winrm-windows/azuredeploy.json#L256-L259
MSDeploy Packages for WebApps
https://github.com/Azure/azure-quickstart-templates/blob/master/demos/private-endpoint-sql-from-appservice/azuredeploy.json#L277
DSC Configuration Modules
https://github.com/Azure/azure-quickstart-templates/blob/master/demos/iis-2vm-sql-1vm/azuredeploy.json#L585
etc, etc...
That help?

Passing customdata to Operating system option of azure vmss - Terraform

While we create Virtual machine scale set in azure , there is an option for passing the Custom data under Operating System like below
How can i pass the script there using terraform , there is an option custom data which seems to be used for newly created machines from terraform, but the script is not getting stored there. How do i fill this with the script i have using terraform. Any help on this would be appreciated.
From the official document, the custom_data can only be passed to the Azure VM at provisioning time.
Custom data is only made available to the VM during first boot/initial
setup, we call this 'provisioning'. Provisioning is the process where
VM Create parameters (for example, hostname, username, password,
certificates, custom data, keys etc.) are made available to the VM and
a provisioning agent processes them, such as the Linux Agent and
cloud-init.
The scripts are saved differed from the OS.
Windows
Custom data is placed in %SYSTEMDRIVE%\AzureData\CustomData.bin as a binary file, but it is not processed.
Linux
Custom data is passed to the VM via the ovf-env.xml file, which is copied to the /var/lib/waagent directory during provisioning. Newer versions of the Microsoft Azure Linux Agent will also copy the base64-encoded data to /var/lib/waagent/CustomData as well for convenience.
To upload custom_data from your local path to your Azure VM with terraform, you can use filebase64 Function.
For example, there is a test.sh script or cloud-init.txt file under the path where your main.tfor terraform.exe file exists.
custom_data = filebase64("${path.module}/test.sh")
If you are looking for executing scripts after VMSS created, you could look at the custom extension and this sample.

Is it possible to update the assigned Azure DSC configuration to a VM via ARM Template?

I need to change the Azure DSC configuration that has been previously assigned to a VM.
I'm trying to do this programatically because it's part of an automation I'm developing and because of this, I'm using ARM Templates.
However, redeploying the same VM DSC extension by ARM Template results in an error stating a VM can't have two of the same extensions, which sounds logical.
What I want to know if it's possible to, by ARM Template, "update" or "modify" the current extension with just one setting changed: The configuration name.
Is this possible?
Sure - you can update the existing VM extension by providing new configuration in your ARM template. As you have found out, you cannot use a different name for the extension - that would result in two VM extensions of the same type on the VM. Instead, you need to reuse the same name of the existing VM extension when performing the update.

How do I update the configuration of a deployed ARM template during run time?

I have a logic app ARM template that is already deployed and at the time of deployment it pulls certain passwords/secrets from Azure key vault storage. But, what if someone changes the password or secret that is being used by the ARM template?
One option is to re-deploy the ARM template. But is there an option so that I don't have to redeploy an ARM template and the configuration gets updated in such cases automatically?
so unless the resource itself is configured to pull values from the Key Vault - your only options is to rerun the template or update those values somehow, because this is what the template does, pulls values and applies them.
You can (perhaps) use something like Azure Event Grid to listen to events like KV secret value change. But I dont know if that listener actually exist.

Deploying a VMSS and injecting secrets

I am wondering if there is any straightforward way of injecting files/secrets into the vms of a scaleset, either as you perform the (ARM) deployment or change the image.
This would be application-level passwords, certificates, and so on, that we would not want to be stored on the images.
I am using the linux custum script extension for the entrypoint script, and realize that it's possible to inject some secrets as parameters to that script. I assume this would not work with certificates however (too big/long), and it would not be very future-proof as we would need to redeploy the template (and rewrite the entrypoint script) whenever we want to add or remove a secret.
Windows based VMSS can get certificates from the KV directly during deployment, but linux ones cannot do that. Also, there is a customData property which allows you to pass in whatever you want (i think its limited to 64kb base64 encoded data), but that is not really flexible as well.
One way of solving this - write an init script that would use Managed Service Identity to get secrets from the Key Vault, this way you get several advantages:
You dont store secrets in the templates\vm configuration
You can update the secret and all the VMSS will get new version on the next deployment
You dont have to edit the init script unless secret names changed or new secrets got introduced.

Resources