azcfg

package module
v0.10.1 Latest Latest
Warning

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

Go to latest
Published: Nov 29, 2023 License: MIT Imports: 13 Imported by: 1

README

azcfg

Go Reference

Azure Config - Set Azure Key Vault secrets and Azure App Config settings to a struct

This module is used to get secrets from an Azure Key Vault and settings from App Configuraion and set them into a struct. The idea of parsing configuration values into a struct was inspired by env.

It is not required to have a Key Vault if not parsing secrets, and it is not required to have an App Configuration if not parsing settings.

To mark a field in a struct to be populated by a secret set the struct tag secret followed by the name of the secret in Azure Key Vault, like so:

`secret:"<secret-name>"`

To mark a field i a struct to be populated by a setting set the struct tag setting followed by the name of the setting in Azure App Configuration, like so:

`setting:"<setting-name>"`

If the secret or setting does not exist the field will keep the value it had prior to the call to Parse.

The secret and setting can be marked as required, this will make the call to Parse return an error if the they do not exist:

secret:"<secret-name>,required"
setting:"<setting-name>,required"

The error message contains all fields that have been marked as required that didn't have a value associated with them.

Note: Unexported fields will be ignored.

Getting started

Install
go get github.com/KarlGW/azcfg
Prerequisites
  • Go 1.18
  • Azure Key Vault (if using secrets)
    • Identity with access to secrets in the Key Vault
  • Azure App Configuration (is using settings and configuration)
    • Identity with access to the App Configuration
Example

Using a managed identity as credentials on an Azure service. For other authentication and credential methods see the sections Authentication and Credentials.

Example with secrets (Key Vault)
package main

import (
    "github.com/KarlGW/azcfg"
)

type config struct {
    Host string
    Port int

    Username string `secret:"username"`
    Password string `secret:"password"`

    Credential credential
}

type credential struct {
    Key int `secret:"key"`
}

func main() {
    cfg := config{}
    if err := azcfg.Parse(&cfg); err != nil {
        // Handle error.
    }

    fmt.Printf("%+v\n", cfg)
}
{Host: Port:0 Username:username-from-keyvault Password:password-from-keyvault Credential:{Key:12345}}
Example with settings (App Configuration)
package main

import (
    "github.com/KarlGW/azcfg"
)

type config struct {
    Host string
    Port int

    Username string `setting:"username"`
    Password string `setting:"password"`

    Credential credential
}

type credential struct {
    Key int `setting:"key"`
}

func main() {
    cfg := config{}
    if err := azcfg.Parse(&cfg); err != nil {
        // Handle error.
    }

    fmt.Printf("%+v\n", cfg)
}
{Host: Port:0 Username:username-from-appconfig Password:password-from-appconfig Credential:{Key:12345}}
Example using both secrets (Key Vault) and settings (App Configuration)
package main

import (
    "github.com/KarlGW/azcfg"
)

type config struct {
    Host string
    Port int

    Username string `setting:"username"`
    Password string `setting:"password"`

    Credential credential
}

type credential struct {
    Key int `secret:"key"`
}

func main() {
    cfg := config{}
    if err := azcfg.Parse(&cfg); err != nil {
        // Handle error.
    }

    fmt.Printf("%+v\n", cfg)
}
{Host: Port:0 Username:username-from-appconfig Password:password-from-appconfig Credential:{Key:12345}}

Usage

Supported types

  • string
  • bool
  • uint, uint8, uint16, uint32, uint64
  • int, int8, int16, int32, int64
  • float32, float64
Options

Options can be provided to Parse or NewParser:

package main

import (
    "github.com/KarlGW/azcfg"
)

func main() {
    cfg := config{}
    if err := azcfg.Parse(&cfg, func(o *Options) {
        o.Credential = cred
        o.KeyVault = "vault"
        o.AppConfiguration = "appconfig"
        o.Concurrency = 20
        o.Timeout = time.Millisecond * 1000 * 20
    }); err != nil {
        // Handle error.
    }
}

Option functions are provided by the module for convenience, see Option.

Required

The default behaviour of Parse is to ignore secrets and settings that does not exist and let the field contain it's original value. To enforce fields to be set the option required can be used.

type Example struct {
    FieldA `secret:"field-a"`
    FieldB `secret:"field-b,required"`
    FieldC `setting:"field-c,required"`
}

If a required secret or setting doesn't exist in the Key Vault an error will be returned. The error message contains all fields that have been marked as required that didn't have a secret or setting associated with them.

Parser

An independent parser can be created and passed around inside of the application.

package main

import (
    "github.com/KarlGW/azcfg"
)

func main() {
    parser, err := azcfg.NewParser()
    if err != nil {
        // Handle error.
    }

    cfg := config{}
    if err := parser.Parse(&cfg); err != nil {
        // Handle error.
    }
}

The constructor function NewParser supports the same options as the module level Parse function. For supported options see Options struct or list of function options in the Options section.

App Configuration setting labels

Settings in App Configuration can have labels associated with them. To target a specific label (applies to all settings) either:

  • Set the label to the environment variable AZCFG_APPCONFIGURATION_LABEL.
  • Use the option function WithLabel.
Authentication

The module supports several ways of authenticating to Azure and get secrets from the target Key Vault and settings from the target App Configuration.

  1. Built-in credentials that supports Service Principal (Client Credentials with secret) and managed identity (system and user assigned)
  2. Credentials from azidentity with the submodule authopts
  3. Custom credential handling by implementing the auth.Credential interface.

For more information about option 2 and 3, see Credentials.

Built-in credentials

By default the module will attempt to determine credentials and target Key Vault with environment variables.

Environment variables

Service Principal

  • AZCFG_KEYVAULT_NAME - Name of the Azure Key Vault (if using secrets).
  • AZCFG_APPCONFIGURATION_NAME - Name of the Azure App Configuration (if using settings).
  • AZCFG_TENANT_ID - Tenant ID of the service principal/application registration.
  • AZCFG_CLIENT_ID - Client ID (also called Application ID) of the service principal/application registration.
  • AZCFG_CLIENT_SECRET- Client Secret of the service principal/application registration.

Managed identity

  • AZCFG_KEYVAULT_NAME - Name of the Azure Key Vault.
  • AZCFG_APPCONFIGURATION_NAME - Name of the Azure App Configuration.
  • AZCFG_CLIENT_ID - (Optional) Client ID (also called Application ID) of the Managed Identity. Set if using a user assigned managed identity.
Options

If more control is needed, such as custom environment variables or other means of getting the necessary values, options can be used.

Service Principal

azcfg.Parse(
    &cfg,
    azcfg.WithClientSecretCredential(tenantID, clientID, clientSecret),
    WithKeyVault(vault),
)

Managed identity

// System assigned identity.
azcfg.Parse(&cfg, WithManagedIdentity(), azcfg.WithKeyVault(vault))
// User assigned identity.
azcfg.Parse(&cfg, WithManagedIdentity(clientID), azcfg.WithKeyVault(vault))

To use a credential provided from elsewhere, such as the azidentity module see the section about Credentials.

Credentials

Custom credentials with token retrieval can be used using the option WithCredential. They must satisfy the interface Credential:

// Credential is the interface that wraps around method Token, Scope
// and SetScope.
type Credential interface {
	Token(ctx context.Context, options ...TokenOption) (Token, error)
}

Since it is reasonable to assume that credentials retrieved with the help of the azidentity module might be used, a submodule, authopts has been provided. This make it easer to reuse credentials from azidentity.

Usage

go get github.com/KarlGW/azcfg/authopts
package main

import (
    "github.com/Azure/azure-sdk-for-go/sdk/azcore"
    "github.com/KarlGW/azcfg"
    "github.com/KarlGW/azcfg/authopts"
)

func main() {
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
        // Handle error.
    }

    cfg := Config{}
    if err := azcfg.Parse(&cfg, authopts.WithTokenCredential(cred)); err != nil {
        // Handle error.
    }
}

For additional information about how to use azidentity, check its documentation.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidSecretClient is returned when a secret client is not configured
	// properly. Either Key Vault name is not set or a provided secretClient
	// is nil.
	ErrInvalidSecretClient = errors.New("invalid secret client")
	// ErrInvalidSettingClient is returned when a setting client is not configured
	// properly. Either App Configuration name is not set or a provided settingClient
	// is nil.
	ErrInvalidSettingClient = errors.New("invalid setting client")
)

Functions

func NewParser added in v0.6.0

func NewParser(options ...Option) (*parser, error)

NewParser creates and returns a *Parser. With no options provided it will have default settings for timeout and concurrency.

func Parse

func Parse(v any, options ...Option) error

Parse secrets from an Azure Key Vault into a struct.

Types

type HasValue added in v0.10.0

type HasValue interface {
	GetValue() string
}

HasValue wraps around method GetValue,

type Option added in v0.7.0

type Option func(o *Options)

Option is a function that sets Options.

func WithAppConfiguration added in v0.10.0

func WithAppConfiguration(appConfiguration string) Option

WithAppConfiguration sets the App Configuration for the parser.

func WithClientSecretCredential added in v0.7.0

func WithClientSecretCredential(tenantID, clientID, clientSecret string) Option

WithClientSecretCredential sets the parser to use client credential with a secret (client secret credential) for the Key Vault.

func WithConcurrency added in v0.7.0

func WithConcurrency(c int) Option

WithConcurrency sets the concurrency of the parser.

func WithCredential added in v0.7.0

func WithCredential(cred auth.Credential) Option

WithCredential sets the provided credential to the parser.

func WithKeyVault added in v0.10.0

func WithKeyVault(keyVault string) Option

WithKeyVault sets the Key Vault for the parser.

func WithLabel added in v0.10.0

func WithLabel(label string) Option

WithLabel sets the label for settings in App Configuration.

func WithManagedIdentity added in v0.7.0

func WithManagedIdentity(clientID ...string) Option

WithManagedIdentity sets the parser to use a managed identity for credentials for the Key Vault.

func WithSecretClient added in v0.8.0

func WithSecretClient(c secretClient) Option

WithSecretClient sets the client for secret retrieval.

func WithSettingClient added in v0.10.0

func WithSettingClient(c settingClient) Option

WithSettingClient sets the client for setting retreival.

func WithTimeout added in v0.7.0

func WithTimeout(d time.Duration) Option

WithTimeout sets the timeout of the parser.

type Options added in v0.4.0

type Options struct {
	// Credential is the credential to be used with the Client. Used to override
	// the default method of aquiring credentials.
	Credential auth.Credential
	// SecretClient is a client used to retrieve secrets.
	SecretClient secretClient
	// SettingClient is a client used to retrieve settings.
	SettingClient settingClient
	// KeyVault is the name of the Key Vault containing secrets. Used to override the
	// default method of aquiring target Key Vault.
	KeyVault string
	// AppConfiguration is the name of the App Configuration containing settibgs. Used to override the
	// default method of aquiring target App Configuration.
	AppConfiguration string
	// Label for setting in an Azure App Configuration.
	Label string
	// TenantID of the Service Principal with access to target Key Vault.
	TenantID string
	// ClientID of the Service Principal or user assigned managed identity with access to target Key Vault.
	ClientID string
	// ClientSecret of the Service Principal with access to target Key Vault.
	ClientSecret string
	// Concurrency is the amount of secrets that will be retrieved concurrently.
	// Defaults to 10.
	Concurrency int
	// Timeout is the total timeout for retrieval of secrets. Defaults to 10 seconds.
	Timeout time.Duration
	// UseManagedIdentity set to use a managed identity. To use a user assigned managed identity, use
	// together with ClientID.
	UseManagedIdentity bool
}

Options contains options for the Parser.

type RequiredFieldsError added in v0.10.0

type RequiredFieldsError struct {
	// contains filtered or unexported fields
}

RequiredFieldsError represents an error when either secrets or settings are required but not set.

func (*RequiredFieldsError) Error added in v0.10.0

func (e *RequiredFieldsError) Error() string

Error returns the combined error messages from the errors contained in RequiredFieldsError.

Directories

Path Synopsis
authopts module
internal

Jump to

Keyboard shortcuts

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