@intentius/chant-lexicon-azure 0.124.38 → 0.124.39

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.
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/composites/catalog.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,eAAO,MAAM,gBAAgB,EAAE,cAAc,EAu1B5C,CAAC"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/composites/catalog.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,eAAO,MAAM,gBAAgB,EAAE,cAAc,EA+8B5C,CAAC"}
@@ -167,6 +167,126 @@ export const compositeCatalog = [
167
167
  }
168
168
  ]
169
169
  },
170
+ {
171
+ "name": "ContainerAppNetwork",
172
+ "lexicon": "azure",
173
+ "description": "A VNet with a subnet delegated to `Microsoft.App/environments`, for ContainerAppSite environments to sit in.",
174
+ "bundles": [
175
+ "Subnet",
176
+ "VirtualNetwork"
177
+ ],
178
+ "params": [
179
+ {
180
+ "name": "name",
181
+ "type": "string",
182
+ "required": true,
183
+ "description": "Network name prefix: the VNet is `<name>-vnet`, its subnet `apps`."
184
+ },
185
+ {
186
+ "name": "location",
187
+ "type": "string",
188
+ "required": false,
189
+ "description": "Azure region (default: resource group location)."
190
+ },
191
+ {
192
+ "name": "addressSpace",
193
+ "type": "string",
194
+ "required": false,
195
+ "description": "VNet address space (default: \"10.0.0.0/16\")."
196
+ },
197
+ {
198
+ "name": "subnetPrefix",
199
+ "type": "string",
200
+ "required": false,
201
+ "description": "The environment subnet's prefix, a /23 or larger (default: \"10.0.0.0/23\")."
202
+ },
203
+ {
204
+ "name": "tags",
205
+ "type": "Record<string, string>",
206
+ "required": false,
207
+ "description": "Resource tags."
208
+ },
209
+ {
210
+ "name": "defaults",
211
+ "type": "{ virtualNetwork?: Partial<ConstructorParameters<typeof VirtualNetwork>[0]>; subnet?: Partial<ConstructorParameters<t...",
212
+ "required": false,
213
+ "description": "Per-member defaults."
214
+ }
215
+ ]
216
+ },
217
+ {
218
+ "name": "ContainerAppSite",
219
+ "lexicon": "azure",
220
+ "description": "A Container Apps environment in a subnet, shipping logs to its own Log Analytics workspace, with one app running as a user-assigned identity.",
221
+ "bundles": [
222
+ "LogAnalyticsWorkspace",
223
+ "ManagedIdentity",
224
+ "containerApps",
225
+ "managedEnvironments"
226
+ ],
227
+ "params": [
228
+ {
229
+ "name": "name",
230
+ "type": "string",
231
+ "required": true,
232
+ "description": "Environment name; the workspace is `<name>-logs` and the identity `<name>-<app>`."
233
+ },
234
+ {
235
+ "name": "app",
236
+ "type": "string",
237
+ "required": true,
238
+ "description": "Container app name."
239
+ },
240
+ {
241
+ "name": "subnetId",
242
+ "type": "string",
243
+ "required": true,
244
+ "description": "Subnet resource ID for the environment, such as a ContainerAppNetwork's `subnet.id`."
245
+ },
246
+ {
247
+ "name": "location",
248
+ "type": "string",
249
+ "required": false,
250
+ "description": "Azure region (default: resource group location)."
251
+ },
252
+ {
253
+ "name": "image",
254
+ "type": "string",
255
+ "required": false,
256
+ "description": "Container image (default: \"mcr.microsoft.com/k8se/quickstart:latest\")."
257
+ },
258
+ {
259
+ "name": "port",
260
+ "type": "number",
261
+ "required": false,
262
+ "description": "Port the container listens on; ingress forwards to it (default: 80)."
263
+ },
264
+ {
265
+ "name": "replicas",
266
+ "type": "number",
267
+ "required": false,
268
+ "description": "Fixed replica count (default: 1)."
269
+ },
270
+ {
271
+ "name": "internal",
272
+ "type": "boolean",
273
+ "required": false,
274
+ "description": "Make the environment reachable only from its VNet (default: false)."
275
+ },
276
+ {
277
+ "name": "tags",
278
+ "type": "Record<string, string>",
279
+ "required": false,
280
+ "description": "Resource tags."
281
+ },
282
+ {
283
+ "name": "defaults",
284
+ "type": "{ workspace?: Partial<ConstructorParameters<typeof LogAnalyticsWorkspace>[0]>; identity?: Partial<ConstructorParamete...",
285
+ "required": false,
286
+ "description": "Per-member defaults."
287
+ }
288
+ ]
289
+ },
170
290
  {
171
291
  "name": "ContainerInstance",
172
292
  "lexicon": "azure",
@@ -0,0 +1,102 @@
1
+ /**
2
+ * ContainerAppNetwork and ContainerAppSite composites: a website on Azure
3
+ * Container Apps and the network it sits in.
4
+ *
5
+ * Split the way the aws lexicon splits VpcDefault from FargateAlb, so several
6
+ * sites can share one network. Container Apps brings its own ingress and load
7
+ * balancing, so there is no load balancer to declare.
8
+ */
9
+ import { VirtualNetwork, Subnet, LogAnalyticsWorkspace, ManagedIdentity, managedEnvironments, containerApps } from "../generated/index.js";
10
+ export interface ContainerAppNetworkProps {
11
+ /** Network name prefix: the VNet is `<name>-vnet`, its subnet `apps`. */
12
+ name: string;
13
+ /** Azure region (default: resource group location). */
14
+ location?: string;
15
+ /** VNet address space (default: "10.0.0.0/16"). */
16
+ addressSpace?: string;
17
+ /** The environment subnet's prefix, a /23 or larger (default: "10.0.0.0/23"). */
18
+ subnetPrefix?: string;
19
+ /** Resource tags. */
20
+ tags?: Record<string, string>;
21
+ /** Per-member defaults. */
22
+ defaults?: {
23
+ virtualNetwork?: Partial<ConstructorParameters<typeof VirtualNetwork>[0]>;
24
+ subnet?: Partial<ConstructorParameters<typeof Subnet>[0]>;
25
+ };
26
+ }
27
+ export interface ContainerAppNetworkResult {
28
+ virtualNetwork: InstanceType<typeof VirtualNetwork>;
29
+ subnet: InstanceType<typeof Subnet>;
30
+ }
31
+ /**
32
+ * A VNet with a subnet delegated to `Microsoft.App/environments`, for
33
+ * ContainerAppSite environments to sit in.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * import { ContainerAppNetwork } from "@intentius/chant-lexicon-azure";
38
+ *
39
+ * export const network = ContainerAppNetwork({ name: "web" });
40
+ * ```
41
+ */
42
+ export declare const ContainerAppNetwork: import("@intentius/chant").CompositeDefinition<ContainerAppNetworkProps, {
43
+ virtualNetwork: import("@intentius/chant").Declarable & Record<string, string>;
44
+ subnet: import("@intentius/chant").Declarable & Record<string, string>;
45
+ }>;
46
+ export interface ContainerAppSiteProps {
47
+ /** Environment name; the workspace is `<name>-logs` and the identity `<name>-<app>`. */
48
+ name: string;
49
+ /** Container app name. */
50
+ app: string;
51
+ /** Subnet resource ID for the environment, such as a ContainerAppNetwork's `subnet.id`. */
52
+ subnetId: string;
53
+ /** Azure region (default: resource group location). */
54
+ location?: string;
55
+ /** Container image (default: "mcr.microsoft.com/k8se/quickstart:latest"). */
56
+ image?: string;
57
+ /** Port the container listens on; ingress forwards to it (default: 80). */
58
+ port?: number;
59
+ /** Fixed replica count (default: 1). */
60
+ replicas?: number;
61
+ /** Make the environment reachable only from its VNet (default: false). */
62
+ internal?: boolean;
63
+ /** Resource tags. */
64
+ tags?: Record<string, string>;
65
+ /** Per-member defaults. */
66
+ defaults?: {
67
+ workspace?: Partial<ConstructorParameters<typeof LogAnalyticsWorkspace>[0]>;
68
+ identity?: Partial<ConstructorParameters<typeof ManagedIdentity>[0]>;
69
+ environment?: Partial<ConstructorParameters<typeof managedEnvironments>[0]>;
70
+ containerApp?: Partial<ConstructorParameters<typeof containerApps>[0]>;
71
+ };
72
+ }
73
+ export interface ContainerAppSiteResult {
74
+ workspace: InstanceType<typeof LogAnalyticsWorkspace>;
75
+ identity: InstanceType<typeof ManagedIdentity>;
76
+ environment: InstanceType<typeof managedEnvironments>;
77
+ containerApp: InstanceType<typeof containerApps>;
78
+ }
79
+ /**
80
+ * A Container Apps environment in a subnet, shipping logs to its own Log
81
+ * Analytics workspace, with one app running as a user-assigned identity.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { ContainerAppNetwork, ContainerAppSite } from "@intentius/chant-lexicon-azure";
86
+ *
87
+ * export const network = ContainerAppNetwork({ name: "web" });
88
+ * export const site = ContainerAppSite({
89
+ * name: "web",
90
+ * app: "frontend",
91
+ * subnetId: network.subnet.id,
92
+ * image: "nginx:1.27",
93
+ * });
94
+ * ```
95
+ */
96
+ export declare const ContainerAppSite: import("@intentius/chant").CompositeDefinition<ContainerAppSiteProps, {
97
+ workspace: import("@intentius/chant").Declarable & Record<string, string>;
98
+ identity: import("@intentius/chant").Declarable & Record<string, string>;
99
+ environment: import("@intentius/chant").Declarable & Record<string, string>;
100
+ containerApp: import("@intentius/chant").Declarable & Record<string, string>;
101
+ }>;
102
+ //# sourceMappingURL=container-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-app.d.ts","sourceRoot":"","sources":["../../src/composites/container-app.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,cAAc,EACd,MAAM,EACN,qBAAqB,EACrB,eAAe,EACf,mBAAmB,EACnB,aAAa,EACd,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,wBAAwB;IACvC,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,2BAA2B;IAC3B,QAAQ,CAAC,EAAE;QACT,cAAc,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAC3D,CAAC;CACH;AAED,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC;IACpD,MAAM,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB;;;EA+BP,CAAC;AAE1B,MAAM,WAAW,qBAAqB;IACpC,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,2FAA2F;IAC3F,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,2BAA2B;IAC3B,QAAQ,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,WAAW,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,YAAY,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACxE,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,YAAY,CAAC,OAAO,qBAAqB,CAAC,CAAC;IACtD,QAAQ,EAAE,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC;IAC/C,WAAW,EAAE,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;IACtD,YAAY,EAAE,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB;;;;;EAsEP,CAAC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * ContainerAppNetwork and ContainerAppSite composites: a website on Azure
3
+ * Container Apps and the network it sits in.
4
+ *
5
+ * Split the way the aws lexicon splits VpcDefault from FargateAlb, so several
6
+ * sites can share one network. Container Apps brings its own ingress and load
7
+ * balancing, so there is no load balancer to declare.
8
+ */
9
+ import { Composite, mergeDefaults } from "@intentius/chant";
10
+ import { VirtualNetwork, Subnet, LogAnalyticsWorkspace, ManagedIdentity, managedEnvironments, containerApps, } from "../generated/index.js";
11
+ /**
12
+ * A VNet with a subnet delegated to `Microsoft.App/environments`, for
13
+ * ContainerAppSite environments to sit in.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { ContainerAppNetwork } from "@intentius/chant-lexicon-azure";
18
+ *
19
+ * export const network = ContainerAppNetwork({ name: "web" });
20
+ * ```
21
+ */
22
+ export const ContainerAppNetwork = Composite((props) => {
23
+ const { name, location = "[resourceGroup().location]", addressSpace = "10.0.0.0/16", subnetPrefix = "10.0.0.0/23", tags = {}, defaults, } = props;
24
+ const mergedTags = { "managed-by": "chant", ...tags };
25
+ const vnetName = `${name}-vnet`;
26
+ const delegations = [{ name: "apps", properties: { serviceName: "Microsoft.App/environments" } }];
27
+ // The subnet is also listed inline, as VnetDefault does, so a later
28
+ // deployment of the VNet does not try to remove it.
29
+ const virtualNetwork = new VirtualNetwork(mergeDefaults({
30
+ name: vnetName,
31
+ location,
32
+ tags: mergedTags,
33
+ addressSpace: { addressPrefixes: [addressSpace] },
34
+ subnets: [{ name: "apps", properties: { addressPrefix: subnetPrefix, delegations } }],
35
+ }, defaults?.virtualNetwork), { apiVersion: "2023-05-01" });
36
+ const subnet = new Subnet(mergeDefaults({
37
+ name: `${vnetName}/apps`,
38
+ addressPrefix: subnetPrefix,
39
+ delegations,
40
+ }, defaults?.subnet), { apiVersion: "2023-05-01" });
41
+ return { virtualNetwork, subnet };
42
+ }, "ContainerAppNetwork");
43
+ /**
44
+ * A Container Apps environment in a subnet, shipping logs to its own Log
45
+ * Analytics workspace, with one app running as a user-assigned identity.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { ContainerAppNetwork, ContainerAppSite } from "@intentius/chant-lexicon-azure";
50
+ *
51
+ * export const network = ContainerAppNetwork({ name: "web" });
52
+ * export const site = ContainerAppSite({
53
+ * name: "web",
54
+ * app: "frontend",
55
+ * subnetId: network.subnet.id,
56
+ * image: "nginx:1.27",
57
+ * });
58
+ * ```
59
+ */
60
+ export const ContainerAppSite = Composite((props) => {
61
+ const { name, app, subnetId, location = "[resourceGroup().location]", image = "mcr.microsoft.com/k8se/quickstart:latest", port = 80, replicas = 1, internal = false, tags = {}, defaults, } = props;
62
+ const mergedTags = { "managed-by": "chant", ...tags };
63
+ const workspaceName = `${name}-logs`;
64
+ const identityName = `${name}-${app}`;
65
+ const workspaceId = `resourceId('Microsoft.OperationalInsights/workspaces', '${workspaceName}')`;
66
+ const workspace = new LogAnalyticsWorkspace(mergeDefaults({
67
+ name: workspaceName,
68
+ location,
69
+ tags: mergedTags,
70
+ // A workspace's sku sits inside its properties, not beside them, so it is
71
+ // passed there rather than hoisted to the resource like other skus.
72
+ properties: { sku: { name: "PerGB2018" } },
73
+ retentionInDays: 30,
74
+ }, defaults?.workspace), { apiVersion: "2023-09-01" });
75
+ const identity = new ManagedIdentity(mergeDefaults({
76
+ name: identityName,
77
+ location,
78
+ tags: mergedTags,
79
+ }, defaults?.identity), { apiVersion: "2023-01-31" });
80
+ const environment = new managedEnvironments(mergeDefaults({
81
+ name,
82
+ location,
83
+ tags: mergedTags,
84
+ vnetConfiguration: { infrastructureSubnetId: subnetId, internal },
85
+ appLogsConfiguration: {
86
+ destination: "log-analytics",
87
+ logAnalyticsConfiguration: {
88
+ customerId: `[reference(${workspaceId}, '2023-09-01').customerId]`,
89
+ sharedKey: `[listKeys(${workspaceId}, '2023-09-01').primarySharedKey]`,
90
+ },
91
+ },
92
+ workloadProfiles: [{ name: "Consumption", workloadProfileType: "Consumption" }],
93
+ }, defaults?.environment), { apiVersion: "2024-03-01" });
94
+ const containerApp = new containerApps(mergeDefaults({
95
+ name: app,
96
+ location,
97
+ tags: mergedTags,
98
+ identity: {
99
+ type: "UserAssigned",
100
+ userAssignedIdentities: {
101
+ [`[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', '${identityName}')]`]: {},
102
+ },
103
+ },
104
+ managedEnvironmentId: environment.id,
105
+ workloadProfileName: "Consumption",
106
+ configuration: { ingress: { external: true, targetPort: port, transport: "auto" } },
107
+ template: {
108
+ containers: [{ name: app, image, resources: { cpu: 0.25, memory: "0.5Gi" } }],
109
+ scale: { minReplicas: replicas, maxReplicas: replicas },
110
+ },
111
+ }, defaults?.containerApp), { apiVersion: "2024-03-01" });
112
+ return { workspace, identity, environment, containerApp };
113
+ }, "ContainerAppSite");
@@ -28,6 +28,8 @@ export { RedisCache } from "./redis-cache.js";
28
28
  export type { RedisCacheProps, RedisCacheResult } from "./redis-cache.js";
29
29
  export { PrivateEndpoint } from "./private-endpoint.js";
30
30
  export type { PrivateEndpointProps, PrivateEndpointResult } from "./private-endpoint.js";
31
+ export { ContainerAppNetwork, ContainerAppSite } from "./container-app.js";
32
+ export type { ContainerAppNetworkProps, ContainerAppNetworkResult, ContainerAppSiteProps, ContainerAppSiteResult, } from "./container-app.js";
31
33
  export { GovernanceFoundation, GovernanceBaseline, LocationRestriction, ActivityLogSink } from "./landing-zone.js";
32
34
  export type { GovernanceFoundationProps, GovernanceFoundationResult, GovernanceBaselineProps, GovernanceBaselineResult, LocationRestrictionProps, LocationRestrictionResult, ActivityLogSinkProps, ActivityLogSinkResult, } from "./landing-zone.js";
33
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAChH,YAAY,EACV,yBAAyB,EAAE,0BAA0B,EACrD,uBAAuB,EAAE,wBAAwB,EACjD,wBAAwB,EAAE,yBAAyB,EACnD,oBAAoB,EAAE,qBAAqB,GAC5C,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,YAAY,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,YAAY,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,YAAY,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,YAAY,EACV,wBAAwB,EAAE,yBAAyB,EACnD,qBAAqB,EAAE,sBAAsB,GAC9C,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAChH,YAAY,EACV,yBAAyB,EAAE,0BAA0B,EACrD,uBAAuB,EAAE,wBAAwB,EACjD,wBAAwB,EAAE,yBAAyB,EACnD,oBAAoB,EAAE,qBAAqB,GAC5C,MAAM,gBAAgB,CAAC"}
@@ -13,4 +13,5 @@ export { ApplicationGateway } from "./application-gateway.js";
13
13
  export { ContainerInstance } from "./container-instance.js";
14
14
  export { RedisCache } from "./redis-cache.js";
15
15
  export { PrivateEndpoint } from "./private-endpoint.js";
16
+ export { ContainerAppNetwork, ContainerAppSite } from "./container-app.js";
16
17
  export { GovernanceFoundation, GovernanceBaseline, LocationRestriction, ActivityLogSink } from "./landing-zone.js";
package/dist/index.d.ts CHANGED
@@ -16,7 +16,7 @@ export { isChildProject, type ChildProjectInstance } from "@intentius/chant/chil
16
16
  export { stackOutput, isStackOutput, type StackOutput } from "@intentius/chant/stack-output";
17
17
  export { LexiconOutput, output, isLexiconOutput } from "@intentius/chant/lexicon-output";
18
18
  export * from "./generated/index.js";
19
- export { StorageAccountSecure, type StorageAccountSecureProps, type StorageAccountSecureResult, VnetDefault, type VnetDefaultProps, type VnetDefaultResult, VmLinux, type VmLinuxProps, type VmLinuxResult, AppService, type AppServiceProps, type AppServiceResult, AksCluster, type AksClusterProps, type AksClusterResult, SqlDatabase, type SqlDatabaseProps, type SqlDatabaseResult, KeyVaultSecure, type KeyVaultSecureProps, type KeyVaultSecureResult, ContainerRegistrySecure, type ContainerRegistrySecureProps, type ContainerRegistrySecureResult, FunctionApp, type FunctionAppProps, type FunctionAppResult, ServiceBusPipeline, type ServiceBusPipelineProps, type ServiceBusPipelineResult, CosmosDatabase, type CosmosDatabaseProps, type CosmosDatabaseResult, ApplicationGateway, type ApplicationGatewayProps, type ApplicationGatewayResult, ContainerInstance, type ContainerInstanceProps, type ContainerInstanceResult, RedisCache, type RedisCacheProps, type RedisCacheResult, PrivateEndpoint, type PrivateEndpointProps, type PrivateEndpointResult, GovernanceFoundation, type GovernanceFoundationProps, type GovernanceFoundationResult, GovernanceBaseline, type GovernanceBaselineProps, type GovernanceBaselineResult, LocationRestriction, type LocationRestrictionProps, type LocationRestrictionResult, ActivityLogSink, type ActivityLogSinkProps, type ActivityLogSinkResult, } from "./composites/index.js";
19
+ export { StorageAccountSecure, type StorageAccountSecureProps, type StorageAccountSecureResult, VnetDefault, type VnetDefaultProps, type VnetDefaultResult, VmLinux, type VmLinuxProps, type VmLinuxResult, AppService, type AppServiceProps, type AppServiceResult, AksCluster, type AksClusterProps, type AksClusterResult, SqlDatabase, type SqlDatabaseProps, type SqlDatabaseResult, KeyVaultSecure, type KeyVaultSecureProps, type KeyVaultSecureResult, ContainerRegistrySecure, type ContainerRegistrySecureProps, type ContainerRegistrySecureResult, FunctionApp, type FunctionAppProps, type FunctionAppResult, ServiceBusPipeline, type ServiceBusPipelineProps, type ServiceBusPipelineResult, CosmosDatabase, type CosmosDatabaseProps, type CosmosDatabaseResult, ApplicationGateway, type ApplicationGatewayProps, type ApplicationGatewayResult, ContainerInstance, type ContainerInstanceProps, type ContainerInstanceResult, RedisCache, type RedisCacheProps, type RedisCacheResult, PrivateEndpoint, type PrivateEndpointProps, type PrivateEndpointResult, ContainerAppNetwork, type ContainerAppNetworkProps, type ContainerAppNetworkResult, ContainerAppSite, type ContainerAppSiteProps, type ContainerAppSiteResult, GovernanceFoundation, type GovernanceFoundationProps, type GovernanceFoundationResult, GovernanceBaseline, type GovernanceBaselineProps, type GovernanceBaselineResult, LocationRestriction, type LocationRestrictionProps, type LocationRestrictionResult, ActivityLogSink, type ActivityLogSinkProps, type ActivityLogSinkResult, } from "./composites/index.js";
20
20
  export { landingZoneConfig, locationRestriction, DENY_CLASSIC_RESOURCES, DENY_UNMANAGED_DISKS, ACTIVITY_LOG_TO_LOG_ANALYTICS_DEFINITION_ID, FOUNDATION_MANAGEMENT_GROUPS, } from "./governance.js";
21
21
  export type { AzureGovernanceConfig, LandingZoneConfigProps, ManagementGroupConfig, PolicyConfig, SubscriptionConfig, } from "./governance.js";
22
22
  export { StorageRoles, ComputeRoles, NetworkRoles, KeyVaultRoles, SqlRoles, ContainerRoles, AppServiceRoles, IdentityRoles, } from "./actions/index.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ export { LexiconOutput, output, isLexiconOutput } from "@intentius/chant/lexicon
30
30
  // --- Generated resource classes ---
31
31
  export * from "./generated/index.js";
32
32
  // --- Composites ---
33
- export { StorageAccountSecure, VnetDefault, VmLinux, AppService, AksCluster, SqlDatabase, KeyVaultSecure, ContainerRegistrySecure, FunctionApp, ServiceBusPipeline, CosmosDatabase, ApplicationGateway, ContainerInstance, RedisCache, PrivateEndpoint, GovernanceFoundation, GovernanceBaseline, LocationRestriction, ActivityLogSink, } from "./composites/index.js";
33
+ export { StorageAccountSecure, VnetDefault, VmLinux, AppService, AksCluster, SqlDatabase, KeyVaultSecure, ContainerRegistrySecure, FunctionApp, ServiceBusPipeline, CosmosDatabase, ApplicationGateway, ContainerInstance, RedisCache, PrivateEndpoint, ContainerAppNetwork, ContainerAppSite, GovernanceFoundation, GovernanceBaseline, LocationRestriction, ActivityLogSink, } from "./composites/index.js";
34
34
  // Azure governance authoring: the desired-state config the Azure
35
35
  // external governance reconciler applies, and the typed landing-zone authoring layer.
36
36
  export { landingZoneConfig, locationRestriction, DENY_CLASSIC_RESOURCES, DENY_UNMANAGED_DISKS, ACTIVITY_LOG_TO_LOG_ANALYTICS_DEFINITION_ID, FOUNDATION_MANAGEMENT_GROUPS, } from "./governance.js";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "6d96e57d05d492a3402cf1747adb5bea4cb892aa0c471a8a762f64965657a8fe",
4
+ "manifest.json": "6a7ba60e1ad5cc1b94809c91f7dab1293ceec2074f2600f4b8ce4ea81a242421",
5
5
  "meta.json": "d2521221ed616d882ded4296f0071685bd74e4b645d55dabc9685733c37dc419",
6
6
  "types/index.d.ts": "29631032bda9533849178968290e65d72250eab0b8bab424f2d9ef9b4e8546a4",
7
7
  "rules/hardcoded-location.ts": "0b895449c8c94066e81721c46be24249231029fe13b471477456df5c4e45b8bf",
@@ -32,10 +32,10 @@
32
32
  "rules/azr031.ts": "7f0654c9dce1e3a1a86818d8b4d0201fb4600021f7a4a757c36b1513fe16e0fd",
33
33
  "rules/azr032.ts": "ea94cc7fdece0812c43898c76c4b8a115a306157b741fe3b76fe726335f6c2d2",
34
34
  "rules/azr033.ts": "d440ec79a1563160bb7c8cc29c81880da71997c872215f14ec3be18f05a07ed3",
35
- "skills/chant-azure.md": "86399e4fafd35cdf56670b32dbff5db42a4bfa1453b25231c4ee15eea9a2a1b9",
36
- "skills/chant-azure-security.md": "95ab789202662f60b43cf2fce1ae549cbcf5b689306481dabb656847281879ff",
37
- "skills/chant-azure-patterns.md": "1a3bacfac612826b77332d2692a59195638db9f1b5e8ea2eda7579621d25f603",
35
+ "skills/chant-azure.md": "e81c3a12c31196e3eebe399443328caacf65db61380a621d1fb6f1c359f6a077",
36
+ "skills/chant-azure-security.md": "d9a7a99c861dcab1ff6d0653f1e13e28d907babd045ae67c524b32b6ab80691e",
37
+ "skills/chant-azure-patterns.md": "2d8cb8bbeda73b695856cec4ddaf5b3a0efce76e4ee6e3cf14b90ca69dee5757",
38
38
  "skills/chant-azure-aks.md": "2d4e0098c1a22b54ffadd410564d9df0f3a04cb4eb7c6261f20ae33106e7aca8"
39
39
  },
40
- "composite": "170c51b22ffa7e7a75bdfa326ad514cf831357abb659803cd217edf6102f2925"
40
+ "composite": "2dba446de8873706991b76fe0621dcb83200ee6771fdbe1dd4334ac10ecddfb0"
41
41
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azure",
3
- "version": "0.124.38",
3
+ "version": "0.124.39",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "Azure",
6
6
  "intrinsics": [
@@ -408,6 +408,22 @@ const { privateEndpoint, privateDnsZone, dnsZoneGroup, vnetLink } = PrivateEndpo
408
408
  export { storageAccount, privateEndpoint, privateDnsZone, dnsZoneGroup, vnetLink };
409
409
  ```
410
410
 
411
+ ### ContainerAppNetwork and ContainerAppSite
412
+ A Container Apps site in its own delegated subnet; one network can carry several sites:
413
+
414
+ ```ts
415
+ import { ContainerAppNetwork, ContainerAppSite } from "@intentius/chant-lexicon-azure";
416
+
417
+ export const network = ContainerAppNetwork({ name: "web" });
418
+
419
+ export const site = ContainerAppSite({
420
+ name: "web",
421
+ app: "frontend",
422
+ subnetId: network.subnet.id,
423
+ image: "nginx:1.27",
424
+ });
425
+ ```
426
+
411
427
  ## ARM Template Intrinsic Reference
412
428
 
413
429
  | Function | Description | Example |
@@ -267,6 +267,7 @@ Use the secure composite variants which apply these patterns automatically:
267
267
  - `ContainerInstance` — Managed identity, no public IP by default
268
268
  - `RedisCache` — Non-SSL port disabled, TLS 1.2
269
269
  - `PrivateEndpoint` — Private connectivity pattern with DNS zone
270
+ - `ContainerAppSite`: user-assigned identity, app logs to Log Analytics, optional VNet-only environment
270
271
 
271
272
  ## Post-Synth Check Reference
272
273
 
@@ -157,6 +157,8 @@ Composites group related Azure resources with secure defaults. Each returns an o
157
157
  | `ContainerInstance` | ContainerGroup | No public IP by default, resource limits set |
158
158
  | `RedisCache` | RedisCache | TLS 1.2 required, non-SSL port disabled |
159
159
  | `PrivateEndpoint` | PrivateEndpoint + PrivateDnsZone + VnetLink | DNS zone auto-registration, manual approval disabled |
160
+ | `ContainerAppNetwork` | VirtualNetwork + Subnet | Subnet delegated to Container Apps, /23 by default |
161
+ | `ContainerAppSite` | LogAnalyticsWorkspace + ManagedIdentity + ManagedEnvironment + ContainerApp | App logs to Log Analytics, user-assigned identity, Consumption profile |
160
162
  | `AksCluster` | ManagedCluster + AgentPool | RBAC enabled, network policy (calico), managed identity, Azure CNI |
161
163
  | `SqlDatabase` | SQLServer + Database + FirewallRule + AuditingSettings | TDE enabled, auditing enabled, TLS 1.2, no Azure-wide firewall rule |
162
164
  | `KeyVaultSecure` | KeyVault + AccessPolicy | Soft delete, purge protection, RBAC authorization, network ACLs |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-azure",
3
- "version": "0.124.38",
3
+ "version": "0.124.39",
4
4
  "description": "Azure lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -74,6 +74,6 @@
74
74
  "typescript": "^5.9.3"
75
75
  },
76
76
  "peerDependencies": {
77
- "@intentius/chant": "^0.124.38"
77
+ "@intentius/chant": "^0.124.39"
78
78
  }
79
79
  }
@@ -172,6 +172,126 @@ export const compositeCatalog: CompositeEntry[] = [
172
172
  }
173
173
  ]
174
174
  },
175
+ {
176
+ "name": "ContainerAppNetwork",
177
+ "lexicon": "azure",
178
+ "description": "A VNet with a subnet delegated to `Microsoft.App/environments`, for ContainerAppSite environments to sit in.",
179
+ "bundles": [
180
+ "Subnet",
181
+ "VirtualNetwork"
182
+ ],
183
+ "params": [
184
+ {
185
+ "name": "name",
186
+ "type": "string",
187
+ "required": true,
188
+ "description": "Network name prefix: the VNet is `<name>-vnet`, its subnet `apps`."
189
+ },
190
+ {
191
+ "name": "location",
192
+ "type": "string",
193
+ "required": false,
194
+ "description": "Azure region (default: resource group location)."
195
+ },
196
+ {
197
+ "name": "addressSpace",
198
+ "type": "string",
199
+ "required": false,
200
+ "description": "VNet address space (default: \"10.0.0.0/16\")."
201
+ },
202
+ {
203
+ "name": "subnetPrefix",
204
+ "type": "string",
205
+ "required": false,
206
+ "description": "The environment subnet's prefix, a /23 or larger (default: \"10.0.0.0/23\")."
207
+ },
208
+ {
209
+ "name": "tags",
210
+ "type": "Record<string, string>",
211
+ "required": false,
212
+ "description": "Resource tags."
213
+ },
214
+ {
215
+ "name": "defaults",
216
+ "type": "{ virtualNetwork?: Partial<ConstructorParameters<typeof VirtualNetwork>[0]>; subnet?: Partial<ConstructorParameters<t...",
217
+ "required": false,
218
+ "description": "Per-member defaults."
219
+ }
220
+ ]
221
+ },
222
+ {
223
+ "name": "ContainerAppSite",
224
+ "lexicon": "azure",
225
+ "description": "A Container Apps environment in a subnet, shipping logs to its own Log Analytics workspace, with one app running as a user-assigned identity.",
226
+ "bundles": [
227
+ "LogAnalyticsWorkspace",
228
+ "ManagedIdentity",
229
+ "containerApps",
230
+ "managedEnvironments"
231
+ ],
232
+ "params": [
233
+ {
234
+ "name": "name",
235
+ "type": "string",
236
+ "required": true,
237
+ "description": "Environment name; the workspace is `<name>-logs` and the identity `<name>-<app>`."
238
+ },
239
+ {
240
+ "name": "app",
241
+ "type": "string",
242
+ "required": true,
243
+ "description": "Container app name."
244
+ },
245
+ {
246
+ "name": "subnetId",
247
+ "type": "string",
248
+ "required": true,
249
+ "description": "Subnet resource ID for the environment, such as a ContainerAppNetwork's `subnet.id`."
250
+ },
251
+ {
252
+ "name": "location",
253
+ "type": "string",
254
+ "required": false,
255
+ "description": "Azure region (default: resource group location)."
256
+ },
257
+ {
258
+ "name": "image",
259
+ "type": "string",
260
+ "required": false,
261
+ "description": "Container image (default: \"mcr.microsoft.com/k8se/quickstart:latest\")."
262
+ },
263
+ {
264
+ "name": "port",
265
+ "type": "number",
266
+ "required": false,
267
+ "description": "Port the container listens on; ingress forwards to it (default: 80)."
268
+ },
269
+ {
270
+ "name": "replicas",
271
+ "type": "number",
272
+ "required": false,
273
+ "description": "Fixed replica count (default: 1)."
274
+ },
275
+ {
276
+ "name": "internal",
277
+ "type": "boolean",
278
+ "required": false,
279
+ "description": "Make the environment reachable only from its VNet (default: false)."
280
+ },
281
+ {
282
+ "name": "tags",
283
+ "type": "Record<string, string>",
284
+ "required": false,
285
+ "description": "Resource tags."
286
+ },
287
+ {
288
+ "name": "defaults",
289
+ "type": "{ workspace?: Partial<ConstructorParameters<typeof LogAnalyticsWorkspace>[0]>; identity?: Partial<ConstructorParamete...",
290
+ "required": false,
291
+ "description": "Per-member defaults."
292
+ }
293
+ ]
294
+ },
175
295
  {
176
296
  "name": "ContainerInstance",
177
297
  "lexicon": "azure",
@@ -14,6 +14,7 @@ import { ApplicationGateway } from "./application-gateway";
14
14
  import { ContainerInstance } from "./container-instance";
15
15
  import { RedisCache } from "./redis-cache";
16
16
  import { PrivateEndpoint } from "./private-endpoint";
17
+ import { ContainerAppNetwork, ContainerAppSite } from "./container-app";
17
18
  import { isCompositeInstance } from "@intentius/chant";
18
19
 
19
20
  /** Helper to get flat props from a generated resource instance. */
@@ -744,3 +745,91 @@ describe("PrivateEndpoint", () => {
744
745
  expect(peTags["managed-by"]).toBe("chant");
745
746
  });
746
747
  });
748
+
749
+ // --- ContainerAppNetwork ---
750
+
751
+ describe("ContainerAppNetwork", () => {
752
+ test("returns a VNet and its subnet", () => {
753
+ const result = ContainerAppNetwork({ name: "web" });
754
+ expect(Object.keys(result.members)).toEqual(["virtualNetwork", "subnet"]);
755
+ expect(et(result.virtualNetwork)).toBe("Microsoft.Network/virtualNetworks");
756
+ expect(et(result.subnet)).toBe("Microsoft.Network/virtualNetworks_subnets");
757
+ });
758
+
759
+ test("names the subnet as a child of <name>-vnet and delegates it to Container Apps", () => {
760
+ const { virtualNetwork, subnet } = ContainerAppNetwork({ name: "web", subnetPrefix: "10.1.0.0/23" });
761
+ expect(p(virtualNetwork).name).toBe("web-vnet");
762
+ expect(p(subnet).name).toBe("web-vnet/apps");
763
+ expect(p(subnet).addressPrefix).toBe("10.1.0.0/23");
764
+ const delegations = p(subnet).delegations as Array<{ properties: { serviceName: string } }>;
765
+ expect(delegations[0].properties.serviceName).toBe("Microsoft.App/environments");
766
+ });
767
+
768
+ test("lists the subnet inline on the VNet too", () => {
769
+ const { virtualNetwork } = ContainerAppNetwork({ name: "web" });
770
+ const subnets = p(virtualNetwork).subnets as Array<{ name: string; properties: { addressPrefix: string } }>;
771
+ expect(subnets).toHaveLength(1);
772
+ expect(subnets[0].name).toBe("apps");
773
+ expect(subnets[0].properties.addressPrefix).toBe("10.0.0.0/23");
774
+ });
775
+
776
+ test("defaults override a member's props", () => {
777
+ const { virtualNetwork } = ContainerAppNetwork({ name: "web", defaults: { virtualNetwork: { location: "westeurope" } } });
778
+ expect(p(virtualNetwork).location).toBe("westeurope");
779
+ });
780
+ });
781
+
782
+ // --- ContainerAppSite ---
783
+
784
+ describe("ContainerAppSite", () => {
785
+ const subnetId = "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'web-vnet', 'apps')]";
786
+
787
+ test("returns a workspace, identity, environment and app", () => {
788
+ const result = ContainerAppSite({ name: "web", app: "frontend", subnetId });
789
+ expect(Object.keys(result.members)).toEqual(["workspace", "identity", "environment", "containerApp"]);
790
+ expect(et(result.workspace)).toBe("Microsoft.OperationalInsights/workspaces");
791
+ expect(et(result.identity)).toBe("Microsoft.ManagedIdentity/userAssignedIdentities");
792
+ expect(et(result.environment)).toBe("Microsoft.App/managedEnvironments");
793
+ expect(et(result.containerApp)).toBe("Microsoft.App/containerApps");
794
+ });
795
+
796
+ test("puts the environment in the subnet on the Consumption profile, logging to the workspace", () => {
797
+ const { workspace, environment } = ContainerAppSite({ name: "web", app: "frontend", subnetId });
798
+ expect(p(workspace).name).toBe("web-logs");
799
+ const env = p(environment);
800
+ expect(env.vnetConfiguration).toEqual({ infrastructureSubnetId: subnetId, internal: false });
801
+ expect(env.workloadProfiles).toEqual([{ name: "Consumption", workloadProfileType: "Consumption" }]);
802
+ const logs = (env.appLogsConfiguration as { logAnalyticsConfiguration: Record<string, string> }).logAnalyticsConfiguration;
803
+ expect(logs.customerId).toContain("reference(resourceId('Microsoft.OperationalInsights/workspaces', 'web-logs')");
804
+ expect(logs.sharedKey).toContain("listKeys(resourceId('Microsoft.OperationalInsights/workspaces', 'web-logs')");
805
+ });
806
+
807
+ test("runs the app as the identity behind external ingress", () => {
808
+ const { identity, containerApp } = ContainerAppSite({ name: "web", app: "frontend", subnetId, image: "nginx:1.27", port: 8080, replicas: 2 });
809
+ expect(p(identity).name).toBe("web-frontend");
810
+ const app = p(containerApp);
811
+ expect(app.name).toBe("frontend");
812
+ const ids = (app.identity as { userAssignedIdentities: Record<string, unknown> }).userAssignedIdentities;
813
+ expect(Object.keys(ids)).toEqual(["[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', 'web-frontend')]"]);
814
+ expect(app.configuration).toEqual({ ingress: { external: true, targetPort: 8080, transport: "auto" } });
815
+ const template = app.template as { containers: Array<{ image: string }>; scale: Record<string, number> };
816
+ expect(template.containers[0].image).toBe("nginx:1.27");
817
+ expect(template.scale).toEqual({ minReplicas: 2, maxReplicas: 2 });
818
+ });
819
+
820
+ test("internal makes the environment VNet-only", () => {
821
+ const { environment } = ContainerAppSite({ name: "web", app: "frontend", subnetId, internal: true });
822
+ expect((p(environment).vnetConfiguration as Record<string, unknown>).internal).toBe(true);
823
+ });
824
+
825
+ test("defaults override a member's props", () => {
826
+ const { workspace } = ContainerAppSite({ name: "web", app: "frontend", subnetId, defaults: { workspace: { retentionInDays: 90 } } });
827
+ expect(p(workspace).retentionInDays).toBe(90);
828
+ });
829
+
830
+ test("takes a ContainerAppNetwork's subnet id", () => {
831
+ const network = ContainerAppNetwork({ name: "web" });
832
+ const { environment } = ContainerAppSite({ name: "web", app: "frontend", subnetId: network.subnet.id });
833
+ expect((p(environment).vnetConfiguration as Record<string, unknown>).infrastructureSubnetId).toBe(network.subnet.id);
834
+ });
835
+ });
@@ -0,0 +1,209 @@
1
+ /**
2
+ * ContainerAppNetwork and ContainerAppSite composites: a website on Azure
3
+ * Container Apps and the network it sits in.
4
+ *
5
+ * Split the way the aws lexicon splits VpcDefault from FargateAlb, so several
6
+ * sites can share one network. Container Apps brings its own ingress and load
7
+ * balancing, so there is no load balancer to declare.
8
+ */
9
+
10
+ import { Composite, mergeDefaults } from "@intentius/chant";
11
+ import {
12
+ VirtualNetwork,
13
+ Subnet,
14
+ LogAnalyticsWorkspace,
15
+ ManagedIdentity,
16
+ managedEnvironments,
17
+ containerApps,
18
+ } from "../generated";
19
+
20
+ export interface ContainerAppNetworkProps {
21
+ /** Network name prefix: the VNet is `<name>-vnet`, its subnet `apps`. */
22
+ name: string;
23
+ /** Azure region (default: resource group location). */
24
+ location?: string;
25
+ /** VNet address space (default: "10.0.0.0/16"). */
26
+ addressSpace?: string;
27
+ /** The environment subnet's prefix, a /23 or larger (default: "10.0.0.0/23"). */
28
+ subnetPrefix?: string;
29
+ /** Resource tags. */
30
+ tags?: Record<string, string>;
31
+ /** Per-member defaults. */
32
+ defaults?: {
33
+ virtualNetwork?: Partial<ConstructorParameters<typeof VirtualNetwork>[0]>;
34
+ subnet?: Partial<ConstructorParameters<typeof Subnet>[0]>;
35
+ };
36
+ }
37
+
38
+ export interface ContainerAppNetworkResult {
39
+ virtualNetwork: InstanceType<typeof VirtualNetwork>;
40
+ subnet: InstanceType<typeof Subnet>;
41
+ }
42
+
43
+ /**
44
+ * A VNet with a subnet delegated to `Microsoft.App/environments`, for
45
+ * ContainerAppSite environments to sit in.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { ContainerAppNetwork } from "@intentius/chant-lexicon-azure";
50
+ *
51
+ * export const network = ContainerAppNetwork({ name: "web" });
52
+ * ```
53
+ */
54
+ export const ContainerAppNetwork = Composite((props: ContainerAppNetworkProps) => {
55
+ const {
56
+ name,
57
+ location = "[resourceGroup().location]",
58
+ addressSpace = "10.0.0.0/16",
59
+ subnetPrefix = "10.0.0.0/23",
60
+ tags = {},
61
+ defaults,
62
+ } = props;
63
+
64
+ const mergedTags = { "managed-by": "chant", ...tags };
65
+ const vnetName = `${name}-vnet`;
66
+ const delegations = [{ name: "apps", properties: { serviceName: "Microsoft.App/environments" } }];
67
+
68
+ // The subnet is also listed inline, as VnetDefault does, so a later
69
+ // deployment of the VNet does not try to remove it.
70
+ const virtualNetwork = new VirtualNetwork(mergeDefaults({
71
+ name: vnetName,
72
+ location,
73
+ tags: mergedTags,
74
+ addressSpace: { addressPrefixes: [addressSpace] },
75
+ subnets: [{ name: "apps", properties: { addressPrefix: subnetPrefix, delegations } }],
76
+ }, defaults?.virtualNetwork), { apiVersion: "2023-05-01" });
77
+
78
+ const subnet = new Subnet(mergeDefaults({
79
+ name: `${vnetName}/apps`,
80
+ addressPrefix: subnetPrefix,
81
+ delegations,
82
+ }, defaults?.subnet), { apiVersion: "2023-05-01" });
83
+
84
+ return { virtualNetwork, subnet };
85
+ }, "ContainerAppNetwork");
86
+
87
+ export interface ContainerAppSiteProps {
88
+ /** Environment name; the workspace is `<name>-logs` and the identity `<name>-<app>`. */
89
+ name: string;
90
+ /** Container app name. */
91
+ app: string;
92
+ /** Subnet resource ID for the environment, such as a ContainerAppNetwork's `subnet.id`. */
93
+ subnetId: string;
94
+ /** Azure region (default: resource group location). */
95
+ location?: string;
96
+ /** Container image (default: "mcr.microsoft.com/k8se/quickstart:latest"). */
97
+ image?: string;
98
+ /** Port the container listens on; ingress forwards to it (default: 80). */
99
+ port?: number;
100
+ /** Fixed replica count (default: 1). */
101
+ replicas?: number;
102
+ /** Make the environment reachable only from its VNet (default: false). */
103
+ internal?: boolean;
104
+ /** Resource tags. */
105
+ tags?: Record<string, string>;
106
+ /** Per-member defaults. */
107
+ defaults?: {
108
+ workspace?: Partial<ConstructorParameters<typeof LogAnalyticsWorkspace>[0]>;
109
+ identity?: Partial<ConstructorParameters<typeof ManagedIdentity>[0]>;
110
+ environment?: Partial<ConstructorParameters<typeof managedEnvironments>[0]>;
111
+ containerApp?: Partial<ConstructorParameters<typeof containerApps>[0]>;
112
+ };
113
+ }
114
+
115
+ export interface ContainerAppSiteResult {
116
+ workspace: InstanceType<typeof LogAnalyticsWorkspace>;
117
+ identity: InstanceType<typeof ManagedIdentity>;
118
+ environment: InstanceType<typeof managedEnvironments>;
119
+ containerApp: InstanceType<typeof containerApps>;
120
+ }
121
+
122
+ /**
123
+ * A Container Apps environment in a subnet, shipping logs to its own Log
124
+ * Analytics workspace, with one app running as a user-assigned identity.
125
+ *
126
+ * @example
127
+ * ```ts
128
+ * import { ContainerAppNetwork, ContainerAppSite } from "@intentius/chant-lexicon-azure";
129
+ *
130
+ * export const network = ContainerAppNetwork({ name: "web" });
131
+ * export const site = ContainerAppSite({
132
+ * name: "web",
133
+ * app: "frontend",
134
+ * subnetId: network.subnet.id,
135
+ * image: "nginx:1.27",
136
+ * });
137
+ * ```
138
+ */
139
+ export const ContainerAppSite = Composite((props: ContainerAppSiteProps) => {
140
+ const {
141
+ name,
142
+ app,
143
+ subnetId,
144
+ location = "[resourceGroup().location]",
145
+ image = "mcr.microsoft.com/k8se/quickstart:latest",
146
+ port = 80,
147
+ replicas = 1,
148
+ internal = false,
149
+ tags = {},
150
+ defaults,
151
+ } = props;
152
+
153
+ const mergedTags = { "managed-by": "chant", ...tags };
154
+ const workspaceName = `${name}-logs`;
155
+ const identityName = `${name}-${app}`;
156
+ const workspaceId = `resourceId('Microsoft.OperationalInsights/workspaces', '${workspaceName}')`;
157
+
158
+ const workspace = new LogAnalyticsWorkspace(mergeDefaults({
159
+ name: workspaceName,
160
+ location,
161
+ tags: mergedTags,
162
+ // A workspace's sku sits inside its properties, not beside them, so it is
163
+ // passed there rather than hoisted to the resource like other skus.
164
+ properties: { sku: { name: "PerGB2018" } },
165
+ retentionInDays: 30,
166
+ }, defaults?.workspace), { apiVersion: "2023-09-01" });
167
+
168
+ const identity = new ManagedIdentity(mergeDefaults({
169
+ name: identityName,
170
+ location,
171
+ tags: mergedTags,
172
+ }, defaults?.identity), { apiVersion: "2023-01-31" });
173
+
174
+ const environment = new managedEnvironments(mergeDefaults({
175
+ name,
176
+ location,
177
+ tags: mergedTags,
178
+ vnetConfiguration: { infrastructureSubnetId: subnetId, internal },
179
+ appLogsConfiguration: {
180
+ destination: "log-analytics",
181
+ logAnalyticsConfiguration: {
182
+ customerId: `[reference(${workspaceId}, '2023-09-01').customerId]`,
183
+ sharedKey: `[listKeys(${workspaceId}, '2023-09-01').primarySharedKey]`,
184
+ },
185
+ },
186
+ workloadProfiles: [{ name: "Consumption", workloadProfileType: "Consumption" }],
187
+ }, defaults?.environment), { apiVersion: "2024-03-01" });
188
+
189
+ const containerApp = new containerApps(mergeDefaults({
190
+ name: app,
191
+ location,
192
+ tags: mergedTags,
193
+ identity: {
194
+ type: "UserAssigned",
195
+ userAssignedIdentities: {
196
+ [`[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', '${identityName}')]`]: {},
197
+ },
198
+ },
199
+ managedEnvironmentId: environment.id,
200
+ workloadProfileName: "Consumption",
201
+ configuration: { ingress: { external: true, targetPort: port, transport: "auto" } },
202
+ template: {
203
+ containers: [{ name: app, image, resources: { cpu: 0.25, memory: "0.5Gi" } }],
204
+ scale: { minReplicas: replicas, maxReplicas: replicas },
205
+ },
206
+ }, defaults?.containerApp), { apiVersion: "2024-03-01" });
207
+
208
+ return { workspace, identity, environment, containerApp };
209
+ }, "ContainerAppSite");
@@ -28,6 +28,11 @@ export { RedisCache } from "./redis-cache";
28
28
  export type { RedisCacheProps, RedisCacheResult } from "./redis-cache";
29
29
  export { PrivateEndpoint } from "./private-endpoint";
30
30
  export type { PrivateEndpointProps, PrivateEndpointResult } from "./private-endpoint";
31
+ export { ContainerAppNetwork, ContainerAppSite } from "./container-app";
32
+ export type {
33
+ ContainerAppNetworkProps, ContainerAppNetworkResult,
34
+ ContainerAppSiteProps, ContainerAppSiteResult,
35
+ } from "./container-app";
31
36
  export { GovernanceFoundation, GovernanceBaseline, LocationRestriction, ActivityLogSink } from "./landing-zone";
32
37
  export type {
33
38
  GovernanceFoundationProps, GovernanceFoundationResult,
package/src/index.ts CHANGED
@@ -78,6 +78,8 @@ export {
78
78
  ContainerInstance, type ContainerInstanceProps, type ContainerInstanceResult,
79
79
  RedisCache, type RedisCacheProps, type RedisCacheResult,
80
80
  PrivateEndpoint, type PrivateEndpointProps, type PrivateEndpointResult,
81
+ ContainerAppNetwork, type ContainerAppNetworkProps, type ContainerAppNetworkResult,
82
+ ContainerAppSite, type ContainerAppSiteProps, type ContainerAppSiteResult,
81
83
  GovernanceFoundation, type GovernanceFoundationProps, type GovernanceFoundationResult,
82
84
  GovernanceBaseline, type GovernanceBaselineProps, type GovernanceBaselineResult,
83
85
  LocationRestriction, type LocationRestrictionProps, type LocationRestrictionResult,
@@ -408,6 +408,22 @@ const { privateEndpoint, privateDnsZone, dnsZoneGroup, vnetLink } = PrivateEndpo
408
408
  export { storageAccount, privateEndpoint, privateDnsZone, dnsZoneGroup, vnetLink };
409
409
  ```
410
410
 
411
+ ### ContainerAppNetwork and ContainerAppSite
412
+ A Container Apps site in its own delegated subnet; one network can carry several sites:
413
+
414
+ ```ts
415
+ import { ContainerAppNetwork, ContainerAppSite } from "@intentius/chant-lexicon-azure";
416
+
417
+ export const network = ContainerAppNetwork({ name: "web" });
418
+
419
+ export const site = ContainerAppSite({
420
+ name: "web",
421
+ app: "frontend",
422
+ subnetId: network.subnet.id,
423
+ image: "nginx:1.27",
424
+ });
425
+ ```
426
+
411
427
  ## ARM Template Intrinsic Reference
412
428
 
413
429
  | Function | Description | Example |
@@ -267,6 +267,7 @@ Use the secure composite variants which apply these patterns automatically:
267
267
  - `ContainerInstance` — Managed identity, no public IP by default
268
268
  - `RedisCache` — Non-SSL port disabled, TLS 1.2
269
269
  - `PrivateEndpoint` — Private connectivity pattern with DNS zone
270
+ - `ContainerAppSite`: user-assigned identity, app logs to Log Analytics, optional VNet-only environment
270
271
 
271
272
  ## Post-Synth Check Reference
272
273
 
@@ -157,6 +157,8 @@ Composites group related Azure resources with secure defaults. Each returns an o
157
157
  | `ContainerInstance` | ContainerGroup | No public IP by default, resource limits set |
158
158
  | `RedisCache` | RedisCache | TLS 1.2 required, non-SSL port disabled |
159
159
  | `PrivateEndpoint` | PrivateEndpoint + PrivateDnsZone + VnetLink | DNS zone auto-registration, manual approval disabled |
160
+ | `ContainerAppNetwork` | VirtualNetwork + Subnet | Subnet delegated to Container Apps, /23 by default |
161
+ | `ContainerAppSite` | LogAnalyticsWorkspace + ManagedIdentity + ManagedEnvironment + ContainerApp | App logs to Log Analytics, user-assigned identity, Consumption profile |
160
162
  | `AksCluster` | ManagedCluster + AgentPool | RBAC enabled, network policy (calico), managed identity, Azure CNI |
161
163
  | `SqlDatabase` | SQLServer + Database + FirewallRule + AuditingSettings | TDE enabled, auditing enabled, TLS 1.2, no Azure-wide firewall rule |
162
164
  | `KeyVaultSecure` | KeyVault + AccessPolicy | Soft delete, purge protection, RBAC authorization, network ACLs |