@@ -59,6 +59,24 @@ func (inst *Installer) createCluster(ctx context.Context, clusterConfig *Cluster
5959 }
6060 tags [TagKey ] = & inst .Config .EnvironmentName
6161
62+ if clusterAlreadyExists {
63+ if * existingCluster .Properties .KubernetesVersion != clusterConfig .KubernetesVersion {
64+ existingCluster .Properties .KubernetesVersion = & clusterConfig .KubernetesVersion
65+ log .Ctx (ctx ).Info ().Msgf ("Updating Kubernetes version to %s" , clusterConfig .KubernetesVersion )
66+ resp , err := clustersClient .BeginCreateOrUpdate (ctx , inst .Config .Cloud .ResourceGroup , clusterConfig .Name , existingCluster .ManagedCluster , nil )
67+ if err != nil {
68+ return nil , fmt .Errorf ("failed to update cluster: %w" , err )
69+ }
70+ if _ , err := resp .PollUntilDone (ctx , nil ); err != nil {
71+ return nil , fmt .Errorf ("failed to update cluster: %w" , err )
72+ }
73+ existingCluster , err = clustersClient .Get (ctx , inst .Config .Cloud .ResourceGroup , clusterConfig .Name , nil )
74+ if err != nil {
75+ return nil , fmt .Errorf ("failed to get cluster: %w" , err )
76+ }
77+ }
78+ }
79+
6280 cluster := armcontainerservice.ManagedCluster {
6381 Tags : tags ,
6482 Location : Ptr (clusterConfig .Location ),
@@ -82,6 +100,10 @@ func (inst *Installer) createCluster(ctx context.Context, clusterConfig *Cluster
82100 },
83101 },
84102 },
103+ SKU : & armcontainerservice.ManagedClusterSKU {
104+ Name : Ptr (armcontainerservice .ManagedClusterSKUNameBase ),
105+ Tier : Ptr (armcontainerservice .ManagedClusterSKUTier (clusterConfig .Sku )),
106+ },
85107 }
86108
87109 if workspace := inst .Config .Cloud .LogAnalyticsWorkspace ; workspace != nil {
@@ -104,34 +126,35 @@ func (inst *Installer) createCluster(ctx context.Context, clusterConfig *Cluster
104126 "logAnalyticsWorkspaceResourceID" : resp .ID ,
105127 },
106128 }
107-
108129 }
109130
110131 cluster .Properties .AgentPoolProfiles = []* armcontainerservice.ManagedClusterAgentPoolProfile {
111132 {
112- Name : Ptr ("system" ),
113- Mode : Ptr (armcontainerservice .AgentPoolModeSystem ),
114- VMSize : Ptr ("Standard_DS2_v2" ),
115- EnableAutoScaling : Ptr (true ),
116- Count : Ptr (int32 (1 )),
117- MinCount : Ptr (int32 (1 )),
118- MaxCount : Ptr (int32 (3 )),
119- OSType : Ptr (armcontainerservice .OSTypeLinux ),
120- OSSKU : Ptr (armcontainerservice .OSSKUAzureLinux ),
133+ Name : & clusterConfig .SystemNodePool .Name ,
134+ Mode : Ptr (armcontainerservice .AgentPoolModeSystem ),
135+ OrchestratorVersion : & clusterConfig .KubernetesVersion ,
136+ VMSize : & clusterConfig .SystemNodePool .VMSize ,
137+ EnableAutoScaling : Ptr (true ),
138+ Count : & clusterConfig .SystemNodePool .MinCount ,
139+ MinCount : & clusterConfig .SystemNodePool .MinCount ,
140+ MaxCount : & clusterConfig .SystemNodePool .MaxCount ,
141+ OSType : Ptr (armcontainerservice .OSTypeLinux ),
142+ OSSKU : Ptr (armcontainerservice .OSSKUAzureLinux ),
121143 },
122144 }
123145
124146 for _ , np := range clusterConfig .UserNodePools {
125147 profile := armcontainerservice.ManagedClusterAgentPoolProfile {
126- Name : & np .Name ,
127- Mode : Ptr (armcontainerservice .AgentPoolModeUser ),
128- VMSize : & np .VMSize ,
129- EnableAutoScaling : Ptr (true ),
130- Count : & np .MinCount ,
131- MinCount : & np .MinCount ,
132- MaxCount : & np .MaxCount ,
133- OSType : Ptr (armcontainerservice .OSTypeLinux ),
134- OSSKU : Ptr (armcontainerservice .OSSKUAzureLinux ),
148+ Name : & np .Name ,
149+ Mode : Ptr (armcontainerservice .AgentPoolModeUser ),
150+ OrchestratorVersion : & clusterConfig .KubernetesVersion ,
151+ VMSize : & np .VMSize ,
152+ EnableAutoScaling : Ptr (true ),
153+ Count : & np .MinCount ,
154+ MinCount : & np .MinCount ,
155+ MaxCount : & np .MaxCount ,
156+ OSType : Ptr (armcontainerservice .OSTypeLinux ),
157+ OSSKU : Ptr (armcontainerservice .OSSKUAzureLinux ),
135158 NodeLabels : map [string ]* string {
136159 "tyger" : Ptr ("run" ),
137160 },
@@ -158,46 +181,28 @@ func (inst *Installer) createCluster(ctx context.Context, clusterConfig *Cluster
158181
159182 if clusterAlreadyExists {
160183 // Check for node pools that need to be added or removed, which
161- // need to be handled separately other cluster property updates.
184+ // need to be handled separately from other cluster property updates.
162185
163186 agentPoolsClient , err := armcontainerservice .NewAgentPoolsClient (inst .Config .Cloud .SubscriptionID , inst .Credential , nil )
164187 if err != nil {
165188 return nil , fmt .Errorf ("failed to create agent pools client: %w" , err )
166189 }
167190
168- agentPoolDeletePollers := make ([]* runtime.Poller [armcontainerservice.AgentPoolsClientDeleteResponse ], 0 )
169-
170- for _ , existingNodePool := range existingCluster .ManagedCluster .Properties .AgentPoolProfiles {
171- found := false
172- for _ , newPool := range cluster .Properties .AgentPoolProfiles {
173- if * newPool .Name == * existingNodePool .Name {
174- found = true
175- break
176- }
177- }
178- if ! found {
179- log .Info ().Msgf ("Deleting node pool '%s' from cluster '%s'" , * existingNodePool .Name , clusterConfig .Name )
180- p , err := agentPoolsClient .BeginDelete (ctx , inst .Config .Cloud .ResourceGroup , clusterConfig .Name , * existingNodePool .Name , nil )
181- if err != nil {
182- return nil , fmt .Errorf ("failed to delete node pool: %w" , err )
183- }
184- agentPoolDeletePollers = append (agentPoolDeletePollers , p )
185- }
186- }
187-
188- for _ , deletePoller := range agentPoolDeletePollers {
189- if _ , err := deletePoller .PollUntilDone (ctx , nil ); err != nil {
190- return nil , fmt .Errorf ("failed to delete node pool: %w" , err )
191- }
192- }
193-
194191 agentPoolCreatePollers := make ([]* runtime.Poller [armcontainerservice.AgentPoolsClientCreateOrUpdateResponse ], 0 )
195192
196193 for _ , newNodePool := range cluster .Properties .AgentPoolProfiles {
197194 found := false
198195 for _ , existingNodePool := range existingCluster .ManagedCluster .Properties .AgentPoolProfiles {
199196 if * newNodePool .Name == * existingNodePool .Name {
200197 found = true
198+ if * newNodePool .VMSize != * existingNodePool .VMSize {
199+ return nil , fmt .Errorf ("create a new node pool instead of changing the VM size of node pool '%s'" , * newNodePool .Name )
200+ }
201+
202+ if * newNodePool .Mode != * existingNodePool .Mode {
203+ return nil , fmt .Errorf ("cannot change existing node pool '%s' from user to system (or vice-versa)" , * newNodePool .Name )
204+ }
205+
201206 break
202207 }
203208 }
@@ -222,12 +227,38 @@ func (inst *Installer) createCluster(ctx context.Context, clusterConfig *Cluster
222227 }
223228 agentPoolCreatePollers = append (agentPoolCreatePollers , p )
224229 }
230+ }
225231
226- for _ , p := range agentPoolCreatePollers {
227- if _ , err := p .PollUntilDone (ctx , nil ); err != nil {
228- return nil , fmt .Errorf ("failed to create node pool: %w" , err )
232+ for _ , p := range agentPoolCreatePollers {
233+ if _ , err := p .PollUntilDone (ctx , nil ); err != nil {
234+ return nil , fmt .Errorf ("failed to create node pool: %w" , err )
235+ }
236+ }
237+
238+ agentPoolDeletePollers := make ([]* runtime.Poller [armcontainerservice.AgentPoolsClientDeleteResponse ], 0 )
239+
240+ for _ , existingNodePool := range existingCluster .ManagedCluster .Properties .AgentPoolProfiles {
241+ found := false
242+ for _ , newPool := range cluster .Properties .AgentPoolProfiles {
243+ if * newPool .Name == * existingNodePool .Name {
244+ found = true
245+ break
229246 }
230247 }
248+ if ! found {
249+ log .Info ().Msgf ("Deleting node pool '%s' from cluster '%s'" , * existingNodePool .Name , clusterConfig .Name )
250+ p , err := agentPoolsClient .BeginDelete (ctx , inst .Config .Cloud .ResourceGroup , clusterConfig .Name , * existingNodePool .Name , nil )
251+ if err != nil {
252+ return nil , fmt .Errorf ("failed to delete node pool: %w" , err )
253+ }
254+ agentPoolDeletePollers = append (agentPoolDeletePollers , p )
255+ }
256+ }
257+
258+ for _ , deletePoller := range agentPoolDeletePollers {
259+ if _ , err := deletePoller .PollUntilDone (ctx , nil ); err != nil {
260+ return nil , fmt .Errorf ("failed to delete node pool: %w" , err )
261+ }
231262 }
232263
233264 if len (agentPoolDeletePollers ) > 0 || len (agentPoolCreatePollers ) > 0 {
@@ -342,6 +373,10 @@ func clusterNeedsUpdating(cluster, existingCluster armcontainerservice.ManagedCl
342373 }
343374 }
344375
376+ if * cluster .SKU .Tier != * existingCluster .SKU .Tier {
377+ return true , false
378+ }
379+
345380 if len (cluster .Properties .AgentPoolProfiles ) != len (existingCluster .Properties .AgentPoolProfiles ) {
346381 return true , false
347382 }
@@ -366,6 +401,9 @@ func clusterNeedsUpdating(cluster, existingCluster armcontainerservice.ManagedCl
366401 onlyScaleDown = false
367402 }
368403 }
404+ if * np .OrchestratorVersion != * existingNp .OrchestratorVersion {
405+ return true , false
406+ }
369407 break
370408 }
371409 }
0 commit comments