Skip to content

Commit 836de59

Browse files
Copilotbcho
andcommitted
Add full kubeadm bootstrap config and VHD parameterization in vm.bicep module
Co-authored-by: bcho <1975118+bcho@users.noreply.github.com>
1 parent 949e7bc commit 836de59

2 files changed

Lines changed: 149 additions & 14 deletions

File tree

hack/e2e/infra/modules/vm.bicep

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// =============================================================================
22
// modules/vm.bicep - Reusable Ubuntu flex-node VM module
33
//
4-
// Creates a public IP, NIC, and Ubuntu 22.04 VM in the given subnet.
4+
// Creates a public IP, NIC, and Ubuntu VM in the given subnet.
5+
// The VHD image defaults to Ubuntu 24.04 LTS (Noble) but can be overridden.
56
// =============================================================================
67

78
@description('Azure region for all resources.')
@@ -26,6 +27,18 @@ param subnetId string
2627
@description('Whether to assign a system-assigned managed identity to the VM.')
2728
param assignManagedIdentity bool = false
2829

30+
@description('Marketplace image publisher.')
31+
param imagePublisher string = 'Canonical'
32+
33+
@description('Marketplace image offer.')
34+
param imageOffer string = 'ubuntu-24_04-lts'
35+
36+
@description('Marketplace image SKU.')
37+
param imageSku string = 'server'
38+
39+
@description('Marketplace image version.')
40+
param imageVersion string = 'latest'
41+
2942
@description('Tags applied to all resources in this module.')
3043
param tags object = {}
3144

@@ -98,10 +111,10 @@ resource vm 'Microsoft.Compute/virtualMachines@2024-03-01' = {
98111
}
99112
storageProfile: {
100113
imageReference: {
101-
publisher: 'Canonical'
102-
offer: '0001-com-ubuntu-server-jammy'
103-
sku: '22_04-lts-gen2'
104-
version: 'latest'
114+
publisher: imagePublisher
115+
offer: imageOffer
116+
sku: imageSku
117+
version: imageVersion
105118
}
106119
osDisk: {
107120
createOption: 'FromImage'

hack/e2e/lib/node-join.sh

Lines changed: 131 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,13 @@ stringData:
363363
EOF
364364

365365
# Create RBAC bindings for TLS bootstrapping (idempotent).
366-
# These three bindings mirror what kubeadm init normally sets up:
367-
# 1. system:node-bootstrapper – allows nodes to create CSRs
368-
# 2. nodeclient auto-approval – auto-approves initial node certs
369-
# 3. selfnodeclient auto-approval – auto-approves certificate rotations
366+
# Mirrors the full set of resources that kubeadm init sets up:
367+
# - ClusterRoleBindings for CSR creation and auto-approval
368+
# - Roles/RoleBindings granting bootstrappers read access to kubeadm config
369+
# and kubelet config (required by kubeadm join's preflight phase)
370+
# - ClusterRole/ClusterRoleBinding for bootstrappers to GET nodes
371+
# - ConfigMaps: cluster-info (kube-public), kubeadm-config and
372+
# kubelet-config (kube-system) consumed by kubeadm join
370373
kubectl apply -f - <<EOF
371374
apiVersion: rbac.authorization.k8s.io/v1
372375
kind: ClusterRoleBinding
@@ -396,6 +399,19 @@ subjects:
396399
---
397400
apiVersion: rbac.authorization.k8s.io/v1
398401
kind: ClusterRoleBinding
402+
metadata:
403+
name: aks-flex-node-auto-approve-certificate-rotation
404+
roleRef:
405+
apiGroup: rbac.authorization.k8s.io
406+
kind: ClusterRole
407+
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
408+
subjects:
409+
- apiGroup: rbac.authorization.k8s.io
410+
kind: Group
411+
name: system:nodes
412+
---
413+
apiVersion: rbac.authorization.k8s.io/v1
414+
kind: ClusterRoleBinding
399415
metadata:
400416
name: aks-flex-node-role
401417
roleRef:
@@ -408,17 +424,123 @@ subjects:
408424
name: system:bootstrappers:aks-flex-node
409425
---
410426
apiVersion: rbac.authorization.k8s.io/v1
427+
kind: Role
428+
metadata:
429+
namespace: kube-system
430+
name: kubeadm:nodes-kubeadm-config
431+
rules:
432+
- verbs: ["get"]
433+
apiGroups: [""]
434+
resources: ["configmaps"]
435+
resourceNames: ["kubeadm-config"]
436+
---
437+
apiVersion: rbac.authorization.k8s.io/v1
438+
kind: RoleBinding
439+
metadata:
440+
namespace: kube-system
441+
name: kubeadm:nodes-kubeadm-config
442+
roleRef:
443+
apiGroup: rbac.authorization.k8s.io
444+
kind: Role
445+
name: kubeadm:nodes-kubeadm-config
446+
subjects:
447+
- kind: Group
448+
apiGroup: rbac.authorization.k8s.io
449+
name: system:bootstrappers:aks-flex-node
450+
---
451+
apiVersion: rbac.authorization.k8s.io/v1
452+
kind: Role
453+
metadata:
454+
namespace: kube-system
455+
name: kubeadm:kubelet-config
456+
rules:
457+
- verbs: ["get"]
458+
apiGroups: [""]
459+
resources: ["configmaps"]
460+
resourceNames: ["kubelet-config"]
461+
---
462+
apiVersion: rbac.authorization.k8s.io/v1
463+
kind: RoleBinding
464+
metadata:
465+
namespace: kube-system
466+
name: kubeadm:kubelet-config
467+
roleRef:
468+
apiGroup: rbac.authorization.k8s.io
469+
kind: Role
470+
name: kubeadm:kubelet-config
471+
subjects:
472+
- kind: Group
473+
apiGroup: rbac.authorization.k8s.io
474+
name: system:bootstrappers:aks-flex-node
475+
---
476+
apiVersion: rbac.authorization.k8s.io/v1
477+
kind: ClusterRole
478+
metadata:
479+
name: kubeadm:get-nodes
480+
rules:
481+
- verbs: ["get"]
482+
apiGroups: [""]
483+
resources: ["nodes"]
484+
---
485+
apiVersion: rbac.authorization.k8s.io/v1
411486
kind: ClusterRoleBinding
412487
metadata:
413-
name: aks-flex-node-auto-approve-certificate-rotation
488+
name: kubeadm:get-nodes
414489
roleRef:
415490
apiGroup: rbac.authorization.k8s.io
416491
kind: ClusterRole
417-
name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
492+
name: kubeadm:get-nodes
418493
subjects:
419-
- apiGroup: rbac.authorization.k8s.io
420-
kind: Group
421-
name: system:nodes
494+
- kind: Group
495+
apiGroup: rbac.authorization.k8s.io
496+
name: system:bootstrappers:aks-flex-node
497+
EOF
498+
499+
# Publish the ConfigMaps that kubeadm join reads during its preflight phase.
500+
# cluster-info goes into kube-public (publicly readable).
501+
# kubeadm-config and kubelet-config go into kube-system (bootstrapper-readable).
502+
kubectl apply -f - <<EOF
503+
apiVersion: v1
504+
kind: ConfigMap
505+
metadata:
506+
namespace: kube-public
507+
name: cluster-info
508+
data:
509+
kubeconfig: |
510+
apiVersion: v1
511+
kind: Config
512+
clusters:
513+
- cluster:
514+
certificate-authority-data: ${ca_cert_data}
515+
server: ${server_url}
516+
name: ""
517+
contexts: []
518+
current-context: ""
519+
preferences: {}
520+
users: []
521+
---
522+
apiVersion: v1
523+
kind: ConfigMap
524+
metadata:
525+
namespace: kube-system
526+
name: kubeadm-config
527+
data:
528+
ClusterConfiguration: |
529+
apiVersion: kubeadm.k8s.io/v1beta4
530+
kind: ClusterConfiguration
531+
kubernetesVersion: ${E2E_KUBERNETES_VERSION}
532+
networking:
533+
serviceSubnet: 10.0.0.0/16
534+
---
535+
apiVersion: v1
536+
kind: ConfigMap
537+
metadata:
538+
namespace: kube-system
539+
name: kubelet-config
540+
data:
541+
kubelet: |
542+
apiVersion: kubelet.config.k8s.io/v1beta1
543+
kind: KubeletConfiguration
422544
EOF
423545

424546
log_success "Bootstrap token and RBAC configured"

0 commit comments

Comments
 (0)