Skip to content

Terraform / IaC Extensibility

Terraform / IaC Extensibility

The IConfigurationSource interface is designed to be extended without modifying ConfigurationManager itself. This page describes the pattern for adding remote configuration sources such as Terraform outputs, Vault secrets, or remote APIs.


Adding a custom source

Implement IConfigurationSource:

import type { IConfigurationSource } from '../src/configuration/sources/index.ts';
import type { IConfiguration } from '../src/types/index.ts';
/**
* Loads a configuration from a Terraform output JSON file.
*
* Usage: terraform output -json > tf-config.json
*/
export class TerraformConfigurationSource implements IConfigurationSource {
readonly sourceType = 'terraform';
constructor(private readonly tfOutputPath: string) {}
async load(): Promise<Partial<IConfiguration>> {
const raw = JSON.parse(await Deno.readTextFile(this.tfOutputPath));
// Terraform outputs have the shape: { "key": { "value": ..., "type": ... } }
return {
name: raw.list_name?.value,
version: raw.list_version?.value,
sources: raw.sources?.value,
};
}
}

Then wire it into the manager:

import { ConfigurationManager, FileConfigurationSource } from '../src/configuration/index.ts';
const cfg = await ConfigurationManager.fromSources([
new TerraformConfigurationSource('./tf-config.json'),
new FileConfigurationSource('./override.json'),
]).load();

Precedence note

Custom sources follow the same merge order as built-in sources. Place higher-priority sources later in the array passed to fromSources().


Remote / async sources

Because load() is async, sources can fetch from remote APIs:

export class RemoteConfigSource implements IConfigurationSource {
readonly sourceType = 'remote';
constructor(private readonly url: string, private readonly token: string) {}
async load(): Promise<Partial<IConfiguration>> {
const res = await fetch(this.url, {
headers: { Authorization: `Bearer ${this.token}` },
});
if (!res.ok) throw new Error(`Remote config fetch failed: ${res.status}`);
return res.json();
}
}