forked from pulumi/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
azureFunction.ts
124 lines (93 loc) · 4.21 KB
/
azureFunction.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import * as pulumi from "@pulumi/pulumi";
import * as azure from "@pulumi/azure";
import * as azurefunctions from "azure-functions-ts-essentials";
import { signedBlobReadUrl } from "./sas";
export type Context = azurefunctions.Context;
export type HttpRequest = azurefunctions.HttpRequest;
export * from "azure-functions-ts-essentials";
export type AzureFunctionHandler = (context: Context, request: HttpRequest) => void;
async function blobContent(name: string, handler: AzureFunctionHandler): Promise<pulumi.asset.AssetMap> {
let serializedHandler = await pulumi.runtime.serializeFunction(handler);
let map: pulumi.asset.AssetMap = {};
map["host.json"] = new pulumi.asset.StringAsset(JSON.stringify({}));
map[`${name}/function.json`] = new pulumi.asset.StringAsset(JSON.stringify({
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}));
map[`${name}/index.js`] = new pulumi.asset.StringAsset(`module.exports = require("./handler").handler`),
map[`${name}/handler.js`] = new pulumi.asset.StringAsset(serializedHandler.text);
return map;
}
// An Azure function exposed via an HTTP endpoint.
export class HttpFunction extends pulumi.ComponentResource {
readonly resourceGroup: azure.core.ResourceGroup;
readonly storageAccount: azure.storage.Account;
readonly storageContainer: azure.storage.Container;
readonly blob: azure.storage.ZipBlob;
readonly appServicePlan: azure.appservice.Plan;
readonly functionApp: azure.appservice.FunctionApp;
readonly codeBlobUrl: pulumi.Output<string>;
readonly endpoint: pulumi.Output<string>;
constructor(name: string, handler: AzureFunctionHandler, options?: pulumi.ResourceOptions) {
super("azure:HttpFunction", name, {}, options);
let parentArgs = { parent: this };
this.resourceGroup = new azure.core.ResourceGroup(`${name}-rg`, {
location: "West US 2",
}, parentArgs);
let resourceGroupArgs = {
resourceGroupName: this.resourceGroup.name,
location: this.resourceGroup.location,
};
this.storageAccount = new azure.storage.Account(`${name}sa`, {
...resourceGroupArgs,
accountKind: "StorageV2",
accountTier: "Standard",
accountReplicationType: "LRS",
}, parentArgs);
this.storageContainer = new azure.storage.Container(`${name}-c`, {
resourceGroupName: this.resourceGroup.name,
storageAccountName: this.storageAccount.name,
containerAccessType: "private",
}, parentArgs);
this.blob = new azure.storage.ZipBlob(`${name}-b`, {
resourceGroupName: this.resourceGroup.name,
storageAccountName: this.storageAccount.name,
storageContainerName: this.storageContainer.name,
type: "block",
content: new pulumi.asset.AssetArchive(blobContent(name, handler)),
}, parentArgs);
this.codeBlobUrl = signedBlobReadUrl(this.blob, this.storageAccount, this.storageContainer);
this.appServicePlan = new azure.appservice.Plan(`${name}-p`, {
...resourceGroupArgs,
kind: "FunctionApp",
// https://social.msdn.microsoft.com/Forums/azure/en-US/665c365d-2b86-4a77-8cea-72ccffef216c
sku: {
tier: "Dynamic",
size: "Y1",
},
}, parentArgs);
this.functionApp = new azure.appservice.FunctionApp(`${name}-app`, {
...resourceGroupArgs,
appServicePlanId: this.appServicePlan.id,
storageConnectionString: this.storageAccount.primaryConnectionString,
appSettings: {
"WEBSITE_RUN_FROM_ZIP": this.codeBlobUrl,
},
}, parentArgs);
this.endpoint = this.functionApp.defaultHostname.apply(h => {
return `https://${h}/api/${name}`;
});
}
};