Skip to content

Commit 2854136

Browse files
authored
Allow upgrades on azure without Terraform changes on LBs created from within Kubernetes (#3257)
* k8s: use separate lb for K8s services on azure * terraform: introduce local revision variable and data resource * terraform: azure: dont expose full nodeport range * docs: add Azure load balancer migration
1 parent 2dcea4f commit 2854136

File tree

8 files changed

+75
-13
lines changed

8 files changed

+75
-13
lines changed

docs/docs/reference/migration.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,19 @@
33
This document describes breaking changes and migrations between Constellation releases.
44
Use [`constellation config migrate`](./cli.md#constellation-config-migrate) to automatically update an old config file to a new format.
55

6-
## Migrating from Azure's service principal authentication to managed identity authentication
6+
7+
## Migrations to v2.19.0
8+
9+
### Azure
10+
11+
* To allow seamless upgrades on Azure when Kubernetes services of type `LoadBalancer` are deployed, the target
12+
load balancer in which the `cloud-controller-manager` creates load balancing rules was changed. Instead of using the load balancer
13+
created and maintained by the CLI's Terraform code, the `cloud-controller-manager` now creates its own load balancer in Azure.
14+
If your Constellation has services of type `LoadBalancer`, please remove them before the upgrade and re-apply them
15+
afterward.
16+
17+
18+
## Migrating from Azure's service principal authentication to managed identity authentication (during the upgrade to Constellation v2.8.0)
719

820
- The `provider.azure.appClientID` and `provider.azure.appClientSecret` fields are no longer supported and should be removed.
921
- To keep using an existing UAMI, add the `Owner` permission with the scope of your `resourceGroup`.

internal/constellation/helm/overrides.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func getCCMConfig(azureState state.Azure, serviceAccURI string) ([]byte, error)
243243
ResourceGroup: azureState.ResourceGroup,
244244
LoadBalancerSku: "standard",
245245
SecurityGroupName: azureState.NetworkSecurityGroupName,
246-
LoadBalancerName: azureState.LoadBalancerName,
246+
LoadBalancerName: "kubernetes-lb",
247247
UseInstanceMetadata: true,
248248
VMType: "vmss",
249249
Location: creds.Location,

terraform/infrastructure/aws/main.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ locals {
5555

5656
in_cluster_endpoint = aws_lb.front_end.dns_name
5757
out_of_cluster_endpoint = var.internal_load_balancer && var.debug ? module.jump_host[0].ip : local.in_cluster_endpoint
58+
revision = 1
59+
}
60+
61+
# A way to force replacement of resources if the provider does not want to replace them
62+
# see: https://developer.hashicorp.com/terraform/language/resources/terraform-data#example-usage-data-for-replace_triggered_by
63+
resource "terraform_data" "replacement" {
64+
input = local.revision
5865
}
5966

6067
resource "random_id" "uid" {

terraform/infrastructure/azure/main.tf

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ locals {
3737
{ name = "kubernetes", port = "6443", health_check_protocol = "Https", path = "/readyz", priority = 100 },
3838
{ name = "bootstrapper", port = "9000", health_check_protocol = "Tcp", path = null, priority = 101 },
3939
{ name = "verify", port = "30081", health_check_protocol = "Tcp", path = null, priority = 102 },
40-
{ name = "konnectivity", port = "8132", health_check_protocol = "Tcp", path = null, priority = 103 },
4140
{ name = "recovery", port = "9999", health_check_protocol = "Tcp", path = null, priority = 104 },
4241
{ name = "join", port = "30090", health_check_protocol = "Tcp", path = null, priority = 105 },
4342
var.debug ? [{ name = "debugd", port = "4000", health_check_protocol = "Tcp", path = null, priority = 106 }] : [],
@@ -53,6 +52,13 @@ locals {
5352

5453
in_cluster_endpoint = var.internal_load_balancer ? azurerm_lb.loadbalancer.frontend_ip_configuration[0].private_ip_address : azurerm_public_ip.loadbalancer_ip[0].ip_address
5554
out_of_cluster_endpoint = var.debug && var.internal_load_balancer ? module.jump_host[0].ip : local.in_cluster_endpoint
55+
revision = 1
56+
}
57+
58+
# A way to force replacement of resources if the provider does not want to replace them
59+
# see: https://developer.hashicorp.com/terraform/language/resources/terraform-data#example-usage-data-for-replace_triggered_by
60+
resource "terraform_data" "replacement" {
61+
input = local.revision
5662
}
5763

5864
resource "random_id" "uid" {
@@ -223,10 +229,13 @@ resource "azurerm_network_security_group" "security_group" {
223229
tags = local.tags
224230

225231
dynamic "security_rule" {
226-
for_each = concat(
227-
local.ports,
228-
[{ name = "nodeports", port = local.ports_node_range, priority = 200 }]
229-
)
232+
# we keep this rule for one last release since the azurerm provider does not
233+
# support moving security rules that are inlined (like this) to the external resource one.
234+
# Even worse, just defining the azurerm_network_security_group without the
235+
# "security_rule" block will NOT remove all the rules but do nothing.
236+
# TODO(@3u13r): remove the "security_rule" block in the next release after this code has landed.
237+
# So either after 2.19 or after 2.18.X if cherry-picked release.
238+
for_each = [{ name = "konnectivity", priority = 1000, port = 8132 }]
230239
content {
231240
name = security_rule.value.name
232241
priority = security_rule.value.priority
@@ -241,6 +250,24 @@ resource "azurerm_network_security_group" "security_group" {
241250
}
242251
}
243252

253+
resource "azurerm_network_security_rule" "nsg_rule" {
254+
for_each = {
255+
for o in local.ports : o.name => o
256+
}
257+
258+
name = each.value.name
259+
priority = each.value.priority
260+
direction = "Inbound"
261+
access = "Allow"
262+
protocol = "Tcp"
263+
source_port_range = "*"
264+
destination_port_range = each.value.port
265+
source_address_prefix = "*"
266+
destination_address_prefix = "*"
267+
resource_group_name = var.resource_group
268+
network_security_group_name = azurerm_network_security_group.security_group.name
269+
}
270+
244271
module "scale_set_group" {
245272
source = "./modules/scale_set"
246273
for_each = var.node_groups
@@ -268,12 +295,6 @@ module "scale_set_group" {
268295
subnet_id = azurerm_subnet.node_subnet.id
269296
backend_address_pool_ids = each.value.role == "control-plane" ? [module.loadbalancer_backend_control_plane.backendpool_id] : []
270297
marketplace_image = var.marketplace_image
271-
272-
# We still depend on the backends, since we are not sure if the VMs inside the VMSS have been
273-
# "updated" to the new version (note: this is the update in Azure which "refreshes" the NICs and not
274-
# our Constellation update).
275-
# TODO(@3u13r): Remove this dependency after v2.18.0 has been released.
276-
depends_on = [module.loadbalancer_backend_worker, azurerm_lb_backend_address_pool.all]
277298
}
278299

279300
module "jump_host" {

terraform/infrastructure/azure/modules/scale_set/main.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ resource "azurerm_linux_virtual_machine_scale_set" "scale_set" {
122122
instances, # required. autoscaling modifies the instance count externally
123123
source_image_id, # required. update procedure modifies the image id externally
124124
source_image_reference, # required. update procedure modifies the image reference externally
125+
network_interface[0].ip_configuration[0].load_balancer_backend_address_pool_ids
125126
]
126127
}
127128
}

terraform/infrastructure/gcp/main.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ locals {
6060
]
6161
in_cluster_endpoint = var.internal_load_balancer ? google_compute_address.loadbalancer_ip_internal[0].address : google_compute_global_address.loadbalancer_ip[0].address
6262
out_of_cluster_endpoint = var.debug && var.internal_load_balancer ? module.jump_host[0].ip : local.in_cluster_endpoint
63+
revision = 1
64+
}
65+
66+
# A way to force replacement of resources if the provider does not want to replace them
67+
# see: https://developer.hashicorp.com/terraform/language/resources/terraform-data#example-usage-data-for-replace_triggered_by
68+
resource "terraform_data" "replacement" {
69+
input = local.revision
6370
}
6471

6572
resource "random_id" "uid" {

terraform/infrastructure/openstack/main.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ locals {
5959
cloudsyaml_path = length(var.openstack_clouds_yaml_path) > 0 ? var.openstack_clouds_yaml_path : "~/.config/openstack/clouds.yaml"
6060
cloudsyaml = yamldecode(file(pathexpand(local.cloudsyaml_path)))
6161
cloudyaml = local.cloudsyaml.clouds[var.cloud]
62+
revision = 1
63+
}
64+
65+
# A way to force replacement of resources if the provider does not want to replace them
66+
# see: https://developer.hashicorp.com/terraform/language/resources/terraform-data#example-usage-data-for-replace_triggered_by
67+
resource "terraform_data" "replacement" {
68+
input = local.revision
6269
}
6370

6471
resource "random_id" "uid" {

terraform/infrastructure/qemu/main.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ locals {
2323
cidr_vpc_subnet_nodes = "10.42.0.0/22"
2424
cidr_vpc_subnet_control_planes = "10.42.1.0/24"
2525
cidr_vpc_subnet_worker = "10.42.2.0/24"
26+
revision = 1
27+
}
28+
29+
# A way to force replacement of resources if the provider does not want to replace them
30+
# see: https://developer.hashicorp.com/terraform/language/resources/terraform-data#example-usage-data-for-replace_triggered_by
31+
resource "terraform_data" "replacement" {
32+
input = local.revision
2633
}
2734

2835
resource "random_password" "init_secret" {

0 commit comments

Comments
 (0)