add in-cluster endpoint to terraform output

This commit is contained in:
Leonard Cohnen 2023-10-10 19:11:09 +02:00
parent d2fb17442b
commit e924f234a6
11 changed files with 112 additions and 61 deletions

View File

@ -42,7 +42,7 @@ func extraCiliumValues(provider cloudprovider.Provider, conformanceMode bool, ou
}
}
extraVals["k8sServiceHost"] = output.ClusterEndpoint
extraVals["k8sServiceHost"] = output.InClusterEndpoint
extraVals["k8sServicePort"] = constants.KubernetesPort
if provider == cloudprovider.GCP {
extraVals["ipv4NativeRoutingCIDR"] = output.GCP.IPCidrPod

View File

@ -89,9 +89,13 @@ type Infrastructure struct {
// Unique identifier the cluster's cloud resources are tagged with.
UID string `yaml:"uid"`
// description: |
// Endpoint the cluster can be reached at.
// Endpoint the cluster can be reached at. This is the endpoint that is being used by the CLI.
ClusterEndpoint string `yaml:"clusterEndpoint"`
// description: |
// The Cluster uses to reach itself. This might differ from the ClusterEndpoint in case e.g.,
// an internal load balancer is used.
InClusterEndpoint string `yaml:"inClusterEndpoint"`
// description: |
// Secret used to authenticate the bootstrapping node.
InitSecret HexBytes `yaml:"initSecret"`
// description: |

View File

@ -74,7 +74,7 @@ func init() {
FieldName: "infrastructure",
},
}
InfrastructureDoc.Fields = make([]encoder.Doc, 7)
InfrastructureDoc.Fields = make([]encoder.Doc, 8)
InfrastructureDoc.Fields[0].Name = "uid"
InfrastructureDoc.Fields[0].Type = "string"
InfrastructureDoc.Fields[0].Note = ""
@ -83,33 +83,38 @@ func init() {
InfrastructureDoc.Fields[1].Name = "clusterEndpoint"
InfrastructureDoc.Fields[1].Type = "string"
InfrastructureDoc.Fields[1].Note = ""
InfrastructureDoc.Fields[1].Description = "Endpoint the cluster can be reached at."
InfrastructureDoc.Fields[1].Comments[encoder.LineComment] = "Endpoint the cluster can be reached at."
InfrastructureDoc.Fields[2].Name = "initSecret"
InfrastructureDoc.Fields[2].Type = "HexBytes"
InfrastructureDoc.Fields[1].Description = "Endpoint the cluster can be reached at. This is the endpoint that is being used by the CLI."
InfrastructureDoc.Fields[1].Comments[encoder.LineComment] = "Endpoint the cluster can be reached at. This is the endpoint that is being used by the CLI."
InfrastructureDoc.Fields[2].Name = "inClusterEndpoint"
InfrastructureDoc.Fields[2].Type = "string"
InfrastructureDoc.Fields[2].Note = ""
InfrastructureDoc.Fields[2].Description = "Secret used to authenticate the bootstrapping node."
InfrastructureDoc.Fields[2].Comments[encoder.LineComment] = "Secret used to authenticate the bootstrapping node."
InfrastructureDoc.Fields[3].Name = "apiServerCertSANs"
InfrastructureDoc.Fields[3].Type = "[]string"
InfrastructureDoc.Fields[2].Description = "The Cluster uses to reach itself. This might differ from the ClusterEndpoint in case e.g.,\nan internal load balancer is used."
InfrastructureDoc.Fields[2].Comments[encoder.LineComment] = "The Cluster uses to reach itself. This might differ from the ClusterEndpoint in case e.g.,"
InfrastructureDoc.Fields[3].Name = "initSecret"
InfrastructureDoc.Fields[3].Type = "HexBytes"
InfrastructureDoc.Fields[3].Note = ""
InfrastructureDoc.Fields[3].Description = "description: |\n List of Subject Alternative Names (SANs) to add to the Kubernetes API server certificate.\n If no SANs should be added, this field can be left empty.\n"
InfrastructureDoc.Fields[3].Comments[encoder.LineComment] = "description: |"
InfrastructureDoc.Fields[4].Name = "name"
InfrastructureDoc.Fields[4].Type = "string"
InfrastructureDoc.Fields[3].Description = "Secret used to authenticate the bootstrapping node."
InfrastructureDoc.Fields[3].Comments[encoder.LineComment] = "Secret used to authenticate the bootstrapping node."
InfrastructureDoc.Fields[4].Name = "apiServerCertSANs"
InfrastructureDoc.Fields[4].Type = "[]string"
InfrastructureDoc.Fields[4].Note = ""
InfrastructureDoc.Fields[4].Description = "Name used in the cluster's named resources."
InfrastructureDoc.Fields[4].Comments[encoder.LineComment] = "Name used in the cluster's named resources."
InfrastructureDoc.Fields[5].Name = "azure"
InfrastructureDoc.Fields[5].Type = "Azure"
InfrastructureDoc.Fields[4].Description = "description: |\n List of Subject Alternative Names (SANs) to add to the Kubernetes API server certificate.\n If no SANs should be added, this field can be left empty.\n"
InfrastructureDoc.Fields[4].Comments[encoder.LineComment] = "description: |"
InfrastructureDoc.Fields[5].Name = "name"
InfrastructureDoc.Fields[5].Type = "string"
InfrastructureDoc.Fields[5].Note = ""
InfrastructureDoc.Fields[5].Description = "Values specific to a Constellation cluster running on Azure."
InfrastructureDoc.Fields[5].Comments[encoder.LineComment] = "Values specific to a Constellation cluster running on Azure."
InfrastructureDoc.Fields[6].Name = "gcp"
InfrastructureDoc.Fields[6].Type = "GCP"
InfrastructureDoc.Fields[5].Description = "Name used in the cluster's named resources."
InfrastructureDoc.Fields[5].Comments[encoder.LineComment] = "Name used in the cluster's named resources."
InfrastructureDoc.Fields[6].Name = "azure"
InfrastructureDoc.Fields[6].Type = "Azure"
InfrastructureDoc.Fields[6].Note = ""
InfrastructureDoc.Fields[6].Description = "Values specific to a Constellation cluster running on GCP."
InfrastructureDoc.Fields[6].Comments[encoder.LineComment] = "Values specific to a Constellation cluster running on GCP."
InfrastructureDoc.Fields[6].Description = "Values specific to a Constellation cluster running on Azure."
InfrastructureDoc.Fields[6].Comments[encoder.LineComment] = "Values specific to a Constellation cluster running on Azure."
InfrastructureDoc.Fields[7].Name = "gcp"
InfrastructureDoc.Fields[7].Type = "GCP"
InfrastructureDoc.Fields[7].Note = ""
InfrastructureDoc.Fields[7].Description = "Values specific to a Constellation cluster running on GCP."
InfrastructureDoc.Fields[7].Comments[encoder.LineComment] = "Values specific to a Constellation cluster running on GCP."
GCPDoc.Type = "GCP"
GCPDoc.Comments[encoder.LineComment] = "GCP describes the infra state related to GCP."

View File

@ -181,11 +181,20 @@ func (c *Client) ShowInfrastructure(ctx context.Context, provider cloudprovider.
return state.Infrastructure{}, errors.New("terraform show: no values returned")
}
ipOutput, ok := tfState.Values.Outputs["ip"]
outOfClusterEndpointOutput, ok := tfState.Values.Outputs["out_of_cluster_endpoint"]
if !ok {
return state.Infrastructure{}, errors.New("no IP output found")
return state.Infrastructure{}, errors.New("no out_of_cluster_endpoint output found")
}
ip, ok := ipOutput.Value.(string)
outOfClusterEndpoint, ok := outOfClusterEndpointOutput.Value.(string)
if !ok {
return state.Infrastructure{}, errors.New("invalid type in IP output: not a string")
}
inClusterEndpointOutput, ok := tfState.Values.Outputs["in_cluster_endpoint"]
if !ok {
return state.Infrastructure{}, errors.New("no in_cluster_endpoint output found")
}
inClusterEndpoint, ok := inClusterEndpointOutput.Value.(string)
if !ok {
return state.Infrastructure{}, errors.New("invalid type in IP output: not a string")
}
@ -231,7 +240,8 @@ func (c *Client) ShowInfrastructure(ctx context.Context, provider cloudprovider.
}
res := state.Infrastructure{
ClusterEndpoint: ip,
ClusterEndpoint: outOfClusterEndpoint,
InClusterEndpoint: inClusterEndpoint,
APIServerCertSANs: apiServerCertSANs,
InitSecret: []byte(secret),
UID: uid,

View File

@ -51,6 +51,9 @@ locals {
tags = {
constellation-uid = local.uid,
}
in_cluster_endpoint = aws_lb.front_end.dns_name
out_of_cluster_endpoint = var.internal_load_balancer && var.debug ? module.jump_host[0].ip : local.in_cluster_endpoint
}
resource "random_id" "uid" {

View File

@ -1,15 +1,22 @@
output "ip" {
value = var.internal_load_balancer && var.debug ? module.jump_host[0].ip : aws_lb.front_end.dns_name
output "out_of_cluster_endpoint" {
value = local.out_of_cluster_endpoint
}
output "in_cluster_endpoint" {
value = local.in_cluster_endpoint
}
output "api_server_cert_sans" {
value = sort(
concat(
[
var.internal_load_balancer ? module.jump_host[0].ip : aws_eip.lb[var.zone].public_ip,
local.wildcard_lb_dns_name
],
var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
distinct(
concat(
[
local.in_cluster_endpoint,
local.out_of_cluster_endpoint,
],
var.custom_endpoint == "" ? [] : [var.custom_endpoint],
)
)
)
}
output "uid" {

View File

@ -47,8 +47,8 @@ locals {
// deduce as above
uai_name = element(split("/", var.user_assigned_identity), length(split("/", var.user_assigned_identity)) - 1)
internal_ip = var.debug && var.internal_load_balancer ? module.jump_host[0].ip : azurerm_lb.loadbalancer.frontend_ip_configuration[0].private_ip_address
output_ip = var.internal_load_balancer ? local.internal_ip : azurerm_public_ip.loadbalancer_ip[0].ip_address
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
out_of_cluster_endpoint = var.debug && var.internal_load_balancer ? module.jump_host[0].ip : local.in_cluster_endpoint
}
resource "random_id" "uid" {

View File

@ -1,15 +1,23 @@
output "ip" {
value = local.output_ip
output "out_of_cluster_endpoint" {
value = local.out_of_cluster_endpoint
}
output "in_cluster_endpoint" {
value = local.in_cluster_endpoint
}
output "api_server_cert_sans" {
value = sort(
concat(
[
local.output_ip,
var.internal_load_balancer ? "" : local.wildcard_lb_dns_name
],
var.custom_endpoint == "" ? [] : [var.custom_endpoint])
distinct(
concat(
[
local.in_cluster_endpoint,
local.out_of_cluster_endpoint,
],
var.custom_endpoint == "" ? [] : [var.custom_endpoint],
var.internal_load_balancer ? [] : [local.wildcard_lb_dns_name],
)
)
)
}

View File

@ -57,8 +57,8 @@ locals {
control_plane_instance_groups = [
for control_plane in local.node_groups_by_role["control-plane"] : module.instance_group[control_plane].instance_group
]
internal_ip = var.debug && var.internal_load_balancer ? module.jump_host[0].ip : google_compute_address.loadbalancer_ip_internal[0].address
output_ip = var.internal_load_balancer ? local.internal_ip : google_compute_global_address.loadbalancer_ip[0].address
in_cluster_endpoint = var.internal_load_balancer ? google_compute_address.loadbalancer_ip_internal[0].address : google_compute_global_address.loadbalancer_ip[0].address
out_of_cluster_endpoint = var.debug && var.internal_load_balancer ? module.jump_host[0].ip : local.in_cluster_endpoint
}
resource "random_id" "uid" {
@ -215,6 +215,7 @@ module "loadbalancer_public" {
health_check = each.value.health_check
backend_instance_groups = local.control_plane_instance_groups
ip_address = google_compute_global_address.loadbalancer_ip[0].self_link
frontend_labels = merge(local.labels, { constellation-use = each.value.name })
}
module "loadbalancer_internal" {

View File

@ -1,16 +1,22 @@
output "ip" {
value = local.output_ip
output "out_of_cluster_endpoint" {
value = local.out_of_cluster_endpoint
}
output "in_cluster_endpoint" {
value = local.in_cluster_endpoint
}
output "api_server_cert_sans" {
value = sort(concat([
local.output_ip,
],
var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
}
output "fallback_endpoint" {
value = local.output_ip
value = sort(
distinct(
concat(
[
local.in_cluster_endpoint,
local.out_of_cluster_endpoint,
],
var.custom_endpoint == "" ? [] : [var.custom_endpoint],
)
)
)
}
output "uid" {

View File

@ -212,9 +212,12 @@ func TestCreateCluster(t *testing.T) {
workingState := tfjson.State{
Values: &tfjson.StateValues{
Outputs: map[string]*tfjson.StateOutput{
"ip": {
"out_of_cluster_endpoint": {
Value: "192.0.2.100",
},
"in_cluster_endpoint": {
Value: "192.0.2.101",
},
"initSecret": {
Value: "initSecret",
},
@ -236,9 +239,12 @@ func TestCreateCluster(t *testing.T) {
workingState := tfjson.State{
Values: &tfjson.StateValues{
Outputs: map[string]*tfjson.StateOutput{
"ip": {
"out_of_cluster_endpoint": {
Value: "192.0.2.100",
},
"in_cluster_endpoint": {
Value: "192.0.2.101",
},
"initSecret": {
Value: "initSecret",
},
@ -480,6 +486,7 @@ func TestCreateCluster(t *testing.T) {
assert.Equal("192.0.2.100", infraState.ClusterEndpoint)
assert.Equal(state.HexBytes("initSecret"), infraState.InitSecret)
assert.Equal("12345abc", infraState.UID)
assert.Equal("192.0.2.101", infraState.InClusterEndpoint)
if tc.provider == cloudprovider.Azure {
assert.Equal(tc.expectedAttestationURL, infraState.Azure.AttestationURL)
}