Skip to content

Commit 8c1686c

Browse files
committed
move source code to here
0 parents  commit 8c1686c

File tree

195 files changed

+27346
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

195 files changed

+27346
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
node_modules/*

.idea/.gitignore

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/HBD.Pulumi.Share.iml

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.vscode/settings.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"files.exclude": {
3+
"**/.DS_Store": true,
4+
"**/node_modules": true,
5+
"**/._*": true,
6+
"**/.nyc_output": true
7+
},
8+
"git.ignoreLimitWarning": true
9+
}

AKS.WP.code-workspace

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"folders": [
3+
{
4+
"path": "."
5+
}
6+
],
7+
"settings": {
8+
"files.exclude": {
9+
"_Shared/**/.DS_Store": true,
10+
"_Shared/**/node_modules": true,
11+
"_Shared/**/._*": true,
12+
"_Shared/**/.nyc_output": true,
13+
"az-dc-KubeApps/bin/": true,
14+
"az-dc-KubeApps/node_modules/": true,
15+
"az-dc-Aks/bin/": true,
16+
"az-dc-Aks/node_modules/": true
17+
},
18+
"cSpell.words": ["containerservice"]
19+
}
20+
}

Aks/Helper.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import * as containerservice from "@pulumi/azure-native/containerservice";
2+
import { KeyVaultInfo } from "../types";
3+
import { getIdentitySecrets } from "../AzAd/Helper";
4+
import { getAksName, getResourceGroupName } from "../Common/Naming";
5+
6+
export const getAksConfig = async ({
7+
name,
8+
groupName,
9+
}: {
10+
name: string;
11+
groupName?: string;
12+
}) => {
13+
const aksName = getAksName(name);
14+
const group = groupName || getResourceGroupName(name);
15+
16+
const aks = await containerservice.listManagedClusterAdminCredentials({
17+
resourceName: aksName,
18+
resourceGroupName: group,
19+
});
20+
21+
return Buffer.from(aks.kubeconfigs[0].value, "base64").toString("utf8");
22+
};
23+
24+
export const getAksIdentitySecrets = async ({
25+
name,
26+
vaultInfo,
27+
}: {
28+
name: string;
29+
vaultInfo: KeyVaultInfo;
30+
}) => {
31+
name = getAksName(name);
32+
return getIdentitySecrets({ name, vaultInfo });
33+
};

Aks/Identity.ts

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Input } from '@pulumi/pulumi';
2+
3+
import { KeyVaultInfo, ResourceGroupInfo } from '../types';
4+
import { getGraphPermissions } from '../AzAd/GraphDefinition';
5+
import identityCreator from '../AzAd/Identity';
6+
import { roleAssignment } from '../AzAd/RoleAssignment';
7+
import { getResourceIdFromInfo } from '../Common/ResourceEnv';
8+
import { defaultScope } from '../Common/AzureEnv';
9+
10+
interface Props {
11+
name: string;
12+
group?: ResourceGroupInfo;
13+
vaultInfo: KeyVaultInfo;
14+
containerRegistryId?: Input<string>;
15+
privateCluster?: boolean;
16+
}
17+
18+
//** The Az AD app Identity for Azure Kubernetes */
19+
export default async ({
20+
name,
21+
group,
22+
vaultInfo,
23+
containerRegistryId,
24+
privateCluster,
25+
}: Props) => {
26+
//AKS need this permission for AAD integration
27+
const graphAccess = getGraphPermissions(
28+
{ name: 'User.Read', type: 'Scope' },
29+
{ name: 'Group.Read.All', type: 'Scope' },
30+
//{ name: 'Directory.Read.All', type: 'Scope' },
31+
{ name: 'Directory.Read.All', type: 'Role' }
32+
);
33+
34+
const serverIdentity = await identityCreator({
35+
name,
36+
createClientSecret: true,
37+
createPrincipal: true,
38+
requiredResourceAccesses: [graphAccess],
39+
publicClient: false,
40+
allowImplicit: false,
41+
vaultInfo,
42+
});
43+
44+
//Permission for Server Identity
45+
if (serverIdentity.principalId) {
46+
//Allows to pull image from ACR
47+
await roleAssignment({
48+
name: `${name}-acr-pull`,
49+
principalId: serverIdentity.principalId,
50+
roleName: 'AcrPull',
51+
scope: containerRegistryId || defaultScope,
52+
principalType: 'ServicePrincipal',
53+
});
54+
55+
//Allows to update Private DNS Zone
56+
if (privateCluster) {
57+
await roleAssignment({
58+
name: `${name}-private-dns`,
59+
principalId: serverIdentity.principalId,
60+
roleName: 'Private DNS Zone Contributor',
61+
principalType: 'ServicePrincipal',
62+
});
63+
}
64+
65+
//Add contribute role to resource group
66+
if (group) {
67+
await roleAssignment({
68+
name: `${name}-contributor`,
69+
principalId: serverIdentity.principalId,
70+
roleName: 'Contributor',
71+
principalType: 'ServicePrincipal',
72+
scope: getResourceIdFromInfo({ group }),
73+
});
74+
}
75+
}
76+
77+
return serverIdentity;
78+
};

Aks/VmSetAutoScale/index.ts

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
import * as insights from '@pulumi/azure-native/insights';
2+
import { input as inputs, enums } from '@pulumi/azure-native/types';
3+
import { AzureResourceItem, findVMScaleSet } from '../../Core/Helper';
4+
import { BasicMonitorArgs, ResourceGroupInfo } from '../../types';
5+
import { Input, Resource } from '@pulumi/pulumi';
6+
7+
interface Props extends BasicMonitorArgs {
8+
group: ResourceGroupInfo;
9+
getCapacity?: typeof defaultGetCapacity;
10+
dependsOn?: Input<Input<Resource>[]> | Input<Resource>;
11+
}
12+
13+
const defaultGetCapacity = (
14+
vmScaleSet: AzureResourceItem
15+
): {
16+
nightCapacity?: 0 | 1 | number;
17+
default: number;
18+
minimum: number;
19+
maximum: number;
20+
} => {
21+
const mode = vmScaleSet.tags ? vmScaleSet.tags['mode'] : 'System';
22+
if (mode === 'System')
23+
return { nightCapacity: 1, default: 1, minimum: 1, maximum: 3 };
24+
return { nightCapacity: 0, default: 0, minimum: 1, maximum: 3 };
25+
};
26+
27+
export default async ({
28+
group,
29+
getCapacity = defaultGetCapacity,
30+
dependsOn,
31+
}: Props) => {
32+
const vmScaleSets = await findVMScaleSet(group.resourceGroupName);
33+
if (!vmScaleSets) return;
34+
35+
return vmScaleSets.map((vm) => {
36+
const cap = getCapacity(vm);
37+
const profiles = new Array<inputs.insights.AutoscaleProfileArgs>();
38+
const timeZone =
39+
vm.location === 'southeastasia'
40+
? 'Singapore Standard Time'
41+
: 'Singapore Standard Time';
42+
43+
if (cap.nightCapacity) {
44+
profiles.push({
45+
name: 'Scale down at night',
46+
capacity: {
47+
default: cap.nightCapacity.toString(),
48+
minimum: cap.nightCapacity.toString(),
49+
maximum: cap.nightCapacity > 0 ? cap.nightCapacity.toString() : '1',
50+
},
51+
rules: [],
52+
recurrence: {
53+
frequency: 'Week',
54+
schedule: {
55+
timeZone,
56+
days: [
57+
'Monday',
58+
'Tuesday',
59+
'Wednesday',
60+
'Thursday',
61+
'Friday',
62+
'Saturday',
63+
'Sunday',
64+
],
65+
hours: [19],
66+
minutes: [0],
67+
},
68+
},
69+
});
70+
}
71+
72+
profiles.push({
73+
name: 'auto scale by CPU',
74+
capacity: {
75+
default: cap.default.toString(),
76+
minimum: cap.minimum.toString(),
77+
maximum: cap.maximum.toString(),
78+
},
79+
80+
rules: [
81+
{
82+
//Scale Up
83+
metricTrigger: {
84+
metricName: 'Percentage CPU',
85+
metricNamespace: 'microsoft.compute/virtualmachinescalesets',
86+
metricResourceUri: vm.id,
87+
timeGrain: 'PT1M',
88+
statistic: 'Average',
89+
timeWindow: 'PT15M',
90+
timeAggregation: 'Average',
91+
operator: 'GreaterThanOrEqual',
92+
threshold: 75,
93+
dimensions: [],
94+
dividePerInstance: false,
95+
},
96+
scaleAction: {
97+
direction: 'Increase',
98+
type: 'ChangeCount',
99+
value: '1',
100+
cooldown: 'PT30M',
101+
},
102+
},
103+
{
104+
//Scale down
105+
metricTrigger: {
106+
metricName: 'Percentage CPU',
107+
metricNamespace: 'microsoft.compute/virtualmachinescalesets',
108+
metricResourceUri: vm.id,
109+
timeGrain: 'PT1M',
110+
statistic: 'Average',
111+
timeWindow: 'PT15M',
112+
timeAggregation: 'Average',
113+
operator: 'LessThanOrEqual',
114+
threshold: 50,
115+
dimensions: [],
116+
dividePerInstance: false,
117+
},
118+
scaleAction: {
119+
direction: 'Decrease',
120+
type: 'ChangeCount',
121+
value: '1',
122+
cooldown: 'PT30M',
123+
},
124+
},
125+
],
126+
recurrence: {
127+
frequency: 'Week',
128+
schedule: {
129+
timeZone,
130+
days: [
131+
'Monday',
132+
'Tuesday',
133+
'Wednesday',
134+
'Thursday',
135+
'Friday',
136+
//'Saturday',
137+
//'Sunday',
138+
],
139+
hours: [8],
140+
minutes: [0],
141+
},
142+
},
143+
});
144+
145+
//LinuxDiagnostic
146+
const autoScale = new insights.AutoscaleSetting(
147+
`${vm.name}-AutoScale`,
148+
{
149+
name: `${vm.name}-AutoScale`,
150+
autoscaleSettingName: `${vm.name}-AutoScale`,
151+
152+
resourceGroupName: vm.resourceGroupName,
153+
targetResourceUri: vm.id,
154+
155+
enabled: true,
156+
profiles,
157+
},
158+
{ dependsOn }
159+
);
160+
161+
return autoScale;
162+
});
163+
};

0 commit comments

Comments
 (0)