# README
Helm plugin for Azure template processing
Plugin for Helm to inject Azure information (subscriptions, resources, msgraph) and Azure KeyVault secrets. Also works as standalone executable outside of Helm.
Installation
requires sed
and curl
for installation
# Installation of latest version
helm plugin install https://github.com/webdevops/helm-azure-tpl.git
# Installation of specific version
helm plugin install https://github.com/webdevops/helm-azure-tpl.git --version=0.50.1
# Update to latest version
helm plugin update azure-tpl
# Deinstallation
helm plugin uninstall azure-tpl
Usage
Helm (downloader mode)
you can use helm in "downloader" mode to process files eg:
[!CAUTION] DO NOT use azure-tpl functions in
values.yaml
files as these files are read again by helm without azure-tpl processing! Use different file names and paths.
helm upgrade foobar123 -f azuretpl://config/values.yaml .
for additional values files for azure-tpl you can use environment variabels:
AZURETPL_VALUES=./path/to/azuretpl.yaml helm upgrade foobar123 -f azuretpl://config/values.yaml .
File processing
helm azure-tpl
uses AzureCLI authentication to talk to Azure
Process one file and overwrite it:
helm azure-tpl apply template.tpl
Process one file and saves generated content as another file:
helm azure-tpl apply template.tpl:template.yaml
Processes all .tpl
files and saves them as .yaml
files
helm azure-tpl apply --target.fileext=.yaml *.tpl
General usage:
Usage:
helm-azure-tpl [OPTIONS] [command] [files...]
Application Options:
--log.devel development mode [$LOG_DEVEL]
--log.json Switch log output to json format [$LOG_JSON]
--dry-run dry run, do not write any files [$AZURETPL_DRY_RUN]
--debug debug run, print generated content to stdout (WARNING: can expose secrets!) [$HELMHELM_DEBUG_DEBUG]
--stdout Print parsed content to stdout instead of file (logs will be written to stderr) [$AZURETPL_STDOUT]
--template.basepath= sets custom base path (if empty, base path is set by base directory for each file. will be
appended to all root paths inside templates) [$AZURETPL_TEMPLATE_BASEPATH]
--target.prefix= adds this value as prefix to filename on save (not used if targetfile is specified in argument)
[$AZURETPL_TARGET_PREFIX]
--target.suffix= adds this value as suffix to filename on save (not used if targetfile is specified in argument)
[$AZURETPL_TARGET_SUFFIX]
--target.fileext= replaces file extension (or adds if empty) with this value (eg. '.yaml') [$AZURETPL_TARGET_FILEEXT]
--keyvault.expiry.warningduration= warn before soon expiring Azure KeyVault entries (default: 168h)
[$AZURETPL_KEYVAULT_EXPIRY_WARNING_DURATION]
--keyvault.expiry.ignore ignore expiry date of Azure KeyVault entries and don't fail' [$AZURETPL_KEYVAULT_EXPIRY_IGNORE]
--values= path to yaml files for .Values [$AZURETPL_VALUES]
--set-json= set JSON values on the command line (can specify multiple or separate values with commas:
key1=jsonval1,key2=jsonval2)
--set= set values on the command line (can specify multiple or separate values with commas:
key1=val1,key2=val2)
--set-string= set STRING values on the command line (can specify multiple or separate values with commas:
key1=val1,key2=val2)
--set-file= set values from respective files specified via the command line (can specify multiple or separate
values with commas: key1=path1,key2=path2)
Help Options:
-h, --help Show this help message
Arguments:
command: specifies what to do (help, version, lint, apply)
files: list of files to process (will overwrite files, different target file can be specified as
sourcefile:targetfile)
Build-in objects
Object | Description |
---|---|
.Values | Additional data can be passed via --values=values.yaml files which is available under .Values (like Helm) |
Template functions
Azure template functions
[!NOTE] Functions can also be used starting with
azure
prefix instead ofaz
Function | Parameters | Description |
---|---|---|
azAccountInfo | Output of az account show | |
azManagementGroup | groupID (string) | Fetches Azure managementGroup |
azManagementGroupSubscriptionList | groupID (string) | Fetches list of all subscriptions (recursive) inside an Azure managementGroup |
azSubscription | subscriptionID (string, optional) | Fetches Azure subscription (current selected one if subscriptionID is empty) |
azSubscriptionList | Fetches list of all visible azure subscriptions | |
azResource | resourceID (string), apiVersion (string) | Fetches Azure resource information (json representation, interface object) |
azResourceList | scope (string), filter (string, optional) | Fetches list of Azure resources and filters it by using $filter, scope can be subscription ID or resourceGroup ID (array, json representation, interface object) |
azPublicIpAddress | resourceID (string) | Fetches ip address from Azure Public IP |
azPublicIpPrefixAddressPrefix | resourceID (string) | Fetches ip address prefix from Azure Public IP prefix |
azVirtualNetworkAddressPrefixes | resourceID (string) | Fetches address prefix (string array) from Azure VirtualNetwork |
azVirtualNetworkSubnetAddressPrefixes | resourceID (string), subnetName (string) | Fetches address prefix (string array) from Azure VirtualNetwork subnet |
Azure KeyVault functions
Function | Parameters | Description |
---|---|---|
azKeyVaultSecret | vaultUrl (string), secretName (string), version (string, optional) | Fetches secret object from Azure KeyVault |
azKeyVaultSecretVersions | vaultUrl (string), secretName (string), count (integer) | Fetches the list of count secret versions (as array, excluding disabled secrets) from Azure KeyVault |
azKeyVaultSecretList | vaultUrl (string), secretNamePattern (string, regexp) | Fetche the list of secret objects (without secret value) from Azure KeyVault and filters list by regular expression secretNamePattern |
response format:
{
"attributes": {
"created": 1620236104,
"enabled": true,
"exp": 1724593377,
"nbf": 1661362977,
"recoverableDays": 0,
"recoveryLevel": "Purgeable",
"updated": 1661449616
},
"contentType": "...",
"id": "https://xxx.vault.azure.net/secrets/xxx/xxxxxxxxxx",
"managed": false,
"name": "xxx",
"tags": {},
"value": "...",
"version": "xxxxxxxxxx"
}
Azure ManagedCluster functions
Function | Parameters | Description |
---|---|---|
azManagedClusterUserCredentials | resourceID (string) | Fetches managedCluster user credentials object |
Azure Redis cache functions
Function | Parameters | Description |
---|---|---|
azRedisAccessKeys | resourceID (string) | Fetches access keys from Azure Redis Cache as array |
Azure StorageAccount functions
Function | Parameters | Description |
---|---|---|
azStorageAccountAccessKeys | resourceID (string) | Fetches access keys from Azure StorageAccount as array |
azStorageAccountContainerBlob | containerBlobUrl (string) | Fetches container blob from Azure StorageAccount as string |
Azure AppConfig functions
Function | Parameters | Description |
---|---|---|
azAppConfigSetting | appConfigUrl (string), settingName (string), label (string) | Fetches setting value from app configuration instance (resolves keyvault references) |
response format:
{
"contentType": "...",
"eTag": "...",
"isReadOnly": false,
"key":" ...",
"label": null,
"lastModified": null,
"syncToken": "...",
"tags": {},
"value": "..."
}
Azure RBAC functions
Function | Parameters | Description |
---|---|---|
azRoleDefinition | scope (string), roleName (string) | Fetches Azure RoleDefinition using scope (eg /subscriptions/xxx ) and roleName |
azRoleDefinitionList | scope (string), filter (string,optional) | Fetches list of Azure RoleDefinitions using scope (eg /subscriptions/xxx ) and optional $filter query |
Azure ResourceGraph functions
Function | Parameters | Description |
---|---|---|
azResourceGraphQuery | scope (string or []string), query (string) | Executes Azure ResourceGraph query against selected subscription IDs or management group IDs (as string comma separated or string array) |
[!NOTE] ManagementGroups must be defined with their resource ID
/providers/microsoft.management/managementgroups/{MANAGEMENT_GROUP_ID}
. Subscriptions must either be defined by the subscription id or their resource id/subscriptions/{SUBSCRIPTION_ID}
.
MsGraph (AzureAD) functions
[!NOTE] Functions can also be used starting with
msGraph
prefix instead ofmg
Function | Parameters | Description |
---|---|---|
mgUserByUserPrincipalName | userPrincipalName | Fetches one user by UserPrincipalName |
mgUserList | filter (string) | Fetches list of users based on $filter query |
mgGroupByDisplayName | displayName (string) | Fetches one group by displayName |
mgGroupList | filter (string) | Fetches list of groups based on $filter query |
mgServicePrincipalByDisplayName | displayName (string) | Fetches one serviceprincipal by displayName |
mgServicePrincipalList | filter (string) | Fetches list of servicePrincipals based on $filter query |
mgApplicationByDisplayName | displayName (string) | Fetches one application by displayName |
mgApplicationList | filter (string) | Fetches list of applications based on $filter query |
Time template functions
Function | Parameters | Description |
---|---|---|
fromUnixtime | timestamp (int/float/string) | Converts unixtimestamp to Time object |
toRFC3339 | time (time.Time) | Converts time object to RFC3339 time string |
Misc template functions
Function | Parameters | Description |
---|---|---|
jsonPath | jsonPath (string) | Fetches object information using jsonPath (useful to process azureResource output) |
filesGet | path (string) | Fetches content of file and returns content as string |
filesGlob | pattern (string) | Lists files using glob pattern |
{{
azResource
"/subscriptions/d86bcf13-ddf7-45ea-82f1-6f656767a318/resourcegroups/k8s/providers/Microsoft.ContainerService/managedClusters/mblaschke"
"2022-01-01"
| jsonPath "$.properties.aadProfile"
| toYaml
}}
Helm template functions (borrowed from helm project)
Function | Parameters | Description |
---|---|---|
include | path (string), data (interface) | Parses and includes template file |
required | message (string) | Throws error if passed object/value is empty |
fail | message (string) | Throws error |
toYaml | Convert object to yaml | |
fromYaml | Convert yaml to object | |
fromYamlArray | Convert yaml array to array | |
toJson | Convert object to json | |
fromJson | Convert json to object | |
fromJsonArray | Convert json array to array |
Sprig template functions
Sprig template functions are also available
Examples
## Fetch resource as object and convert to yaml
{{ azResource
"/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourcegroups/example-rg/providers/Microsoft.ContainerService/managedClusters/k8scluster"
"2022-01-01"
| toYaml
}}
## Fetch resource as object, select .properties.aadProfile via jsonPath and convert to yaml
{{ azResource
"/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourcegroups/example-rg/providers/Microsoft.ContainerService/managedClusters/k8scluster"
"2022-01-01"
| jsonPath "$.properties.aadProfile"
| toYaml
}}
## Fetches all resources from subscription
{{ (azResourceList "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx") | toYaml }}
## Fetches all virtualNetwork resources from subscription
{{ (azResourceList "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" "resourceType eq 'Microsoft.Network/virtualNetworks'") | toYaml }}
## Fetches all resources from resourceGroup
{{ (azResourceList "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourcegroups/example-rg") | toYaml }}
## Fetch Azure VirtualNetwork address prefixes
{{ azVirtualNetworkAddressPrefixes
"/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourcegroups/example-rg/providers/Microsoft.Network/virtualNetworks/k8s-vnet"
}}xxx/resourcegroups/example-rg/providers/Microsoft.Network/virtualNetworks/k8s-vnet"
"default2"
| join ","
}}
## Fetch first storageaccount key
{{ (index (azStorageAccountAccessKeys "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/example-rg/providers/Microsoft.Storage/storageAccounts/foobar") 0).value }}
## fetch blob from storageaccount container
{{ azureStorageAccountContainerBlob "https://foobar.blob.core.windows.net/examplecontainer/file.json" }}
## Fetch secret value from Azure KeyVault (using only name; only AzurePublicCloud, AzureChinaCloud and AzureGovernmentCloud)
{{ (azKeyVaultSecret "examplevault" "secretname").value }}
{{ (azKeyVaultSecret "examplevault" "secretname").attributes.exp | fromUnixtime | toRFC3339 }}
## Fetch secret value from Azure KeyVault (using full url)
{{ (azKeyVaultSecret "https://examplevault.vault.azure.net/" "secretname").value }}
## Fetch current environmentName
{{ azAccountInfo.environmentName }}
## Fetch current tenantId
{{ azAccountInfo.tenantId }}
## Fetch current selected subscription displayName
{{ azSubscription.displayName }}
## Fetch RoleDefinition id for "owner" role
{{ (azRoleDefinition "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" "Owner").name }}
## Executes ResourceGraph query and returns result as yaml
{{ azResourceGraphQuery "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" `resources | where resourceGroup contains "xxxx"` | toYaml }}
or
{{ `resources | where resourceGroup contains "xxxx"` | azResourceGraphQuery "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" | toYaml }}
## Fetch kubeconfig from AKS managed cluster
{{ (index (azManagedClusterUserCredentials "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourcegroups/example-rg/providers/Microsoft.ContainerService/managedClusters/foobar").kubeconfigs 0).value | b64dec }}
PS: some code is borrowed from Helm