@windstream/app-config
v1.0.12
Published
module to load azure app config settings into process environment
Maintainers
Keywords
Readme
@windstream/app-config
Load Azure App Configuration settings (and their linked Key Vault secrets) into process.env for any service, in any environment.
1 Quick Start
Package Flow
The following diagram shows how the package components interact:
graph TD
A[Other Apps] -->|Uses| B[AppConfigManager]
B[AppConfigManager] -->|Calls| C[initAppConfiguration]
C -->|Returns| D[AppConfigData]You can use either the high-level AppConfigManager for automatic env file handling: RECCOMENDED USAGE
import { AppConfigManager } from '@windstream/app-config';
await AppConfigManager.init({
serviceName: 'my-service',
// Optional: envFileHandling check | skip, defaults to skip
// check forces attempt to update your .env.local generally used for build script to force update of .env.local
// skip will try to use you .env.local file only, if its missing it will try to create one
// RECOMMEND using default skip in your app and only using check for build script
});Or use the core initAppConfiguration function directly: BACKWARD COMPATILBLE USAGE
import { initAppConfiguration } from '@windstream/app-config';
await initAppConfiguration();Usage Examples
// if app config is only needed at runtime and not for build time like pre-rendering pages
// src/main.ts or possibly server.js
import * as dotenv from 'dotenv';
import { initAppConfiguration } from '@windstream/app-config';
// 1. Load .env when running locally (optional in CI/CD)
dotenv.config();
// 2. Populate process.env from Azure App Configuration only
await initAppConfiguration();
// 3. Your application logic…
bootstrap();// next.config.js
// Example of using next.config.js to load app configuration to support pre-rendering during build.
// You must still load your app configuration at run time, if you expect a an app restart to load the new config.
/** @type {import('next').NextConfig | (() => Promise<NextConfig>)} */
const nextConfig = async () => {
import { AppConfigManager } from '@windstream/app-config';
await AppConfigManager.init({
serviceName: 'my-service',
// Optional: envFileHandling check | skip, defaults to skip
// check forces attempt to update your .env.local generally used for build script to force update of .env.local
// skip will try to use you .env.local file only, if its missing it will try to create one
// RECOMMEND using default skip in your app and only using check for build script
});
return {
reactStrictMode: true,
output: "export",
trailingSlash: true,
transpilePackages: ["@win-kinetic/ui"],
images: {
unoptimized: true,
dangerouslyAllowSVG: true,
remotePatterns: [
{
protocol: "https",
hostname: "images.ctfassets.net",
pathname: "/8d4yn2ywtegc/**",
},
],
},
};
};
module.exports = nextConfig;2 Required Environment Variables
Set these four variables in your pipeline or .env file:
| Variable | Example | Description |
| -------- | ------- | ----------- |
| AZURE_APP_CONFIGURATION_ENDPOINT | https://appconfig-dotcom-dev-eus-001.azconfig.io | URL of the App Configuration instance. Defaults to https://appconfig-dotcom-dev-eus-001.azconfig.io|
| SERVICE_NAME | my-service | Must match the AKS service name (Helm serviceName). |
| DEPLOY_ENV | dev, uat, prod, or local | AKS environment. Defaults to local for desktop use. |
| REVIEW_ENV_PREFIX | 123456 | Optional. Pull-request/preview identifier that overrides other settings. |
These variables are only required when not using managed idenity or personal az login. In this case you will need to use a service principal. NOT RECCOMMENDED
| Variable | Example | Description |
| -------- | ------- | ----------- |
| AZURE_TENANT_ID | | Windstream Azure tenant ID |
| AZURE_CLIENT_ID | | Service Principal Client ID |
| AZURE_CLIENT_SECRET | | Service Principal Secret |
Endpoint cheat-sheet
| Cluster | App Config | Key Vault |
| ------- | ---------- | --------- |
| Non-prod | https://appconfig-dotcom-dev-eus-001.azconfig.io | https://kv-dotcom-dev-eus-001.vault.azure.net/ |
| Prod (East) | https://appconfig-dotcom-prod-eus-001.azconfig.io | https://kv-dotcom-prod-eus-001.vault.azure.net/ |
| Prod (West) | https://appconfig-dotcom-prod-wus-001.azconfig.io | https://kv-dotcom-prod-wus-001.vault.azure.net/ |
3 App Setting Naming Convention
: # e.g. my-service:API_URL• service-name ⇒ lower-case, kebab-case (matches AKS).
• ENV_VAR_NAME ⇒ UPPER_SNAKE_CASE (matches code).
Only keys that start with SERVICE_NAME: are loaded, allowing many services to share one App Config instance. Settings will be loaded in the order shown below. Any duplicate settings will be overwritten by the last setting loaded.
Labels
| Label | Purpose |
| ----- | ------- |
| common | Shared across every environment. |
| dev, uat, prod, local | Environment-specific overrides. |
| 123456 | Preview-specific overrides (optional). |
Filter by label or prefix in the Azure portal under Configuration Explorer.
4 Local Development
- Install the Azure CLI and run
az login. - Place
SERVICE_NAME(and optionally the other variables) in a.envfile. DEPLOY_ENVdefaults tolocal; most developers preferdevso desktop calls the shared dev resources.
5 AKS Authentication (Workload Identity)
Each namespace has a pre-configured Service Account federated to a Managed Identity:
| Cluster | Service Account |
| ------- | --------------- |
| AKS08 (dev) | mi-dotcom-apps-dev-eus |
| AKS09 (prod-east) | mi-dotcom-apps-prod-eus |
| AKS11 (prod-west) | mi-dotcom-apps-prod-wus |
Example Required Helm setting:
# values.yaml
deployment:
extraLabels:
azure.workload.identity/use: "true"Example deployment pipeline snippet:
- stage: DeployDev
dependsOn: Build
condition: and(succeeded('Build'),eq(variables.isDevelop, true))
jobs:
- template: std-deploy-2023-04-01.yaml@templates
parameters:
nodeSelector: kineticres
adoEnvName: ${{variables.adoEnv}}
clusterName: ${{variables.clusterName}}
environment: ${{variables.aksEnv}}
host: ${{variables.host}}
namespace: ${{variables.namespaceRoot}}-${{variables.aksEnv}}
serviceName: ${{variables.serviceName}}
dockerRepo: ${{variables.dockerRepo}}
dockerTag: ${{variables.dockerTag}}
pool : NODE-Builds
extraArg: >-
--set envArgs.DEPLOY_ENV="${{ variables.aksEnv }}"
--set envArgs.AZURE_APP_CONFIGURATION_ENDPOINT="${{ variables.appConfigUrl }}"
--set envArgs.REVIEW_ENV_PREFIX="$( reviewEnvPrefix )"
--set deployment.serviceAccountName="${{ variables.serviceAccountName }}"6 Using the Private npm Registry
Retrieve the read-only token (once per session):
• Bash
source scripts/get-npm-token.sh # requires az login• PowerShell
.\scripts\get-npm-token.ps1 # requires az loginNote: These scripts should be added to you repo. You can also manually retreive the token from any of the key vaults. Secret name is
npm-readonly-token.Ensure
NPM_TOKENis in your environment and.npmrccontains:@windstream:registry=https://registry.npmjs.org/ //registry.npmjs.org/:_authToken=${NPM_TOKEN} //registry.npmjs.org/:always-auth=true
7 Publishing This Package
pnpm install # install deps
pnpm version patch # bump version (or minor/major)
# at this point make your desired changes to the package then continue.
git add -A
git commit -m "chore: release vX.Y.Z"
git push
pnpm login # one-time (opens browser)
pnpm publishYour git workspace must be clean before running pnpm version.
8 Resources
• Azure AKS Workload Identity — https://learn.microsoft.com/azure/aks/workload-identity-deploy-cluster
• Managed identity setup details — managed-identity.txt
