@gradientedge/cdk-utils-azure 2.19.0 → 2.21.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.
- package/dist/src/common/tagging.js +3 -0
- package/dist/src/construct/function-app/main.js +12 -9
- package/dist/src/construct/rest-api/main.js +32 -18
- package/dist/src/construct/rest-api-function/main.js +32 -28
- package/dist/src/construct/rest-api-with-cache/main.js +8 -8
- package/dist/src/construct/site-with-webapp/main.js +3 -0
- package/dist/src/services/api-management/main.d.ts +1 -1
- package/dist/src/services/api-management/main.js +4 -4
- package/dist/src/services/app-service/main.js +1 -0
- package/dist/src/services/application-insights/main.js +10 -6
- package/dist/src/services/authorisation/main.d.ts +7 -5
- package/dist/src/services/authorisation/main.js +16 -6
- package/dist/src/services/cosmosdb/main.js +10 -5
- package/dist/src/services/eventgrid/main.js +3 -1
- package/dist/src/services/function/main.js +12 -10
- package/dist/src/services/monitor/main.js +1 -1
- package/dist/src/services/operational-insights/main.js +7 -2
- package/dist/src/services/portal/main.js +11 -4
- package/dist/src/services/portal/renderer.js +5 -7
- package/dist/src/services/redis/main.js +8 -1
- package/dist/src/services/storage/main.js +2 -1
- package/package.json +3 -2
|
@@ -14,6 +14,9 @@ export function isTaggableResource(resourceType) {
|
|
|
14
14
|
return false;
|
|
15
15
|
if (resourceType.startsWith('pulumi:'))
|
|
16
16
|
return false;
|
|
17
|
+
if (resourceType.startsWith('azure-native:apimanagement:') &&
|
|
18
|
+
resourceType !== 'azure-native:apimanagement:ApiManagementService')
|
|
19
|
+
return false;
|
|
17
20
|
// Extract the resource name from the type (e.g., 'ResourceGroup' from 'azure-native:resources:ResourceGroup')
|
|
18
21
|
const resourceName = resourceType.split(':').pop() || '';
|
|
19
22
|
// Check if this resource is in the exclusion list
|
|
@@ -3,6 +3,7 @@ import * as path from 'path';
|
|
|
3
3
|
import * as archive from '@pulumi/archive';
|
|
4
4
|
import { getConfigurationStoreOutput, } from '@pulumi/azure-native/appconfiguration/index.js';
|
|
5
5
|
import { getComponentOutput } from '@pulumi/azure-native/applicationinsights/index.js';
|
|
6
|
+
import { PrincipalType } from '@pulumi/azure-native/authorization/index.js';
|
|
6
7
|
import { SkuFamily, SkuName } from '@pulumi/azure-native/keyvault/index.js';
|
|
7
8
|
import { listStorageAccountKeysOutput } from '@pulumi/azure-native/storage/index.js';
|
|
8
9
|
import { AuthenticationType, FunctionsDeploymentStorageType, } from '@pulumi/azure-native/web/index.js';
|
|
@@ -93,6 +94,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
93
94
|
this.appServicePlan = this.appServiceManager.createAppServicePlan(`${this.id}-app-service-plan`, this, {
|
|
94
95
|
...this.props.functionApp.servicePlan,
|
|
95
96
|
name: this.id,
|
|
97
|
+
kind: this.props.functionApp.servicePlan?.kind ?? 'functionapp',
|
|
96
98
|
resourceGroupName: this.resourceGroup.name,
|
|
97
99
|
location: this.resourceGroup.location,
|
|
98
100
|
});
|
|
@@ -240,7 +242,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
240
242
|
* @summary Method to create and configure the function host.json
|
|
241
243
|
*/
|
|
242
244
|
createFunctionHosts() {
|
|
243
|
-
const currentDirectory = path.resolve();
|
|
245
|
+
const currentDirectory = path.resolve(process.cwd(), '..');
|
|
244
246
|
const hostsJsonFile = `${currentDirectory}/${this.props.functionApp.deploySource}/host.json`;
|
|
245
247
|
if (!fs.existsSync(hostsJsonFile))
|
|
246
248
|
return;
|
|
@@ -252,7 +254,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
252
254
|
* @summary Method to create the code package archive for deployment
|
|
253
255
|
*/
|
|
254
256
|
createCodePackage() {
|
|
255
|
-
const currentDirectory = path.resolve();
|
|
257
|
+
const currentDirectory = path.resolve(process.cwd(), '..');
|
|
256
258
|
this.appCodeArchiveFile = archive.getFileOutput({
|
|
257
259
|
type: 'zip',
|
|
258
260
|
sourceDir: `${currentDirectory}/${this.props.functionApp.deploySource}`,
|
|
@@ -272,6 +274,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
272
274
|
this.app = this.functionManager.createFunctionAppFlexConsumption(`${this.id}-function-app-flex`, this, {
|
|
273
275
|
...this.props.functionApp,
|
|
274
276
|
name: this.props.functionApp.app?.name ?? this.id,
|
|
277
|
+
scaleAndConcurrency: this.props.functionApp.app?.scaleAndConcurrency,
|
|
275
278
|
serverFarmId: this.appServicePlan.id,
|
|
276
279
|
resourceGroupName: this.resourceGroup.name,
|
|
277
280
|
functionAppConfig: {
|
|
@@ -281,7 +284,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
281
284
|
value: pulumi.interpolate `${this.appStorageAccount.primaryEndpoints.apply(e => e?.blob)}${this.appDeploymentStorageContainer.name}`,
|
|
282
285
|
authentication: {
|
|
283
286
|
type: AuthenticationType.StorageAccountConnectionString,
|
|
284
|
-
storageAccountConnectionStringName: '
|
|
287
|
+
storageAccountConnectionStringName: 'DEPLOYMENT_STORAGE_CONNECTION_STRING',
|
|
285
288
|
},
|
|
286
289
|
},
|
|
287
290
|
},
|
|
@@ -298,7 +301,7 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
298
301
|
value: this.applicationInsights.instrumentationKey,
|
|
299
302
|
},
|
|
300
303
|
{
|
|
301
|
-
name: '
|
|
304
|
+
name: 'DEPLOYMENT_STORAGE_CONNECTION_STRING',
|
|
302
305
|
value: pulumi.interpolate `DefaultEndpointsProtocol=https;AccountName=${this.appStorageAccount.name};AccountKey=${listStorageAccountKeysOutput({
|
|
303
306
|
resourceGroupName: this.resourceGroup.name,
|
|
304
307
|
accountName: this.appStorageAccount.name,
|
|
@@ -321,11 +324,11 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
321
324
|
*/
|
|
322
325
|
createRoleAssignments() {
|
|
323
326
|
if (this.props.dataStorageAccount) {
|
|
324
|
-
this.authorisationManager.grantRoleAssignmentToStorageAccount(`${this.id}-data`, this, this.dataStorageAccount.id, this.getFunctionAppPrincipalId(), 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));
|
|
325
328
|
}
|
|
326
|
-
this.authorisationManager.grantRoleAssignmentToStorageAccount(this.id, this, this.appStorageAccount.id, this.getFunctionAppPrincipalId(), 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));
|
|
327
330
|
if (!this.props.useConfigOverride) {
|
|
328
|
-
this.authorisationManager.grantRoleAssignmentToApplicationConfiguration(this.id, this, this.appConfig.id, this.getFunctionAppPrincipalId(), RoleDefinitionId.APP_CONFIGURATION_DATA_READER);
|
|
331
|
+
this.authorisationManager.grantRoleAssignmentToApplicationConfiguration(this.id, this, this.appConfig.id, this.getFunctionAppPrincipalId(), PrincipalType.ServicePrincipal, this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.APP_CONFIGURATION_DATA_READER));
|
|
329
332
|
}
|
|
330
333
|
if (this.appConfigurationsParsedConfig &&
|
|
331
334
|
AzureAppConfigurationManager.hasCosmosDependencies(this.appConfigurationsParsedConfig)) {
|
|
@@ -334,12 +337,12 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
334
337
|
if (this.appKeyVaultsByResourceGroup && this.appKeyVaultsByResourceGroup.size > 0) {
|
|
335
338
|
this.appKeyVaultsByResourceGroup.forEach((keyVaultNames, resourceGroup) => {
|
|
336
339
|
keyVaultNames.forEach(keyVaultName => {
|
|
337
|
-
this.authorisationManager.grantRoleAssignmentToKeyVault(this.id, this, keyVaultName, resourceGroup, this.getFunctionAppPrincipalId(), 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));
|
|
338
341
|
});
|
|
339
342
|
});
|
|
340
343
|
}
|
|
341
344
|
if (AzureAppConfigurationManager.hasEventGridTargets(this.appConfigurationsParsedConfig)) {
|
|
342
|
-
this.authorisationManager.grantRoleAssignmentToEventgridTopic(this.id, this, this.props.existingTopicName, this.props.existingTopicResourceGroupName, this.getFunctionAppPrincipalId(), 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));
|
|
343
346
|
}
|
|
344
347
|
}
|
|
345
348
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { HostnameType, LoggerType } from '@pulumi/azure-native/apimanagement/index.js';
|
|
1
|
+
import { getApiManagementServiceOutput, HostnameType, LoggerType } from '@pulumi/azure-native/apimanagement/index.js';
|
|
2
2
|
import { getComponentOutput } from '@pulumi/azure-native/applicationinsights/index.js';
|
|
3
|
+
import { PrincipalType } from '@pulumi/azure-native/authorization/index.js';
|
|
3
4
|
import { getVaultOutput } from '@pulumi/azure-native/keyvault/index.js';
|
|
4
5
|
import * as pulumi from '@pulumi/pulumi';
|
|
5
6
|
import { CommonAzureConstruct } from '../../common/index.js';
|
|
@@ -83,7 +84,7 @@ export class AzureRestApi extends CommonAzureConstruct {
|
|
|
83
84
|
{
|
|
84
85
|
hostName: `api-${this.props.locationConfig?.[this.props.location].name}.${this.props.domainName}`,
|
|
85
86
|
keyVaultId: this.props.apiManagement.certificateKeyVaultId,
|
|
86
|
-
type: HostnameType.
|
|
87
|
+
type: HostnameType.Proxy,
|
|
87
88
|
},
|
|
88
89
|
];
|
|
89
90
|
}
|
|
@@ -97,10 +98,15 @@ export class AzureRestApi extends CommonAzureConstruct {
|
|
|
97
98
|
this.api.id = this.api.apim.id;
|
|
98
99
|
this.api.name = this.api.apim.name;
|
|
99
100
|
this.api.resourceGroupName = this.resourceGroup.name;
|
|
100
|
-
|
|
101
|
+
const apimIdentity = getApiManagementServiceOutput({
|
|
102
|
+
serviceName: this.api.apim.name,
|
|
103
|
+
resourceGroupName: this.resourceGroup.name,
|
|
104
|
+
}).identity;
|
|
105
|
+
if (this.props.apiManagement.certificateKeyVaultId && apimIdentity) {
|
|
101
106
|
this.authorisationManager.createRoleAssignment(`${this.id}-kv-role`, this, {
|
|
102
|
-
principalId:
|
|
103
|
-
roleDefinitionId: RoleDefinitionId.KEY_VAULT_CERTIFICATE_USER,
|
|
107
|
+
principalId: apimIdentity.apply(id => id?.principalId ?? ''),
|
|
108
|
+
roleDefinitionId: this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.KEY_VAULT_CERTIFICATE_USER),
|
|
109
|
+
principalType: PrincipalType.ServicePrincipal,
|
|
104
110
|
scope: this.props.apiManagement.certificateKeyVaultId,
|
|
105
111
|
});
|
|
106
112
|
}
|
|
@@ -117,11 +123,18 @@ export class AzureRestApi extends CommonAzureConstruct {
|
|
|
117
123
|
createNamespaceSecretRole() {
|
|
118
124
|
if (this.props.apiManagement.useExistingApiManagement)
|
|
119
125
|
return;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
const apimIdentity = getApiManagementServiceOutput({
|
|
127
|
+
serviceName: this.api.apim.name,
|
|
128
|
+
resourceGroupName: this.resourceGroup.name,
|
|
129
|
+
}).identity;
|
|
130
|
+
if (apimIdentity) {
|
|
131
|
+
this.api.namedValueRoleAssignment = this.authorisationManager.createRoleAssignment(`${this.id}-key-vault-role-api-namespace`, this, {
|
|
132
|
+
principalId: apimIdentity.apply(id => id?.principalId ?? ''),
|
|
133
|
+
principalType: PrincipalType.ServicePrincipal,
|
|
134
|
+
roleDefinitionId: this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.KEY_VAULT_SECRETS_USER),
|
|
135
|
+
scope: this.api.authKeyVault.id,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
125
138
|
}
|
|
126
139
|
/**
|
|
127
140
|
* @summary Method to create the namespace secret in Key Vault for Application Insights
|
|
@@ -131,8 +144,8 @@ export class AzureRestApi extends CommonAzureConstruct {
|
|
|
131
144
|
return;
|
|
132
145
|
this.api.namedValueSecret = this.keyVaultManager.createKeyVaultSecret(`${this.id}-key-vault-api-namespace-secret`, this, {
|
|
133
146
|
vaultName: this.api.authKeyVault.name,
|
|
134
|
-
secretName: `${this.applicationInsights.name}-${this.id}-key`,
|
|
135
|
-
resourceGroupName: this.
|
|
147
|
+
secretName: pulumi.interpolate `${this.applicationInsights.name}-${this.id}-key`,
|
|
148
|
+
resourceGroupName: this.props.apiAuthKeyVault.resourceGroupName,
|
|
136
149
|
properties: {
|
|
137
150
|
value: this.applicationInsights.instrumentationKey,
|
|
138
151
|
},
|
|
@@ -150,12 +163,12 @@ export class AzureRestApi extends CommonAzureConstruct {
|
|
|
150
163
|
displayName: 'all-apis',
|
|
151
164
|
state: 'active',
|
|
152
165
|
allowTracing: false,
|
|
153
|
-
scope: '',
|
|
166
|
+
scope: '/apis',
|
|
154
167
|
});
|
|
155
168
|
this.keyVaultManager.createKeyVaultSecret(`${this.id}-key-vault-api-subscription-key-secret`, this, {
|
|
156
169
|
vaultName: this.api.authKeyVault.name,
|
|
157
170
|
secretName: `${this.id}-subscription-key`,
|
|
158
|
-
resourceGroupName: this.
|
|
171
|
+
resourceGroupName: this.props.apiAuthKeyVault.resourceGroupName,
|
|
159
172
|
properties: {
|
|
160
173
|
value: apiManagementSubscription.primaryKey.apply(key => key ?? ''),
|
|
161
174
|
},
|
|
@@ -171,21 +184,22 @@ export class AzureRestApi extends CommonAzureConstruct {
|
|
|
171
184
|
displayName: this.applicationInsights.name,
|
|
172
185
|
resourceGroupName: this.resourceGroup.name,
|
|
173
186
|
serviceName: this.api.apim.name,
|
|
174
|
-
namedValueId: `${this.applicationInsights.name}-key`,
|
|
187
|
+
namedValueId: pulumi.interpolate `${this.applicationInsights.name}-key`,
|
|
175
188
|
secret: true,
|
|
176
189
|
keyVault: {
|
|
177
|
-
secretIdentifier: this.api.namedValueSecret.
|
|
190
|
+
secretIdentifier: this.api.namedValueSecret.properties.apply(p => p.secretUri),
|
|
178
191
|
},
|
|
179
192
|
});
|
|
180
193
|
this.api.logger = this.apiManagementManager.createLogger(`${this.id}-am-logger`, this, {
|
|
194
|
+
loggerId: this.applicationInsights.name,
|
|
181
195
|
resourceGroupName: this.resourceGroup.name,
|
|
182
196
|
serviceName: this.api.apim.name,
|
|
183
197
|
resourceId: this.applicationInsights.id,
|
|
184
198
|
loggerType: LoggerType.ApplicationInsights,
|
|
185
199
|
credentials: {
|
|
186
|
-
instrumentationKey: `{{${apiAppNamedValue.displayName}}}`,
|
|
200
|
+
instrumentationKey: pulumi.interpolate `{{${apiAppNamedValue.displayName}}}`,
|
|
187
201
|
},
|
|
188
|
-
});
|
|
202
|
+
}, { dependsOn: [apiAppNamedValue] });
|
|
189
203
|
}
|
|
190
204
|
/**
|
|
191
205
|
* @summary Method to create the API diagnostic settings for API Management
|
|
@@ -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.
|
|
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
|
-
|
|
98
|
-
this.api.
|
|
99
|
-
this.api.
|
|
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 {
|
|
@@ -123,7 +124,7 @@ export class AzureRestApiFunction extends AzureFunctionApp {
|
|
|
123
124
|
if (this.props.apiManagement.certificateKeyVaultId) {
|
|
124
125
|
this.authorisationManager.createRoleAssignment(`${this.id}-kv-role`, this, {
|
|
125
126
|
principalId: this.api.apim.identity.apply(identity => identity?.principalId ?? ''),
|
|
126
|
-
roleDefinitionId: RoleDefinitionId.KEY_VAULT_CERTIFICATE_USER,
|
|
127
|
+
roleDefinitionId: this.authorisationManager.resolveRoleDefinitionId(this, RoleDefinitionId.KEY_VAULT_CERTIFICATE_USER),
|
|
127
128
|
scope: this.props.apiManagement.certificateKeyVaultId,
|
|
128
129
|
});
|
|
129
130
|
}
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
-
<
|
|
205
|
-
<
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
<
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
<
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
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.
|
|
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
|
}
|
|
@@ -64,8 +64,8 @@ export class AzureRestApiWithCache extends AzureRestApi {
|
|
|
64
64
|
}).apply(keys => `${hostName}:10000,password=${keys.primaryKey},ssl=True,abortConnect=False`));
|
|
65
65
|
this.api.redisNamedValueSecret = this.keyVaultManager.createKeyVaultSecret(`${this.id}-key-vault-redis-namespace-secret`, this, {
|
|
66
66
|
vaultName: this.api.authKeyVault.name,
|
|
67
|
-
secretName: `${this.api.redisCluster.name}key`,
|
|
68
|
-
resourceGroupName: this.
|
|
67
|
+
secretName: pulumi.interpolate `${this.api.redisCluster.name}key`,
|
|
68
|
+
resourceGroupName: this.props.apiAuthKeyVault.resourceGroupName,
|
|
69
69
|
properties: {
|
|
70
70
|
value: connectionString,
|
|
71
71
|
},
|
|
@@ -76,13 +76,13 @@ export class AzureRestApiWithCache extends AzureRestApi {
|
|
|
76
76
|
*/
|
|
77
77
|
createRedisCacheNamespace() {
|
|
78
78
|
this.api.redisNamedValue = this.apiManagementManager.createNamedValue(`${this.id}-redis-nv`, this, {
|
|
79
|
-
displayName: `${this.api.redisCluster.name}key`,
|
|
79
|
+
displayName: pulumi.interpolate `${this.api.redisCluster.name}key`,
|
|
80
80
|
resourceGroupName: this.resourceGroup.name,
|
|
81
81
|
serviceName: this.api.apim.name,
|
|
82
|
-
namedValueId: `${this.api.redisCluster.name}key`,
|
|
82
|
+
namedValueId: pulumi.interpolate `${this.api.redisCluster.name}key`,
|
|
83
83
|
secret: true,
|
|
84
84
|
keyVault: {
|
|
85
|
-
secretIdentifier: this.api.redisNamedValueSecret.
|
|
85
|
+
secretIdentifier: this.api.redisNamedValueSecret.properties.apply(p => p.secretUri),
|
|
86
86
|
},
|
|
87
87
|
});
|
|
88
88
|
}
|
|
@@ -92,11 +92,11 @@ export class AzureRestApiWithCache extends AzureRestApi {
|
|
|
92
92
|
createRedisCacheApiManagement() {
|
|
93
93
|
this.apiManagementManager.createCache(`${this.id}-am-redis-cache`, this, {
|
|
94
94
|
serviceName: this.api.apim.name,
|
|
95
|
-
connectionString: `{{${this.api.redisNamedValue.name}}}`,
|
|
96
|
-
cacheId: this.api.redisCluster.
|
|
95
|
+
connectionString: pulumi.interpolate `{{${this.api.redisNamedValue.name}}}`,
|
|
96
|
+
cacheId: this.api.redisCluster.name,
|
|
97
97
|
resourceGroupName: this.resourceGroup.name,
|
|
98
98
|
useFromLocation: this.api.redisCluster.location,
|
|
99
|
-
description: `Redis cache for ${this.api.apim.name}`,
|
|
99
|
+
description: pulumi.interpolate `Redis cache for ${this.api.apim.name}`,
|
|
100
100
|
});
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -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,
|
|
@@ -71,7 +71,7 @@ export declare class AzureApiManagementManager {
|
|
|
71
71
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
72
72
|
* @see [Pulumi Azure Native API Management Diagnostic]{@link https://www.pulumi.com/registry/packages/azure-native/api-docs/apimanagement/apidiagnostic/}
|
|
73
73
|
*/
|
|
74
|
-
createApiDiagnostic(id: string, scope: CommonAzureConstruct, props: ApiDiagnosticProps, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/apimanagement/
|
|
74
|
+
createApiDiagnostic(id: string, scope: CommonAzureConstruct, props: ApiDiagnosticProps, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/apimanagement/diagnostic.js").Diagnostic;
|
|
75
75
|
/**
|
|
76
76
|
* @summary Method to create a new API Logger
|
|
77
77
|
* @param id scoped id of the resource
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Api,
|
|
1
|
+
import { Api, ApiManagementService, ApiOperation, ApiOperationPolicy, ApiPolicy, Backend, BackendProtocol, Cache, Diagnostic, getApiManagementServiceOutput, Logger, LoggerType, NamedValue, Protocol, Subscription, } from '@pulumi/azure-native/apimanagement/index.js';
|
|
2
2
|
import { listDatabaseKeysOutput } from '@pulumi/azure-native/redisenterprise/index.js';
|
|
3
3
|
import * as pulumi from '@pulumi/pulumi';
|
|
4
4
|
/**
|
|
@@ -148,7 +148,7 @@ export class AzureApiManagementManager {
|
|
|
148
148
|
createApiDiagnostic(id, scope, props, resourceOptions) {
|
|
149
149
|
if (!props)
|
|
150
150
|
throw new Error(`Props undefined for ${id}`);
|
|
151
|
-
return new
|
|
151
|
+
return new Diagnostic(`${id}`, props, { parent: scope, ...resourceOptions });
|
|
152
152
|
}
|
|
153
153
|
/**
|
|
154
154
|
* @summary Method to create a new API Logger
|
|
@@ -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',
|
|
@@ -30,14 +30,13 @@ export class AzureApplicationInsightsManager {
|
|
|
30
30
|
if (!props)
|
|
31
31
|
throw new Error(`Props undefined for ${id}`);
|
|
32
32
|
// Get resource group name
|
|
33
|
-
const resourceGroupName =
|
|
34
|
-
? `${scope.props.resourceGroupName}-${scope.props.stage}`
|
|
35
|
-
: props.resourceGroupName;
|
|
33
|
+
const resourceGroupName = props.resourceGroupName ?? scope.resourceNameFormatter.format(scope.props.resourceGroupName);
|
|
36
34
|
if (!resourceGroupName)
|
|
37
35
|
throw new Error(`Resource group name undefined for ${id}`);
|
|
38
|
-
const
|
|
36
|
+
const resourceName = scope.resourceNameFormatter.format(props.resourceName?.toString(), scope.props.resourceNameOptions?.applicationInsights);
|
|
37
|
+
const component = new Component(`${id}`, {
|
|
39
38
|
...props,
|
|
40
|
-
resourceName
|
|
39
|
+
resourceName,
|
|
41
40
|
resourceGroupName,
|
|
42
41
|
applicationType: props.applicationType ?? ApplicationType.Web,
|
|
43
42
|
kind: props.kind ?? 'web',
|
|
@@ -48,7 +47,12 @@ export class AzureApplicationInsightsManager {
|
|
|
48
47
|
},
|
|
49
48
|
}, { parent: scope, ...resourceOptions });
|
|
50
49
|
if (props.billingFeatures) {
|
|
51
|
-
this.createComponentCurrentBillingFeature(`${id}-billing`, scope,
|
|
50
|
+
this.createComponentCurrentBillingFeature(`${id}-billing`, scope, {
|
|
51
|
+
...props.billingFeatures,
|
|
52
|
+
currentBillingFeatures: props.billingFeatures?.currentBillingFeatures ?? ['Basic'],
|
|
53
|
+
resourceName,
|
|
54
|
+
resourceGroupName,
|
|
55
|
+
}, {
|
|
52
56
|
parent: scope,
|
|
53
57
|
...resourceOptions,
|
|
54
58
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PrincipalType } from '@pulumi/azure-native/authorization/index.js';
|
|
1
2
|
import { Input, ResourceOptions } from '@pulumi/pulumi';
|
|
2
3
|
import { CommonAzureConstruct } from '../../common/index.js';
|
|
3
4
|
import { RoleDefinitionId } from './constants.js';
|
|
@@ -40,7 +41,7 @@ export declare class AzureAuthorisationManager {
|
|
|
40
41
|
* @param roleDefinitionId the role definition id
|
|
41
42
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
42
43
|
*/
|
|
43
|
-
grantRoleAssignmentToKeyVault(id: string, scope: CommonAzureConstruct, vaultName: string, resourceGroupName: Input<string>, principalId: Input<string>, roleDefinitionId:
|
|
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;
|
|
44
45
|
/**
|
|
45
46
|
* @summary Method to grant a role assignment to event grid topic
|
|
46
47
|
* @param id scoped id of the resource
|
|
@@ -51,7 +52,7 @@ export declare class AzureAuthorisationManager {
|
|
|
51
52
|
* @param roleDefinitionId the role definition id
|
|
52
53
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
53
54
|
*/
|
|
54
|
-
grantRoleAssignmentToEventgridTopic(id: string, scope: CommonAzureConstruct, topicName: Input<string>, resourceGroupName: Input<string>, principalId: Input<string>, roleDefinitionId:
|
|
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;
|
|
55
56
|
/**
|
|
56
57
|
* @summary Method to grant a role assignment to application configuration
|
|
57
58
|
* @param id scoped id of the resource
|
|
@@ -61,7 +62,7 @@ export declare class AzureAuthorisationManager {
|
|
|
61
62
|
* @param roleDefinitionId the role definition id
|
|
62
63
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
63
64
|
*/
|
|
64
|
-
grantRoleAssignmentToApplicationConfiguration(id: string, scope: CommonAzureConstruct, appConfigId: Input<string>, principalId: Input<string>, roleDefinitionId:
|
|
65
|
+
grantRoleAssignmentToApplicationConfiguration(id: string, scope: CommonAzureConstruct, appConfigId: Input<string>, principalId: Input<string>, principalType: Input<PrincipalType>, roleDefinitionId: string, resourceOptions?: ResourceOptions): import("@pulumi/azure-native/authorization/roleAssignment.js").RoleAssignment;
|
|
65
66
|
/**
|
|
66
67
|
* @summary Method to grant a role assignment to storage account
|
|
67
68
|
* @param id scoped id of the resource
|
|
@@ -71,7 +72,7 @@ export declare class AzureAuthorisationManager {
|
|
|
71
72
|
* @param roleDefinitionId the role definition id
|
|
72
73
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
73
74
|
*/
|
|
74
|
-
grantRoleAssignmentToStorageAccount(id: string, scope: CommonAzureConstruct, accountId: Input<string>, principalId: Input<string>, roleDefinitionId:
|
|
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;
|
|
75
76
|
/**
|
|
76
77
|
* @summary Method to grant a role assignment to storage table
|
|
77
78
|
* @param id scoped id of the resource
|
|
@@ -81,5 +82,6 @@ export declare class AzureAuthorisationManager {
|
|
|
81
82
|
* @param roleDefinitionId the role definition id
|
|
82
83
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
83
84
|
*/
|
|
84
|
-
grantRoleAssignmentToStorageTable(id: string, scope: CommonAzureConstruct, tableId: Input<string>, principalId: Input<string>, roleDefinitionId:
|
|
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
|
+
resolveRoleDefinitionId(scope: CommonAzureConstruct, roleDefinitionId: RoleDefinitionId): string;
|
|
85
87
|
}
|
|
@@ -29,7 +29,7 @@ export class AzureAuthorisationManager {
|
|
|
29
29
|
createRoleAssignment(id, scope, props, resourceOptions) {
|
|
30
30
|
if (!props)
|
|
31
31
|
throw new Error(`Props undefined for ${id}`);
|
|
32
|
-
return new RoleAssignment(`${id}`, props, { parent: scope, ...resourceOptions });
|
|
32
|
+
return new RoleAssignment(`${id}`, props, { parent: scope, ignoreChanges: ['scope'], ...resourceOptions });
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* @summary Method to grant a role assignment to key vault
|
|
@@ -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);
|
|
@@ -79,9 +81,10 @@ export class AzureAuthorisationManager {
|
|
|
79
81
|
* @param roleDefinitionId the role definition id
|
|
80
82
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
81
83
|
*/
|
|
82
|
-
grantRoleAssignmentToApplicationConfiguration(id, scope, appConfigId, principalId, roleDefinitionId, resourceOptions) {
|
|
84
|
+
grantRoleAssignmentToApplicationConfiguration(id, scope, appConfigId, principalId, principalType, roleDefinitionId, resourceOptions) {
|
|
83
85
|
return this.createRoleAssignment(`${id}-ac-role`, scope, {
|
|
84
86
|
principalId,
|
|
87
|
+
principalType,
|
|
85
88
|
roleDefinitionId,
|
|
86
89
|
scope: appConfigId,
|
|
87
90
|
}, resourceOptions);
|
|
@@ -95,9 +98,10 @@ export class AzureAuthorisationManager {
|
|
|
95
98
|
* @param roleDefinitionId the role definition id
|
|
96
99
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
97
100
|
*/
|
|
98
|
-
grantRoleAssignmentToStorageAccount(id, scope, accountId, principalId, roleDefinitionId, resourceOptions) {
|
|
101
|
+
grantRoleAssignmentToStorageAccount(id, scope, accountId, principalId, principalType, roleDefinitionId, resourceOptions) {
|
|
99
102
|
return this.createRoleAssignment(`${id}-sa-role`, scope, {
|
|
100
103
|
principalId,
|
|
104
|
+
principalType,
|
|
101
105
|
roleDefinitionId,
|
|
102
106
|
scope: accountId,
|
|
103
107
|
}, resourceOptions);
|
|
@@ -111,11 +115,17 @@ export class AzureAuthorisationManager {
|
|
|
111
115
|
* @param roleDefinitionId the role definition id
|
|
112
116
|
* @param resourceOptions Optional settings to control resource behaviour
|
|
113
117
|
*/
|
|
114
|
-
grantRoleAssignmentToStorageTable(id, scope, tableId, principalId, roleDefinitionId, resourceOptions) {
|
|
118
|
+
grantRoleAssignmentToStorageTable(id, scope, tableId, principalId, principalType, roleDefinitionId, resourceOptions) {
|
|
115
119
|
return this.createRoleAssignment(`${id}-st-role`, scope, {
|
|
116
120
|
principalId,
|
|
121
|
+
principalType,
|
|
117
122
|
roleDefinitionId,
|
|
118
123
|
scope: tableId,
|
|
119
124
|
}, resourceOptions);
|
|
120
125
|
}
|
|
126
|
+
resolveRoleDefinitionId(scope, roleDefinitionId) {
|
|
127
|
+
if (!scope.props.subscriptionId)
|
|
128
|
+
throw Error('Subscription id undefined');
|
|
129
|
+
return `/subscriptions/${scope.props.subscriptionId}${roleDefinitionId}`;
|
|
130
|
+
}
|
|
121
131
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DatabaseAccount, getDatabaseAccountOutput, getSqlResourceSqlRoleDefinitionOutput, ResourceIdentityType, SqlResourceSqlContainer, SqlResourceSqlDatabase, SqlResourceSqlRoleAssignment, } from '@pulumi/azure-native/cosmosdb/index.js';
|
|
2
|
+
import { v5 as uuidv5 } from 'uuid';
|
|
2
3
|
import { CosmosRoleDefinition, CosmosRoleDefinitionId } from './constants.js';
|
|
3
4
|
/**
|
|
4
5
|
* Provides operations on Azure CosmosDB using Pulumi
|
|
@@ -78,14 +79,14 @@ export class AzureCosmosDbManager {
|
|
|
78
79
|
if (!props)
|
|
79
80
|
throw new Error(`Props undefined for ${id}`);
|
|
80
81
|
// Get resource group name
|
|
81
|
-
const resourceGroupName =
|
|
82
|
-
? `${scope.props.resourceGroupName}-${scope.props.stage}`
|
|
83
|
-
: props.resourceGroupName;
|
|
82
|
+
const resourceGroupName = props.resourceGroupName ?? scope.resourceNameFormatter.format(scope.props.resourceGroupName);
|
|
84
83
|
if (!resourceGroupName)
|
|
85
84
|
throw new Error(`Resource group name undefined for ${id}`);
|
|
86
85
|
return new SqlResourceSqlContainer(`${id}-cc`, {
|
|
87
86
|
...props,
|
|
88
|
-
|
|
87
|
+
...(props.containerName && {
|
|
88
|
+
containerName: scope.resourceNameFormatter.format(props.containerName.toString(), scope.props.resourceNameOptions?.cosmosDbSqlContainer),
|
|
89
|
+
}),
|
|
89
90
|
resourceGroupName,
|
|
90
91
|
}, { parent: scope, ...resourceOptions });
|
|
91
92
|
}
|
|
@@ -98,7 +99,11 @@ export class AzureCosmosDbManager {
|
|
|
98
99
|
* @see [Pulumi Azure Native CosmosDB SQL Role Assignment]{@link https://www.pulumi.com/registry/packages/azure-native/api-docs/documentdb/sqlresourcesqlroleassignment/}
|
|
99
100
|
*/
|
|
100
101
|
createSqlResourceSqlRoleAssignment(id, scope, props, resourceOptions) {
|
|
101
|
-
|
|
102
|
+
const namespace = uuidv5(`${scope.id}-${id}`, uuidv5.URL);
|
|
103
|
+
return new SqlResourceSqlRoleAssignment(`${id}`, {
|
|
104
|
+
...props,
|
|
105
|
+
roleAssignmentId: props.roleAssignmentId ?? uuidv5(id, namespace),
|
|
106
|
+
}, { parent: scope, ...resourceOptions });
|
|
102
107
|
}
|
|
103
108
|
/**
|
|
104
109
|
* @summary Method to resolve an existing cosmosdb account
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventDeliverySchema, EventSubscription, getTopicOutput, SystemTopic, SystemTopicEventSubscription, Topic, } from '@pulumi/azure-native/eventgrid/index.js';
|
|
1
|
+
import { DataResidencyBoundary, EventDeliverySchema, EventSubscription, getTopicOutput, SystemTopic, SystemTopicEventSubscription, TlsVersion, Topic, } from '@pulumi/azure-native/eventgrid/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Provides operations on Azure Event Grid using Pulumi
|
|
4
4
|
* - A new instance of this class is injected into {@link CommonAzureConstruct} constructor.
|
|
@@ -36,6 +36,8 @@ export class AzureEventgridManager {
|
|
|
36
36
|
topicName: scope.resourceNameFormatter.format(props.topicName?.toString(), scope.props.resourceNameOptions?.eventGridTopic),
|
|
37
37
|
location: props.location ?? scope.props.location,
|
|
38
38
|
resourceGroupName,
|
|
39
|
+
dataResidencyBoundary: props.dataResidencyBoundary ?? DataResidencyBoundary.WithinGeopair,
|
|
40
|
+
minimumTlsVersionAllowed: props.minimumTlsVersionAllowed ?? TlsVersion.TlsVersion_1_2,
|
|
39
41
|
tags: {
|
|
40
42
|
environment: scope.props.stage,
|
|
41
43
|
...scope.props.defaultTags,
|
|
@@ -1,5 +1,5 @@
|
|
|
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
3
|
import { CommonAzureStack } from '../../common/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Provides operations on Azure Functions using Pulumi
|
|
@@ -92,11 +92,17 @@ export class AzureFunctionManager {
|
|
|
92
92
|
location: props.location ?? scope.props.location,
|
|
93
93
|
resourceGroupName,
|
|
94
94
|
kind: props.kind ?? 'functionapp,linux',
|
|
95
|
+
reserved: props.reserved ?? true,
|
|
95
96
|
httpsOnly: props.httpsOnly ?? true,
|
|
96
97
|
identity: props.identity ?? {
|
|
97
98
|
type: ManagedServiceIdentityType.SystemAssigned,
|
|
98
99
|
},
|
|
99
|
-
|
|
100
|
+
clientAffinityEnabled: props.clientAffinityEnabled ?? false,
|
|
101
|
+
clientAffinityProxyEnabled: props.clientAffinityProxyEnabled ?? false,
|
|
102
|
+
clientCertMode: props.clientCertMode ?? ClientCertMode.Optional,
|
|
103
|
+
clientCertEnabled: props.clientCertEnabled ?? false,
|
|
104
|
+
functionAppConfig: {
|
|
105
|
+
...props.functionAppConfig,
|
|
100
106
|
runtime: {
|
|
101
107
|
...props.runtime,
|
|
102
108
|
name: props.runtime?.name ?? 'node',
|
|
@@ -119,7 +125,7 @@ export class AzureFunctionManager {
|
|
|
119
125
|
},
|
|
120
126
|
}, { parent: scope, ...resourceOptions });
|
|
121
127
|
const functionAppConfig = props.functionAppConfig;
|
|
122
|
-
new Deployment(`${id}-
|
|
128
|
+
new Deployment(`${id}-depl`, {
|
|
123
129
|
resourceGroupName,
|
|
124
130
|
properties: {
|
|
125
131
|
mode: DeploymentMode.Incremental,
|
|
@@ -144,12 +150,8 @@ export class AzureFunctionManager {
|
|
|
144
150
|
},
|
|
145
151
|
scaleAndConcurrency: {
|
|
146
152
|
...props.scaleAndConcurrency,
|
|
147
|
-
instanceMemoryMB: props.scaleAndConcurrency?.instanceMemoryMB ??
|
|
148
|
-
|
|
149
|
-
4096,
|
|
150
|
-
maximumInstanceCount: props.scaleAndConcurrency?.maximumInstanceCount ??
|
|
151
|
-
functionAppConfig?.scaleAndConcurrency?.maximumInstanceCount ??
|
|
152
|
-
40,
|
|
153
|
+
instanceMemoryMB: props.scaleAndConcurrency?.instanceMemoryMB ?? 4096,
|
|
154
|
+
maximumInstanceCount: props.scaleAndConcurrency?.maximumInstanceCount ?? 40,
|
|
153
155
|
},
|
|
154
156
|
siteUpdateStrategy: {
|
|
155
157
|
type: 'RollingUpdate',
|
|
@@ -160,7 +162,7 @@ export class AzureFunctionManager {
|
|
|
160
162
|
],
|
|
161
163
|
},
|
|
162
164
|
},
|
|
163
|
-
}, { parent:
|
|
165
|
+
}, { parent: functionApp, ...resourceOptions });
|
|
164
166
|
return functionApp;
|
|
165
167
|
}
|
|
166
168
|
/**
|
|
@@ -32,6 +32,6 @@ export class AzureMonitorManager {
|
|
|
32
32
|
return new DiagnosticSetting(`${id}-ds`, {
|
|
33
33
|
...props,
|
|
34
34
|
name: scope.resourceNameFormatter.format(props.name?.toString(), scope.props.resourceNameOptions?.monitorDiagnosticSetting),
|
|
35
|
-
}, { parent: scope, ...resourceOptions });
|
|
35
|
+
}, { parent: scope, ignoreChanges: ['resourceUri'], ...resourceOptions });
|
|
36
36
|
}
|
|
37
37
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Table, Workspace, WorkspaceSkuNameEnum } from '@pulumi/azure-native/operationalinsights/index.js';
|
|
1
|
+
import { Table, TablePlanEnum, Workspace, WorkspaceSkuNameEnum, } from '@pulumi/azure-native/operationalinsights/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Provides operations on Azure Log Analytics Workspace using Pulumi
|
|
4
4
|
* - A new instance of this class is injected into {@link CommonAzureConstruct} constructor.
|
|
@@ -58,6 +58,11 @@ export class AzureOperationalInsightsManager {
|
|
|
58
58
|
createTable(id, scope, props, resourceOptions) {
|
|
59
59
|
if (!props)
|
|
60
60
|
throw new Error(`Props undefined for ${id}`);
|
|
61
|
-
return new Table(`${id}`,
|
|
61
|
+
return new Table(`${id}`, {
|
|
62
|
+
...props,
|
|
63
|
+
plan: props.plan ?? TablePlanEnum.Analytics,
|
|
64
|
+
retentionInDays: props.retentionInDays ?? 30,
|
|
65
|
+
totalRetentionInDays: props.totalRetentionInDays ?? 30,
|
|
66
|
+
}, { parent: scope, ...resourceOptions });
|
|
62
67
|
}
|
|
63
68
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import { Dashboard } from '@pulumi/azure-native/portal/index.js';
|
|
3
|
+
import * as pulumi from '@pulumi/pulumi';
|
|
3
4
|
import { AzureDashboardRenderer } from './renderer.js';
|
|
4
5
|
/**
|
|
5
6
|
* Provides operations on Azure Portal Dashboards using Pulumi
|
|
@@ -32,21 +33,27 @@ export class AzurePortalManager {
|
|
|
32
33
|
createDashBoard(id, scope, props, renderer, resourceOptions) {
|
|
33
34
|
if (!props)
|
|
34
35
|
throw new Error(`Props undefined for ${id}`);
|
|
35
|
-
const resourceGroup = scope.
|
|
36
|
+
const resourceGroup = scope.resourceGroup ??
|
|
37
|
+
scope.resourceGroupManager.resolveResourceGroup(scope, props.resourceGroupName.toString() ?? scope.props.resourceGroupName, resourceOptions);
|
|
36
38
|
const dashboardName = scope.resourceNameFormatter.format(props.dashboardName?.toString(), scope.props.resourceNameOptions?.portalDashboard);
|
|
37
39
|
const dashboardRenderer = renderer ?? new AzureDashboardRenderer();
|
|
38
40
|
const templateFile = dashboardRenderer.renderToFile(dashboardName, props);
|
|
39
41
|
const template = fs.readFileSync(templateFile, 'utf-8');
|
|
40
|
-
const
|
|
42
|
+
const keys = Object.keys(props.variables);
|
|
43
|
+
const values = Object.values(props.variables);
|
|
44
|
+
const properties = pulumi.all(values).apply(resolved => {
|
|
45
|
+
const content = keys.reduce((result, key, i) => result.replaceAll(`\${${key}}`, JSON.stringify(String(resolved[i])).slice(1, -1)), template);
|
|
46
|
+
return JSON.parse(content);
|
|
47
|
+
});
|
|
41
48
|
return new Dashboard(`${id}-dashboard`, {
|
|
42
49
|
...props,
|
|
43
50
|
dashboardName: scope.resourceNameFormatter.format(props.dashboardName?.toString(), scope.props.resourceNameOptions?.portalDashboard),
|
|
44
51
|
resourceGroupName: resourceGroup.name,
|
|
45
52
|
location: props.location ?? resourceGroup.location,
|
|
46
|
-
properties
|
|
53
|
+
properties,
|
|
47
54
|
tags: {
|
|
48
55
|
'hidden-title': `${props.location} - ${props.displayName}`,
|
|
49
56
|
},
|
|
50
|
-
}, { ...resourceOptions, ignoreChanges: ['location'] });
|
|
57
|
+
}, { parent: scope, ...resourceOptions, ignoreChanges: ['location'] });
|
|
51
58
|
}
|
|
52
59
|
}
|
|
@@ -35,9 +35,8 @@ export class AzureDashboardRenderer {
|
|
|
35
35
|
render(params) {
|
|
36
36
|
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
|
37
37
|
// if client is used instead of hosts
|
|
38
|
-
let partsIndex = 0;
|
|
39
38
|
let yIndex = 0;
|
|
40
|
-
const parts =
|
|
39
|
+
const parts = [];
|
|
41
40
|
for (const pane of params.panes) {
|
|
42
41
|
try {
|
|
43
42
|
const paneTemplate = this.getPaneId(pane.id);
|
|
@@ -91,8 +90,7 @@ export class AzureDashboardRenderer {
|
|
|
91
90
|
const paneJSON = JSON.parse(paneContent);
|
|
92
91
|
const templateParts = paneJSON.parts;
|
|
93
92
|
for (const part of templateParts) {
|
|
94
|
-
parts
|
|
95
|
-
partsIndex++;
|
|
93
|
+
parts.push(part);
|
|
96
94
|
}
|
|
97
95
|
yIndex += paneTemplate.dimensions.height;
|
|
98
96
|
}
|
|
@@ -104,12 +102,12 @@ export class AzureDashboardRenderer {
|
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
104
|
const dashboard = {
|
|
107
|
-
lenses:
|
|
108
|
-
|
|
105
|
+
lenses: [
|
|
106
|
+
{
|
|
109
107
|
order: 0,
|
|
110
108
|
parts,
|
|
111
109
|
},
|
|
112
|
-
|
|
110
|
+
],
|
|
113
111
|
metadata: {
|
|
114
112
|
model: {
|
|
115
113
|
timeRange: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Database, RedisEnterprise, SkuName } from '@pulumi/azure-native/redisenterprise/index.js';
|
|
1
|
+
import { AccessKeysAuthentication, ClusteringPolicy, Database, DeferUpgradeSetting, EvictionPolicy, Protocol, RedisEnterprise, SkuName, } from '@pulumi/azure-native/redisenterprise/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* Provides operations on Azure Managed Redis (Enterprise) using Pulumi
|
|
4
4
|
* - A new instance of this class is injected into {@link CommonAzureConstruct} constructor.
|
|
@@ -49,6 +49,13 @@ export class AzureRedisManager {
|
|
|
49
49
|
clusterName: cluster.name,
|
|
50
50
|
resourceGroupName,
|
|
51
51
|
databaseName: databaseProps?.databaseName ?? 'default',
|
|
52
|
+
accessKeysAuthentication: databaseProps?.accessKeysAuthentication ?? AccessKeysAuthentication.Enabled,
|
|
53
|
+
clientProtocol: databaseProps?.clientProtocol ?? Protocol.Encrypted,
|
|
54
|
+
clusteringPolicy: databaseProps?.clusteringPolicy ?? ClusteringPolicy.OSSCluster,
|
|
55
|
+
evictionPolicy: databaseProps?.evictionPolicy ?? EvictionPolicy.VolatileLRU,
|
|
56
|
+
port: databaseProps?.port ?? 10000,
|
|
57
|
+
persistence: databaseProps?.persistence ?? { aofEnabled: false, rdbEnabled: false },
|
|
58
|
+
deferUpgrade: databaseProps?.deferUpgrade ?? DeferUpgradeSetting.NotDeferred,
|
|
52
59
|
}, { parent: scope, dependsOn: [cluster], ...resourceOptions });
|
|
53
60
|
return { cluster, database };
|
|
54
61
|
}
|
|
@@ -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.
|
|
3
|
+
"version": "2.21.0",
|
|
4
4
|
"description": "Azure Pulumi utilities for @gradientedge/cdk-utils",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -17,10 +17,11 @@
|
|
|
17
17
|
"@pulumi/archive": "0.3.7",
|
|
18
18
|
"@pulumi/azure-native": "3.16.0",
|
|
19
19
|
"@pulumi/azuread": "6.9.0",
|
|
20
|
-
"@pulumi/pulumi": "3.
|
|
20
|
+
"@pulumi/pulumi": "3.231.0",
|
|
21
21
|
"@types/lodash": "4.17.24",
|
|
22
22
|
"app-root-path": "3.1.0",
|
|
23
23
|
"lodash": "4.18.1",
|
|
24
|
+
"uuid": "13.0.0",
|
|
24
25
|
"yaml": "2.8.3",
|
|
25
26
|
"@gradientedge/cdk-utils-common": "2.1.0"
|
|
26
27
|
},
|