-
Notifications
You must be signed in to change notification settings - Fork 3
/
aks-provisioner.sh
357 lines (270 loc) · 10.8 KB
/
aks-provisioner.sh
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
#!/bin/bash
set -x
PROJECT_CODE=<Company-Name>
# Set the environment that this deployment represent (dev, qa, prod,...)
ENVIRONMENT="dev"
SUBSCRIPTION_CODE=<Company-Name>
# Primary location
LOCATION="westeurope"
# Location code will be used to setup multi-region resources
LOCATION_CODE="weu"
# Prefix is a combination of project and environment
PREFIX="${ENVIRONMENT}${PROJECT_CODE}"
# Azure subscription vars (uncomment if you will supply the values)
SUBSCRIPTION_ID=<Subscription-Id>
TENANT_ID=<Tenant-Id>
### Resource groups
export RG_AKS="${PREFIX}-aks-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
export RG_AKS_NODES="${PREFIX}-aks-nodes-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
export RG_INFOSEC="central-infosec-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
export RG_SHARED="${PREFIX}-shared-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
export RG_DEVOPS="${PREFIX}-devops-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
### Virtual networks
export PROJ_VNET_NAME="spoke-${PREFIX}-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
export HUB_EXT_VNET_NAME="hub-ext-vnet-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
# HUB_INT_VNET_NAME can be added to introduce on-premise connectivity
# AKS primary subnet
export AKS_SUBNET_NAME="${PREFIX}-aks"
# AKS exposed ingress services subnet
export SVC_SUBNET_NAME="${PREFIX}-ingress"
# 2046 allocated addresses (from 8.0 to 15.255)
export PROJ_VNET_ADDRESS_SPACE_1="10.165.8.0/21"
# 2046 allocated addresses (from 16.0 to 23.255)
export PROJ_VNET_ADDRESS_SPACE_2="10.165.16.0/21"
# Incase you need the next address space, you can use this
# export PROJ_VNET_ADDRESS_SPACE_3="10.165.24.0/22"
# This /21 size would support around 60 node cluster (given that 30 pods/cluster is used)
export AKS_SUBNET_IP_PREFIX="10.165.8.0/21"
export VN_SUBNET_IP_PREFIX="10.165.16.0/22"
export SVC_SUBNET_IP_PREFIX="10.165.20.0/24"
export APIM_HOSTED_SUBNET_IP_PREFIX="10.165.21.0/24"
export PROJ_DEVOPS_AGENTS_SUBNET_IP_PREFIX="10.165.22.0/24"
export PRIVATE_ENDPOINTS_SUBNET_NAME="10.165.23.0/24"
# 2048 allocated addresses (from 0.0 to 7.255)
export HUB_EXT_VNET_ADDRESS_SPACE="10.165.0.0/21"
### AAD Integration
# AKS Service Principal
export AKS_SP_NAME="${PREFIX}-aks-sp-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
# The following will be loaded by AAD module
AKS_SP_ID="REPLACE"
AKS_SP_PASSWORD="REPLACE"
AKS_CLUSTER_NAME="${PREFIX}-aks-${SUBSCRIPTION_CODE}-${LOCATION_CODE}"
# AKS version will be set at the cluster provisioning time
# AKS_VERSION=REPLACE
# Default node pool name must all small letters and not exceed 15 letters
AKS_DEFAULT_NODEPOOL="primary"
export AKS_CLUSTER_NAME=$AKS_CLUSTER_NAME
export AKS_VERSION=$AKS_VERSION
export AKS_DEFAULT_NODEPOOL=$AKS_DEFAULT_NODEPOOL
export AKS_SERVICE_CIDR="10.41.0.0/16"
export AKS_DNS_SERVICE_IP="10.41.0.10"
export AKS_DOCKER_BRIDGE_ADDRESS="172.17.0.1/16"
# Range to be used when using kubenet (not Azure CNI)
export AKS_POD_CIDR="10.244.0.0/16"
export AKS_PIP_NAME="${AKS_CLUSTER_NAME}-pip"
export TAG_ENV_DEV="Environment=DEV"
export TAG_ENV_STG="Environment=STG"
export TAG_ENV_QA="Environment=QA"
export TAG_ENV_PROD="Environment=PROD"
export TAG_ENV_DR_PROD="Environment=DR-PROD"
export TAG_PROJ_CODE="Project=${PROJECT_CODE}"
export TAG_PROJ_SHARED="Project=Shared-Service"
export TAG_DEPT_IT="Department=IT"
export TAG_STATUS_EXP="Status=Experimental"
export TAG_STATUS_PILOT="Status=PILOT"
export TAG_STATUS_APPROVED="Status=APPROVED"
echo "Setting up subscription and tenant id based on the signed in account"
SUBSCRIPTION_ACCOUNT=$(az account show)
echo $SUBSCRIPTION_ACCOUNT
# Get the tenant ID
TENANT_ID=$(echo $SUBSCRIPTION_ACCOUNT | jq -r .tenantId)
# or use TENANT_ID=$(az account show --query tenantId -o tsv)
echo $TENANT_ID
echo export TENANT_ID=$TENANT_ID
# Get the subscription ID
SUBSCRIPTION_ID=$(echo $SUBSCRIPTION_ACCOUNT | jq -r .id)
# or use TENANT_ID=$(az account show --query tenantId -o tsv)
echo $SUBSCRIPTION_ID
echo export SUBSCRIPTION_ID=$SUBSCRIPTION_ID
clear
echo $"Subscription Id: ${SUBSCRIPTION_ID}"
echo $"Tenant Id: ${TENANT_ID}"
echo "Login Script Completed"
# Enabling Azure Policy for AKS
# Docs: https://docs.microsoft.com/en-us/azure/governance/policy/concepts/rego-for-aks
# Register the Azure Policy provider
# az provider register --namespace Microsoft.PolicyInsights
# Enables installing the add-on
az feature register --namespace Microsoft.ContainerService --name AKS-AzurePolicyAutoApprove
# Enables the add-on to call the Azure Policy resource provider
az feature register --namespace Microsoft.PolicyInsights --name AKS-DataplaneAutoApprove
# Once the above shows 'Registered' run the following to propagate the update
az provider register -n Microsoft.PolicyInsights
# As the new resource provider takes time (several mins) to register, you can check the status here. Wait for the state to show "Registered"
az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/WindowsPreview')].{Name:name,State:properties.state}"
az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-AzurePolicyAutoApprove')].{Name:name,State:properties.state}"
az feature list -o table --query "[?contains(name, 'Microsoft.PolicyInsights/AKS-DataPlaneAutoApprove')].{Name:name,State:properties.state}"
# After registrations finish with status "Registered", you can update the provider
az provider register --namespace Microsoft.ContainerService
echo "Preview Providers Registration Completed"
az tag create --name Environment
az tag create --name Project
az tag create --name Department
az tag create --name Status
az tag add-value \
--name Environment \
--value DEV
az tag add-value \
--name Environment \
--value STG
az tag add-value \
--name Environment \
--value QA
az tag add-value \
--name Environment \
--value PROD
az tag add-value \
--name Environment \
--value DR-PROD
az tag add-value \
--name Project \
--value $PROJECT_CODE
az tag add-value \
--name Project \
--value Shared-Service
az tag add-value \
--name Department \
--value IT
az tag add-value \
--name Status \
--value Experimental
az tag add-value \
--name Status \
--value PILOT
az tag add-value \
--name Status \
--value Approved
# Saving the key/value pairs into variables
# This is only a reference, the tags savings to variables happen in the 02-variables.sh if you need to update it
export TAG_ENV_DEV="Environment=DEV"
export TAG_ENV_STG="Environment=STG"
export TAG_ENV_QA="Environment=QA"
export TAG_ENV_PROD="Environment=PROD"
export TAG_ENV_DR_PROD="Environment=DR-PROD"
export TAG_PROJ_CODE="Project=${PROJECT_CODE}"
export TAG_PROJ_SHARED="Project=Shared-Service"
export TAG_DEPT_IT="Department=IT"
export TAG_STATUS_EXP="Status=Experimental"
export TAG_STATUS_PILOT="Status=PILOT"
export TAG_STATUS_APPROVED="Status=APPROVED"
az group create \
--name $RG_AKS \
--location $LOCATION \
--tags $TAG_ENV $TAG_PROJ_CODE $TAG_DEPT_IT $TAG_STATUS_EXP
az group create \
--name $RG_SHARED \
--location $LOCATION \
--tags $TAG_ENV $TAG_PROJ_SHARED $TAG_DEPT_IT $TAG_STATUS_EXP
az group create \
--name $RG_SHARED \
--location $LOCATION \
--tags $TAG_ENV $TAG_PROJ_SHARED $TAG_DEPT_IT $TAG_STATUS_EXP
az network vnet create \
--resource-group $RG_SHARED \
--name $PROJ_VNET_NAME \
--address-prefixes $PROJ_VNET_ADDRESS_SPACE_1 $PROJ_VNET_ADDRESS_SPACE_2 \
--tags $TAG_ENV $TAG_PROJ_CODE $TAG_DEPT_IT $TAG_STATUS_EXP
# AKS primary subnet
az network vnet subnet create \
--resource-group $RG_SHARED \
--vnet-name $PROJ_VNET_NAME \
--name $AKS_SUBNET_NAME \
--address-prefix $AKS_SUBNET_IP_PREFIX
az network vnet subnet create \
--resource-group $RG_SHARED \
--vnet-name $PROJ_VNET_NAME \
--name $SVC_SUBNET_NAME \
--address-prefix $SVC_SUBNET_IP_PREFIX
# Create subnet for kubernetes exposed services (usually by internal load-balancer)
# Good security practice to isolate exposed services from the internal services
az network vnet subnet create \
--resource-group $RG_SHARED \
--vnet-name $PROJ_VNET_NAME \
--name $SVC_SUBNET_NAME \
--address-prefix $SVC_SUBNET_IP_PREFIX
# Get the id for project vnet.
PROJ_VNET_ID=$(az network vnet show \
--resource-group $RG_SHARED \
--name $PROJ_VNET_NAME \
--query id --out tsv)
az network public-ip create \
-g $RG_AKS \
-n $AKS_PIP_NAME \
-l $LOCATION \
--sku Standard \
--tags $TAG_ENV $TAG_PROJ_CODE $TAG_DEPT_IT $TAG_STATUS_EXP
echo "AKS Public IP Scripts Execution Completed"
az aks get-versions -l $LOCATION -o table
# To get the latest "production" supported version use the following (even if preview flag is activated):
AKS_VERSION=$(az aks get-versions -l ${LOCATION} --query "orchestrators[?isPreview==null].{Version:orchestratorVersion} | [-1]" -o tsv)
echo $AKS_VERSION
# Get latest AKS versions.
# Note that this command will get the latest preview version if preview flag is activated)
# AKS_VERSION=$(az aks get-versions -l ${LOCATION} --query 'orchestrators[-1].orchestratorVersion' -o tsv)
# echo $AKS_VERSION
# Save the selected version
export AKS_VERSION=$AKS_VERSION
# Get the public IP for AKS outbound traffic
AKS_PIP_ID=$(az network public-ip show -g $RG_AKS --name $AKS_PIP_NAME --query id -o tsv)
AKS_SUBNET_ID=$(az network vnet subnet show -g $RG_SHARED --vnet-name $PROJ_VNET_NAME --name $AKS_SUBNET_NAME --query id -o tsv)
az aks create \
--resource-group $RG_AKS \
--name $AKS_CLUSTER_NAME \
--location $LOCATION \
--kubernetes-version '1.19.7' \
--generate-ssh-keys \
--load-balancer-outbound-ips $AKS_PIP_ID \
--vnet-subnet-id <Subnet-Id> \
--network-plugin azure \
--network-policy calico \
--service-cidr $AKS_SERVICE_CIDR \
--dns-service-ip $AKS_DNS_SERVICE_IP \
--docker-bridge-address $AKS_DOCKER_BRIDGE_ADDRESS \
--nodepool-name $AKS_DEFAULT_NODEPOOL \
--node-count 1 \
--max-pods 30 \
--node-vm-size "Standard_D4s_v3" \
--vm-set-type VirtualMachineScaleSets \
--enable-managed-identity \
--zones 1 2 3 \
--nodepool-labels app=system \
--service-principal <Service-Principal> \
--client-secret <Client-Secret> \
--tags $TAG_ENV $TAG_PROJ_CODE $TAG_DEPT_IT $TAG_STATUS_EXP
export SECOND_NOODEPOOL="dbpool"
az aks nodepool add \
--resource-group $RG_AKS \
--cluster-name $AKS_CLUSTER_NAME \
--os-type Linux \
--name $SECOND_NOODEPOOL \
--node-count 1 \
--max-pods 30 \
--kubernetes-version '1.19.7' \
--node-vm-size "Standard_E4as_v4" \
--mode User \
--labels app=db \
--no-wait
export THIRD_NOODEPOOL="apppool"
az aks nodepool add \
--resource-group $RG_AKS \
--cluster-name $AKS_CLUSTER_NAME \
--os-type Linux \
--name $THIRD_NOODEPOOL \
--node-count 1 \
--max-pods 30 \
--kubernetes-version '1.19.7' \
--node-vm-size "Standard_E4as_v4" \
--mode User \
--labels app=app \
--no-wait
set +x