@gradientedge/cdk-utils-azure 2.21.0 → 2.23.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 +4 -0
- package/dist/src/construct/function-app/main.js +7 -0
- package/dist/src/construct/rest-api-function/main.js +27 -5
- package/dist/src/construct/rest-api-function/types.d.ts +2 -1
- package/dist/src/services/eventgrid/main.js +1 -3
- package/dist/src/services/function/main.js +26 -29
- package/package.json +1 -1
|
@@ -14,6 +14,10 @@ export function isTaggableResource(resourceType) {
|
|
|
14
14
|
return false;
|
|
15
15
|
if (resourceType.startsWith('pulumi:'))
|
|
16
16
|
return false;
|
|
17
|
+
if (resourceType.startsWith('command:'))
|
|
18
|
+
return false;
|
|
19
|
+
if (resourceType === 'azure-native:appconfiguration:KeyValue')
|
|
20
|
+
return false;
|
|
17
21
|
if (resourceType.startsWith('azure-native:apimanagement:') &&
|
|
18
22
|
resourceType !== 'azure-native:apimanagement:ApiManagementService')
|
|
19
23
|
return false;
|
|
@@ -307,6 +307,13 @@ export class AzureFunctionApp extends CommonAzureConstruct {
|
|
|
307
307
|
accountName: this.appStorageAccount.name,
|
|
308
308
|
}).keys[0].value};EndpointSuffix=core.windows.net`,
|
|
309
309
|
},
|
|
310
|
+
{
|
|
311
|
+
name: 'AzureWebJobsStorage',
|
|
312
|
+
value: pulumi.interpolate `DefaultEndpointsProtocol=https;AccountName=${this.appStorageAccount.name};AccountKey=${listStorageAccountKeysOutput({
|
|
313
|
+
resourceGroupName: this.resourceGroup.name,
|
|
314
|
+
accountName: this.appStorageAccount.name,
|
|
315
|
+
}).keys[0].value};EndpointSuffix=core.windows.net`,
|
|
316
|
+
},
|
|
310
317
|
],
|
|
311
318
|
connectionStrings: Object.fromEntries(this.appConnectionStrings.map(cs => [cs.name, { type: cs.type, value: cs.value }])),
|
|
312
319
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HostnameType, NamedValue, PolicyContentFormat } from '@pulumi/azure-native/apimanagement/index.js';
|
|
2
2
|
import { getVaultOutput } from '@pulumi/azure-native/keyvault/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { listWebAppHostKeys } from '@pulumi/azure-native/web/index.js';
|
|
4
4
|
import * as pulumi from '@pulumi/pulumi';
|
|
5
5
|
import _ from 'lodash';
|
|
6
6
|
import { RoleDefinitionId } from '../../services/index.js';
|
|
@@ -74,16 +74,38 @@ export class AzureRestApiFunction extends AzureFunctionApp {
|
|
|
74
74
|
createNamespaceSecret() {
|
|
75
75
|
if (!this.props.apiManagement.useExistingApiManagement)
|
|
76
76
|
return;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
// Fetch function host keys with retry — the runtime may not be ready immediately after code deployment
|
|
78
|
+
const functionKey = pulumi.all([this.app.name, this.resourceGroup.name]).apply(async ([appName, rgName]) => {
|
|
79
|
+
if (pulumi.runtime.isDryRun())
|
|
80
|
+
return 'previewing';
|
|
81
|
+
const maxRetries = 10;
|
|
82
|
+
const delayMs = 15000;
|
|
83
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
84
|
+
try {
|
|
85
|
+
const keys = await listWebAppHostKeys({ name: appName, resourceGroupName: rgName });
|
|
86
|
+
const defaultKey = keys.functionKeys?.['default'];
|
|
87
|
+
if (defaultKey)
|
|
88
|
+
return defaultKey;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// runtime not ready yet
|
|
92
|
+
}
|
|
93
|
+
if (i < maxRetries - 1) {
|
|
94
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`Failed to retrieve function host keys for ${appName} after ${maxRetries} attempts`);
|
|
80
98
|
});
|
|
81
99
|
this.api.namedValueSecret = this.keyVaultManager.createKeyVaultSecret(`${this.id}-key-vault-api-namespace-secret`, this, {
|
|
82
100
|
vaultName: this.api.authKeyVault.name,
|
|
83
101
|
secretName: pulumi.interpolate `${this.app.name}key`,
|
|
84
102
|
resourceGroupName: this.props.apiAuthKeyVault.resourceGroupName,
|
|
85
103
|
properties: {
|
|
86
|
-
value:
|
|
104
|
+
value: functionKey,
|
|
105
|
+
attributes: {
|
|
106
|
+
enabled: true,
|
|
107
|
+
},
|
|
108
|
+
contentType: '',
|
|
87
109
|
},
|
|
88
110
|
});
|
|
89
111
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Api, ApiOperation, Backend, NamedValue } from '@pulumi/azure-native/apimanagement/index.js';
|
|
2
|
+
import { Input } from '@pulumi/pulumi';
|
|
2
3
|
import { ApiManagementApiProps, ApiManagementBackendProps, ApiManagementProps, ApplicationInsightsProps, AzureApi, AzureFunctionAppProps, AzureRestApiProps } from '../../index.js';
|
|
3
4
|
/** @category Interface */
|
|
4
5
|
export interface ApiManagementRestApiProps extends ApiManagementProps {
|
|
@@ -30,5 +31,5 @@ export interface AzureApiFunction extends AzureApi {
|
|
|
30
31
|
corsPolicyXmlContent?: string;
|
|
31
32
|
managementApi: Api;
|
|
32
33
|
namedValue: NamedValue;
|
|
33
|
-
validateJwtPolicyXmlContent?: string
|
|
34
|
+
validateJwtPolicyXmlContent?: Input<string>;
|
|
34
35
|
}
|
|
@@ -58,9 +58,7 @@ export class AzureEventgridManager {
|
|
|
58
58
|
throw new Error(`Props undefined for ${id}`);
|
|
59
59
|
return getTopicOutput({
|
|
60
60
|
topicName: scope.resourceNameFormatter.format(props.topicName?.toString(), scope.props.resourceNameOptions?.eventGridTopic),
|
|
61
|
-
resourceGroupName:
|
|
62
|
-
? scope.resourceNameFormatter.format(scope.props.resourceGroupName)
|
|
63
|
-
: props.resourceGroupName,
|
|
61
|
+
resourceGroupName: props.resourceGroupName ?? scope.resourceNameFormatter.format(scope.props.resourceGroupName),
|
|
64
62
|
}, { parent: scope, ...resourceOptions });
|
|
65
63
|
}
|
|
66
64
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Deployment, DeploymentMode, Resource } from '@pulumi/azure-native/resources/index.js';
|
|
2
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,10 +87,22 @@ 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
|
|
92
|
-
location
|
|
104
|
+
name,
|
|
105
|
+
location,
|
|
93
106
|
resourceGroupName,
|
|
94
107
|
kind: props.kind ?? 'functionapp,linux',
|
|
95
108
|
reserved: props.reserved ?? true,
|
|
@@ -103,16 +116,8 @@ export class AzureFunctionManager {
|
|
|
103
116
|
clientCertEnabled: props.clientCertEnabled ?? false,
|
|
104
117
|
functionAppConfig: {
|
|
105
118
|
...props.functionAppConfig,
|
|
106
|
-
runtime
|
|
107
|
-
|
|
108
|
-
name: props.runtime?.name ?? 'node',
|
|
109
|
-
version: props.runtime?.version ?? CommonAzureStack.NODEJS_RUNTIME,
|
|
110
|
-
},
|
|
111
|
-
scaleAndConcurrency: {
|
|
112
|
-
...props.scaleAndConcurrency,
|
|
113
|
-
instanceMemoryMB: props.scaleAndConcurrency?.instanceMemoryMB ?? 4096,
|
|
114
|
-
maximumInstanceCount: props.scaleAndConcurrency?.maximumInstanceCount ?? 40,
|
|
115
|
-
},
|
|
119
|
+
runtime,
|
|
120
|
+
scaleAndConcurrency,
|
|
116
121
|
},
|
|
117
122
|
siteConfig: props.siteConfig ?? {
|
|
118
123
|
http20Enabled: true,
|
|
@@ -124,8 +129,10 @@ export class AzureFunctionManager {
|
|
|
124
129
|
...props.tags,
|
|
125
130
|
},
|
|
126
131
|
}, { parent: scope, ...resourceOptions });
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
// perform a deployment for the rolling update strategy
|
|
133
|
+
const deploymentId = uuidv5(`${id}-depl`, uuidv5.DNS);
|
|
134
|
+
new Deployment(deploymentId, {
|
|
135
|
+
deploymentName: deploymentId,
|
|
129
136
|
resourceGroupName,
|
|
130
137
|
properties: {
|
|
131
138
|
mode: DeploymentMode.Incremental,
|
|
@@ -136,23 +143,13 @@ export class AzureFunctionManager {
|
|
|
136
143
|
{
|
|
137
144
|
type: 'Microsoft.Web/sites',
|
|
138
145
|
apiVersion: '2024-04-01',
|
|
139
|
-
name
|
|
140
|
-
location
|
|
146
|
+
name,
|
|
147
|
+
location,
|
|
141
148
|
properties: {
|
|
142
149
|
functionAppConfig: {
|
|
143
150
|
...props.functionAppConfig,
|
|
144
|
-
runtime
|
|
145
|
-
|
|
146
|
-
name: props.runtime?.name ?? functionAppConfig?.runtime?.name ?? 'node',
|
|
147
|
-
version: props.runtime?.version ??
|
|
148
|
-
functionAppConfig?.runtime?.version ??
|
|
149
|
-
CommonAzureStack.NODEJS_RUNTIME,
|
|
150
|
-
},
|
|
151
|
-
scaleAndConcurrency: {
|
|
152
|
-
...props.scaleAndConcurrency,
|
|
153
|
-
instanceMemoryMB: props.scaleAndConcurrency?.instanceMemoryMB ?? 4096,
|
|
154
|
-
maximumInstanceCount: props.scaleAndConcurrency?.maximumInstanceCount ?? 40,
|
|
155
|
-
},
|
|
151
|
+
runtime,
|
|
152
|
+
scaleAndConcurrency,
|
|
156
153
|
siteUpdateStrategy: {
|
|
157
154
|
type: 'RollingUpdate',
|
|
158
155
|
},
|
|
@@ -162,7 +159,7 @@ export class AzureFunctionManager {
|
|
|
162
159
|
],
|
|
163
160
|
},
|
|
164
161
|
},
|
|
165
|
-
}, { parent: functionApp, ...resourceOptions });
|
|
162
|
+
}, { parent: functionApp, dependsOn: [functionApp], ...resourceOptions });
|
|
166
163
|
return functionApp;
|
|
167
164
|
}
|
|
168
165
|
/**
|