env

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 13, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package env provides environment variable utilities for Azure Developer CLI (azd) extensions.

This package includes:

  • Key Vault reference resolution (ResolveMap, ResolveSlice)
  • Format conversion (MapToSlice, SliceToMap)
  • Pattern-based extraction (FilterByPrefix, ExtractPattern)
  • Service name normalization (NormalizeServiceName)

Key Vault Resolution

Use ResolveMap to resolve Azure Key Vault references in environment maps:

import (
	"github.com/jongio/azd-core/env"
	"github.com/jongio/azd-core/keyvault"
)

resolver, err := keyvault.NewKeyVaultResolver()
if err != nil {
	return err
}

envMap := map[string]string{
	"DATABASE_URL": "postgres://localhost/db",
	"API_KEY": "@Microsoft.KeyVault(VaultName=myvault;SecretName=api-key)",
}

resolved, warnings, err := env.ResolveMap(ctx, envMap, resolver, keyvault.ResolveEnvironmentOptions{})
if err != nil {
	return err
}
// resolved["API_KEY"] now contains the actual secret value from Key Vault

Pattern-Based Extraction

Extract environment variables matching specific patterns:

// Filter by prefix (case-insensitive)
azureVars := env.FilterByPrefix(envVars, "AZURE_")
// Returns: {"AZURE_TENANT_ID": "xyz", "AZURE_CLIENT_ID": "abc"}

// Extract SERVICE_*_URL with normalization
serviceURLs := env.ExtractPattern(envVars, env.PatternOptions{
	Prefix:       "SERVICE_",
	Suffix:       "_URL",
	TrimPrefix:   true,
	TrimSuffix:   true,
	Transform:    env.NormalizeServiceName,
})
// Returns: {"my-api": "https://...", "web-app": "https://..."}

Service Name Normalization

Convert environment variable naming to service naming conventions:

serviceName := env.NormalizeServiceName("MY_API_SERVICE")
// Returns: "my-api-service"

This is useful for converting uppercase underscore-separated names (common in environment variables) to lowercase hyphen-separated names (common in service identifiers, DNS labels, and container names).

Supported Key Vault Reference Formats

  • @Microsoft.KeyVault(SecretUri=https://...)
  • @Microsoft.KeyVault(VaultName=...;SecretName=...;SecretVersion=...)
  • akvs://<subscription-id>/<vault-name>/<secret-name>[/<version>]

Authentication

Key Vault resolution uses azidentity.DefaultAzureCredential, which supports:

  • Environment variables (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET)
  • Managed identity (Azure VM, App Service, Container Apps)
  • Azure CLI (az login)
  • Azure PowerShell
  • Interactive browser authentication

Error Handling

By default, resolution continues even if individual references fail (warnings are collected). Use StopOnError to fail fast:

opts := keyvault.ResolveEnvironmentOptions{StopOnError: true}
resolved, warnings, err := env.ResolveMap(ctx, envMap, resolver, opts)
if err != nil {
	// First error encountered
}

Package env provides environment variable resolution utilities with Azure Key Vault integration.

This package makes it easy for consumers (like azd-app and azd-exec) to resolve Azure Key Vault references in environment variables. It provides adapter functions to work with both map[string]string and []string representations of environment variables.

Usage with Environment Maps

Use ResolveMap when working with environment maps:

resolver, err := keyvault.NewKeyVaultResolver()
if err != nil {
	// handle error
}

envMap := map[string]string{
	"DATABASE_URL": "postgres://localhost/db",
	"API_KEY": "@Microsoft.KeyVault(VaultName=myvault;SecretName=api-key)",
}

resolved, warnings, err := env.ResolveMap(ctx, envMap, resolver, keyvault.ResolveEnvironmentOptions{})
if err != nil {
	// handle error
}
for _, w := range warnings {
	// log warning: w.Key, w.Err
}
// resolved["API_KEY"] now contains the actual secret value from Key Vault

Usage with Environment Slices

Use ResolveSlice when working with KEY=VALUE slices (e.g., from os.Environ()):

resolver, err := keyvault.NewKeyVaultResolver()
if err != nil {
	// handle error
}

envSlice := os.Environ() // or []string{"KEY=value", ...}
resolved, warnings, err := env.ResolveSlice(ctx, envSlice, resolver, keyvault.ResolveEnvironmentOptions{})
if err != nil {
	// handle error
}
// Use resolved with exec.Cmd: cmd.Env = resolved

Error Handling Options

By default, resolution continues even if individual references fail (warnings are collected). Use StopOnError to fail fast:

opts := keyvault.ResolveEnvironmentOptions{StopOnError: true}
resolved, warnings, err := env.ResolveMap(ctx, envMap, resolver, opts)
if err != nil {
	// Resolution failed, warnings contains details
}

Supported Key Vault Reference Formats

The package supports three Key Vault reference formats:

Helper Functions

The package also provides utility functions for working with environment variables:

  • MapToSlice: Convert map[string]string to []string (KEY=VALUE format)
  • SliceToMap: Convert []string to map[string]string (skips malformed entries)
  • HasKeyVaultReferences: Check if any Key Vault references exist

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractPattern added in v0.3.0

func ExtractPattern(envVars map[string]string, opts PatternOptions) map[string]string

ExtractPattern extracts environment variables matching prefix/suffix with key transformation. Pattern matching is case-insensitive. Returns a new map with transformed keys.

Example:

envVars := map[string]string{
	"SERVICE_API_URL": "https://api.example.com",
	"SERVICE_WEB_URL": "https://web.example.com",
	"SERVICE_DB_HOST": "db.example.com",
}

// Extract all SERVICE_*_URL variables and normalize service names
urls := env.ExtractPattern(envVars, env.PatternOptions{
	Prefix:     "SERVICE_",
	Suffix:     "_URL",
	TrimPrefix: true,
	TrimSuffix: true,
	Transform:  func(s string) string { return strings.ToLower(strings.ReplaceAll(s, "_", "-")) },
})
// Returns: {"api": "https://api.example.com", "web": "https://web.example.com"}

func FilterByPrefix added in v0.3.0

func FilterByPrefix(envVars map[string]string, prefix string) map[string]string

FilterByPrefix returns environment variables matching a prefix. The prefix matching is case-insensitive for keys. Returns a new map containing only the matching entries.

Example:

envVars := map[string]string{
	"AZURE_TENANT_ID": "xyz",
	"AZURE_CLIENT_ID": "abc",
	"DATABASE_URL": "postgres://...",
}
azureVars := env.FilterByPrefix(envVars, "AZURE_")
// Returns: {"AZURE_TENANT_ID": "xyz", "AZURE_CLIENT_ID": "abc"}

func FilterByPrefixSlice added in v0.3.0

func FilterByPrefixSlice(envSlice []string, prefix string) []string

FilterByPrefixSlice returns KEY=VALUE pairs matching a prefix. The prefix matching is case-insensitive for keys. Returns a new slice containing only the matching entries. Malformed entries (without "=") are skipped.

Example:

envSlice := []string{
	"AZURE_TENANT_ID=xyz",
	"AZURE_CLIENT_ID=abc",
	"DATABASE_URL=postgres://...",
}
azureVars := env.FilterByPrefixSlice(envSlice, "AZURE_")
// Returns: ["AZURE_TENANT_ID=xyz", "AZURE_CLIENT_ID=abc"]

func HasKeyVaultReferences

func HasKeyVaultReferences(envVars []string) bool

HasKeyVaultReferences quickly checks for any key vault formatted values.

func MapToSlice

func MapToSlice(env map[string]string) []string

MapToSlice converts an env map into KEY=VALUE entries.

func NormalizeServiceName added in v0.3.0

func NormalizeServiceName(envVarName string) string

NormalizeServiceName converts environment variable naming to service naming. Converts uppercase underscore-separated names to lowercase hyphen-separated names. Commonly used with ExtractPattern to normalize service names from environment variables.

Example:

name := env.NormalizeServiceName("MY_API_SERVICE")
// Returns: "my-api-service"

name = env.NormalizeServiceName("WEB_APP")
// Returns: "web-app"

func Resolve

Resolve applies a key vault resolver to the provided env map if needed.

func ResolveMap

ResolveMap applies the Key Vault resolver to an environment map. It converts the map to a slice, resolves any Key Vault references, and returns a new map with the resolved values. If resolver is nil or no Key Vault references are found, the original map is returned (as a copy).

This is the primary helper for consumers like azd-app and azd-exec that work with environment maps (e.g., from os.Environ() converted to a map).

Example usage:

resolver, err := keyvault.NewKeyVaultResolver()
if err != nil {
	// handle error
}
envMap := map[string]string{
	"DATABASE_URL": "postgres://localhost/db",
	"API_KEY": "@Microsoft.KeyVault(VaultName=myvault;SecretName=api-key)",
}
resolved, warnings, err := env.ResolveMap(ctx, envMap, resolver, keyvault.ResolveEnvironmentOptions{})
if err != nil {
	// handle error
}
for _, w := range warnings {
	// log warning: w.Key, w.Err
}
// resolved["API_KEY"] now contains the actual secret value

func ResolveSlice

func ResolveSlice(ctx context.Context, envSlice []string, resolver Resolver, opts keyvault.ResolveEnvironmentOptions) ([]string, []keyvault.KeyVaultResolutionWarning, error)

ResolveSlice applies the Key Vault resolver to an environment slice. It takes KEY=VALUE entries, resolves any Key Vault references, and returns a new slice with the resolved values. If resolver is nil or no Key Vault references are found, the original slice is returned (as a copy).

This is useful for consumers that work directly with environment slices (e.g., from os.Environ() or for passing to exec.Cmd.Env).

Example usage:

resolver, err := keyvault.NewKeyVaultResolver()
if err != nil {
	// handle error
}
envSlice := []string{
	"DATABASE_URL=postgres://localhost/db",
	"API_KEY=@Microsoft.KeyVault(VaultName=myvault;SecretName=api-key)",
}
resolved, warnings, err := env.ResolveSlice(ctx, envSlice, resolver, keyvault.ResolveEnvironmentOptions{})
if err != nil {
	// handle error
}
for _, w := range warnings {
	// log warning: w.Key, w.Err
}
// resolved can now be used with cmd.Env = resolved

func SliceToMap

func SliceToMap(envSlice []string) map[string]string

SliceToMap converts KEY=VALUE entries into a map, skipping malformed rows.

Types

type PatternOptions added in v0.3.0

type PatternOptions struct {
	// Prefix is the required prefix for keys (e.g., "SERVICE_")
	Prefix string

	// Suffix is the optional suffix for keys (e.g., "_URL")
	Suffix string

	// TrimPrefix removes the prefix from result keys if true
	TrimPrefix bool

	// TrimSuffix removes the suffix from result keys if true
	TrimSuffix bool

	// Transform is an optional key transformation function applied after trimming
	// Example: func(s string) string { return strings.ToLower(s) }
	Transform func(string) string

	// Validator is an optional value validation function
	// If provided, only entries where Validator(value) returns true are included
	// Example: func(v string) bool { return v != "" }
	Validator func(string) bool
}

PatternOptions configures pattern-based environment variable extraction.

type Resolver

type Resolver interface {
	ResolveEnvironmentVariables(ctx context.Context, env []string, opts keyvault.ResolveEnvironmentOptions) ([]string, []keyvault.KeyVaultResolutionWarning, error)
}

Resolver abstracts key vault environment resolution to ease testing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL