Deploying Key Vault with secrets using Terraform to Azure
Terraform is a software tool created by HashiCorp. Terraform is used for building, changing and versioning infrastructure safely and efficiently using code. For those who have had minimal experience in Terraform I have some good tips to help you move forward and potentially apply to other use cases involving terraform.
Tips:
· Create a diagram of the terraform structure using the folder structure in your repo.
- This will help you to follow the inheritance of information through the terraform.
· Each module in the structure may have these files however, these are by choice:
- Main.tf — this file verifies the inputs into the module, a good way to think of it is: “what is needed for this resource to work”.
- Variables.tf — this file allows you to initialise variables within the level, mainly used by the main.tf it also allows you to call in any variables that may come from different modules particularly those stated in the output.tf files (see below).
- Outputs.tf — this file dictates what variables will be outputted by the module, potentially to be used elsewhere, this is possible because for every variable within this file there is a value which is a Uri to where the variable comes from. A good way to think of this file’s contents is “what variables are created that I might later use elsewhere in the repo”
· It is good practise to have a ‘.tfvars’ file in the outer layer of the folder structure where you can initialise personal variables needed for resource deployment, such as resource group names, locations, object Ids, secrets.
· Whilst terraform does not inherit in any way, in certain scenarios it helps to think of the inheritance as either
- “BOTTOM-UP” — When deploying a resource, ie deploying key vault to your azure subscription
- “TOP-DOWN” — when utilising variables from other resources to your resource, i.e when adding secrets to your keyvault outputted from Application insights .
Deploying a Key Vault in Azure
When creating a key vault, first thing you will need to consider is the access policy (there are ordinarily two types: owners and readers). These policies help to assign specific permissions to the user so that their access and manipulation of the keys/secrets are managed. If you already have an existing key vault resource ordinarily you can use the Azure portal to add an access policy (figure 1). However, as this post is based on deploying resources via terraform, we can assign access policies from within the terraform modules, as shown in figure 2.
In figure 2, in order to assign the permissions, you are required to give an object id and tenant id so that when you look at the portal you can see who is assigned what permissions.
Adding a secret from another resource to the Key vault
As mentioned before terraform does not have a specific inheritance approach however, when you are adding secrets from other resources within the terraform it helps to consider a TOP-DOWN approach. This is because when we deploy individual resources all their outputs go to the top level on the folder structure therefore, for another resource to use that output variable it must be input into the resource from the top level down to the key vault resource.
From the diagram above the steps are as follows:
- In our scenario, we take the connection string and the instrumentation string from the outputs of the app insights modules (figure 3). These outputs come from the resource in the appinsights >main.tf. These outputs are then remembered throughout the terraform so you can then call these outputs in the top level main.tf . Important: “sensitive = true” must be declared for all keys and secrets so that during plans or saving to states the keys and secrets are hidden and only visible in the key vault in the portal to those with access.
2. In the top level main.tf, you can then pull the app insights outputs as variables inputs in the key vault module (see figure 4). A good example is the ‘keyvault_applicationInsights_ConnectionString’ here you can see that we pull the connection string from the application insights module as we have assigned the variable as an output of that module in step 1.
3. Now the application insights connection string has been inputted into the key vault module as ‘keyvault_applicationInsights_ConnectionString’ you can pass this variable through the key vault modules main.tf (making sure you declare the variables in variables.tf) so that the connection string can be added as a secret in the key vault (figure 5).
To accompany this post I have created a Github repo that you can pull down and run from your local machine onto azure. I hope it has been useful, feel free to reach out if there are any questions or additions I should make