@intentius/chant-lexicon-azure 0.124.31 → 0.124.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/appservice.js +7 -0
- package/dist/actions/compute.js +9 -0
- package/dist/actions/container.js +14 -0
- package/dist/actions/identity.js +11 -0
- package/dist/actions/index.js +11 -0
- package/dist/actions/keyvault.js +12 -0
- package/dist/actions/network.js +9 -0
- package/dist/actions/sql.js +9 -0
- package/dist/actions/storage.js +15 -0
- package/dist/api/read-client.js +146 -0
- package/dist/codegen/docs-cli.js +2 -0
- package/dist/codegen/docs.js +83 -0
- package/dist/codegen/generate-cli.js +11 -0
- package/dist/codegen/generate-lexicon.js +77 -0
- package/dist/codegen/generate-typescript.js +163 -0
- package/dist/codegen/generate.js +106 -0
- package/dist/codegen/naming.js +139 -0
- package/dist/codegen/package.js +64 -0
- package/dist/composites/aks-cluster.js +68 -0
- package/dist/composites/app-service.js +62 -0
- package/dist/composites/application-gateway.js +107 -0
- package/dist/composites/catalog.js +856 -0
- package/dist/composites/container-instance.js +36 -0
- package/dist/composites/container-registry.js +62 -0
- package/dist/composites/cosmos-database.js +56 -0
- package/dist/composites/from-arm.js +47 -0
- package/dist/composites/function-app.js +57 -0
- package/dist/composites/index.js +16 -0
- package/dist/composites/keyvault.js +69 -0
- package/dist/composites/landing-zone.js +119 -0
- package/dist/composites/private-endpoint.js +61 -0
- package/dist/composites/redis-cache.js +21 -0
- package/dist/composites/service-bus-pipeline.js +54 -0
- package/dist/composites/sql-database.js +62 -0
- package/dist/composites/storage-account.js +59 -0
- package/dist/composites/vm-linux.js +139 -0
- package/dist/composites/vnet-default.js +102 -0
- package/dist/coverage.js +28 -0
- package/dist/deep-observe.js +356 -0
- package/dist/default-tags.js +50 -0
- package/dist/deploy-scopes.d.ts.map +1 -1
- package/dist/deploy-scopes.js +157 -0
- package/dist/describe-resources.js +187 -0
- package/dist/detect.js +17 -0
- package/dist/export-resources.js +108 -0
- package/dist/generated/index.js +16598 -0
- package/dist/generated/runtime.js +4 -0
- package/dist/governance.js +144 -0
- package/dist/import/generator.js +140 -0
- package/dist/import/live-export.js +39 -0
- package/dist/import/parser.js +192 -0
- package/dist/index.js +44 -0
- package/dist/integrity.json +2 -2
- package/dist/intrinsics.js +179 -0
- package/dist/lint/audit-catalog.js +36 -0
- package/dist/lint/audit-lineage.js +71 -0
- package/dist/lint/post-synth/arm-refs.js +94 -0
- package/dist/lint/post-synth/azr010.js +45 -0
- package/dist/lint/post-synth/azr011.js +43 -0
- package/dist/lint/post-synth/azr012.js +41 -0
- package/dist/lint/post-synth/azr013.js +50 -0
- package/dist/lint/post-synth/azr014.js +49 -0
- package/dist/lint/post-synth/azr015.js +66 -0
- package/dist/lint/post-synth/azr016.js +37 -0
- package/dist/lint/post-synth/azr017.js +37 -0
- package/dist/lint/post-synth/azr018.js +42 -0
- package/dist/lint/post-synth/azr019.js +41 -0
- package/dist/lint/post-synth/azr020.js +37 -0
- package/dist/lint/post-synth/azr021.js +36 -0
- package/dist/lint/post-synth/azr022.js +39 -0
- package/dist/lint/post-synth/azr023.js +39 -0
- package/dist/lint/post-synth/azr024.js +39 -0
- package/dist/lint/post-synth/azr025.js +37 -0
- package/dist/lint/post-synth/azr026.js +38 -0
- package/dist/lint/post-synth/azr027.js +37 -0
- package/dist/lint/post-synth/azr028.js +37 -0
- package/dist/lint/post-synth/azr029.js +38 -0
- package/dist/lint/post-synth/azr030.js +44 -0
- package/dist/lint/post-synth/azr031.js +36 -0
- package/dist/lint/post-synth/azr032.js +53 -0
- package/dist/lint/post-synth/azr033.js +35 -0
- package/dist/lint/post-synth/index.js +50 -0
- package/dist/lint/rules/hardcoded-location.js +82 -0
- package/dist/lint/rules/index.js +6 -0
- package/dist/lint/rules/nsg-wildcard.js +44 -0
- package/dist/lint/rules/storage-https.js +62 -0
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +18 -0
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +44 -0
- package/dist/manifest.json +1 -1
- package/dist/op/activities/az-apply.js +563 -0
- package/dist/op/activities/azure.js +48 -0
- package/dist/op/activities/floci-az.js +37 -0
- package/dist/op/activities/index.js +10 -0
- package/dist/op/builders.js +70 -0
- package/dist/ownership.js +13 -0
- package/dist/package-cli.js +21 -0
- package/dist/parameter.js +13 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +472 -0
- package/dist/pseudo.js +40 -0
- package/dist/serializer.js +457 -0
- package/dist/spec/api-versions.js +130 -0
- package/dist/spec/fetch.js +196 -0
- package/dist/spec/parse.js +308 -0
- package/dist/taggable.js +34 -0
- package/dist/validate-cli.js +16 -0
- package/dist/validate.js +53 -0
- package/package.json +8 -8
- package/src/codegen/package.ts +2 -2
- package/src/deploy-scopes.ts +2 -1
- package/src/lsp/completions.ts +2 -1
- package/src/lsp/hover.ts +2 -1
- package/src/plugin.ts +3 -2
- package/src/serializer.ts +2 -2
- package/src/taggable.ts +2 -2
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed step-builder wrappers for this lexicon's activities (chant #1288
|
|
3
|
+
* Stage 2). See `lexicons/k8s/src/op/builders.ts`'s module doc for why these
|
|
4
|
+
* live beside their `*Args` interfaces rather than in core: core cannot
|
|
5
|
+
* import a lexicon's types, so a wrapper whose `opts` IS the activity's own
|
|
6
|
+
* `*Args` interface can only sit in the lexicon that declares that
|
|
7
|
+
* interface. `opts`'s type in each wrapper below IS the activity's own
|
|
8
|
+
* `*Args` interface (via `Omit`/`WithStepRefs`) — never restated. `core`'s own
|
|
9
|
+
* `azApply`/`azDelete`/`azGroupEnsure`/`azGroupDelete`/`flociAzUp`/
|
|
10
|
+
* `flociAzDown` are unchanged and produce byte-identical `ActivityStep`
|
|
11
|
+
* output; these are purely additive.
|
|
12
|
+
*/
|
|
13
|
+
import { activity, takeProfileAndId, } from "@intentius/chant/op";
|
|
14
|
+
/**
|
|
15
|
+
* Ensure an Azure resource group exists before an ARM apply — the fully
|
|
16
|
+
* typed twin of core's `azGroupEnsure`. `opts` is {@link AzGroupEnsureArgs}
|
|
17
|
+
* itself, minus the positional `resourceGroup`. Defaults to the
|
|
18
|
+
* `fastIdempotent` profile.
|
|
19
|
+
*/
|
|
20
|
+
export const azGroupEnsure = (resourceGroup, opts) => {
|
|
21
|
+
const { args, profile, id } = takeProfileAndId(opts);
|
|
22
|
+
return activity("azGroupEnsure", { resourceGroup, ...args }, { profile: profile ?? "fastIdempotent", ...(id ? { id } : {}) });
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Delete an Azure resource group and its contents — the fully typed twin of
|
|
26
|
+
* core's `azGroupDelete`. `opts` is {@link AzGroupDeleteArgs} itself, minus
|
|
27
|
+
* the positional `resourceGroup`. Defaults to the `fastIdempotent` profile.
|
|
28
|
+
*/
|
|
29
|
+
export const azGroupDelete = (resourceGroup, opts) => {
|
|
30
|
+
const { args, profile, id } = takeProfileAndId(opts);
|
|
31
|
+
return activity("azGroupDelete", { resourceGroup, ...args }, { profile: profile ?? "fastIdempotent", ...(id ? { id } : {}) });
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Apply a built ARM template directly to the ARM resource API — the fully
|
|
35
|
+
* typed twin of core's `azApply`. `opts` is {@link AzApplyArgs} itself,
|
|
36
|
+
* minus the positional `templatePath` (`resourceGroup` remains required).
|
|
37
|
+
* Defaults to the `longInfra` profile.
|
|
38
|
+
*/
|
|
39
|
+
export const azApply = (templatePath, opts) => {
|
|
40
|
+
const { args, profile, id } = takeProfileAndId(opts);
|
|
41
|
+
return activity("azApply", { templatePath, ...args }, { profile: profile ?? "longInfra", ...(id ? { id } : {}) });
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Delete the Azure (ARM) resources in a built template — the inverse of
|
|
45
|
+
* {@link azApply}, fully typed twin of core's `azDelete`. `opts` is
|
|
46
|
+
* {@link AzApplyArgs} itself (the activity reuses it), minus the positional
|
|
47
|
+
* `templatePath`. Defaults to the `longInfra` profile.
|
|
48
|
+
*/
|
|
49
|
+
export const azDelete = (templatePath, opts) => {
|
|
50
|
+
const { args, profile, id } = takeProfileAndId(opts);
|
|
51
|
+
return activity("azDelete", { templatePath, ...args }, { profile: profile ?? "longInfra", ...(id ? { id } : {}) });
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Boot a local floci-az (Azure emulator) — the fully typed twin of core's
|
|
55
|
+
* `flociAzUp`. `opts` is {@link FlociAzUpArgs} itself. Defaults to the
|
|
56
|
+
* `longInfra` profile.
|
|
57
|
+
*/
|
|
58
|
+
export const flociAzUp = (opts) => {
|
|
59
|
+
const { args, profile, id } = takeProfileAndId(opts);
|
|
60
|
+
return activity("flociAzUp", args, { profile: profile ?? "longInfra", ...(id ? { id } : {}) });
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Stop and remove the local floci-az container — the fully typed twin of
|
|
64
|
+
* core's `flociAzDown`. `opts` is {@link FlociAzDownArgs} itself. Defaults
|
|
65
|
+
* to the `fastIdempotent` profile.
|
|
66
|
+
*/
|
|
67
|
+
export const flociAzDown = (opts) => {
|
|
68
|
+
const { args, profile, id } = takeProfileAndId(opts);
|
|
69
|
+
return activity("flociAzDown", args, { profile: profile ?? "fastIdempotent", ...(id ? { id } : {}) });
|
|
70
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The azure lexicon's ownership tag convention. Azure tag keys forbid `/`, so
|
|
3
|
+
* chant's markers use a hyphenated `chant-<name>` form (distinct from the
|
|
4
|
+
* label-based convention core keeps for k8s/gcp, and from AWS's `chant:<name>`).
|
|
5
|
+
* Core owns the generic stamp/detect logic (@intentius/chant/ownership); this is
|
|
6
|
+
* the azure-specific key naming it stamps.
|
|
7
|
+
*/
|
|
8
|
+
/** Azure tag keys for chant's ownership markers. */
|
|
9
|
+
export const AZURE_TAG_OWNERSHIP_KEYS = {
|
|
10
|
+
managedBy: "chant-managed-by",
|
|
11
|
+
stack: "chant-stack",
|
|
12
|
+
env: "chant-env",
|
|
13
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Thin entry point for `npm run bundle` in lexicon-azure.
|
|
4
|
+
* Generates src/generated/ files and writes dist/ bundle.
|
|
5
|
+
*/
|
|
6
|
+
import { generate, writeGeneratedFiles } from "./codegen/generate.js";
|
|
7
|
+
import { packageLexicon } from "./codegen/package.js";
|
|
8
|
+
import { writeBundleSpec } from "@intentius/chant/codegen/package";
|
|
9
|
+
import { join, dirname } from "path";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
12
|
+
// 1. Generate src/generated/ files
|
|
13
|
+
const genResult = await generate({ verbose: true });
|
|
14
|
+
writeGeneratedFiles(genResult, pkgDir);
|
|
15
|
+
console.error(`Generated ${genResult.resources} resources, ${genResult.properties} property types, ${genResult.enums} enums`);
|
|
16
|
+
// 2. Run package pipeline and write dist/
|
|
17
|
+
const { spec, stats } = await packageLexicon({ verbose: true });
|
|
18
|
+
const distDir = join(pkgDir, "dist");
|
|
19
|
+
writeBundleSpec(spec, distDir);
|
|
20
|
+
console.error(`Packaged ${stats.resources} resources, ${stats.ruleCount} rules, ${stats.skillCount} skills`);
|
|
21
|
+
console.error(`dist/ written to ${distDir}`);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { DECLARABLE_MARKER } from "@intentius/chant/declarable";
|
|
3
|
+
export class Parameter {
|
|
4
|
+
constructor(type, options) {
|
|
5
|
+
this[_a] = true;
|
|
6
|
+
this.lexicon = "azure";
|
|
7
|
+
this.entityType = "Microsoft.Resources/deployments/parameter";
|
|
8
|
+
this.parameterType = type;
|
|
9
|
+
this.description = options?.description;
|
|
10
|
+
this.defaultValue = options?.defaultValue;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
_a = DECLARABLE_MARKER;
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,0BAA0B,CAAC;AA0B5E;;;;;GAKG;AACH,eAAO,MAAM,WAAW,EAAE,aAodzB,CAAC"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { compositeCatalog } from "./composites/catalog.js";
|
|
2
|
+
import { detectTemplate } from "./detect.js";
|
|
3
|
+
import { postSynthChecks as postSynthCheckList } from "./lint/post-synth/index.js";
|
|
4
|
+
import { azureAuditCatalog } from "./lint/audit-catalog.js";
|
|
5
|
+
import { FLOCI_AZ_EMULATOR } from "./op/activities/floci-az.js";
|
|
6
|
+
import { createSkillsLoader } from "@intentius/chant/lexicon-plugin-helpers";
|
|
7
|
+
import { readFileSync, readdirSync, existsSync } from "fs";
|
|
8
|
+
import { join, dirname } from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import { moduleSourceDir } from "@intentius/chant/module-source";
|
|
11
|
+
import { azureSerializer } from "./serializer.js";
|
|
12
|
+
import { hardcodedLocationRule } from "./lint/rules/hardcoded-location.js";
|
|
13
|
+
import { storageHttpsRule } from "./lint/rules/storage-https.js";
|
|
14
|
+
import { nsgWildcardRule } from "./lint/rules/nsg-wildcard.js";
|
|
15
|
+
import { ArmParser } from "./import/parser.js";
|
|
16
|
+
import { ArmGenerator } from "./import/generator.js";
|
|
17
|
+
import { azureCompletions } from "./lsp/completions.js";
|
|
18
|
+
import { azureHover } from "./lsp/hover.js";
|
|
19
|
+
import { azureDeepNormalizationHooks, observeResourcesDeepAzure } from "./deep-observe.js";
|
|
20
|
+
import { AZURE_TAG_OWNERSHIP_KEYS } from "./ownership.js";
|
|
21
|
+
/**
|
|
22
|
+
* Azure Resource Manager lexicon plugin.
|
|
23
|
+
*
|
|
24
|
+
* Provides serializer, lint rules, template detection,
|
|
25
|
+
* import parsing, and code generation for Azure ARM templates.
|
|
26
|
+
*/
|
|
27
|
+
export const azurePlugin = {
|
|
28
|
+
name: "azure",
|
|
29
|
+
ownershipChannel: { keys: AZURE_TAG_OWNERSHIP_KEYS, reads: ["exportResources"] },
|
|
30
|
+
emulator: FLOCI_AZ_EMULATOR,
|
|
31
|
+
auditCatalog: () => azureAuditCatalog,
|
|
32
|
+
serializer: azureSerializer,
|
|
33
|
+
lintRules() {
|
|
34
|
+
return [hardcodedLocationRule, storageHttpsRule, nsgWildcardRule];
|
|
35
|
+
},
|
|
36
|
+
/**
|
|
37
|
+
* chant #1044 — azure has no tagged templates at all, so before this every
|
|
38
|
+
* intrinsic use fell the whole file back to the run path. All nine opt
|
|
39
|
+
* their call form in.
|
|
40
|
+
*
|
|
41
|
+
* Audited against `IntrinsicDef.foldsAsCall` (core's lexicon.ts): each one
|
|
42
|
+
* stores its arguments and renders an ARM bracket expression at
|
|
43
|
+
* serialization time (../intrinsics.ts). Nothing is evaluated locally —
|
|
44
|
+
* `UniqueString(x)` emits `[uniqueString(x)]` for ARM to hash at deployment
|
|
45
|
+
* (it does not hash anything at build time), and `Reference`/`ListKeys`
|
|
46
|
+
* name a deployment-time read rather than performing one. Every call is a
|
|
47
|
+
* pure function of its arguments, so calling it while folding is
|
|
48
|
+
* indistinguishable from calling it during a real run of the file.
|
|
49
|
+
*/
|
|
50
|
+
intrinsics() {
|
|
51
|
+
return [
|
|
52
|
+
{ name: "ResourceId", description: "Generate a resource ID for an Azure resource", isTag: false, foldsAsCall: true },
|
|
53
|
+
{ name: "Reference", description: "Get the runtime state of a deployed resource", isTag: false, foldsAsCall: true },
|
|
54
|
+
{ name: "Concat", description: "Concatenate multiple string values", isTag: false, foldsAsCall: true },
|
|
55
|
+
{ name: "ResourceGroup", description: "Get the current resource group object", isTag: false, foldsAsCall: true },
|
|
56
|
+
{ name: "Subscription", description: "Get the current subscription object", isTag: false, foldsAsCall: true },
|
|
57
|
+
{ name: "UniqueString", description: "Generate a deterministic hash string", isTag: false, foldsAsCall: true },
|
|
58
|
+
{ name: "Format", description: "Format a string with arguments", isTag: false, foldsAsCall: true },
|
|
59
|
+
{ name: "If", description: "Conditional expression", isTag: false, foldsAsCall: true },
|
|
60
|
+
{ name: "ListKeys", description: "List access keys for a resource", isTag: false, foldsAsCall: true },
|
|
61
|
+
];
|
|
62
|
+
},
|
|
63
|
+
pseudoParameters() {
|
|
64
|
+
return [
|
|
65
|
+
"Azure.ResourceGroupName",
|
|
66
|
+
"Azure.ResourceGroupLocation",
|
|
67
|
+
"Azure.ResourceGroupId",
|
|
68
|
+
"Azure.SubscriptionId",
|
|
69
|
+
"Azure.TenantId",
|
|
70
|
+
"Azure.DeploymentName",
|
|
71
|
+
];
|
|
72
|
+
},
|
|
73
|
+
initTemplates(template) {
|
|
74
|
+
if (template === "web-app") {
|
|
75
|
+
return {
|
|
76
|
+
src: {
|
|
77
|
+
"main.ts": `/**
|
|
78
|
+
* Azure infrastructure — App Service web application
|
|
79
|
+
*
|
|
80
|
+
* Deploys an App Service Plan + Web App with:
|
|
81
|
+
* - Managed identity (SystemAssigned)
|
|
82
|
+
* - HTTPS-only traffic
|
|
83
|
+
* - Minimum TLS 1.2
|
|
84
|
+
* - FTPS disabled
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
import { AppService } from "@intentius/chant-lexicon-azure";
|
|
88
|
+
import { CoreParameter, StackOutput } from "@intentius/chant";
|
|
89
|
+
|
|
90
|
+
export const environment = new CoreParameter({
|
|
91
|
+
name: "environment",
|
|
92
|
+
type: "string",
|
|
93
|
+
default: "dev",
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const { plan, webApp } = AppService({
|
|
97
|
+
name: "my-web-app",
|
|
98
|
+
sku: "B1",
|
|
99
|
+
runtime: "NODE|18-lts",
|
|
100
|
+
tags: { environment: "dev" },
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
export { plan, webApp };
|
|
104
|
+
|
|
105
|
+
export const appUrl = new StackOutput({
|
|
106
|
+
name: "appUrl",
|
|
107
|
+
value: \`https://my-web-app.azurewebsites.net\`,
|
|
108
|
+
});
|
|
109
|
+
`,
|
|
110
|
+
"tags.ts": `import { defaultTags } from "@intentius/chant-lexicon-azure";
|
|
111
|
+
|
|
112
|
+
export const tags = defaultTags([
|
|
113
|
+
{ key: "Project", value: "my-web-app" },
|
|
114
|
+
{ key: "Environment", value: "dev" },
|
|
115
|
+
]);
|
|
116
|
+
`,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (template === "aks-cluster") {
|
|
121
|
+
return {
|
|
122
|
+
src: {
|
|
123
|
+
"main.ts": `/**
|
|
124
|
+
* Azure infrastructure — AKS Kubernetes cluster
|
|
125
|
+
*
|
|
126
|
+
* Deploys an AKS cluster with:
|
|
127
|
+
* - Managed identity
|
|
128
|
+
* - RBAC enabled
|
|
129
|
+
* - Standard load balancer
|
|
130
|
+
* - Azure CNI networking
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
import { AksCluster, VnetDefault, ContainerRegistrySecure } from "@intentius/chant-lexicon-azure";
|
|
134
|
+
import { CoreParameter, StackOutput } from "@intentius/chant";
|
|
135
|
+
|
|
136
|
+
export const kubernetesVersion = new CoreParameter({
|
|
137
|
+
name: "kubernetesVersion",
|
|
138
|
+
type: "string",
|
|
139
|
+
default: "1.28",
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const { virtualNetwork, subnet1, subnet2, nsg, routeTable } = VnetDefault({
|
|
143
|
+
name: "aks-vnet",
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const { cluster } = AksCluster({
|
|
147
|
+
name: "my-aks",
|
|
148
|
+
nodeCount: 3,
|
|
149
|
+
vmSize: "Standard_D2s_v5",
|
|
150
|
+
tags: { workload: "kubernetes" },
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const { registry } = ContainerRegistrySecure({
|
|
154
|
+
name: "myaksacr",
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
export { virtualNetwork, subnet1, subnet2, nsg, routeTable, cluster, registry };
|
|
158
|
+
|
|
159
|
+
export const clusterName = new StackOutput({
|
|
160
|
+
name: "clusterName",
|
|
161
|
+
value: "my-aks",
|
|
162
|
+
});
|
|
163
|
+
`,
|
|
164
|
+
"tags.ts": `import { defaultTags } from "@intentius/chant-lexicon-azure";
|
|
165
|
+
|
|
166
|
+
export const tags = defaultTags([
|
|
167
|
+
{ key: "Project", value: "my-aks-cluster" },
|
|
168
|
+
{ key: "Environment", value: "dev" },
|
|
169
|
+
]);
|
|
170
|
+
`,
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (template === "function-app") {
|
|
175
|
+
return {
|
|
176
|
+
src: {
|
|
177
|
+
"main.ts": `/**
|
|
178
|
+
* Azure infrastructure — Consumption Function App
|
|
179
|
+
*
|
|
180
|
+
* Deploys a Function App with:
|
|
181
|
+
* - Consumption (Y1) App Service Plan
|
|
182
|
+
* - Storage Account for function runtime
|
|
183
|
+
* - Managed identity (SystemAssigned)
|
|
184
|
+
* - HTTPS-only traffic
|
|
185
|
+
* - Minimum TLS 1.2
|
|
186
|
+
* - FTPS disabled
|
|
187
|
+
*/
|
|
188
|
+
|
|
189
|
+
import { FunctionApp } from "@intentius/chant-lexicon-azure";
|
|
190
|
+
import { CoreParameter, StackOutput } from "@intentius/chant";
|
|
191
|
+
|
|
192
|
+
export const environment = new CoreParameter({
|
|
193
|
+
name: "environment",
|
|
194
|
+
type: "string",
|
|
195
|
+
default: "dev",
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const { plan, functionApp, storageAccount } = FunctionApp({
|
|
199
|
+
name: "my-function-app",
|
|
200
|
+
runtime: "node",
|
|
201
|
+
tags: { environment: "dev" },
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
export { plan, functionApp, storageAccount };
|
|
205
|
+
|
|
206
|
+
export const functionAppUrl = new StackOutput({
|
|
207
|
+
name: "functionAppUrl",
|
|
208
|
+
value: \`https://my-function-app.azurewebsites.net\`,
|
|
209
|
+
});
|
|
210
|
+
`,
|
|
211
|
+
"tags.ts": `import { defaultTags } from "@intentius/chant-lexicon-azure";
|
|
212
|
+
|
|
213
|
+
export const tags = defaultTags([
|
|
214
|
+
{ key: "Project", value: "my-function-app" },
|
|
215
|
+
{ key: "Environment", value: "dev" },
|
|
216
|
+
]);
|
|
217
|
+
`,
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// Default template — basic storage account
|
|
222
|
+
return {
|
|
223
|
+
src: {
|
|
224
|
+
"main.ts": `/**
|
|
225
|
+
* Azure infrastructure — Storage Account with secure defaults
|
|
226
|
+
*/
|
|
227
|
+
|
|
228
|
+
import { StorageAccount, Azure } from "@intentius/chant-lexicon-azure";
|
|
229
|
+
|
|
230
|
+
export const storage = new StorageAccount({
|
|
231
|
+
name: "mystorageaccount",
|
|
232
|
+
location: Azure.ResourceGroupLocation,
|
|
233
|
+
kind: "StorageV2",
|
|
234
|
+
sku: { name: "Standard_LRS" },
|
|
235
|
+
supportsHttpsTrafficOnly: true,
|
|
236
|
+
minimumTlsVersion: "TLS1_2",
|
|
237
|
+
allowBlobPublicAccess: false,
|
|
238
|
+
});
|
|
239
|
+
`,
|
|
240
|
+
"tags.ts": `import { defaultTags } from "@intentius/chant-lexicon-azure";
|
|
241
|
+
|
|
242
|
+
export const tags = defaultTags([
|
|
243
|
+
{ key: "Project", value: "my-app" },
|
|
244
|
+
{ key: "Environment", value: "dev" },
|
|
245
|
+
]);
|
|
246
|
+
`,
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
},
|
|
250
|
+
detectTemplate,
|
|
251
|
+
templateParser() {
|
|
252
|
+
return new ArmParser();
|
|
253
|
+
},
|
|
254
|
+
templateGenerator() {
|
|
255
|
+
return new ArmGenerator();
|
|
256
|
+
},
|
|
257
|
+
postSynthChecks() {
|
|
258
|
+
return postSynthCheckList;
|
|
259
|
+
},
|
|
260
|
+
skills: createSkillsLoader(import.meta.url, [
|
|
261
|
+
{
|
|
262
|
+
file: "chant-azure.md",
|
|
263
|
+
name: "chant-azure",
|
|
264
|
+
description: "Azure Resource Manager infrastructure generation with chant",
|
|
265
|
+
triggers: [
|
|
266
|
+
{ type: "file-pattern", value: "*.azure.ts" },
|
|
267
|
+
{ type: "context", value: "azure" },
|
|
268
|
+
],
|
|
269
|
+
parameters: [
|
|
270
|
+
{ name: "resourceType", type: "string", description: "Azure resource type to generate" },
|
|
271
|
+
],
|
|
272
|
+
examples: [
|
|
273
|
+
{
|
|
274
|
+
title: "Storage Account",
|
|
275
|
+
input: "Create an Azure storage account with secure defaults",
|
|
276
|
+
output: 'import { StorageAccount } from "@intentius/chant-lexicon-azure";\n\nexport const storage = new StorageAccount({ ... });',
|
|
277
|
+
},
|
|
278
|
+
],
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
file: "chant-azure-security.md",
|
|
282
|
+
name: "chant-azure-security",
|
|
283
|
+
description: "Azure security best practices for infrastructure",
|
|
284
|
+
triggers: [
|
|
285
|
+
{ type: "context", value: "azure security" },
|
|
286
|
+
{ type: "context", value: "azure identity" },
|
|
287
|
+
],
|
|
288
|
+
parameters: [],
|
|
289
|
+
examples: [
|
|
290
|
+
{
|
|
291
|
+
title: "Secure Storage Account",
|
|
292
|
+
input: "Create a storage account with encryption and no public access",
|
|
293
|
+
output: 'import { StorageAccountSecure } from "@intentius/chant-lexicon-azure";\n\nconst { storageAccount } = StorageAccountSecure({ name: "mystorage" });',
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
file: "chant-azure-patterns.md",
|
|
299
|
+
name: "chant-azure-patterns",
|
|
300
|
+
description: "Advanced Azure ARM template patterns",
|
|
301
|
+
triggers: [
|
|
302
|
+
{ type: "context", value: "azure patterns" },
|
|
303
|
+
{ type: "context", value: "azure composites" },
|
|
304
|
+
],
|
|
305
|
+
parameters: [],
|
|
306
|
+
examples: [
|
|
307
|
+
{
|
|
308
|
+
title: "Linked Deployment",
|
|
309
|
+
input: "Deploy a child project as a linked template",
|
|
310
|
+
output: 'import { ChildProjectInstance } from "@intentius/chant";\n\nexport const deploy = new ChildProjectInstance({ project: "../network" });',
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
file: "chant-azure-aks.md",
|
|
316
|
+
name: "chant-azure-aks",
|
|
317
|
+
description: "AKS end-to-end workflow — deploy ARM template, configure kubectl, deploy K8s workloads",
|
|
318
|
+
triggers: [
|
|
319
|
+
{ type: "context", value: "aks" },
|
|
320
|
+
{ type: "context", value: "azure kubernetes" },
|
|
321
|
+
{ type: "context", value: "agic" },
|
|
322
|
+
],
|
|
323
|
+
parameters: [],
|
|
324
|
+
examples: [
|
|
325
|
+
{
|
|
326
|
+
title: "Deploy AKS microservice",
|
|
327
|
+
input: "Deploy an AKS project end-to-end",
|
|
328
|
+
output: "npm run deploy",
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
},
|
|
332
|
+
]),
|
|
333
|
+
completionProvider(ctx) {
|
|
334
|
+
return azureCompletions(ctx);
|
|
335
|
+
},
|
|
336
|
+
hoverProvider(ctx) {
|
|
337
|
+
return azureHover(ctx);
|
|
338
|
+
},
|
|
339
|
+
composites() {
|
|
340
|
+
return compositeCatalog;
|
|
341
|
+
},
|
|
342
|
+
mcpTools() {
|
|
343
|
+
return [{
|
|
344
|
+
name: "azure:lookup-resource",
|
|
345
|
+
description: "Look up an Azure resource type by name",
|
|
346
|
+
inputSchema: {
|
|
347
|
+
type: "object",
|
|
348
|
+
properties: {
|
|
349
|
+
query: { type: "string", description: "Resource name to search for (e.g. 'StorageAccount', 'VirtualMachine')" },
|
|
350
|
+
},
|
|
351
|
+
required: ["query"],
|
|
352
|
+
},
|
|
353
|
+
handler: async (args) => {
|
|
354
|
+
const dir = moduleSourceDir(import.meta.url);
|
|
355
|
+
try {
|
|
356
|
+
const lexicon = JSON.parse(readFileSync(join(dir, "generated", "lexicon-azure.json"), "utf-8"));
|
|
357
|
+
const query = args.query.toLowerCase();
|
|
358
|
+
const matches = Object.entries(lexicon)
|
|
359
|
+
.filter(([name]) => name.toLowerCase().includes(query))
|
|
360
|
+
.slice(0, 10);
|
|
361
|
+
return JSON.stringify(matches, null, 2);
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
return "Lexicon not available — run `npm run generate` first.";
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
}];
|
|
368
|
+
},
|
|
369
|
+
mcpResources() {
|
|
370
|
+
return [
|
|
371
|
+
{
|
|
372
|
+
uri: "resource-catalog",
|
|
373
|
+
name: "Azure Resource Catalog",
|
|
374
|
+
description: "All available Azure resource types",
|
|
375
|
+
mimeType: "application/json",
|
|
376
|
+
handler: async () => {
|
|
377
|
+
const dir = moduleSourceDir(import.meta.url);
|
|
378
|
+
try {
|
|
379
|
+
return readFileSync(join(dir, "generated", "lexicon-azure.json"), "utf-8");
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
return "{}";
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
uri: "examples",
|
|
388
|
+
name: "Azure Example Projects",
|
|
389
|
+
description: "Example project summaries with code snippets for Azure ARM templates",
|
|
390
|
+
mimeType: "application/json",
|
|
391
|
+
handler: async () => {
|
|
392
|
+
const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
393
|
+
const examplesDir = join(pkgDir, "examples");
|
|
394
|
+
const examples = [];
|
|
395
|
+
try {
|
|
396
|
+
if (!existsSync(examplesDir))
|
|
397
|
+
return "[]";
|
|
398
|
+
const dirs = readdirSync(examplesDir, { withFileTypes: true })
|
|
399
|
+
.filter((e) => e.isDirectory());
|
|
400
|
+
for (const dir of dirs) {
|
|
401
|
+
const exDir = join(examplesDir, dir.name);
|
|
402
|
+
const srcDir = join(exDir, "src");
|
|
403
|
+
const files = {};
|
|
404
|
+
const scanDir = existsSync(srcDir) ? srcDir : exDir;
|
|
405
|
+
const entries = readdirSync(scanDir).filter((f) => f.endsWith(".ts"));
|
|
406
|
+
for (const f of entries) {
|
|
407
|
+
try {
|
|
408
|
+
files[f] = readFileSync(join(scanDir, f), "utf-8");
|
|
409
|
+
}
|
|
410
|
+
catch { /* skip unreadable */ }
|
|
411
|
+
}
|
|
412
|
+
if (Object.keys(files).length > 0) {
|
|
413
|
+
examples.push({ name: dir.name, files });
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return JSON.stringify(examples, null, 2);
|
|
417
|
+
}
|
|
418
|
+
catch {
|
|
419
|
+
return "[]";
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
];
|
|
424
|
+
},
|
|
425
|
+
async generate(opts) {
|
|
426
|
+
const { generate: gen, writeGeneratedFiles } = await import("./codegen/generate.js");
|
|
427
|
+
const result = await gen(opts);
|
|
428
|
+
writeGeneratedFiles(result, dirname(dirname(fileURLToPath(import.meta.url))));
|
|
429
|
+
},
|
|
430
|
+
async validate() {
|
|
431
|
+
const { validate } = await import("./validate.js");
|
|
432
|
+
await validate();
|
|
433
|
+
},
|
|
434
|
+
async coverage(options) {
|
|
435
|
+
const { analyzeAzureCoverage } = await import("./coverage.js");
|
|
436
|
+
await analyzeAzureCoverage({ verbose: options?.verbose, minOverall: options?.minOverall });
|
|
437
|
+
},
|
|
438
|
+
async package(opts) {
|
|
439
|
+
const { packageLexicon } = await import("./codegen/package.js");
|
|
440
|
+
await packageLexicon(opts);
|
|
441
|
+
},
|
|
442
|
+
async describeResources(options) {
|
|
443
|
+
const { describeResources } = await import("./describe-resources.js");
|
|
444
|
+
return describeResources(options);
|
|
445
|
+
},
|
|
446
|
+
/**
|
|
447
|
+
* Property-level live read (#1086) — `az resource show` already returns
|
|
448
|
+
* the full ARM resource; this normalizes it. Implementation in
|
|
449
|
+
* ./deep-observe.ts.
|
|
450
|
+
*/
|
|
451
|
+
async observeResourcesDeep(options) {
|
|
452
|
+
return observeResourcesDeepAzure({
|
|
453
|
+
environment: options.environment,
|
|
454
|
+
entityNames: options.entityNames,
|
|
455
|
+
entities: options.entities,
|
|
456
|
+
});
|
|
457
|
+
},
|
|
458
|
+
/** The noise rules the deep pass applies to both the live and declared trees. */
|
|
459
|
+
deepNormalizationHooks: azureDeepNormalizationHooks,
|
|
460
|
+
async exportResources(options) {
|
|
461
|
+
const { exportResources } = await import("./export-resources.js");
|
|
462
|
+
return exportResources(options);
|
|
463
|
+
},
|
|
464
|
+
/**
|
|
465
|
+
* The generator has always existed in src/codegen/docs.ts; only the package
|
|
466
|
+
* script reached it, so `plugin.docs()` was a no-op for azure alone (#1342).
|
|
467
|
+
*/
|
|
468
|
+
async docs(options) {
|
|
469
|
+
const { generateDocs } = await import("./codegen/docs.js");
|
|
470
|
+
await generateDocs(options);
|
|
471
|
+
},
|
|
472
|
+
};
|
package/dist/pseudo.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ARM pseudo-parameters — references to deployment-time values.
|
|
3
|
+
*
|
|
4
|
+
* These serialize to ARM template expressions:
|
|
5
|
+
* Azure.ResourceGroupName → "[resourceGroup().name]"
|
|
6
|
+
* Azure.SubscriptionId → "[subscription().subscriptionId]"
|
|
7
|
+
*/
|
|
8
|
+
var _a;
|
|
9
|
+
import { INTRINSIC_MARKER } from "@intentius/chant/intrinsic";
|
|
10
|
+
class ArmPseudoParameter {
|
|
11
|
+
constructor(expression, displayName) {
|
|
12
|
+
this[_a] = true;
|
|
13
|
+
this.expression = expression;
|
|
14
|
+
this.displayName = displayName;
|
|
15
|
+
}
|
|
16
|
+
toJSON() {
|
|
17
|
+
return this.expression;
|
|
18
|
+
}
|
|
19
|
+
toString() {
|
|
20
|
+
return this.displayName;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
_a = INTRINSIC_MARKER;
|
|
24
|
+
export const ResourceGroupName = new ArmPseudoParameter("[resourceGroup().name]", "Azure.ResourceGroupName");
|
|
25
|
+
export const ResourceGroupLocation = new ArmPseudoParameter("[resourceGroup().location]", "Azure.ResourceGroupLocation");
|
|
26
|
+
export const ResourceGroupId = new ArmPseudoParameter("[resourceGroup().id]", "Azure.ResourceGroupId");
|
|
27
|
+
export const SubscriptionId = new ArmPseudoParameter("[subscription().subscriptionId]", "Azure.SubscriptionId");
|
|
28
|
+
export const TenantId = new ArmPseudoParameter("[subscription().tenantId]", "Azure.TenantId");
|
|
29
|
+
export const DeploymentName = new ArmPseudoParameter("[deployment().name]", "Azure.DeploymentName");
|
|
30
|
+
/**
|
|
31
|
+
* Azure namespace containing all pseudo-parameters.
|
|
32
|
+
*/
|
|
33
|
+
export const Azure = {
|
|
34
|
+
ResourceGroupName,
|
|
35
|
+
ResourceGroupLocation,
|
|
36
|
+
ResourceGroupId,
|
|
37
|
+
SubscriptionId,
|
|
38
|
+
TenantId,
|
|
39
|
+
DeploymentName,
|
|
40
|
+
};
|