forked from pulumi/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
keda.ts
161 lines (144 loc) · 6.02 KB
/
keda.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright 2016-2019, Pulumi Corporation. All rights reserved.
import * as azure from "@pulumi/azure";
import * as docker from "@pulumi/docker";
import * as k8s from "@pulumi/kubernetes";
import * as pulumi from "@pulumi/pulumi";
// Arguments for a KEDA deployment.
export interface KedaServiceArgs {
resourceGroup: azure.core.ResourceGroup;
k8sProvider: k8s.Provider;
}
// A component to deploy shared parts of KEDA (container registry, kedacore/keda-edge Helm chart)
export class KedaService extends pulumi.ComponentResource {
public registry: azure.containerservice.Registry;
public k8sProvider: k8s.Provider;
public registrySecretName: pulumi.Output<string>;
constructor(name: string,
args: KedaServiceArgs,
opts: pulumi.ComponentResourceOptions = {}) {
super("examples:keda:KedaEdge", name, args, opts);
// Add a container registry to store custom images of Azure Functions
const registry = new azure.containerservice.Registry("registry", {
resourceGroupName: args.resourceGroup.name,
adminEnabled: true,
sku: "Premium",
}, { parent: this });
const dockercfg = pulumi.all([registry.loginServer, registry.adminUsername, registry.adminPassword])
.apply(([server, username, password]) => {
const r: any = {};
r[server] = {
email: "notneeded@notneeded.com",
username,
password,
};
return r;
});
// Storage the docker registry credentials as a secret
const secretRegistry = new k8s.core.v1.Secret("registry-secret", {
data: {
".dockercfg": dockercfg.apply(c => Buffer.from(JSON.stringify(c)).toString("base64")),
},
type: "kubernetes.io/dockercfg",
},
{ provider: args.k8sProvider, parent: this });
// Deploy a KEDA Edge Helm chart
const keda = new k8s.helm.v2.Chart("keda-edge", {
repo: "kedacore",
chart: "keda",
version: "1.2.0",
fetchOpts: {
repo: "https://kedacore.github.io/charts",
},
values: {
logLevel: "debug",
},
}, { providers: { kubernetes: args.k8sProvider }, parent: this });
this.k8sProvider = args.k8sProvider;
this.registry = registry;
this.registrySecretName = secretRegistry.metadata.name;
this.registerOutputs();
}
}
// Arguments for an Azure Function App that processes messages from a given storage queue.
export interface KedaStorageQueueHandlerArgs {
resourceGroup: azure.core.ResourceGroup;
service: KedaService;
storageAccount: azure.storage.Account;
queue: azure.storage.Queue;
path: pulumi.Input<string>;
}
// A KEDA-deployed Azure Function App that processes messages from a given storage queue.
export class KedaStorageQueueHandler extends pulumi.ComponentResource {
constructor(name: string,
args: KedaStorageQueueHandlerArgs,
opts: pulumi.ComponentResourceOptions = {}) {
super("examples:keda:KedaStorageQueueHandler", name, args, opts);
const registry = args.service.registry;
// Deploy the docker image of the Function App
const dockerImage = new docker.Image("image", {
imageName: pulumi.interpolate`${registry.loginServer}/${args.queue.name}:v1.0.0`,
build: {
context: args.path,
},
registry: {
server: registry.loginServer,
username: registry.adminUsername,
password: registry.adminPassword,
},
}, { parent: this });
// Put the storage account connection string into a secret
const secretQueue = new k8s.core.v1.Secret("queue-secret", {
data: {
queueConnectionString:
args.storageAccount.primaryConnectionString.apply(c => Buffer.from(c).toString("base64")),
},
}, { provider: args.service.k8sProvider, parent: this });
// Deploy the Function App from the image
const appLabels = { app: name };
const deployment = new k8s.apps.v1.Deployment(name, {
apiVersion: "apps/v1",
kind: "Deployment",
metadata: {
labels: appLabels,
},
spec: {
selector: { matchLabels: appLabels },
template: {
metadata: {
labels: appLabels,
},
spec: {
containers: [{
name,
image: dockerImage.imageName,
env: [{ name: "queuename", value: args.queue.name }],
envFrom: [{ secretRef: {name: secretQueue.metadata.name } }],
}],
imagePullSecrets: [{ name: args.service.registrySecretName }],
},
},
},
}, { provider: args.service.k8sProvider, parent: this });
// Deploy a custom resource Scale Object and point it to the queue
const scaledObject = new k8s.apiextensions.CustomResource("scaleobject", {
apiVersion: "keda.k8s.io/v1alpha1",
kind: "ScaledObject",
metadata: {
labels: { deploymentName: name },
},
spec: {
scaleTargetRef: { deploymentName: name },
triggers: [{
type: "azure-queue",
metadata: {
type: "queueTrigger",
connection: "queueConnectionString",
queueName: args.queue.name,
name: "myQueueItem",
},
}],
},
}, { provider: args.service.k8sProvider, parent: this });
this.registerOutputs();
}
}