@gradientedge/cdk-utils-azure 2.20.0 → 2.22.0

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.
@@ -94,6 +94,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
94
94
  this.appServicePlan = this.appServiceManager.createAppServicePlan(`${this.id}-app-service-plan`, this, {
95
95
  ...this.props.functionApp.servicePlan,
96
96
  name: this.id,
97
+ kind: this.props.functionApp.servicePlan?.kind ?? 'functionapp',
97
98
  resourceGroupName: this.resourceGroup.name,
98
99
  location: this.resourceGroup.location,
99
100
  });
@@ -241,7 +242,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
241
242
  * @summary Method to create and configure the function host.json
242
243
  */
243
244
  createFunctionHosts() {
244
- const currentDirectory = path.resolve();
245
+ const currentDirectory = path.resolve(process.cwd(), '..');
245
246
  const hostsJsonFile = `${currentDirectory}/${this.props.functionApp.deploySource}/host.json`;
246
247
  if (!fs.existsSync(hostsJsonFile))
247
248
  return;
@@ -253,7 +254,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
253
254
  * @summary Method to create the code package archive for deployment
254
255
  */
255
256
  createCodePackage() {
256
- const currentDirectory = path.resolve();
257
+ const currentDirectory = path.resolve(process.cwd(), '..');
257
258
  this.appCodeArchiveFile = archive.getFileOutput({
258
259
  type: 'zip',
259
260
  sourceDir: `${currentDirectory}/${this.props.functionApp.deploySource}`,
@@ -273,6 +274,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
273
274
  this.app = this.functionManager.createFunctionAppFlexConsumption(`${this.id}-function-app-flex`, this, {
274
275
  ...this.props.functionApp,
275
276
  name: this.props.functionApp.app?.name ?? this.id,
277
+ scaleAndConcurrency: this.props.functionApp.app?.scaleAndConcurrency,
276
278
  serverFarmId: this.appServicePlan.id,
277
279
  resourceGroupName: this.resourceGroup.name,
278
280
  functionAppConfig: {
@@ -282,7 +284,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
282
284
  value: pulumi.interpolate `${this.appStorageAccount.primaryEndpoints.apply(e => e?.blob)}${this.appDeploymentStorageContainer.name}`,
283
285
  authentication: {
284
286
  type: AuthenticationType.StorageAccountConnectionString,
285
- storageAccountConnectionStringName: 'AzureWebJobsStorage',
287
+ storageAccountConnectionStringName: 'DEPLOYMENT_STORAGE_CONNECTION_STRING',
286
288
  },
287
289
  },
288
290
  },
@@ -299,7 +301,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
299
301
  value: this.applicationInsights.instrumentationKey,
300
302
  },
301
303
  {
302
- name: 'AzureWebJobsStorage',
304
+ name: 'DEPLOYMENT_STORAGE_CONNECTION_STRING',
303
305
  value: pulumi.interpolate `DefaultEndpointsProtocol=https;AccountName=${this.appStorageAccount.name};AccountKey=${listStorageAccountKeysOutput({
304
306
  resourceGroupName: this.resourceGroup.name,
305
307
  accountName: this.appStorageAccount.name,
@@ -322,9 +324,9 @@ export class AzureFunctionApp extends CommonAzureConstruct {
322
324
  */
323
325
  createRoleAssignments() {
324
326
  if (this.props.dataStorageAccount) {
325
- this.authorisationManager.grantRoleAssignmentToStorageAccount(`${this.id}-data`, this, this.dataStorageAccount.id, this.getFunctionAppPrincipalId(), this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.STORAGE_BLOB_DATA_CONTRIBUTOR));
327
+ this.authorisationManager.grantRoleAssignmentToStorageAccount(`${this.id}-data`, this, this.dataStorageAccount.id, this.getFunctionAppPrincipalId(), PrincipalType.ServicePrincipal, this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.STORAGE_BLOB_DATA_CONTRIBUTOR));
326
328
  }
327
- this.authorisationManager.grantRoleAssignmentToStorageAccount(this.id, this, this.appStorageAccount.id, this.getFunctionAppPrincipalId(), this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.STORAGE_BLOB_DATA_CONTRIBUTOR));
329
+ this.authorisationManager.grantRoleAssignmentToStorageAccount(this.id, this, this.appStorageAccount.id, this.getFunctionAppPrincipalId(), PrincipalType.ServicePrincipal, this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.STORAGE_BLOB_DATA_CONTRIBUTOR));
328
330
  if (!this.props.useConfigOverride) {
329
331
  this.authorisationManager.grantRoleAssignmentToApplicationConfiguration(this.id, this, this.appConfig.id, this.getFunctionAppPrincipalId(), PrincipalType.ServicePrincipal, this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.APP_CONFIGURATION_DATA_READER));
330
332
  }
@@ -335,12 +337,12 @@ export class AzureFunctionApp extends CommonAzureConstruct {
335
337
  if (this.appKeyVaultsByResourceGroup && this.appKeyVaultsByResourceGroup.size > 0) {
336
338
  this.appKeyVaultsByResourceGroup.forEach((keyVaultNames, resourceGroup) => {
337
339
  keyVaultNames.forEach(keyVaultName => {
338
- this.authorisationManager.grantRoleAssignmentToKeyVault(this.id, this, keyVaultName, resourceGroup, this.getFunctionAppPrincipalId(), this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.KEY_VAULT_SECRETS_USER));
340
+ this.authorisationManager.grantRoleAssignmentToKeyVault(this.id, this, keyVaultName, resourceGroup, this.getFunctionAppPrincipalId(), PrincipalType.ServicePrincipal, this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.KEY_VAULT_SECRETS_USER));
339
341
  });
340
342
  });
341
343
  }
342
344
  if (AzureAppConfigurationManager.hasEventGridTargets(this.appConfigurationsParsedConfig)) {
343
- this.authorisationManager.grantRoleAssignmentToEventgridTopic(this.id, this, this.props.existingTopicName, this.props.existingTopicResourceGroupName, this.getFunctionAppPrincipalId(), this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.EVENTGRID_DATA_SENDER));
345
+ this.authorisationManager.grantRoleAssignmentToEventgridTopic(this.id, this, this.props.existingTopicName, this.props.existingTopicResourceGroupName, this.getFunctionAppPrincipalId(), PrincipalType.ServicePrincipal, this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.EVENTGRID_DATA_SENDER));
344
346
  }
345
347
  }
346
348
  /**
@@ -1,4 +1,4 @@
1
- import { HostnameType, NamedValue } from '@pulumi/azure-native/apimanagement/index.js';
1
+ import { HostnameType, NamedValue, PolicyContentFormat } from '@pulumi/azure-native/apimanagement/index.js';
2
2
  import { getVaultOutput } from '@pulumi/azure-native/keyvault/index.js';
3
3
  import { listWebAppHostKeysOutput } from '@pulumi/azure-native/web/index.js';
4
4
  import * as pulumi from '@pulumi/pulumi';
@@ -81,7 +81,7 @@ export class AzureRestApiFunction extends AzureFunctionApp {
81
81
  this.api.namedValueSecret = this.keyVaultManager.createKeyVaultSecret(`${this.id}-key-vault-api-namespace-secret`, this, {
82
82
  vaultName: this.api.authKeyVault.name,
83
83
  secretName: pulumi.interpolate `${this.app.name}key`,
84
- resourceGroupName: this.resourceGroup.name,
84
+ resourceGroupName: this.props.apiAuthKeyVault.resourceGroupName,
85
85
  properties: {
86
86
  value: functionDefaultKey.functionKeys?.apply(keys => keys?.['default'] ?? ''),
87
87
  },
@@ -94,9 +94,10 @@ export class AzureRestApiFunction extends AzureFunctionApp {
94
94
  if (this.props.apiManagement.useExistingApiManagement) {
95
95
  if (this.props.apiManagement.apiStackName) {
96
96
  const apiStack = new pulumi.StackReference(this.props.apiManagement.apiStackName);
97
- this.api.id = apiStack.getOutput('apiId');
98
- this.api.name = apiStack.getOutput('apiName');
99
- this.api.resourceGroupName = apiStack.getOutput('apiResourceGroupName');
97
+ const stackOutputs = apiStack.getOutput('stackOutputs');
98
+ this.api.id = stackOutputs.apply(o => o.apiId);
99
+ this.api.name = stackOutputs.apply(o => o.apiName);
100
+ this.api.resourceGroupName = stackOutputs.apply(o => o.resourceGroupName);
100
101
  }
101
102
  }
102
103
  else {
@@ -136,14 +137,15 @@ export class AzureRestApiFunction extends AzureFunctionApp {
136
137
  this.api.namedValue = new NamedValue(`${this.id}-am-nv`, {
137
138
  displayName: this.app.name,
138
139
  keyVault: {
139
- secretIdentifier: this.api.namedValueSecret.id,
140
+ secretIdentifier: this.api.namedValueSecret.properties.apply(p => p.secretUri),
140
141
  },
141
142
  resourceGroupName: this.api.resourceGroupName,
142
143
  secret: true,
143
144
  serviceName: this.api.name,
144
- });
145
+ }, { parent: this });
145
146
  this.api.backend = this.apiManagementManager.createBackend(this.id, this, {
146
147
  ...this.props.apiManagementBackend,
148
+ backendId: this.id,
147
149
  title: this.id,
148
150
  resourceGroupName: this.api.resourceGroupName,
149
151
  serviceName: this.api.name,
@@ -151,7 +153,7 @@ export class AzureRestApiFunction extends AzureFunctionApp {
151
153
  resourceId: pulumi.interpolate `https://management.azure.com/subscriptions/${this.props.subscriptionId}/resourceGroups/${this.resourceGroup.name}/providers/Microsoft.Web/sites/${this.app.name}`,
152
154
  credentials: {
153
155
  header: {
154
- 'x-functions-key': [`{{${this.api.namedValue.name}}}`],
156
+ 'x-functions-key': [pulumi.interpolate `{{${this.api.namedValue.name}}}`],
155
157
  },
156
158
  },
157
159
  });
@@ -162,6 +164,7 @@ export class AzureRestApiFunction extends AzureFunctionApp {
162
164
  createApiManagementRoutes() {
163
165
  this.api.managementApi = this.apiManagementManager.createApi(`${this.id}-apim-api`, this, {
164
166
  ...this.props.apiManagementApi,
167
+ apiId: this.id,
165
168
  displayName: this.props.apiManagementApi.displayName ?? this.id,
166
169
  serviceName: this.api.name,
167
170
  resourceGroupName: this.api.resourceGroupName,
@@ -182,7 +185,7 @@ export class AzureRestApiFunction extends AzureFunctionApp {
182
185
  method: operation.method.toString().toUpperCase(),
183
186
  serviceName: this.api.name,
184
187
  resourceGroupName: this.api.resourceGroupName,
185
- apiId: this.api.id,
188
+ apiId: this.resourceNameFormatter.format(this.id, this.props.resourceNameOptions?.apiManagementApi),
186
189
  displayName: operation.displayName,
187
190
  urlTemplate: operation.urlTemplate,
188
191
  templateParameters: operation.templateParameters,
@@ -195,28 +198,28 @@ export class AzureRestApiFunction extends AzureFunctionApp {
195
198
  if (!operation.caching || !operation.caching.enableCacheSet)
196
199
  return;
197
200
  this.apiManagementManager.createOperationPolicy(`${this.id}-apim-api-operation-policy-${operation.displayName}-${operation.method}`, this, {
198
- apiId: this.api.id,
201
+ apiId: this.resourceNameFormatter.format(this.id, this.props.resourceNameOptions?.apiManagementApi),
199
202
  resourceGroupName: this.api.resourceGroupName,
200
203
  serviceName: this.api.name,
201
204
  operationId: `${operation.displayName}-${operation.method}`,
205
+ format: PolicyContentFormat.Rawxml,
202
206
  value: `
203
207
  <policies>
204
- <policies>
205
- <inbound>
206
- <base />
207
- ${this.props.apiManagementApi.cacheSetInboundPolicy}
208
- </inbound>
209
- <backend>
210
- <base />
211
- </backend>
212
- <outbound>
213
- <base />
214
- ${this.props.apiManagementApi.cacheSetOutboundPolicy}
215
- </outbound>
216
- <on-error>
217
- <base />
218
- </on-error>
219
- </policies>`.replace(/\n[ \t]*\n/g, '\n'), // move to utils
208
+ <inbound>
209
+ <base />
210
+ ${this.props.apiManagementApi.cacheSetInboundPolicy ?? ''}
211
+ </inbound>
212
+ <backend>
213
+ <base />
214
+ </backend>
215
+ <outbound>
216
+ <base />
217
+ ${this.props.apiManagementApi.cacheSetOutboundPolicy ?? ''}
218
+ </outbound>
219
+ <on-error>
220
+ <base />
221
+ </on-error>
222
+ </policies>`.replace(/\n[ \t]*\n/g, '\n'),
220
223
  });
221
224
  }
222
225
  /**
@@ -287,8 +290,9 @@ export class AzureRestApiFunction extends AzureFunctionApp {
287
290
  </policies>`;
288
291
  this.apiManagementManager.createPolicy(`${this.id}-apim-api-policy`, this, {
289
292
  serviceName: this.api.name,
290
- apiId: this.api.id,
293
+ apiId: this.resourceNameFormatter.format(this.id, this.props.resourceNameOptions?.apiManagementApi),
291
294
  resourceGroupName: this.api.resourceGroupName,
295
+ format: PolicyContentFormat.Rawxml,
292
296
  value: policyXmlContent.apply(xml => xml.replace(/\n[ \t]*\n/g, '\n')),
293
297
  });
294
298
  }
@@ -60,6 +60,8 @@ export class SiteWithWebApp extends CommonAzureConstruct {
60
60
  createSiteAppServicePlan() {
61
61
  this.site.appServicePlan = this.appServiceManager.createAppServicePlan(`${this.id}-app-service-plan`, this, {
62
62
  ...this.props.site.appServicePlan,
63
+ name: this.id,
64
+ kind: this.props.site.appServicePlan?.kind ?? 'linux',
63
65
  location: this.resourceGroup.location,
64
66
  resourceGroupName: this.resourceGroup.name,
65
67
  });
@@ -131,6 +133,7 @@ export class SiteWithWebApp extends CommonAzureConstruct {
131
133
  createWebApp(resourceOptions) {
132
134
  this.site.webApp = this.appServiceManager.createLinuxWebApp(`${this.id}-web-app`, this, {
133
135
  ...this.props.site.webApp,
136
+ kind: this.props.site.webApp.kind ?? 'app,linux',
134
137
  location: this.resourceGroup.location,
135
138
  resourceGroupName: this.resourceGroup.name,
136
139
  serverFarmId: this.site.appServicePlan.id,
@@ -222,7 +222,7 @@ export class AzureApiManagementManager {
222
222
  * @see [Pulumi Azure Native API Management Operation Policy]{@link https://www.pulumi.com/registry/packages/azure-native/api-docs/apimanagement/apioperationpolicy/}
223
223
  */
224
224
  createOperationPolicy(id, scope, props, resourceOptions) {
225
- return new ApiOperationPolicy(`${id}`, props, { parent: scope, ...resourceOptions });
225
+ return new ApiOperationPolicy(`${id}`, { ...props, policyId: 'policy' }, { parent: scope, ...resourceOptions });
226
226
  }
227
227
  /**
228
228
  * @summary Method to create a new API policy
@@ -233,7 +233,7 @@ export class AzureApiManagementManager {
233
233
  * @see [Pulumi Azure Native API Management Policy]{@link https://www.pulumi.com/registry/packages/azure-native/api-docs/apimanagement/apipolicy/}
234
234
  */
235
235
  createPolicy(id, scope, props, resourceOptions) {
236
- return new ApiPolicy(`${id}`, props, { parent: scope, ...resourceOptions });
236
+ return new ApiPolicy(`${id}`, { ...props, policyId: 'policy' }, { parent: scope, ...resourceOptions });
237
237
  }
238
238
  /**
239
239
  * @summary Method to create a new API Management custom domain
@@ -36,6 +36,7 @@ export class AzureAppServiceManager {
36
36
  name: scope.resourceNameFormatter.format(props.name?.toString(), scope.props.resourceNameOptions?.appServicePlan),
37
37
  resourceGroupName,
38
38
  location: props.location ?? scope.props.location,
39
+ kind: props.kind ?? 'functionapp',
39
40
  sku: props.sku ?? {
40
41
  name: 'FC1',
41
42
  tier: 'FlexConsumption',
@@ -41,7 +41,7 @@ export declare class AzureAuthorisationManager {
41
41
  * @param roleDefinitionId the role definition id
42
42
  * @param resourceOptions Optional settings to control resource behaviour
43
43
  */
44
- grantRoleAssignmentToKeyVault(id: string, scope: CommonAzureConstruct, vaultName: string, resourceGroupName: Input<string>, principalId: Input<string>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
44
+ grantRoleAssignmentToKeyVault(id: string, scope: CommonAzureConstruct, vaultName: string, resourceGroupName: Input<string>, principalId: Input<string>, principalType: Input<PrincipalType>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
45
45
  /**
46
46
  * @summary Method to grant a role assignment to event grid topic
47
47
  * @param id scoped id of the resource
@@ -52,7 +52,7 @@ export declare class AzureAuthorisationManager {
52
52
  * @param roleDefinitionId the role definition id
53
53
  * @param resourceOptions Optional settings to control resource behaviour
54
54
  */
55
- grantRoleAssignmentToEventgridTopic(id: string, scope: CommonAzureConstruct, topicName: Input<string>, resourceGroupName: Input<string>, principalId: Input<string>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
55
+ grantRoleAssignmentToEventgridTopic(id: string, scope: CommonAzureConstruct, topicName: Input<string>, resourceGroupName: Input<string>, principalId: Input<string>, principalType: Input<PrincipalType>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
56
56
  /**
57
57
  * @summary Method to grant a role assignment to application configuration
58
58
  * @param id scoped id of the resource
@@ -72,7 +72,7 @@ export declare class AzureAuthorisationManager {
72
72
  * @param roleDefinitionId the role definition id
73
73
  * @param resourceOptions Optional settings to control resource behaviour
74
74
  */
75
- grantRoleAssignmentToStorageAccount(id: string, scope: CommonAzureConstruct, accountId: Input<string>, principalId: Input<string>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
75
+ grantRoleAssignmentToStorageAccount(id: string, scope: CommonAzureConstruct, accountId: Input<string>, principalId: Input<string>, principalType: Input<PrincipalType>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
76
76
  /**
77
77
  * @summary Method to grant a role assignment to storage table
78
78
  * @param id scoped id of the resource
@@ -82,6 +82,6 @@ export declare class AzureAuthorisationManager {
82
82
  * @param roleDefinitionId the role definition id
83
83
  * @param resourceOptions Optional settings to control resource behaviour
84
84
  */
85
- grantRoleAssignmentToStorageTable(id: string, scope: CommonAzureConstruct, tableId: Input<string>, principalId: Input<string>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
85
+ grantRoleAssignmentToStorageTable(id: string, scope: CommonAzureConstruct, tableId: Input<string>, principalId: Input<string>, principalType: Input<PrincipalType>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
86
86
  resolveRoleDefinitionId(scope: CommonAzureConstruct, roleDefinitionId: RoleDefinitionId): string;
87
87
  }
@@ -41,10 +41,11 @@ export class AzureAuthorisationManager {
41
41
  * @param roleDefinitionId the role definition id
42
42
  * @param resourceOptions Optional settings to control resource behaviour
43
43
  */
44
- grantRoleAssignmentToKeyVault(id, scope, vaultName, resourceGroupName, principalId, roleDefinitionId, resourceOptions) {
44
+ grantRoleAssignmentToKeyVault(id, scope, vaultName, resourceGroupName, principalId, principalType, roleDefinitionId, resourceOptions) {
45
45
  const keyVault = scope.keyVaultManager.resolveKeyVault(scope, vaultName, resourceGroupName, resourceOptions);
46
46
  return this.createRoleAssignment(`${id}-kv-role-${vaultName}`, scope, {
47
47
  principalId,
48
+ principalType,
48
49
  roleDefinitionId,
49
50
  scope: keyVault.id,
50
51
  }, resourceOptions);
@@ -59,13 +60,14 @@ export class AzureAuthorisationManager {
59
60
  * @param roleDefinitionId the role definition id
60
61
  * @param resourceOptions Optional settings to control resource behaviour
61
62
  */
62
- grantRoleAssignmentToEventgridTopic(id, scope, topicName, resourceGroupName, principalId, roleDefinitionId, resourceOptions) {
63
+ grantRoleAssignmentToEventgridTopic(id, scope, topicName, resourceGroupName, principalId, principalType, roleDefinitionId, resourceOptions) {
63
64
  const topic = scope.eventgridManager.resolveEventgridTopic(`${id}-egt-role-${topicName}`, scope, {
64
65
  topicName,
65
66
  resourceGroupName,
66
67
  }, resourceOptions);
67
68
  return this.createRoleAssignment(`${id}-egt-role-${topicName}`, scope, {
68
69
  principalId,
70
+ principalType,
69
71
  roleDefinitionId,
70
72
  scope: topic.id,
71
73
  }, resourceOptions);
@@ -96,9 +98,10 @@ export class AzureAuthorisationManager {
96
98
  * @param roleDefinitionId the role definition id
97
99
  * @param resourceOptions Optional settings to control resource behaviour
98
100
  */
99
- grantRoleAssignmentToStorageAccount(id, scope, accountId, principalId, roleDefinitionId, resourceOptions) {
101
+ grantRoleAssignmentToStorageAccount(id, scope, accountId, principalId, principalType, roleDefinitionId, resourceOptions) {
100
102
  return this.createRoleAssignment(`${id}-sa-role`, scope, {
101
103
  principalId,
104
+ principalType,
102
105
  roleDefinitionId,
103
106
  scope: accountId,
104
107
  }, resourceOptions);
@@ -112,9 +115,10 @@ export class AzureAuthorisationManager {
112
115
  * @param roleDefinitionId the role definition id
113
116
  * @param resourceOptions Optional settings to control resource behaviour
114
117
  */
115
- grantRoleAssignmentToStorageTable(id, scope, tableId, principalId, roleDefinitionId, resourceOptions) {
118
+ grantRoleAssignmentToStorageTable(id, scope, tableId, principalId, principalType, roleDefinitionId, resourceOptions) {
116
119
  return this.createRoleAssignment(`${id}-st-role`, scope, {
117
120
  principalId,
121
+ principalType,
118
122
  roleDefinitionId,
119
123
  scope: tableId,
120
124
  }, resourceOptions);
@@ -1,5 +1,6 @@
1
1
  import { Deployment, DeploymentMode, Resource } from '@pulumi/azure-native/resources/index.js';
2
- import { ManagedServiceIdentityType, WebApp, WebAppFunction } from '@pulumi/azure-native/web/index.js';
2
+ import { ClientCertMode, ManagedServiceIdentityType, WebApp, WebAppFunction } from '@pulumi/azure-native/web/index.js';
3
+ import { v5 as uuidv5 } from 'uuid';
3
4
  import { CommonAzureStack } from '../../common/index.js';
4
5
  /**
5
6
  * Provides operations on Azure Functions using Pulumi
@@ -86,27 +87,37 @@ export class AzureFunctionManager {
86
87
  throw new Error(`Props undefined for ${id}`);
87
88
  // Get resource group name
88
89
  const resourceGroupName = props.resourceGroupName ?? scope.resourceNameFormatter.format(scope.props.resourceGroupName);
90
+ const name = scope.resourceNameFormatter.format(props.name, scope.props.resourceNameOptions?.functionApp);
91
+ const location = props.location ?? scope.props.location;
92
+ const runtime = {
93
+ ...props.runtime,
94
+ name: props.runtime?.name ?? 'node',
95
+ version: props.runtime?.version ?? CommonAzureStack.NODEJS_RUNTIME,
96
+ };
97
+ const scaleAndConcurrency = {
98
+ ...props.scaleAndConcurrency,
99
+ instanceMemoryMB: props.scaleAndConcurrency?.instanceMemoryMB ?? 4096,
100
+ maximumInstanceCount: props.scaleAndConcurrency?.maximumInstanceCount ?? 40,
101
+ };
89
102
  const functionApp = new WebApp(`${id}-fc`, {
90
103
  ...props,
91
- name: scope.resourceNameFormatter.format(props.name, scope.props.resourceNameOptions?.functionApp),
92
- location: props.location ?? scope.props.location,
104
+ name,
105
+ location,
93
106
  resourceGroupName,
94
107
  kind: props.kind ?? 'functionapp,linux',
108
+ reserved: props.reserved ?? true,
95
109
  httpsOnly: props.httpsOnly ?? true,
96
110
  identity: props.identity ?? {
97
111
  type: ManagedServiceIdentityType.SystemAssigned,
98
112
  },
99
- functionAppConfig: props.functionAppConfig ?? {
100
- runtime: {
101
- ...props.runtime,
102
- name: props.runtime?.name ?? 'node',
103
- version: props.runtime?.version ?? CommonAzureStack.NODEJS_RUNTIME,
104
- },
105
- scaleAndConcurrency: {
106
- ...props.scaleAndConcurrency,
107
- instanceMemoryMB: props.scaleAndConcurrency?.instanceMemoryMB ?? 4096,
108
- maximumInstanceCount: props.scaleAndConcurrency?.maximumInstanceCount ?? 40,
109
- },
113
+ clientAffinityEnabled: props.clientAffinityEnabled ?? false,
114
+ clientAffinityProxyEnabled: props.clientAffinityProxyEnabled ?? false,
115
+ clientCertMode: props.clientCertMode ?? ClientCertMode.Optional,
116
+ clientCertEnabled: props.clientCertEnabled ?? false,
117
+ functionAppConfig: {
118
+ ...props.functionAppConfig,
119
+ runtime,
120
+ scaleAndConcurrency,
110
121
  },
111
122
  siteConfig: props.siteConfig ?? {
112
123
  http20Enabled: true,
@@ -118,8 +129,10 @@ export class AzureFunctionManager {
118
129
  ...props.tags,
119
130
  },
120
131
  }, { parent: scope, ...resourceOptions });
121
- const functionAppConfig = props.functionAppConfig;
122
- new Deployment(`${id}-deployment`, {
132
+ // perform a deployment for the rolling update strategy
133
+ const deploymentId = uuidv5(`${id}-depl`, uuidv5.DNS);
134
+ new Deployment(deploymentId, {
135
+ deploymentName: deploymentId,
123
136
  resourceGroupName,
124
137
  properties: {
125
138
  mode: DeploymentMode.Incremental,
@@ -130,27 +143,13 @@ export class AzureFunctionManager {
130
143
  {
131
144
  type: 'Microsoft.Web/sites',
132
145
  apiVersion: '2024-04-01',
133
- name: scope.resourceNameFormatter.format(props.name, scope.props.resourceNameOptions?.functionApp),
134
- location: props.location ?? scope.props.location,
146
+ name,
147
+ location,
135
148
  properties: {
136
149
  functionAppConfig: {
137
150
  ...props.functionAppConfig,
138
- runtime: {
139
- ...props.runtime,
140
- name: props.runtime?.name ?? functionAppConfig?.runtime?.name ?? 'node',
141
- version: props.runtime?.version ??
142
- functionAppConfig?.runtime?.version ??
143
- CommonAzureStack.NODEJS_RUNTIME,
144
- },
145
- scaleAndConcurrency: {
146
- ...props.scaleAndConcurrency,
147
- instanceMemoryMB: props.scaleAndConcurrency?.instanceMemoryMB ??
148
- functionAppConfig?.scaleAndConcurrency?.instanceMemoryMB ??
149
- 4096,
150
- maximumInstanceCount: props.scaleAndConcurrency?.maximumInstanceCount ??
151
- functionAppConfig?.scaleAndConcurrency?.maximumInstanceCount ??
152
- 40,
153
- },
151
+ runtime,
152
+ scaleAndConcurrency,
154
153
  siteUpdateStrategy: {
155
154
  type: 'RollingUpdate',
156
155
  },
@@ -160,7 +159,7 @@ export class AzureFunctionManager {
160
159
  ],
161
160
  },
162
161
  },
163
- }, { parent: scope, ...resourceOptions });
162
+ }, { parent: functionApp, ...resourceOptions });
164
163
  return functionApp;
165
164
  }
166
165
  /**
@@ -38,6 +38,7 @@ export class AzureStorageManager {
38
38
  .replace(/\W/g, '')
39
39
  .toLowerCase(),
40
40
  allowBlobPublicAccess: props.allowBlobPublicAccess ?? false,
41
+ isHnsEnabled: props.isHnsEnabled ?? false,
41
42
  resourceGroupName,
42
43
  sku: props.sku ?? {
43
44
  name: SkuName.Standard_LRS,
@@ -61,7 +62,7 @@ export class AzureStorageManager {
61
62
  enabled: true,
62
63
  days: 7,
63
64
  },
64
- });
65
+ }, { parent: scope, ...resourceOptions });
65
66
  return storageAccount;
66
67
  }
67
68
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradientedge/cdk-utils-azure",
3
- "version": "2.20.0",
3
+ "version": "2.22.0",
4
4
  "description": "Azure Pulumi utilities for @gradientedge/cdk-utils",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",