Skip to content

Commit

Permalink
arch: support internal lb on AWS
Browse files Browse the repository at this point in the history
  • Loading branch information
3u13r committed Sep 27, 2023
1 parent 28280d8 commit 82c4c0b
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 263 deletions.
6 changes: 3 additions & 3 deletions cli/internal/terraform/terraform/aws/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ resource "aws_eip" "lb" {
# in a future version to support all availability zones in the chosen region
# This should only be done after we migrated to DNS-based addressing for the
# control-plane.
for_each = toset([var.zone])
for_each = var.internal_loadbalancer ? [] : toset([var.zone])
domain = "vpc"
tags = merge(local.tags, { "constellation-ip-endpoint" = each.key == var.zone ? "legacy-primary-zone" : "additional-zone" })
}

resource "aws_lb" "front_end" {
name = "${local.name}-loadbalancer"
internal = false
internal = var.internal_loadbalancer
load_balancer_type = "network"
tags = local.tags
security_groups = [aws_security_group.security_group.id]
Expand All @@ -110,7 +110,7 @@ resource "aws_lb" "front_end" {
for_each = toset([var.zone])
content {
subnet_id = module.public_private_subnet.public_subnet_id[subnet_mapping.key]
allocation_id = aws_eip.lb[subnet_mapping.key].id
allocation_id = var.internal_loadbalancer ? "" : aws_eip.lb[subnet_mapping.key].id
}
}
enable_cross_zone_load_balancing = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ terraform {
}

resource "aws_lb_target_group" "front_end" {
name = var.name
port = var.port
protocol = "TCP"
vpc_id = var.vpc_id
tags = var.tags
name = var.name
port = var.port
protocol = "TCP"
vpc_id = var.vpc_id
tags = var.tags
preserve_client_ip = "false"

health_check {
port = var.port
Expand Down
10 changes: 8 additions & 2 deletions cli/internal/terraform/terraform/aws/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
output "ip" {
value = aws_eip.lb[var.zone].public_ip
value = var.internal_loadbalancer ? aws_lb.front_end.dns_name : aws_lb.front_end.dns_name
}

output "api_server_cert_sans" {
value = sort(concat([aws_eip.lb[var.zone].public_ip, local.wildcard_lb_dns_name], var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
value = sort(
concat(
[
var.internal_loadbalancer ? aws_lb.front_end.dns_name : aws_eip.lb[var.zone].public_ip,
local.wildcard_lb_dns_name
],
var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
}

output "uid" {
Expand Down
6 changes: 6 additions & 0 deletions cli/internal/terraform/terraform/aws/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,9 @@ variable "custom_endpoint" {
default = ""
description = "Custom endpoint to use for the Kubernetes apiserver. If not set, the default endpoint will be used."
}

variable "internal_loadbalancer" {
type = bool
default = false
description = "Use an internal load balancer."
}
56 changes: 2 additions & 54 deletions internal/cloud/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,65 +130,14 @@ func (c *Cloud) InitSecretHash(ctx context.Context) ([]byte, error) {
}

// GetLoadBalancerEndpoint returns the endpoint of the load balancer.
// TODO(malt3): remove old infrastructure code once we have migrated to using DNS as the load balancer endpoint.
func (c *Cloud) GetLoadBalancerEndpoint(ctx context.Context) (host, port string, err error) {
// try new architecture first
uid, err := c.readInstanceTag(ctx, cloud.TagUID)
hostname, err := c.getLoadBalancerDNSName(ctx)
if err != nil {
return "", "", fmt.Errorf("retrieving uid tag: %w", err)
}
describeIPsOutput, err := c.ec2.DescribeAddresses(ctx, &ec2.DescribeAddressesInput{
Filters: []ec2Types.Filter{
{
Name: aws.String(cloud.TagUID),
Values: []string{uid},
},
{
Name: aws.String("constellation-ip-endpoint"),
Values: []string{"legacy-primary-zone"},
},
},
})
if err == nil && len(describeIPsOutput.Addresses) == 1 && describeIPsOutput.Addresses[0].PublicIp != nil {
return *describeIPsOutput.Addresses[0].PublicIp, strconv.FormatInt(constants.KubernetesPort, 10), nil
}
// fallback to old architecture
// this will be removed in the future
hostname, err := c.getLoadBalancerIPOldInfrastructure(ctx)
if err != nil {
return "", "", fmt.Errorf("retrieving load balancer ip: %w", err)
return "", "", fmt.Errorf("retrieving load balancer dns name: %w", err)
}
return hostname, strconv.FormatInt(constants.KubernetesPort, 10), nil
}

// getLoadBalancerIPOldInfrastructure returns the IP of the load balancer.
// This is only used for the old infrastructure.
// This will be removed in the future.
func (c *Cloud) getLoadBalancerIPOldInfrastructure(ctx context.Context) (string, error) {
loadbalancer, err := c.getLoadBalancer(ctx)
if err != nil {
return "", fmt.Errorf("finding Constellation load balancer: %w", err)
}

// TODO(malt3): Add support for multiple availability zones in the lb frontend.
// This can only be done after we have migrated to using DNS as the load balancer endpoint.
// At that point, we don't need to care about the number of availability zones anymore.
if len(loadbalancer.AvailabilityZones) != 1 {
return "", fmt.Errorf("%d availability zones found; expected 1", len(loadbalancer.AvailabilityZones))
}

if len(loadbalancer.AvailabilityZones[0].LoadBalancerAddresses) != 1 {
return "", fmt.Errorf("%d load balancer addresses found; expected 1", len(loadbalancer.AvailabilityZones[0].LoadBalancerAddresses))
}
if loadbalancer.AvailabilityZones[0].LoadBalancerAddresses[0].IpAddress == nil {
return "", errors.New("load balancer address is nil")
}

return *loadbalancer.AvailabilityZones[0].LoadBalancerAddresses[0].IpAddress, nil
}

/*
// TODO(malt3): uncomment and use as soon as we switch the primary endpoint to DNS.
func (c *Cloud) getLoadBalancerDNSName(ctx context.Context) (string, error) {
loadbalancer, err := c.getLoadBalancer(ctx)
if err != nil {
Expand All @@ -199,7 +148,6 @@ func (c *Cloud) getLoadBalancerDNSName(ctx context.Context) (string, error) {
}
return *loadbalancer.DNSName, nil
}
*/

func (c *Cloud) getLoadBalancer(ctx context.Context) (*elasticloadbalancingv2types.LoadBalancer, error) {
uid, err := c.readInstanceTag(ctx, cloud.TagUID)
Expand Down
Loading

0 comments on commit 82c4c0b

Please sign in to comment.