Introduction
In our previous article, we described the development process for provisioning an Azure Resource Group using Terraform Code. I promised a follow-up blog that will try and get rid of some of the hard-coded values we used for critical information like Azure Subscription IDs, Tenant IDs, Client IDs, and Client Secrets. While the earlier blog works perfectly and does the job of provisioning resource groups, it does not comply with security best practices.
The majority of secure environments need applications to avoid storing critical information locally or within application databases. Critical information should be fetched from a central, secure, and regulated location which is where the Azure Key Vault comes into the picture. Azure Key Vault is an offering in Microsoft Azure that provides the capability for securely storing and accessing secrets. We will be integrating our Terraform Code solution that we had set up in an earlier blog with Azure Key Vault. We will be using one of the custom APIs that we built and described in the article here. Below is a technical diagram for the overall solution that we are setting up for this which brings together two solutions that we will keep on enhancing and blogging about.

Pre-Requisites
If you have not already set up the pre-requisites for the Key Vault API and Azure Resource Group provisioning through Terraform that we have described in our earlier articles, all of those will need to be set up now. To summarize, below is what is needed for this to work:
- Custom Key Vault API to fetch secrets from Azure Key Vaults
- Terraform Setup
- Azure Key Vault and stored secrets for Subscription Id, Tenant Id, Client Id, and Client Secret
- Azure API Management Subscription Key
- Get/List Access to client id on Azure Key Vault
Implementation
Let's get down to the code now. As in the previous article, we will have a similar folder structure for code hierarchy with a main, a variable, and an output file.
main.tf
Begin by opening the main.tf file and adding the following data block. Terraform does not natively support API invocation and therefore, we are using HTTP data sources to achieve api invocation. Important to note that HTTP data sources only support GET methods at this time. We will need to write our own custom modules if we wanted to support POST, PATCH, etc.
This HTTP data source takes the secret names as input, which is a comma-separated list of secrets that we will be fetching from the Azure Key Vault, from the variables file. We are then iterating through the secret names provided and fetching the values corresponding to these names from Azure Key Vault using the custom API endpoint we have created for the GetKeyVaultSecrets function in Azure API management as part of our earlier blog. This data block will provide the dynamic values that we need for the Terraform Azure provider and can be used for fetching other values as well on a need-to-need basis.
- #Fetch secrets from Azure Key Vault using custom API
- data "http"
- "GetKeyVaultSecrets" {
- count = length(var.secret_names)
- //Below block fetches the key vault secrets for all comma separated keys specified in variables
- url = "${local.get_secret_api}${element(var.secret_names,count.index)}"
- # Optional request headers
- request_headers = {
- Accept = "application/json"
- Ocp - Apim - Subscription - Key = local.ocp_subscription_key
- }
- }
Now add the below data block which is fetching the target subscription ID for provisioning the resource group using the subscription name we have provided in variables file. This is completely optional and can be substituted with your own business logic or needs.
- #Fetch the subscription Id from Azure Key Vault using custom API
- data "http"
- "GetSubscriptionId" {
- url = "${local.get_secret_api}${replace(var.subscription_name,"
- _ "," - ")}"
- # Optional request headers
- request_headers = {
- Accept = "application/json"
- Ocp - Apim - Subscription - Key = local.ocp_subscription_key
- }
- }

Join the conversation! Your thoughts help the community grow.