One of the cool features of terraform is a custom module. This is where you can define a set of resources kind of as a template which you can call to use multiple times. A great way to use this if if you want to setup private endpoints for your Azure resources.

Imagine I have a VNET and some DNS zones and a storage account and a Key Vault.

In terraform id have set each of those up as resources but when I want to add my private endpoints to the key vault and storage account I need to do the following:

  • Define a terraform resource for the private endpoint and configure it to linking the azure resource and the subnet
  • Read the private endpoint to get the private ip address with a data element
  • Create a dns a record resource in terraform to add the a record to the network dns zone so traffic is routed to the ip address of my resource
  • Create a cname record on the private link dns zone which tells my connection to use the private endpoint

That boils down to 3 terraform resources and 1 data element for each private endpoint I want to create.

Using a custom module I can wrap that logic up in the module and just call my module using the below code snippet to have it setup the private endpoint and dns entries for my key vault. I can then just use my module again for every resource that I want to assign a private endpoint to and they will all be setup consistently.

module "keyvault_private_endpoint" {
    source = "./modules/AzureRm.Resource.PrivateEndpoint"
    resource_group_name             = azurerm_key_vault.ais_key_vault.resource_group_name
    resource_group_location         = azurerm_key_vault.ais_key_vault.location
    resource_name                   =
    resource_id                     =
    private_endpoint_subnet_id      =
    sub_resource_name               = "vault"

    dns_c_name_zone_name            =
    c_name_record                   = "${}.${local.keyvault_private_link}"

    dns_a_record_zone_name          = var.private_endpoint_dns_list["keyvault"].name
    host_name                       = "${}"
    default_tags                    = var.default_tags    


The below video will give you a quick walk through of doing this.

Code Samples

The module I used in my demo is in this folder

The example of using it is in this file


Buy Me A Coffee