AzureDevops ARM template deployment - determine if new or existing - azure

Is there any way to determine if the current ARM template deployment release task is deploying a new resource group or updating an existing one?
I'm planning to utilise conditional deployments on some resources, and that condition would be if it is a totally new deployment.
Specifically, I want to set a keyvault secret as init only, and not set it if it already exists. The main problem now is that if the secret is defined within the template and the value set in the template differs from the current, it gets overwritten. I don't want to save the actual secret value in the template or variable library as that would defeat the purpose of a secret manager.
I want to be able to set a secret with a dummy value as init only, and let the admin set it via portal afterwards. The app will be unaware of this and will continuously reference that secret.

Related

Best way to store Terraform variable values without having them in source control

We have a code repo with our IaC in Terraform. This is in Github, and we're going to pull the code, build it, etc. However, we don't want the values of our variables in Github itself. So this may be a dumb question, but where do we store the values we need for our variables? If my Terraform requires an Azure subscription id, where would I store the subscription id? The vars files won't be in source control. The goal is that we'll be pulling the code into an Azure Devops pipeline so the pipeline will have to know where to go to get the input variable values. I hope that makes sense?
You can store your secrets in Azure Key Vault and retrieve them in Terraform using azurerm_key_vault_secret.
data "azurerm_key_vault_secret" "example" {
name = "secret-sauce"
key_vault_id = data.azurerm_key_vault.existing.id
}
output "secret_value" {
value = data.azurerm_key_vault_secret.example.value
}
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_secret
There has to be a source of truth eventually.
You can store your values in the pipeline definitions as variables themselves and pass them into the Terraform configuration.
Usually it's a combination of tfvar files (dependent on target environment) and some variables from the pipeline. If you do have vars in your pipelines though, the pipelines should be in code.
If the variables are sensitive then you need to connect to a secret management tool to get those variables.
If you have many environments, say 20 environments and the infra is all the same with exception of a single ID you could have the same pipeline definition (normally JSON or YAML) and reference it for the 20 pipelines you build, each of those 20 would have that unique value baked in for use at execution. That var is passed through to Terraform as the missing piece.
There are other key-value property tracking systems out there but Git definitely works well for this purpose.
You can use Azure DevOps Secure files (pipelines -> library) for storing your credentials for each environment. You can create a tfvar file for each environment with all your credentials, upload it as a secure file in Azure DevOps and then download it in the pipeline with a DownloadSecureFile#1 task.

Does ARM template overwrite existing resource created by script?

I have a consomosDB in my azure account created by a script, I want to create an ARM template to manage the resource deployment by ARM template going forward, how can I make sure that ARM template doesn't recreate/overwrite the resource as it is the first time going to be deployed using ARM template?
ARM template willnot recreate/overwrite the existing resource, if the resource is specified in the template. It will update the resource if the property values for a resource are changed. See below extract from the official document.
Resource Manager tries to create all resources specified in the template. If the resource already exists in the resource group and its settings are unchanged, no operation is taken for that resource. If you change the property values for a resource, the resource is updated with those new values. If you try to update the location or type of an existing resource, the deployment fails with an error. Instead, deploy a new resource with the location or type that you need.
In complete mode, Resource Manager deletes resources that exist in the resource group but aren't specified in the template
If you don't specify certain properties, Resource Manager interprets the deployment as overwriting those values. Properties that aren't included in the template are reset to the default values. Specify all non-default values for the resource, not just the ones you're updating
So if you want the existing resource remain intact, you can export the resource template from Azure Portal to make sure all the properties are specified and not changed.
You can also lock the resource, set the lock level to CanNotDelete or ReadOnly to keep the resource from deleted or modified. Check document Lock resources to prevent unexpected changes for more information.
To modify existing resources using ARM templates, export the template for the resource from within the Azure Portal. Then download it locally. You can then modify it to update settings for Cosmos resources. ARM templates have api-versions. This will coincide with the underlying version in PS or CLI that you used to create the Cosmos account. When modifying the ARM template you will need to note the api-version and then refer to that version Cosmos DB schema reference to ensure the properties match the api-version in the template you deployed.

How safe/protect Azure service principal secret

My deploy task using PowerShell script, which use Service Principal for connection to Azure KeyVault for pull secret. Secret (password) store in PowerShell script's code as plain text. Maybe there is another solution how to minimize token viewing.
And also i use powershell inline mode (not separate script) with Azure DevOps Secret Variable in deploy task, but this solution difficult to support (script has several different operations, so you have to keep many versions of the script).
Script is store in Git repository, anyone who has access to it will be able to see the secret and gain access to other keys. Perhaps I don't understand this concept correctly, but if keys cannot be stored in the code, then what should I do?
I devops you can use variable groups and define that the variables is pulled directly from a selected keyvault (if the service principal you have selected have read/list access to the KV) LINK.
This means that you can define all secrets in keyvault, and they would be pulled before any tasks happens in your yaml. To be able to use them in the script you can define them as a env variable or parameter to your script and just reference $env:variable or just $variable, instead of having the secret hardcoded in your script.

Updating Set of Values in ARM Templates Automatically

I have an ARM template, which I will be using it to deploy resources (Mentioned as in Azure Portal) via Azure DevOps Pipeline. These ARM templates were created using my Dev Subscription. If I need to use this same ARM template to move to production, I need to manually update the subscription id etc in the ARM template and then run the respective pipelines. Is there any way to automate this manual updation process in ARM template.
I have tried using File Transform Agent job available under Azure DevOps Release pipeline. But since the values are available inside nested loops of ARM templates, it failed. Is there any PowerShell script that will be suitable for this process of updating values.
I don't want to manually update the ids under the ARM Template. Instead, I want to update it automatically.
Set Json Property task might help to set the property with specific value.
First in the marketplace search for "set Json property" task and install it for your organization.
Then you can set the property path and the value accordingly. check here for detail usage
Instead of hard coding in ARM templates you can use parameters file. For dev and prod you can have separate files and while deploying pass ARM Template along with parameter file whichever is required.
You can use AKV (Azure Key Vault) to access your subscription details in parameter file
subscription().subscriptionid will get you the details

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.

Resources