@adaptiveworx/iac-core

中文文档
0.6.0发布于 2026/10/30Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 2891

Core utilities for AdaptiveWorX™ infrastructure-as-code: secret management, stack context detection, region resolution, CIDR allocation, and Zod-validated configuration schemas.

原始使用文档
文档目录32 节
  1. Install
  2. Quick start
  3. Naming
  4. Quick-start guides per cloud
  5. Public API
  6. config/
  7. utils/
  8. schemas/
  9. validation/
  10. types/
  11. Configuration via environment variables
  12. Required (when calling loadOrganizationOptionsFromEnv() )
  13. AWS-organization specifics
  14. Schema metadata overrides
  15. SecretManager / Infisical
  16. Multi-tenant override pattern
  17. 1. AdaptiveWorX-internal — convenience helper
  18. 2. External consumer (Azure) — explicit construction
  19. 3. External consumer (AWS) — env-var-driven, two-class comp…
  20. Picking your loader
  21. API reference
  22. SecretManager
  23. OrganizationConfig
  24. AWSAccountRegistry
  25. Utilities — region-utils
  26. Utilities — stack-utils
  27. Utilities — cidr-allocation
  28. Schemas — schemas/core
  29. Tested versions
  30. Stability
  31. License
  32. Repository + contributing

@adaptiveworx/iac-core

Core utilities for AdaptiveWorX™ Flow infrastructure-as-code: secret management, stack context detection, region resolution, CIDR allocation, and Zod-validated configuration schemas.

The package is multi-provider-aware (AWS today; Cloudflare, GitHub and Infisical as global providers; Azure and GCP planned) and is licensed under Apache 2.0 for use in any Pulumi + TypeScript project.

Install

pnpm add @adaptiveworx/iac-core
# or
yarn add @adaptiveworx/iac-core
# or
npm install @adaptiveworx/iac-core

zod is a peer dependency:

pnpm add zod

Quick start

import {
  OrganizationConfig,
  loadOrganizationOptionsFromEnv,
  SecretManager,
  detectStackContext,
} from "@adaptiveworx/iac-core";

// 1. Detect Pulumi stack context (provider, environment, region, purpose)
const ctx = detectStackContext();

// 2. Load organization options from env vars
const orgConfig = new OrganizationConfig(loadOrganizationOptionsFromEnv());

// 3. Fetch secrets via Infisical (or env-var fallback)
const sm = new SecretManager({ environment: ctx.environment });
const dbPassword = await sm.getSecret("DB_PASSWORD");

Subpath imports are supported for tree-shaking-sensitive consumers:

import { SecretManager } from "@adaptiveworx/iac-core/config/secrets";
import { resolveRegion } from "@adaptiveworx/iac-core/utils/region-utils";

Naming

A project is one account: {tenant}-{provider}-{account-purpose}-{env}. A stack is {target-env}-{stack-purpose}[-{concern}]-{region} (3 or 4 one-word segments, the target environment always first). Providers: aws, gcp, azure (regional: use1, usw2, …) and cloudflare, github, infisical (global: region glb).

ProjectStackReads as
worx-aws-app-devdev-flow-use1app account in dev, flow, us-east-1
worx-aws-ops-secsec-iam-github-use1ops account in sec, iam, concern github
worx-aws-ops-secdev-vpc-use1centralized: dev's VPC, from the ops account in sec
worx-cloudflare-ops-secsec-ztna-glbops account in sec, ztna, global

Only this grammar parses: a name in the legacy grammar ({tenant}-{provider}-{env} projects and their stacks) is refused, and 0.6 removed the alias map and the legacy parsers and builders (the table of replacements is in the naming doc). See docs/naming.md for the full grammar, the region rules per provider, account references and how to add a provider.

Quick-start guides per cloud

  • AWS quick start — full Pulumi + AWS deploy walkthrough; covers OrganizationConfig, AWSAccountRegistry, CIDR, and policy-pack integration
  • Azure quick start — Azure-shaped OrganizationConfig + region resolution + secrets; what works and what doesn't (yet)
  • GCP quick start — GCP-shaped OrganizationConfig + region resolution; lighter-weight than AWS

Public API

config/

  • SecretManager — fetches secrets from Infisical (mandatory in production paths) with .env.{env} file fallback. Public methods: getSecret, getOptionalSecret, getBooleanSecret, getDeploymentConfiguration, healthCheck.
  • OrganizationConfig — pure consumer of OrganizationOptions. Construct via new OrganizationConfig(opts); load options via loadOrganizationOptionsFromEnv() (generic) or loadAdaptiveOrganizationDefaults() (AdaptiveWorX-internal).
  • AWSAccountRegistry — discovers per-environment AWS accounts from SecretManager, optionally merged with caller-supplied "foundation accounts" (master, audit, log-archive, etc.).

utils/

  • stack-utils — detectStackContext, parseStackIdentity (StackIdentity), projectNameOf, stackNameOf, isAccountGrammarProject, validateStackContext, getEnvironmentConfig, getComplianceRequirements, validateCrossAccountOperation.
  • region-utils — resolveRegion, getRegionAliases, isValidRegion, validateAvailabilityZones (loads region aliases from @adaptiveworx/iac-schemas).
  • cidr-allocation — calculateVpcCidr, getVpcCidr for non-overlapping CIDR allocation across environments + regions.
  • stack-readme — generateStackReadme, exportStackReadme for auto-documenting Pulumi stacks.

schemas/

  • SCHEMA_CONFIG, SCHEMA_BASE_URL — canonical metadata for the IaC schema namespace.
  • schemas/core/core-schemas — Zod validators (StackContextSchema, ProjectNameSchema, StackNameSchema, DeploymentConfigSchema and PolicyConfigSchema (both take a provider and validate regions against it), AwsRegionSchema (derived from iac-schemas' REGIONS), etc.).
  • schemas/core/tags — StandardTagsSchema (the standard tag keys from iac-schemas, Workload included), WorkloadSchema, TagValueSchema.
  • schemas/core/providers — ProviderSchema, PROVIDER_DEFINITIONS, provider regions (isValidProviderRegion, resolveProviderRegion, GLOBAL_REGION_CODE), and provider-neutral account references (AccountReferenceSchema, accountReference).

validation/

  • AgentValidationService, ValidationPatterns — runtime guardrails for agent-driven IaC operations.
  • ConfigurationValidator — config-shape validators for stack/environment/component constraints.

types/

  • All shared infrastructure types: Provider, Environment, StackContext, DeploymentConfig, ComplianceRequirement, AccountConfig, CidrAllocation, etc.

Configuration via environment variables

The package follows a "config-in, behavior-out" pattern. Classes consume validated options; adapter helpers source those options. The library never reads process.env from a class constructor — only from the explicit loadXxxFromEnv() helpers.

Required (when calling loadOrganizationOptionsFromEnv())

VariablePurpose
ORG_NAMEDisplay name of your organization
ORG_TENANTShort tenant identifier (kebab-case)
ORG_DOMAINPrimary DNS domain (e.g. example.com)

AWS-organization specifics

iac-core is cloud-agnostic — AWS-organization config (org ID, master/security accounts, primary/DR region lists) lives in @adaptiveworx/iac-aws as AwsOrganizationConfig, with its own AWS_* env-var loaders. See the AWS quick start for the two-class composition pattern.

Schema metadata overrides

VariablePurposeDefault
IAC_SCHEMA_BASE_URLSchema publish URLhttps://schemas.adaptiveworx.com/iac
IAC_SCHEMA_CONTACT_NAMESchema contact nameAdaptive Intelligence, LLC
IAC_SCHEMA_CONTACT_URLSchema contact URLhttps://adaptiveworx.com

SecretManager / Infisical

VariablePurpose
INFISICAL_CLIENT_IDInfisical Universal Auth client ID
INFISICAL_CLIENT_SECRETInfisical Universal Auth client secret
INFISICAL_PROJECT_IDInfisical project ID
INFISICAL_SITE_URLSelf-hosted Infisical URL (defaults to public Infisical)

When Infisical credentials are absent, SecretManager falls back to .env.{IAC_ENV} files for local development.

Multi-tenant override pattern

OrganizationConfig is a pure consumer of validated options. Three loading patterns cover the common cases:

1. AdaptiveWorX-internal — convenience helper

For deployments inside AdaptiveWorX. Uses canonical defaults with env-var overrides on top.

import {
  OrganizationConfig,
  loadAdaptiveOrganizationDefaults,
} from "@adaptiveworx/iac-core";

const orgConfig = new OrganizationConfig(loadAdaptiveOrganizationDefaults());
// orgName: "AdaptiveWorX" (or process.env.ORG_NAME)
// tenant:  "worx"          (or process.env.ORG_TENANT)
// orgDomain: "adaptiveworx.com" (or process.env.ORG_DOMAIN)

For the AWS-organization specifics (org ID, accounts, regions), compose with AwsOrganizationConfig from @adaptiveworx/iac-aws.

2. External consumer (Azure) — explicit construction

For an Azure-only consumer. No AdaptiveWorX defaults leak in.

import { OrganizationConfig } from "@adaptiveworx/iac-core";

const orgConfig = new OrganizationConfig({
  orgName: "Acme Health",
  tenant: "care",
  orgDomain: "acme.example",
});

OrganizationConfig carries cloud-agnostic identity, environments, stack naming, and network strategy. Cloud-specific organization config (Management Groups, Tenants, Subscriptions) is not yet modeled — apply Azure-shaped values directly to your Pulumi resources for now.

3. External consumer (AWS) — env-var-driven, two-class composition

For an external AWS-based consumer. iac-core loads org identity from ORG_*; @adaptiveworx/iac-aws loads AWS-org specifics from AWS_*. No AdaptiveWorX defaults applied — every value comes from the environment.

import {
  OrganizationConfig,
  loadOrganizationOptionsFromEnv,
} from "@adaptiveworx/iac-core";
import {
  AwsOrganizationConfig,
  loadAwsOrganizationOptionsFromEnv,
} from "@adaptiveworx/iac-aws";

// Acme Co's deploy environment:
//   ORG_NAME="Acme Co"
//   ORG_TENANT="acme"
//   ORG_DOMAIN="acme.example"
//   AWS_ORG_ID="123456789012"
//   AWS_MASTER_ACCOUNT="acme-master"
//   AWS_SECURITY_ACCOUNT="acme-secops"
//   AWS_PRIMARY_REGIONS="us-east-2,us-west-1"
//   AWS_DR_REGIONS="eu-west-1"

const orgConfig = new OrganizationConfig(loadOrganizationOptionsFromEnv());
const awsConfig = new AwsOrganizationConfig(loadAwsOrganizationOptionsFromEnv());

orgConfig.orgName;                  // "Acme Co"
awsConfig.awsOrganizationId;        // "123456789012"
awsConfig.primaryRegions;           // ["us-east-2", "us-west-1"]

Picking your loader

LoaderWhen to useThrows if missing
loadAdaptiveOrganizationDefaults()You're AdaptiveWorX-internal and want canonical defaultsNo (defaults applied)
loadOrganizationOptionsFromEnv()You manage your own env-var contract, no AdaptiveWorX defaults wantedYes, on missing ORG_NAME / ORG_TENANT / ORG_DOMAIN
Direct new OrganizationConfig({...})You're constructing options from a config file, secrets manager, or test fixtureYes, if any of orgName / tenant / orgDomain is empty

The same pattern applies to AWSAccountRegistry — see the loadAdaptiveFoundationAccounts() helper for the AdaptiveWorX foundation-account fixture, or pass your own Map<string, FoundationAccount> via the foundationAccounts constructor option.

API reference

The most important public classes, with signatures and minimal examples. For the full surface, see src/index.ts.

SecretManager

Fetches secrets from Infisical (Universal Auth) with optional fallback to .env.{IAC_ENV} files for local development.

class SecretManager {
  constructor(defaultContext?: SecretContext);

  // Required secret — throws if absent in both Infisical and env vars
  getSecret(key: string, context?: SecretContext): Promise<string>;

  // Optional secret with fallback
  getOptionalSecret(key: string, defaultValue: string, context?: SecretContext): Promise<string>;

  // Boolean parser (truthy: "true" | "1" | "yes")
  getBooleanSecret(key: string, defaultValue?: boolean, context?: SecretContext): Promise<boolean>;

  // Resolves `AWS_ACCOUNTS` JSON from Infisical
  getAwsAccountsJson(): Promise<AwsAccountsMap>;
  getAwsAccountId(purpose: string, environment: string): Promise<string | null>;
  getAwsProfile(purpose: string, environment: string, _org: string): Promise<string | null>;

  // High-level deployment config (combines org config + secrets + accounts)
  getDeploymentConfiguration(): Promise<DeploymentConfig>;

  // Connection check — useful in CI to fail fast before running pulumi
  healthCheck(): Promise<{ infisicalAvailable: boolean; missingSecrets: string[] }>;
}

interface SecretContext {
  environment?: Environment;   // dev | stg | prd | sec
  provider?: string;          // Infisical folder /{provider}; default IAC_PROVIDER, then aws
  region?: string;
  purpose?: string;
}
const sm = new SecretManager({ environment: "dev" });
await sm.getSecret("DB_PASSWORD");
await sm.getOptionalSecret("LOG_LEVEL", "info");
const useFlag = await sm.getBooleanSecret("FEATURE_X_ENABLED", false);

Roadmap note: SecretManager is welded to Infisical today. A SecretsBackend pluggable interface (Azure Key Vault / AWS Secrets Manager / HashiCorp Vault / 1Password Connect / in-memory test) is designed in docs/design-secrets-backend.md but not yet implemented. The shape stays proposal-only until a concrete second consumer validates the interface against their real auth + secret layout. Existing callers will keep working when it lands — no public-API break.

OrganizationConfig

Pure consumer of OrganizationOptions. See the Multi-tenant override pattern above for how to source options.

class OrganizationConfig {
  readonly orgName: string;
  readonly tenant: string;
  readonly orgDomain: string;
  readonly environments: Record<string, EnvironmentConfig>;
  readonly stackNaming: StackNaming;
  readonly network: NetworkConfig;

  constructor(opts: OrganizationOptions);

  getEnvironmentConfig(environment: string): EnvironmentConfig | undefined;

  // Build a stack name from components — applies stackNaming.separator
  // and compresses the region per regionFormat
  formatStackName(org: string, provider: string, purpose: string, env: string, region: string): string;

  // Strategy lookup (none | single | multi-az | high-availability)
  getNatGatewayCount(environment: string): number;

  // Service feature flags — currently "monitoring", "guardduty"
  shouldEnableService(service: string, environment: string): boolean;

  // "data" | "backup" | "logs" → days
  getRetentionDays(retentionType: "data" | "backup" | "logs", environment: string): number;

  exportAsDict(): Record<string, unknown>;
}

The DEFAULT_ENVIRONMENTS, DEFAULT_STACK_NAMING, and DEFAULT_NETWORK constants are exported so consumers can compose their own options on top of the canonical layout without restating it:

import { OrganizationConfig, DEFAULT_ENVIRONMENTS } from "@adaptiveworx/iac-core";

const orgConfig = new OrganizationConfig({
  orgName: "Acme Co", tenant: "acme", orgDomain: "acme.example",
  environments: {
    ...DEFAULT_ENVIRONMENTS,
    qa: { ...DEFAULT_ENVIRONMENTS.dev, name: "QA", shortName: "stg" }, // add a custom env
  },
});

AWSAccountRegistry

Discovers per-environment AWS accounts from a SecretManager (typically Infisical's AWS_ACCOUNTS JSON) and merges them with optional "foundation accounts" — long-lived accounts (master, audit, log-archive, etc.) that sit outside the per-environment structure.

class AWSAccountRegistry {
  constructor(opts?: AwsAccountRegistryOptions);

  getFoundationAccountByName(accountName: string): FoundationAccount | undefined;
  getFoundationAccountByPurpose(purpose: string): FoundationAccount | undefined;

  getAccountsForEnvironment(environment: Environment): Promise<Map<string, AccountInfo>>;
  getAllAccounts(): Promise<Map<string, AccountInfo>>;
  getAccountById(accountId: string): Promise<AccountInfo | null>;
  getAccountByName(accountName: string): Promise<AccountInfo | null>;
  getAccountsByPurpose(purpose: string): Promise<Map<string, AccountInfo>>;

  // Returns the secops/hub account if exactly one is marked isVpcHub
  getHubAccount(): Promise<[string, AccountInfo] | [null, null]>;
  getSpokeAccounts(): Promise<Map<string, AccountInfo>>;

  clearCache(): void;
}

interface AwsAccountRegistryOptions {
  secretManager?: SecretManager;
  foundationAccounts?: Map<string, FoundationAccount>;
  accountNamingPrefix?: string;   // default "account"
}
import {
  AWSAccountRegistry,
  loadAdaptiveFoundationAccounts,
} from "@adaptiveworx/iac-core";

// AdaptiveWorX-internal — uses canonical foundation accounts + "worx" prefix
const registry = new AWSAccountRegistry({
  foundationAccounts: loadAdaptiveFoundationAccounts(),
  accountNamingPrefix: "worx",
});

const audit = registry.getFoundationAccountByName("adaptive-audit");
const dev = await registry.getAccountsForEnvironment("dev");

For external consumers, omit the helpers — the registry will discover accounts dynamically from SecretManager only:

const registry = new AWSAccountRegistry();   // empty foundation map, generic prefix

Utilities — region-utils

function resolveRegion(provider: Provider, regionAlias: string): string;
function getRegionAliases(provider: Provider): Record<string, string>;
function getRegions(provider: Provider): string[];
function isValidRegion(provider: Provider, region: string): boolean;
function validateAvailabilityZones(region: string, count: number): boolean;
import { resolveRegion } from "@adaptiveworx/iac-core";

resolveRegion("aws", "use1");      // "us-east-1"
resolveRegion("azure", "eus2");    // "eastus2"
resolveRegion("aws", "us-east-1"); // "us-east-1" (already canonical)

Utilities — stack-utils

function detectStackContext(): StackContext;
function validateStackContext(ctx: StackContext): ValidationResult;

// Project "{tenant}-{provider}-{account-purpose}-{env}", stack "{target-env}-{stack-purpose}[-{concern}]-{region}"
// e.g. "worx-aws-ops-sec" with "sec-iam-github-use1", or "dev-vpc-use1" (centralized)
function parseStackIdentity(projectName: string, stackName: string): StackIdentity; // throws on any other grammar
function projectNameOf(identity: StackIdentity): string;
function stackNameOf(identity: StackIdentity): string;
function isAccountGrammarProject(projectName: string): boolean;

function getEnvironmentConfig(env: Environment): EnvironmentConfig;
function getComplianceRequirements(env: Environment): ComplianceRequirement[];
function validateCrossAccountOperation(source: string, target: string): ValidationResult;

AWS-typed region resolution (resolveAwsRegion(regionCode): aws.Region) lives in @adaptiveworx/iac-aws — iac-core's cloud-agnostic boundary forbids @pulumi/aws references in its emitted types.

Utilities — cidr-allocation

// Pure CIDR math
function calculateVpcCidr(cidrBase: string, offset: number): string;

// Looks up the cidrBase from SecretManager (`VPC_CIDR_BASE`), then
// resolves an offset from regionsConfig.aws.cidrOffsets[region]
function getVpcCidr(
  environment: string,
  region: string,
  secretManager: SecretManager
): Promise<string>;
calculateVpcCidr("10.224.0.0/11", 0);  // "10.224.0.0/16" — us-east-1
calculateVpcCidr("10.224.0.0/11", 1);  // "10.225.0.0/16" — us-east-2

Schemas — schemas/core

Zod validators ready for safeParse / parse:

import {
  StackContextSchema,
  DeploymentConfigSchema,
  AwsRegionSchema,
  EnvironmentSchema,
  ComplianceRequirementSchema,
} from "@adaptiveworx/iac-core";

const result = StackContextSchema.safeParse(ctx);
if (!result.success) {
  console.error(result.error.issues);
}

Tested versions

DependencyRange
Node.js>=22.0.0
TypeScript^5.9.3
Pulumi^3.200.0
Zod^3.22.0 || ^4.0.0 (peer)
Infisical SDK^4.0.6

Stability

This is a 0.x release. The API may change in backwards-incompatible ways before 1.0. Once 1.0 ships, the package will follow Semantic Versioning.

License

Apache 2.0. See NOTICE for attribution requirements.

Repository + contributing

This package is developed in the AdaptiveWorX/iac-core monorepo at packages/iac-core/. See CONTRIBUTING.md for setup, workflow conventions, and the release process. File issues at https://github.com/AdaptiveWorX/iac-core/issues.

版本与发布记录

@adaptiveworx/iac-core 共发布 12 个版本,首次发布于 2026/04/29;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.6.0latest2026/10/309 天前
0.5.12026/10/2612 天前
0.5.02026/10/041 个月前
0.4.02026/10/041 个月前
0.3.22026/06/094 个月前
0.3.12026/05/135 个月前

关于 @adaptiveworx/iac-core 的常见问题

@adaptiveworx/iac-core 是什么?

Core utilities for AdaptiveWorX™ infrastructure-as-code: secret management, stack context detection, region resolution, CIDR allocation, and Zod-validated configuration schemas.

如何安装 @adaptiveworx/iac-core?

在项目目录运行 npm install @adaptiveworx/iac-core,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^4.0.0)、@pulumi/pulumi(^3.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@adaptiveworx/iac-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@adaptiveworx/iac-core 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@adaptiveworx/iac-core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=26.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@adaptiveworx/iac-core 可以商用吗?

@adaptiveworx/iac-core 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@adaptiveworx/iac-core 的下载量有多少?

根据 npm 官方下载统计,@adaptiveworx/iac-core 在 2026/10/05 – 2026/11/03 这 30 天内被下载 2,891 次,日均约 96 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@adaptiveworx/iac-core 还在维护吗?

最新版本 0.6.0 发布于 2026/10/30(9 天前);至今共发布 12 个版本,其中过去 12 个月发布了 12 个;首次发布于 2026/04/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。