Azure, Power Platform and Everything cloud

Scenario

  1. You have an Azure project and a team with multiple developers working on different services/resources.
  2. One or more developers are writing code that interacts with one or multiple resources that are being provisioned by you or someone on the team.
  3. As development moves forward, new resources are added to the solution, sometimes, new developers join the team, and sometimes developers leave the team.

Development challenge

  1. Developers getting blocked or blocking other developers when azure resources secrets change or resources are dropped and reintroduced.
  2. Secret keys and connection strings flowing through a range of communication channels lingering around, waiting for hackers or uncareful people to let it out into the cyberspace
  3. Whenever a Service Principal secret expires, you need to manually intervein in production, sometimes add a new secret to code or Devops and redeploy

Solution

To eliminate those problems, speedup development and increase security:

  1. Using terraform, create a script that creates secured azure resources like storage accounts, databases, and event hubs (#1).
  2. When you create azure resources, Terraform store secrets on it’s state (#2) allowing you to pass those secrets to the Azure Vault ( #3).
  3. With the secrets in the vault, you know now the secret path and you can use Terraform to add than to the app settings.

The Terraform Code

We start by creating the vault (#1). With the vault created we can now create resources that require access keys\connection strings (#2) and store the secret in the vault (#3)

The azure hub and many other resources don’t force you to renew secret. But sometimes secrets expire, like on the case of a Service Principal and you can run this script before functionality is interrupted.

The secret will be renewed and you won’t need to touch code or manually paste de secret on Devops.

One tricky part is the Vault Policy. This is when you tell the Vault who can access the secret. On our case, for the script, let’s add a policy to allow the Service Principal Account that runs this script. Of course you can add other accounts, like any other service account that needs access.

The Catch here is, that there is a delay between applying this and reflecting on the Vault. Most of the time, this script will fail on the first run, saying you are not authorized to add secrets to the Vault. If you wait five minutes and run again, it will succeed. There are ways to improve that when adding this to DevOps. May discuss that in a future post

Code for the above can be found here: BrunoLucasBlog/TerraformVaultSecret (github.com)

Result: The Resource was created and the secret is now in the Vault.

You could open the vault, copy the secret and paste on your azure function/web app but there is a better way without ever exposing the secret. Will discuss that next.

Azure Functions

When developing, you can also use the Vault path on your config json, but you will need to add it to terraform to deploy.

resource "azurerm_function_app" "example" {
  name                       = "example-azure-function"
  location                   = azurerm_resource_group.example.location
  resource_group_name        = azurerm_resource_group.example.name
  app_service_plan_id        = azurerm_app_service_plan.example.id
  storage_account_name       = azurerm_storage_account.example.name
  storage_account_access_key = azurerm_storage_account.example.primary_access_key
  os_type                    = "linux"
  version                    = "~4"

  app_settings {
    FUNCTIONS_WORKER_RUNTIME = "dotnet"
    ServicePrincipal         = “@Microsoft.KeyVault(SecretUri=${module.lookup.key_vault.vault_uri}secrets/ServicePrincipal/)",
  }

Now with the Key Vault Reference (highlighted above) on the code config file, you can run the Terraform script many times, and the azure function will pick up any new secret.

Suggested dev process:

1. Add a new Azure Resources to terraform

2. Pass the resource’s secret to the vault. Make sure you update the Vault Access Policy to allow a user to “set” secrets

3. Run Terraform

4.Confirm secret is in the Vault.

5.Add the vault path to the Key Vault Reference and the Key Vault Reference to the Azure Function Terraform “app settings” section.

6. To debug the code in Visual Studio, Add the Key Vault Reference to app.setting.json. You may need to create a second vault policy for the account you use to run Visual Studio.

There is much more to add to the Terraform script to make it DevOps ready, but the idea here is to share a core concept. Using this approach I could run my DevOps without disturbing the developers. All the deployments beyond the Dev environment are also much more straightforward. You want to be able to deploy complex cloud infrastructure anytime with minimum impact disturbing the least amount of people.

Leave a Reply

Discover more from Bruno Lucas Azure Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading