terraform: align infrastructure module attributes (#2703)

* all vars have snail_case

* make iam schema consistent

* infrastructure schema

* terraform: update AWS infrastructure module

* fix ci

* terraform: update AWS infrastructure module

* terraform: update AWS IAM module

* terraform: update Azure Infrastructure module inputs

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: update Azure IAM module

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: update GCP infrastructure module

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: update GCP IAM module

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: update OpenStack Infrastructure module

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: update QEMU Infrastructure module

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform-module: fix input name

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: tidy

* cli: ignore whitespace in Terraform variable tests

* terraform-module: fix AWS output names

* terraform-module: fix output references

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* terraform: rename `api_server_cert_sans`

* Update terraform/infrastructure/aws/modules/public_private_subnet/variables.tf

Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>

* fix self-managed

* terraform: revert AWS modules output file renaming

* terraform: remove duplicate varable declaration

* terraform: rename Azure location field

* ci: adjust output name in self-managed e2e test

* e2e: continuously print output in upgrade test

* e2e: write to output variables

* cli: migrate IAM variable names

* cli: make `location` field optional

---------

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
Co-authored-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>
This commit is contained in:
Adrian Stobbe 2023-12-15 10:36:58 +01:00 committed by GitHub
parent 6f6f28b8cc
commit 9667dfff58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 745 additions and 767 deletions

View file

@ -9,13 +9,10 @@ go_library(
"infrastructure/aws/modules/instance_group/main.tf",
"infrastructure/aws/modules/instance_group/variables.tf",
"infrastructure/aws/modules/jump_host/main.tf",
"infrastructure/aws/modules/jump_host/output.tf",
"infrastructure/aws/modules/jump_host/variables.tf",
"infrastructure/aws/modules/load_balancer_target/main.tf",
"infrastructure/aws/modules/load_balancer_target/output.tf",
"infrastructure/aws/modules/load_balancer_target/variables.tf",
"infrastructure/aws/modules/public_private_subnet/main.tf",
"infrastructure/aws/modules/public_private_subnet/output.tf",
"infrastructure/aws/modules/public_private_subnet/variables.tf",
"infrastructure/aws/outputs.tf",
"infrastructure/aws/variables.tf",
@ -46,17 +43,14 @@ go_library(
"infrastructure/gcp/outputs.tf",
"infrastructure/gcp/variables.tf",
"infrastructure/iam/aws/.terraform.lock.hcl",
"infrastructure/iam/aws/README.md",
"infrastructure/iam/aws/main.tf",
"infrastructure/iam/aws/outputs.tf",
"infrastructure/iam/aws/variables.tf",
"infrastructure/iam/azure/.terraform.lock.hcl",
"infrastructure/iam/azure/README.md",
"infrastructure/iam/azure/main.tf",
"infrastructure/iam/azure/outputs.tf",
"infrastructure/iam/azure/variables.tf",
"infrastructure/iam/gcp/.terraform.lock.hcl",
"infrastructure/iam/gcp/README.md",
"infrastructure/iam/gcp/main.tf",
"infrastructure/iam/gcp/outputs.tf",
"infrastructure/iam/gcp/variables.tf",
@ -78,6 +72,9 @@ go_library(
"infrastructure/qemu/modules/instance_group/variables.tf",
"infrastructure/qemu/outputs.tf",
"infrastructure/qemu/variables.tf",
"infrastructure/aws/modules/jump_host/output.tf",
"infrastructure/aws/modules/load_balancer_target/output.tf",
"infrastructure/aws/modules/public_private_subnet/output.tf",
],
importpath = "github.com/edgelesssys/constellation/v2/terraform",
visibility = ["//visibility:public"],

View file

@ -11,7 +11,6 @@ terraform {
}
}
# Configure the AWS Provider
provider "aws" {
region = var.region
}
@ -19,7 +18,7 @@ provider "aws" {
locals {
uid = random_id.uid.hex
name = "${var.name}-${local.uid}"
initSecretHash = random_password.initSecret.bcrypt_hash
init_secret_hash = random_password.init_secret.bcrypt_hash
cidr_vpc_subnet_nodes = "192.168.176.0/20"
ports_node_range = "30000-32767"
load_balancer_ports = flatten([
@ -38,8 +37,8 @@ locals {
worker : []
}
iam_instance_profile = {
control-plane : var.iam_instance_profile_control_plane
worker : var.iam_instance_profile_worker_nodes
control-plane : var.iam_instance_profile_name_control_plane
worker : var.iam_instance_profile_name_worker_nodes
}
# zones are all availability zones that are used by the node groups
zones = distinct(sort([
@ -61,7 +60,7 @@ resource "random_id" "uid" {
byte_length = 4
}
resource "random_password" "initSecret" {
resource "random_password" "init_secret" {
length = 32
special = true
override_special = "_%@"
@ -172,7 +171,7 @@ resource "aws_cloudwatch_log_group" "log_group" {
module "load_balancer_targets" {
for_each = { for port in local.load_balancer_ports : port.name => port }
source = "./modules/load_balancer_target"
name = "${local.name}-${each.value.name}"
base_name = "${local.name}-${each.value.name}"
port = each.value.port
healthcheck_protocol = each.value.health_check
healthcheck_path = each.value.name == "kubernetes" ? "/readyz" : ""
@ -191,7 +190,7 @@ module "instance_group" {
uid = local.uid
instance_type = each.value.instance_type
initial_count = each.value.initial_count
image_id = var.ami
image_id = var.image_id
state_disk_type = each.value.disk_type
state_disk_size = each.value.disk_size
target_group_arns = local.target_group_arns[each.value.role]
@ -205,7 +204,7 @@ module "instance_group" {
{ constellation-role = each.value.role },
{ constellation-node-group = each.key },
{ constellation-uid = local.uid },
{ constellation-init-secret-hash = local.initSecretHash },
{ constellation-init-secret-hash = local.init_secret_hash },
{ "kubernetes.io/cluster/${local.name}" = "owned" }
)
}
@ -217,42 +216,6 @@ module "jump_host" {
subnet_id = module.public_private_subnet.public_subnet_id[var.zone]
lb_internal_ip = aws_lb.front_end.dns_name
ports = [for port in local.load_balancer_ports : port.port]
iam_instance_profile = var.iam_instance_profile_worker_nodes
security_groups = [aws_security_group.security_group.id]
}
# TODO(31u3r): Remove once 2.12 is released
moved {
from = module.load_balancer_target_konnectivity
to = module.load_balancer_targets["konnectivity"]
}
moved {
from = module.load_balancer_target_verify
to = module.load_balancer_targets["verify"]
}
moved {
from = module.load_balancer_target_recovery
to = module.load_balancer_targets["recovery"]
}
moved {
from = module.load_balancer_target_join
to = module.load_balancer_targets["join"]
}
moved {
from = module.load_balancer_target_debugd[0]
to = module.load_balancer_targets["debugd"]
}
moved {
from = module.load_balancer_target_kubernetes
to = module.load_balancer_targets["kubernetes"]
}
moved {
from = module.load_balancer_target_bootstrapper
to = module.load_balancer_targets["bootstrapper"]
iam_instance_profile = var.iam_instance_profile_name_worker_nodes
}

View file

@ -10,7 +10,7 @@ variable "node_group_name" {
variable "role" {
type = string
description = "The role of the instance group."
description = "Role of the instance group."
validation {
condition = contains(["control-plane", "worker"], var.role)
error_message = "The role has to be 'control-plane' or 'worker'."
@ -19,7 +19,7 @@ variable "role" {
variable "uid" {
type = string
description = "UID of the cluster. This is used for tags."
description = "Unique Identifier (UID) of the cluster."
}
variable "instance_type" {
@ -34,7 +34,7 @@ variable "initial_count" {
variable "image_id" {
type = string
description = "Image ID for the nodes."
description = "Amazon Machine Image (AMI) ID for the cluster's nodes."
}
variable "state_disk_type" {
@ -64,18 +64,18 @@ variable "iam_instance_profile" {
variable "security_groups" {
type = list(string)
description = "List of IDs of the security groups for an instance."
description = "List of security group IDs for an instance."
}
variable "tags" {
type = map(string)
description = "The tags to add to the instance group."
description = "Tags to add to the instance group."
}
variable "enable_snp" {
type = bool
default = true
description = "Enable AMD SEV SNP. Setting this to true sets the cpu-option AmdSevSnp to enable."
description = "Enable AMD SEV-SNP for the instances."
}
variable "zone" {

View file

@ -7,7 +7,6 @@ terraform {
}
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
@ -55,5 +54,4 @@ iptables -t nat -A PREROUTING -p tcp --dport ${port} -j DNAT --to-destination $$
iptables -t nat -A POSTROUTING -p tcp -d $${lb_ip} --dport ${port} -j SNAT --to-source $${internal_ip}
%{endfor~}
EOF
}

View file

@ -1,3 +1,4 @@
output "ip" {
value = aws_instance.jump_host.public_ip
value = aws_instance.jump_host.public_ip
description = "Public IP of the jump host."
}

View file

@ -1,28 +1,28 @@
variable "base_name" {
description = "Base name of the jump host"
type = string
}
variable "subnet_id" {
description = "Subnet ID to deploy the jump host into"
type = string
}
variable "lb_internal_ip" {
description = "Internal IP of the load balancer"
type = string
}
variable "iam_instance_profile" {
description = "IAM instance profile to attach to the jump host"
description = "Base name of the jump host."
type = string
}
variable "ports" {
description = "Ports to forward to the load balancer"
description = "Ports to forward to the load balancer."
type = list(number)
}
variable "subnet_id" {
description = "Subnet ID to deploy the jump host into."
type = string
}
variable "lb_internal_ip" {
description = "Internal IP of the load balancer."
type = string
}
variable "iam_instance_profile" {
description = "IAM instance profile to attach to the jump host."
type = string
}
variable "security_groups" {
type = list(string)
description = "List of IDs of the security groups for an instance."

View file

@ -8,7 +8,7 @@ terraform {
}
resource "aws_lb_target_group" "front_end" {
name = var.name
name = var.base_name
port = var.port
protocol = "TCP"
vpc_id = var.vpc_id

View file

@ -1,3 +1,4 @@
output "target_group_arn" {
value = aws_lb_target_group.front_end.arn
value = aws_lb_target_group.front_end.arn
description = "ARN of the load balancer target group."
}

View file

@ -1,6 +1,6 @@
variable "name" {
variable "base_name" {
type = string
description = "Name of the load balancer target."
description = "Base name of the load balancer target."
}
variable "port" {
@ -32,5 +32,5 @@ variable "healthcheck_path" {
variable "tags" {
type = map(string)
description = "The tags to add to the loadbalancer."
description = "Tags to add to the loadbalancer."
}

View file

@ -3,6 +3,7 @@ output "private_subnet_id" {
for az in data.aws_availability_zone.all :
az.name => aws_subnet.private[az.name].id
}
description = "Map of availability zones to private subnet id."
}
output "public_subnet_id" {

View file

@ -1,6 +1,6 @@
variable "name" {
type = string
description = "Name of your Constellation, which is used as a prefix for tags."
description = "Name of the Constellation cluster."
}
variable "vpc_id" {
@ -30,5 +30,5 @@ variable "cidr_vpc_subnet_internet" {
variable "tags" {
type = map(string)
description = "The tags to add to the resource."
description = "Tags to add to the resource."
}

View file

@ -1,10 +1,15 @@
# Outputs common to all CSPs
output "out_of_cluster_endpoint" {
value = local.out_of_cluster_endpoint
value = local.out_of_cluster_endpoint
description = "External endpoint for the Kubernetes API server. Only varies from the `in_cluster_endpoint` when using an internal load balancer."
}
output "in_cluster_endpoint" {
value = local.in_cluster_endpoint
value = local.in_cluster_endpoint
description = "Internal endpoint for the Kubernetes API server."
}
output "api_server_cert_sans" {
value = sort(
distinct(
@ -17,21 +22,26 @@ output "api_server_cert_sans" {
)
)
)
description = "List of additional Subject Alternative Names (SANs) for the API server certificate."
}
output "uid" {
value = local.uid
value = local.uid
description = "Unique Identifier (UID) of the cluster."
}
output "initSecret" {
value = random_password.initSecret.result
sensitive = true
output "init_secret" {
value = random_password.init_secret.result
sensitive = true
description = "Initialization secret to authenticate the bootstrapping node."
}
output "name" {
value = local.name
value = local.name
description = "Unique name of the Constellation cluster, comprised by name and UID."
}
output "ip_cidr_nodes" {
value = local.cidr_vpc_subnet_nodes
output "ip_cidr_node" {
value = local.cidr_vpc_subnet_nodes
description = "CIDR block of the node network."
}

View file

@ -1,13 +1,15 @@
# Variables common to all CSPs
variable "name" {
type = string
description = "Name of your Constellation"
description = "Name of the Constellation cluster."
validation {
condition = length(var.name) <= 10
error_message = "The length of the name of the Constellation must be <= 10 characters"
error_message = "The length of the name of the Constellation must be <= 10 characters."
}
validation {
condition = var.name == lower(var.name)
error_message = "The name of the Constellation must be in lowercase"
error_message = "The name of the Constellation must be in lowercase."
}
}
@ -27,39 +29,53 @@ variable "node_groups" {
}
}
variable "iam_instance_profile_worker_nodes" {
variable "image_id" {
type = string
description = "Name of the IAM instance profile for worker nodes"
}
variable "iam_instance_profile_control_plane" {
type = string
description = "Name of the IAM instance profile for control plane nodes"
}
variable "ami" {
type = string
description = "AMI ID"
description = "Amazon Machine Image (AMI) ID for the cluster's nodes."
validation {
condition = length(var.ami) > 4 && substr(var.ami, 0, 4) == "ami-"
error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"."
condition = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-"
error_message = "The \"image_id\" value must be a valid AMI ID, starting with \"ami-\"."
}
}
variable "region" {
type = string
description = "The AWS region to create the cluster in"
}
variable "zone" {
type = string
description = "The AWS availability zone name to create the cluster in"
}
variable "debug" {
type = bool
default = false
description = "Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
description = "DO NOT USE IN PRODUCTION. Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes API server. If not set, the default endpoint will be used."
}
variable "internal_load_balancer" {
type = bool
default = false
description = "Whether to use an internal load balancer for the cluster."
}
# AWS-specific variables
variable "iam_instance_profile_name_worker_nodes" {
type = string
description = "Name of the IAM instance profile for worker nodes."
}
variable "iam_instance_profile_name_control_plane" {
type = string
description = "Name of the IAM instance profile for control plane nodes."
}
variable "region" {
type = string
description = "AWS region to create the cluster in."
}
variable "zone" {
type = string
description = "AWS availability zone name to create the cluster in."
}
variable "enable_snp" {
@ -67,15 +83,3 @@ variable "enable_snp" {
default = true
description = "Enable AMD SEV SNP. Setting this to true sets the cpu-option AmdSevSnp to enable."
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes apiserver. If not set, the default endpoint will be used."
}
variable "internal_load_balancer" {
type = bool
default = false
description = "Use an internal load balancer."
}

View file

@ -20,9 +20,9 @@ provider "azurerm" {
}
locals {
uid = random_id.uid.hex
name = "${var.name}-${local.uid}"
initSecretHash = random_password.initSecret.bcrypt_hash
uid = random_id.uid.hex
name = "${var.name}-${local.uid}"
init_secret_hash = random_password.init_secret.bcrypt_hash
tags = {
constellation-uid = local.uid,
}
@ -54,7 +54,7 @@ resource "random_id" "uid" {
byte_length = 4
}
resource "random_password" "initSecret" {
resource "random_password" "init_secret" {
length = 32
special = true
override_special = "_%@"
@ -245,7 +245,7 @@ module "scale_set_group" {
zones = each.value.zones
tags = merge(
local.tags,
{ constellation-init-secret-hash = local.initSecretHash },
{ constellation-init-secret-hash = local.init_secret_hash },
{ constellation-maa-url = var.create_maa ? azurerm_attestation_provider.attestation_provider[0].attestation_uri : "" },
)

View file

@ -1,3 +1,4 @@
output "ip" {
value = azurerm_linux_virtual_machine.jump_host.public_ip_address
value = azurerm_linux_virtual_machine.jump_host.public_ip_address
description = "Public IP of the jump host."
}

View file

@ -1,29 +1,29 @@
variable "base_name" {
description = "Base name of the jump host"
description = "Base name of the jump host."
type = string
}
variable "ports" {
description = "Ports to forward to the load balancer"
description = "Ports to forward to the load balancer."
type = list(number)
}
variable "resource_group" {
description = "Resource group name to deploy the jump host into"
type = string
}
variable "location" {
description = "Location to deploy the jump host into"
type = string
}
variable "subnet_id" {
description = "Subnet ID to deploy the jump host into"
description = "Subnet ID to deploy the jump host into."
type = string
}
variable "lb_internal_ip" {
description = "Internal IP of the load balancer"
description = "Internal IP of the load balancer."
type = string
}
variable "resource_group" {
description = "Resource group name to deploy the jump host into."
type = string
}
variable "location" {
description = "Location to deploy the jump host into."
type = string
}

View file

@ -1,4 +1,4 @@
output "backendpool_id" {
value = azurerm_lb_backend_address_pool.backend_pool.id
description = "The ID of the created backend pool."
description = "ID of the created backend address pool."
}

View file

@ -1,17 +1,17 @@
variable "name" {
type = string
default = "constell"
description = "Base name of the cluster."
description = "Name of the Constellation cluster."
}
variable "frontend_ip_configuration_name" {
type = string
description = "The name of the frontend IP configuration to use for the load balancer."
description = "Name of the frontend IP configuration to use for the load balancer."
}
variable "loadbalancer_id" {
type = string
description = "The ID of the load balancer to add the backend to."
description = "ID of the load balancer to add the backend to."
}
variable "ports" {
@ -21,5 +21,5 @@ variable "ports" {
health_check_protocol = string
path = string
}))
description = "The ports to add to the backend. Protocol can be either 'Tcp' or 'Https'. Path is only used for 'Https' protocol and can otherwise be null."
description = "Ports to add to the backend. Healtch check protocol can be either 'Tcp' or 'Https'. Path is only used for the 'Https' protocol and can otherwise be null."
}

View file

@ -24,6 +24,7 @@ locals {
resource "random_id" "uid" {
byte_length = 4
}
resource "random_password" "password" {
length = 16
min_lower = 1
@ -92,7 +93,6 @@ resource "azurerm_linux_virtual_machine_scale_set" "scale_set" {
}
}
data_disk {
storage_account_type = var.state_disk_type
disk_size_gb = var.state_disk_size

View file

@ -1,6 +1,6 @@
variable "base_name" {
type = string
description = "Base name of the instance group."
description = "Base name of the scale set."
}
variable "node_group_name" {
@ -10,7 +10,7 @@ variable "node_group_name" {
variable "role" {
type = string
description = "The role of the instance group."
description = "Role of the instance group."
validation {
condition = contains(["control-plane", "worker"], var.role)
error_message = "The role has to be 'control-plane' or 'worker'."
@ -19,7 +19,7 @@ variable "role" {
variable "tags" {
type = map(string)
description = "Tags to include in the scale_set."
description = "Tags to include in the scale set."
}
variable "zones" {
@ -30,59 +30,59 @@ variable "zones" {
variable "initial_count" {
type = number
description = "The number of instances in this scale set."
description = "Number of instances in this scale set."
}
variable "instance_type" {
type = string
description = "The Azure instance type to deploy."
description = "Azure instance type to deploy."
}
variable "state_disk_size" {
type = number
default = 30
description = "The size of the state disk in GB."
description = "Disk size for the state disk of the nodes [GB]."
}
variable "resource_group" {
type = string
description = "The name of the Azure resource group to create the Constellation cluster in."
description = "Name of the Azure resource group to create the Constellation cluster in."
}
variable "location" {
type = string
description = "The Azure location to deploy the cluster in."
description = "Azure location to deploy the cluster in."
}
variable "image_id" {
type = string
description = "The image to use for the cluster nodes."
description = "OS Image reference for the cluster's nodes."
}
variable "user_assigned_identity" {
type = string
description = "The name of the user assigned identity to attache to the nodes of the cluster."
description = "Name of the user assigned identity to attache to the nodes of the cluster."
}
variable "state_disk_type" {
type = string
default = "Premium_LRS"
description = "The type of the state disk."
description = "Type of the state disk."
}
variable "network_security_group_id" {
type = string
description = "The ID of the network security group to use for the scale set."
description = "ID of the network security group to use for the scale set."
}
variable "backend_address_pool_ids" {
type = list(string)
description = "The IDs of the backend address pools to use for the scale set."
description = "IDs of the backend address pools to use for the scale set."
}
variable "subnet_id" {
type = string
description = "The ID of the subnet to use for the scale set."
description = "ID of the subnet to use for the scale set."
}
variable "confidential_vm" {

View file

@ -1,9 +1,13 @@
# Outputs common to all CSPs
output "out_of_cluster_endpoint" {
value = local.out_of_cluster_endpoint
value = local.out_of_cluster_endpoint
description = "External endpoint for the Kubernetes API server. Only varies from the `in_cluster_endpoint` when using an internal load balancer."
}
output "in_cluster_endpoint" {
value = local.in_cluster_endpoint
value = local.in_cluster_endpoint
description = "Internal endpoint for the Kubernetes API server."
}
output "api_server_cert_sans" {
@ -19,46 +23,58 @@ output "api_server_cert_sans" {
)
)
)
description = "List of Subject Alternative Names (SANs) for the API server certificate."
}
output "uid" {
value = local.uid
value = local.uid
description = "Unique Identifier (UID) of the cluster."
}
output "initSecret" {
value = random_password.initSecret.result
sensitive = true
}
output "attestationURL" {
value = var.create_maa ? azurerm_attestation_provider.attestation_provider[0].attestation_uri : ""
}
output "network_security_group_name" {
value = azurerm_network_security_group.security_group.name
}
output "loadbalancer_name" {
value = azurerm_lb.loadbalancer.name
}
output "user_assigned_identity_client_id" {
value = data.azurerm_user_assigned_identity.uaid.client_id
}
output "resource_group" {
value = var.resource_group
}
output "subscription_id" {
value = data.azurerm_subscription.current.subscription_id
output "init_secret" {
value = random_password.init_secret.result
sensitive = true
description = "Initialization secret to authenticate the bootstrapping node."
}
output "name" {
value = local.name
value = local.name
description = "Unique name of the Constellation cluster, comprised by name and UID."
}
output "ip_cidr_nodes" {
value = local.cidr_vpc_subnet_nodes
output "ip_cidr_node" {
value = local.cidr_vpc_subnet_nodes
description = "CIDR block of the node network."
}
# Azure-specific outputs
output "attestation_url" {
value = var.create_maa ? azurerm_attestation_provider.attestation_provider[0].attestation_uri : ""
description = "URL of the cluster's Microsoft Azure Attestation (MAA) provider."
}
output "network_security_group_name" {
value = azurerm_network_security_group.security_group.name
description = "Name of the cluster's network security group."
}
output "loadbalancer_name" {
value = azurerm_lb.loadbalancer.name
description = "Name of the cluster's load balancer."
}
output "user_assigned_identity_client_id" {
value = data.azurerm_user_assigned_identity.uaid.client_id
description = "Client ID of the user assigned identity used within the cluster."
}
output "resource_group" {
value = var.resource_group
description = "Name of the resource group the cluster resides in."
}
output "subscription_id" {
value = data.azurerm_subscription.current.subscription_id
description = "ID of the Azure subscription the cluster resides in."
}

View file

@ -1,6 +1,8 @@
# Variables common to all CSPs
variable "name" {
type = string
description = "Base name of the cluster."
description = "Name of the Constellation cluster."
}
variable "node_groups" {
@ -19,26 +21,40 @@ variable "node_groups" {
}
}
variable "location" {
type = string
description = "The Azure location to deploy the cluster in."
}
variable "image_id" {
type = string
description = "The image to use for the cluster nodes."
}
variable "create_maa" {
type = bool
default = false
description = "Whether to create a Microsoft Azure attestation provider."
description = "OS image reference for the cluster's nodes."
}
variable "debug" {
type = bool
default = false
description = "Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
description = "DO NOT USE IN PRODUCTION. Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes API server. If not set, the default endpoint will be used."
}
variable "internal_load_balancer" {
type = bool
default = false
description = "Whether to use an internal load balancer for the cluster."
}
# Azure-specific variables
variable "location" {
type = string
description = "Azure location to deploy the cluster in."
}
variable "create_maa" {
type = bool
default = false
description = "Whether to create a Microsoft Azure Attestation (MAA) provider."
}
variable "confidential_vm" {
@ -55,23 +71,12 @@ variable "secure_boot" {
variable "resource_group" {
type = string
description = "The name of the Azure resource group to create the Constellation cluster in."
description = "Name of the Azure resource group to create the cluster in."
}
variable "user_assigned_identity" {
type = string
description = "The name of the user assigned identity to attach to the nodes of the cluster. Should be of format: /subscriptions/$ID/resourceGroups/$RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$NAME"
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes apiserver. If not set, the default endpoint will be used."
}
variable "internal_load_balancer" {
type = bool
default = false
description = "Whether to use an internal load balancer for the Constellation."
description = "Name of the user assigned identity to attach to the nodes of the cluster. Should be of format: /subscriptions/$ID/resourceGroups/$RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$NAME"
}
variable "marketplace_image" {
@ -82,5 +87,5 @@ variable "marketplace_image" {
version = string
})
default = null
description = "Marketplace image to use for the cluster nodes."
description = "Marketplace image for the cluster's nodes."
}

View file

@ -30,9 +30,9 @@ provider "google-beta" {
}
locals {
uid = random_id.uid.hex
name = "${var.name}-${local.uid}"
initSecretHash = random_password.initSecret.bcrypt_hash
uid = random_id.uid.hex
name = "${var.name}-${local.uid}"
init_secret_hash = random_password.init_secret.bcrypt_hash
labels = {
constellation-uid = local.uid,
}
@ -55,7 +55,7 @@ locals {
for name, node_group in var.node_groups : node_group.role => name...
}
control_plane_instance_groups = [
for control_plane in local.node_groups_by_role["control-plane"] : module.instance_group[control_plane].instance_group
for control_plane in local.node_groups_by_role["control-plane"] : module.instance_group[control_plane].instance_group_url
]
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
@ -65,7 +65,7 @@ resource "random_id" "uid" {
byte_length = 4
}
resource "random_password" "initSecret" {
resource "random_password" "init_secret" {
length = 32
special = true
override_special = "_%@"
@ -187,7 +187,7 @@ module "instance_group" {
debug = var.debug
named_ports = each.value.role == "control-plane" ? local.control_plane_named_ports : []
labels = local.labels
init_secret_hash = local.initSecretHash
init_secret_hash = local.init_secret_hash
custom_endpoint = var.custom_endpoint
}

View file

@ -1,3 +1,4 @@
output "instance_group" {
value = google_compute_instance_group_manager.instance_group_manager.instance_group
output "instance_group_url" {
value = google_compute_instance_group_manager.instance_group_manager.instance_group
description = "Full URL of the instance group."
}

View file

@ -10,7 +10,7 @@ variable "node_group_name" {
variable "role" {
type = string
description = "The role of the instance group."
description = "Role of the instance group."
validation {
condition = contains(["control-plane", "worker"], var.role)
error_message = "The role has to be 'control-plane' or 'worker'."
@ -19,7 +19,7 @@ variable "role" {
variable "uid" {
type = string
description = "UID of the cluster. This is used for tags."
description = "Unique Identifier (UID) of the cluster."
}
variable "labels" {
@ -35,22 +35,22 @@ variable "instance_type" {
variable "initial_count" {
type = number
description = "Number of instances in the instance group."
description = "Number of instances in the group."
}
variable "image_id" {
type = string
description = "Image ID for the nodes."
description = "OS Image reference for the cluster's nodes."
}
variable "disk_size" {
type = number
description = "Disk size for the nodes, in GB."
description = "Disk size for the state disk of the nodes [GB]."
}
variable "disk_type" {
type = string
description = "Disk type for the nodes. Has to be 'pd-standard' or 'pd-ssd'."
description = "Disk type for the nodes. Has to be either 'pd-standard' or 'pd-ssd'."
}
variable "network" {
@ -65,12 +65,12 @@ variable "subnetwork" {
variable "kube_env" {
type = string
description = "Kubernetes env."
description = "Value of the \"kube-env\" metadata key."
}
variable "init_secret_hash" {
type = string
description = "Hash of the init secret."
description = "BCrypt Hash of the initialization secret."
}
variable "named_ports" {
@ -82,7 +82,7 @@ variable "named_ports" {
variable "debug" {
type = bool
default = false
description = "Enable debug mode. This will enable serial port access on the instances."
description = "DO NOT USE IN PRODUCTION. Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
}
variable "alias_ip_range_name" {
@ -97,5 +97,5 @@ variable "zone" {
variable "custom_endpoint" {
type = string
description = "Custom endpoint to use for the Kubernetes apiserver. If not set, the default endpoint will be used."
description = "Custom endpoint to use for the Kubernetes API server. If not set, the default endpoint will be used."
}

View file

@ -5,22 +5,22 @@ variable "name" {
variable "region" {
type = string
description = "The region where the load balancer will be created."
description = "Region to create the load balancer in."
}
variable "network" {
type = string
description = "The network to which all network resources will be attached."
description = "Network to which network resources will be attached."
}
variable "backend_subnet" {
type = string
description = "The subnet to which all backend network resources will be attached."
description = "Subnet to which backend network resources will be attached."
}
variable "health_check" {
type = string
description = "The type of the health check. 'HTTPS' or 'TCP'."
description = "Type of the health check. Can either be 'HTTPS' or 'TCP'."
validation {
condition = contains(["HTTPS", "TCP"], var.health_check)
error_message = "Health check must be either 'HTTPS' or 'TCP'."
@ -29,22 +29,22 @@ variable "health_check" {
variable "port" {
type = string
description = "The port on which to listen for incoming traffic."
description = "Port to listen on for incoming traffic."
}
variable "backend_port_name" {
type = string
description = "Name of backend port. The same name should appear in the instance groups referenced by this service."
description = "Name of the load balancer's backend port. The same name should appear in the instance groups referenced by this service."
}
variable "backend_instance_group" {
type = string
description = "The URL of the instance group resource from which the load balancer will direct traffic."
description = "Full URL of the instance group resource from which the load balancer will direct traffic."
}
variable "ip_address" {
type = string
description = "The IP address that this forwarding rule serves."
description = "IP address that this forwarding rule serves."
}
variable "frontend_labels" {

View file

@ -12,7 +12,6 @@ terraform {
}
}
data "google_compute_image" "image_ubuntu" {
family = "ubuntu-2204-lts"
project = "ubuntu-os-cloud"
@ -47,7 +46,7 @@ resource "google_compute_instance" "vm_instance" {
metadata_startup_script = <<EOF
#!/bin/bash
set -x
set -x
# Uncomment to create user with password
# useradd -m user
@ -69,5 +68,4 @@ iptables -t nat -A PREROUTING -p tcp --dport ${port} -j DNAT --to-destination ${
iptables -t nat -A POSTROUTING -p tcp -d ${var.lb_internal_ip} --dport ${port} -j SNAT --to-source $${internal_ip}
%{endfor~}
EOF
}

View file

@ -1,3 +1,4 @@
output "ip" {
value = google_compute_instance.vm_instance.network_interface[0].access_config[0].nat_ip
value = google_compute_instance.vm_instance.network_interface[0].access_config[0].nat_ip
description = "Public IP address of the jump host."
}

View file

@ -1,22 +1,22 @@
variable "base_name" {
type = string
description = "Base name of the instance group."
description = "Base name of the jump host."
}
variable "labels" {
type = map(string)
default = {}
description = "Labels to apply to the instance group."
description = "Labels to apply to the jump host."
}
variable "subnetwork" {
type = string
description = "Name of the subnetwork to use."
description = "Subnetwork to deplyo the jump host into."
}
variable "zone" {
type = string
description = "Zone to deploy the instance group in."
description = "Zone to deploy the jump host into."
}
variable "lb_internal_ip" {

View file

@ -1,35 +1,35 @@
variable "name" {
type = string
description = "Base name of the load balancer."
description = "Name of the Constellation cluster."
}
variable "health_check" {
type = string
description = "The type of the health check. 'HTTPS' or 'TCP'."
description = "Type of the health check. Can either be 'HTTPS' or 'TCP'."
}
variable "backend_port_name" {
type = string
description = "Name of backend port. The same name should appear in the instance groups referenced by this service."
description = "Name of the load balancer's backend port. The same name should appear in the instance groups referenced by this service."
}
variable "backend_instance_groups" {
type = list(string)
description = "The URLs of the instance group resources from which the load balancer will direct traffic."
description = "URLs of the instance group resources from which the load balancer will direct traffic."
}
variable "ip_address" {
type = string
description = "The IP address that this forwarding rule serves. An address can be specified either by a literal IP address or a reference to an existing Address resource."
description = "IP address that this forwarding rule serves. An address can be specified either by a literal IP address or a reference to an existing Address resource."
}
variable "port" {
type = number
description = "The port on which to listen for incoming traffic."
description = "Port to listen on for incoming traffic."
}
variable "frontend_labels" {
type = map(string)
default = {}
description = "Labels to apply to the forwarding rule."
description = "Labels to apply to the load balancer's forwarding rule."
}

View file

@ -1,9 +1,13 @@
# Outputs common to all CSPs
output "out_of_cluster_endpoint" {
value = local.out_of_cluster_endpoint
value = local.out_of_cluster_endpoint
description = "External endpoint for the Kubernetes API server. Only varies from the `in_cluster_endpoint` when using an internal load balancer."
}
output "in_cluster_endpoint" {
value = local.in_cluster_endpoint
value = local.in_cluster_endpoint
description = "Internal endpoint for the Kubernetes API server."
}
output "api_server_cert_sans" {
value = sort(
@ -17,29 +21,38 @@ output "api_server_cert_sans" {
)
)
)
description = "List of Subject Alternative Names (SANs) for the API server certificate."
}
output "uid" {
value = local.uid
value = local.uid
description = "Unique Identifier (UID) of the cluster."
}
output "initSecret" {
value = random_password.initSecret.result
sensitive = true
}
output "project" {
value = var.project
}
output "ip_cidr_nodes" {
value = local.cidr_vpc_subnet_nodes
}
output "ip_cidr_pods" {
value = local.cidr_vpc_subnet_pods
output "init_secret" {
value = random_password.init_secret.result
sensitive = true
description = "Initialization secret to authenticate the bootstrapping node."
}
output "name" {
value = local.name
value = local.name
description = "Unique name of the Constellation cluster, comprised by name and UID."
}
output "ip_cidr_node" {
value = local.cidr_vpc_subnet_nodes
description = "CIDR block of the node network."
}
# GCP-specific outputs
output "project" {
value = var.project
description = "The GCP project the cluster is deployed in."
}
output "ip_cidr_pod" {
value = local.cidr_vpc_subnet_pods
description = "CIDR block of the pod network."
}

View file

@ -1,7 +1,8 @@
# Variables common to all CSPs
variable "name" {
type = string
default = "constell"
description = "Base name of the cluster."
description = "Name of the Constellation cluster."
}
variable "node_groups" {
@ -20,40 +21,42 @@ variable "node_groups" {
}
}
variable "project" {
type = string
description = "The GCP project to deploy the cluster in."
}
variable "region" {
type = string
description = "The GCP region to deploy the cluster in."
}
variable "zone" {
type = string
description = "The GCP zone to deploy the cluster in."
}
variable "image_id" {
type = string
description = "The GCP image to use for the cluster nodes."
description = "OS image reference for the cluster's nodes."
}
variable "debug" {
type = bool
default = false
description = "Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
description = "DO NOT USE IN PRODUCTION. Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes apiserver. If not set, the default endpoint will be used."
description = "Custom endpoint to use for the Kubernetes API server. If not set, the default endpoint will be used."
}
variable "internal_load_balancer" {
type = bool
default = false
description = "Enable internal load balancer. This can only be enabled if the control-plane is deployed in one zone."
description = "Whether to use an internal load balancer for the cluster."
}
# GCP-specific variables
variable "project" {
type = string
description = "GCP project to deploy the cluster in."
}
variable "region" {
type = string
description = "GCP region to deploy the cluster in."
}
variable "zone" {
type = string
description = "GCP zone to deploy the cluster in."
}

View file

@ -1,24 +0,0 @@
# IAM instance profiles for AWS
This terraform script creates the necessary profiles that need to be attached to Constellation nodes.
You can create the profiles with the following commands:
```sh
mkdir constellation_aws_iam
cd constellation_aws_iam
curl --remote-name-all https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/terraform/aws/iam/{main,output,variables}.tf
terraform init
terraform apply -auto-approve -var name_prefix=my_constellation
```
You can either get the profile names from the Terraform output values `control_plane_instance_profile` and `worker_nodes_instance_profile` and manually add them to your Constellation configuration file.
Or you can do this with a `yq` command:
```sh
yq -i "
.provider.aws.iamProfileControlPlane = $(terraform output control_plane_instance_profile) |
.provider.aws.iamProfileWorkerNodes = $(terraform output worker_nodes_instance_profile)
" path/to/constellation-conf.yaml
```

View file

@ -7,7 +7,6 @@ terraform {
}
}
# Configure the AWS Provider
provider "aws" {
region = var.region
}

View file

@ -1,7 +1,9 @@
output "control_plane_instance_profile" {
value = aws_iam_instance_profile.control_plane_instance_profile.name
output "iam_instance_profile_name_control_plane" {
value = aws_iam_instance_profile.control_plane_instance_profile.name
description = "Name of the control plane's instance profile."
}
output "worker_nodes_instance_profile" {
value = aws_iam_instance_profile.worker_node_instance_profile.name
output "iam_instance_profile_name_worker_nodes" {
value = aws_iam_instance_profile.worker_node_instance_profile.name
description = "Name of the worker nodes' instance profile"
}

View file

@ -1,10 +1,10 @@
variable "name_prefix" {
type = string
description = "Prefix for all resources"
description = "Name prefix to use on named resources."
}
variable "region" {
type = string
description = "AWS region"
description = "AWS region."
default = "us-east-2"
}

View file

@ -1,32 +0,0 @@
# Terraform Azure IAM creation
This terraform configuration creates the necessary Azure resources that need to be available to host a Constellation cluster.
You can create the resources with the following commands:
```sh
mkdir constellation_azure_iam
cd constellation_azure_iam
curl --remote-name-all https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/terraform/azure/iam/{main.tf,output.tf,variables.tf,.terraform.lock.hcl}
terraform init
terraform apply
```
The following terraform output values are available (with their corresponding keys in the Constellation configuration file):
- `subscription_id` (subscription)
- `tenant_id` (tenant)
- `uami_id` (userAssignedIdentity)
You can either get the profile names from the Terraform output and manually add them to your Constellation configuration file according to our [Documentation](https://docs.edgeless.systems/constellation/getting-started/first-steps).
Or you can do this with a `yq` command:
```sh
yq -i "
.provider.azure.subscription = $(terraform output subscription_id) |
.provider.azure.tenant = $(terraform output tenant_id) |
.provider.azure.userAssignedIdentity = $(terraform output uami_id) |
" path/to/constellation-conf.yaml
```
Where `path/to/constellation-conf.yaml` is the path to your Constellation configuration file.

View file

@ -28,24 +28,24 @@ provider "azuread" {
# Access current subscription (available via Azure CLI)
data "azurerm_subscription" "current" {}
# # Access current AzureAD configuration
# Access current AzureAD configuration
data "azuread_client_config" "current" {}
# Create base resource group
resource "azurerm_resource_group" "base_resource_group" {
name = var.resource_group_name
location = var.region
location = var.location
}
# Create identity resource group
resource "azurerm_resource_group" "identity_resource_group" {
name = "${var.resource_group_name}-identity"
location = var.region
location = var.location
}
# Create managed identity
resource "azurerm_user_assigned_identity" "identity_uami" {
location = var.region
location = var.location
name = var.service_principal_name
resource_group_name = azurerm_resource_group.identity_resource_group.name
}

View file

@ -1,16 +1,19 @@
output "subscription_id" {
value = data.azurerm_subscription.current.subscription_id
value = data.azurerm_subscription.current.subscription_id
description = "ID of the Azure subscription."
}
output "tenant_id" {
value = data.azurerm_subscription.current.tenant_id
value = data.azurerm_subscription.current.tenant_id
description = "ID of the Azure tenant."
}
output "uami_id" {
description = "Outputs the id in the format: /$ID/resourceGroups/$RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$NAME. Not to be confused with the client_id"
value = azurerm_user_assigned_identity.identity_uami.id
description = "Resource ID of the UAMI in the format: /$ID/resourceGroups/$RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$NAME. Not to be confused with the Client ID of the UAMI."
}
output "base_resource_group" {
value = azurerm_resource_group.base_resource_group.name
value = azurerm_resource_group.base_resource_group.name
description = "Name of the resource group."
}

View file

@ -1,14 +1,14 @@
variable "resource_group_name" {
type = string
description = "Resource group name"
description = "Name for the resource group the cluster should reside in."
}
variable "service_principal_name" {
type = string
description = "Service principal name"
description = "Name for the service principal used within the cluster."
}
variable "region" {
variable "location" {
type = string
description = "Azure resource location"
description = "Azure location the cluster should reside in."
}

View file

@ -1,36 +0,0 @@
# IAM configuration for GCP
This terraform script creates the necessary GCP IAM configuration to be attached to Constellation nodes.
You can create the configuration with the following commands:
```sh
mkdir constellation_gcp_iam
cd constellation_gcp_iam
curl --remote-name-all https://raw.githubusercontent.com/edgelesssys/constellation/main/terraform/infrastructure/iam/gcp/{main.tf,outputs.tf,variables.tf,.terraform.lock.hcl}
terraform init
terraform apply
```
The following terraform output values are available (with their corresponding keys in the Constellation configuration file):
- `sa_key` - **Sensitive Value**
- `region` (region)
- `zone` (zone)
- `project_id` (project)
You can either get the values from the Terraform output and manually add them to your Constellation configuration file according to our [Documentation](https://docs.edgeless.systems/constellation/getting-started/first-steps). (If you add the values manually, you need to base64-decode the `sa_key` value and place it in a JSON file, then specify the path to this file in the Constellation configuration file for the `serviceAccountKeyPath` key.)
Or you can setup the constellation configuration file automaticcaly with the following commands:
```sh
terraform output sa_key | sed "s/\"//g" | base64 --decode | tee gcpServiceAccountKey.json
yq -i "
.provider.gcp.serviceAccountKeyPath = \"$(realpath gcpServiceAccountKey.json)\" |
.provider.gcp.project = $(terraform output project_id) |
.provider.gcp.region = $(terraform output region) |
.provider.gcp.zone = $(terraform output zone)
" path/to/constellation-conf.yaml
```
Where `path/to/constellation-conf.yaml` is the path to your Constellation configuration file.

View file

@ -1,4 +1,5 @@
output "sa_key" {
value = google_service_account_key.service_account_key.private_key
sensitive = true
output "service_account_key" {
value = google_service_account_key.service_account_key.private_key
description = "Private key of the service account."
sensitive = true
}

View file

@ -1,19 +1,19 @@
variable "project_id" {
type = string
description = "GCP Project ID"
description = "ID of the GCP project the cluster should reside in."
}
variable "service_account_id" {
type = string
description = "ID for the service account being created. Must match ^[a-z](?:[-a-z0-9]{4,28}[a-z0-9])$"
description = "ID for the service account being created. Must match ^[a-z](?:[-a-z0-9]{4,28}[a-z0-9])$."
}
variable "region" {
type = string
description = "Region used for constellation clusters. Needs to have the N2D machine type available."
description = "GCP region the cluster should reside in. Needs to have the N2D machine type available."
}
variable "zone" {
type = string
description = "Zone used for constellation clusters. Needs to be within the specified region."
description = "GCP zone the cluster should reside in. Needs to be within the specified region."
}

View file

@ -23,7 +23,7 @@ data "openstack_identity_auth_scope_v3" "scope" {
locals {
uid = random_id.uid.hex
name = "${var.name}-${local.uid}"
initSecretHash = random_password.initSecret.bcrypt_hash
init_secret_hash = random_password.init_secret.bcrypt_hash
ports_node_range_start = "30000"
ports_node_range_end = "32767"
ports_kubernetes = "6443"
@ -49,15 +49,15 @@ resource "random_id" "uid" {
byte_length = 4
}
resource "random_password" "initSecret" {
resource "random_password" "init_secret" {
length = 32
special = true
override_special = "_%@"
}
resource "openstack_images_image_v2" "constellation_os_image" {
resource "openstack_images_image_v2" "image_id" {
name = local.name
image_source_url = var.image_url
image_source_url = var.image_id
web_download = var.direct_download
container_format = "bare"
disk_format = "raw"
@ -168,13 +168,13 @@ module "instance_group" {
disk_size = each.value.state_disk_size
state_disk_type = each.value.state_disk_type
availability_zone = each.value.zone
image_id = openstack_images_image_v2.constellation_os_image.image_id
image_id = openstack_images_image_v2.image_id.image_id
flavor_id = each.value.flavor_id
security_groups = [openstack_compute_secgroup_v2.vpc_secgroup.id]
tags = local.tags
uid = local.uid
network_id = openstack_networking_network_v2.vpc_network.id
init_secret_hash = local.initSecretHash
init_secret_hash = local.init_secret_hash
identity_internal_url = local.identity_internal_url
openstack_username = var.openstack_username
openstack_password = var.openstack_password

View file

@ -1,11 +1,9 @@
output "instance_group" {
value = local.name
}
output "ips" {
value = openstack_compute_instance_v2.instance_group_member.*.access_ip_v4
value = openstack_compute_instance_v2.instance_group_member.*.access_ip_v4
description = "Public IP addresses of the instances."
}
output "instance_ids" {
value = openstack_compute_instance_v2.instance_group_member.*.id
value = openstack_compute_instance_v2.instance_group_member.*.id
description = "IDs of the instances."
}

View file

@ -1,16 +1,11 @@
variable "node_group_name" {
type = string
description = "Constellation name for the node group (used for configuration and CSP-independent naming)."
}
variable "base_name" {
type = string
description = "Base name of the instance group."
}
variable "uid" {
variable "node_group_name" {
type = string
description = "Unique ID of the Constellation."
description = "Constellation name for the instance group (used for configuration and CSP-independent naming)."
}
variable "role" {
@ -22,14 +17,24 @@ variable "role" {
}
}
variable "tags" {
type = list(string)
description = "Tags to attach to each node."
}
variable "uid" {
type = string
description = "Unique ID of the Constellation."
}
variable "initial_count" {
type = number
description = "Number of instances in the instance group."
description = "Number of instances in this instance group."
}
variable "image_id" {
type = string
description = "Image ID for the nodes."
description = "OS Image reference for the cluster's nodes."
}
variable "flavor_id" {
@ -42,24 +47,19 @@ variable "security_groups" {
description = "Security groups to place the nodes in."
}
variable "tags" {
type = list(string)
description = "Tags to attach to each node."
}
variable "disk_size" {
type = number
description = "Disk size for the nodes, in GiB."
description = "Disk size for the state disk of the nodes [GB]."
}
variable "state_disk_type" {
type = string
description = "Disk/volume type to be used."
description = "Type of the state disk."
}
variable "availability_zone" {
type = string
description = "The availability zone to deploy the nodes in."
description = "Availability zone to deploy the nodes in."
}
variable "network_id" {

View file

@ -1,25 +1,25 @@
variable "name" {
type = string
description = "Base name of the load balancer rule."
description = "Base name of the load balancer."
}
variable "member_ips" {
type = list(string)
description = "The IP addresses of the members of the load balancer pool."
description = "IP addresses of the members of the load balancer pool."
default = []
}
variable "loadbalancer_id" {
type = string
description = "The ID of the load balancer."
description = "ID of the load balancer."
}
variable "subnet_id" {
type = string
description = "The ID of the members subnet."
description = "ID of the members subnet."
}
variable "port" {
type = number
description = "The port on which to listen for incoming traffic."
description = "Port to listen on incoming traffic."
}

View file

@ -1,28 +1,37 @@
# Outputs common to all CSPs
output "out_of_cluster_endpoint" {
value = openstack_networking_floatingip_v2.public_ip.address
value = openstack_networking_floatingip_v2.public_ip.address
description = "External endpoint for the Kubernetes API server. Only varies from the `in_cluster_endpoint` when using an internal load balancer."
}
output "in_cluster_endpoint" {
value = openstack_networking_floatingip_v2.public_ip.address
value = openstack_networking_floatingip_v2.public_ip.address
description = "Internal endpoint for the Kubernetes API server."
}
output "api_server_cert_sans" {
value = sort(concat([openstack_networking_floatingip_v2.public_ip.address], var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
value = sort(concat([openstack_networking_floatingip_v2.public_ip.address], var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
description = "List of Subject Alternative Names (SANs) for the API server certificate."
}
output "uid" {
value = local.uid
value = local.uid
description = "Unique Identifier (UID) of the cluster."
}
output "initSecret" {
value = random_password.initSecret.result
sensitive = true
output "init_secret" {
value = random_password.init_secret.result
sensitive = true
description = "Initialization secret to authenticate the bootstrapping node."
}
output "name" {
value = local.name
value = local.name
description = "Unique name of the Constellation cluster, comprised by name and UID."
}
output "ip_cidr_nodes" {
value = local.cidr_vpc_subnet_nodes
output "ip_cidr_node" {
value = local.cidr_vpc_subnet_nodes
description = "CIDR block of the node network."
}

View file

@ -1,3 +1,10 @@
# Variables common to all CSPs
variable "name" {
type = string
default = "constell"
description = "Base name of the cluster."
}
variable "node_groups" {
type = map(object({
role = string
@ -16,31 +23,39 @@ variable "node_groups" {
description = "A map of node group names to node group configurations."
}
variable "image_id" {
type = string
description = "OS image URL for the cluster's nodes."
}
variable "debug" {
type = bool
default = false
description = "DO NOT USE IN PRODUCTION. Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes API server. If not set, the default endpoint will be used."
}
# OpenStack-specific variables
variable "cloud" {
type = string
default = null
description = "The cloud to use within the OpenStack \"clouds.yaml\" file. Optional. If not set, environment variables are used."
}
variable "name" {
type = string
default = "constell"
description = "Base name of the cluster."
}
variable "image_url" {
type = string
description = "The image to use for cluster nodes."
description = "Cloud to use within the OpenStack \"clouds.yaml\" file. Optional. If not set, environment variables are used."
}
variable "direct_download" {
type = bool
description = "If enabled, downloads OS image directly from source URL to OpenStack. Otherwise, downloads image to local machine and uploads to OpenStack."
description = "Download OS image directly from source URL to OpenStack. Otherwise, the image is downloaded to the local machine and uploads to OpenStack."
}
variable "floating_ip_pool_id" {
type = string
description = "The pool (network name) to use for floating IPs."
description = "Pool (network name) to use for floating IPs."
}
variable "openstack_user_domain_name" {
@ -57,15 +72,3 @@ variable "openstack_password" {
type = string
description = "OpenStack password."
}
variable "debug" {
type = bool
default = false
description = "Enable debug mode. This opens up a debugd port that can be used to deploy a custom bootstrapper."
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes apiserver. If not set, the default endpoint will be used."
}

View file

@ -25,7 +25,7 @@ locals {
cidr_vpc_subnet_worker = "10.42.2.0/24"
}
resource "random_password" "initSecret" {
resource "random_password" "init_secret" {
length = 32
special = true
override_special = "_%@"
@ -46,7 +46,7 @@ resource "docker_container" "qemu_metadata" {
"--libvirt-uri",
"${var.metadata_libvirt_uri}",
"--initsecrethash",
"${random_password.initSecret.bcrypt_hash}",
"${random_password.init_secret.bcrypt_hash}",
]
mounts {
source = abspath(var.libvirt_socket_path)
@ -55,7 +55,6 @@ resource "docker_container" "qemu_metadata" {
}
}
module "node_group" {
source = "./modules/instance_group"
base_name = var.name
@ -71,7 +70,7 @@ module "node_group" {
network_id = libvirt_network.constellation.id
pool = libvirt_pool.cluster.name
boot_mode = var.constellation_boot_mode
boot_volume_id = libvirt_volume.constellation_os_image.id
boot_volume_id = libvirt_volume.image_id.id
kernel_volume_id = local.kernel_volume_id
initrd_volume_id = local.initrd_volume_id
kernel_cmdline = each.value.role == "control-plane" ? local.kernel_cmdline : var.constellation_cmdline
@ -85,10 +84,10 @@ resource "libvirt_pool" "cluster" {
path = "/var/lib/libvirt/images"
}
resource "libvirt_volume" "constellation_os_image" {
resource "libvirt_volume" "image_id" {
name = "${var.name}-node-image"
pool = libvirt_pool.cluster.name
source = var.constellation_os_image
source = var.image_id
format = var.image_format
}

View file

@ -1,3 +1,4 @@
output "instance_ips" {
value = flatten(libvirt_domain.instance_group[*].network_interface[*].addresses[*])
value = flatten(libvirt_domain.instance_group[*].network_interface[*].addresses[*])
description = "IP addresses of the instances in the instance group."
}

View file

@ -1,41 +1,51 @@
variable "base_name" {
type = string
description = "Name prefix fort the cluster's VMs."
}
variable "node_group_name" {
type = string
description = "Constellation name for the node group (used for configuration and CSP-independent naming)."
}
variable "amount" {
type = number
description = "amount of nodes"
description = "Amount of nodes."
}
variable "vcpus" {
type = number
description = "amount of vcpus per instance"
description = "Amount of vCPUs per instance."
}
variable "memory" {
type = number
description = "amount of memory per instance (MiB)"
description = "Amount of memory per instance (MiB)."
}
variable "state_disk_size" {
type = number
description = "size of state disk (GiB)"
description = "Disk size for the state disk of the nodes [GB]."
}
variable "cidr" {
type = string
description = "subnet to use for dhcp"
description = "Subnet to use for DHCP."
}
variable "network_id" {
type = string
description = "id of the network to use"
description = "ID of the Libvirt network to use."
}
variable "pool" {
type = string
description = "name of the storage pool to use"
description = "Name of the Libvirt storage pool to use."
}
variable "boot_mode" {
type = string
description = "boot mode. Can be 'uefi' or 'direct-linux-boot'"
description = "Boot mode. Can be 'uefi' or 'direct-linux-boot'"
validation {
condition = can(regex("^(uefi|direct-linux-boot)$", var.boot_mode))
error_message = "boot_mode must be 'uefi' or 'direct-linux-boot'"
@ -44,52 +54,43 @@ variable "boot_mode" {
variable "boot_volume_id" {
type = string
description = "id of the constellation boot disk"
description = "ID of the Constellation boot disk."
}
variable "kernel_volume_id" {
type = string
description = "id of the constellation kernel volume"
description = "ID of the Constellation kernel volume."
default = ""
}
variable "initrd_volume_id" {
type = string
description = "id of the constellation initrd volume"
description = "ID of the constellation initrd volume."
default = ""
}
variable "kernel_cmdline" {
type = string
description = "kernel cmdline"
description = "Kernel cmdline."
default = ""
}
variable "role" {
type = string
description = "role of the node in the constellation. either 'control-plane' or 'worker'"
description = "Role of the node in the Constellation cluster. Can either be'control-plane' or 'worker'."
}
variable "machine" {
type = string
description = "machine type. use 'q35' for secure boot and 'pc' for non secure boot. See 'qemu-system-x86_64 -machine help'"
description = "Machine type. Use 'q35' for secure boot and 'pc' for non secure boot. See 'qemu-system-x86_64 -machine help'."
}
variable "firmware" {
type = string
description = "path to UEFI firmware file. Ignored for direct-linux-boot."
description = "Path to UEFI firmware file. Ignored for direct-linux-boot."
}
variable "nvram" {
type = string
description = "path to UEFI NVRAM template file. Used for secure boot."
}
variable "base_name" {
type = string
description = "name prefix of the cluster VMs"
}
variable "node_group_name" {
type = string
description = "name of the node group"
description = "Path to UEFI NVRAM template file. Used for secure boot."
}

View file

@ -1,30 +1,50 @@
# Outputs common to all CSPs
output "out_of_cluster_endpoint" {
value = module.node_group["control_plane_default"].instance_ips[0]
value = module.node_group["control_plane_default"].instance_ips[0]
description = "External endpoint for the Kubernetes API server. Only varies from the `in_cluster_endpoint` when using an internal load balancer."
}
output "in_cluster_endpoint" {
value = module.node_group["control_plane_default"].instance_ips[0]
value = module.node_group["control_plane_default"].instance_ips[0]
description = "Internal endpoint for the Kubernetes API server."
}
output "api_server_cert_sans" {
value = sort(concat([module.node_group["control_plane_default"].instance_ips[0]], var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
value = sort(concat([module.node_group["control_plane_default"].instance_ips[0]], var.custom_endpoint == "" ? [] : [var.custom_endpoint]))
description = "List of Subject Alternative Names (SANs) for the API server certificate."
}
output "uid" {
value = "qemu" // placeholder
value = "qemu" // placeholder
description = "Unique Identifier (UID) of the cluster."
}
output "initSecret" {
value = random_password.initSecret.result
sensitive = true
output "init_secret" {
value = random_password.init_secret.result
sensitive = true
description = "Initialization secret to authenticate the bootstrapping node."
}
output "name" {
value = "${var.name}-qemu" // placeholder, as per "uid" output
description = "Unique name of the Constellation cluster, comprised by name and UID."
}
output "ip_cidr_node" {
value = local.cidr_vpc_subnet_nodes
description = "CIDR block of the node network."
}
# QEMU-specific outputs
output "validate_constellation_kernel" {
value = null
precondition {
condition = var.constellation_boot_mode != "direct-linux-boot" || length(var.constellation_kernel) > 0
error_message = "constellation_kernel must be set if constellation_boot_mode is 'direct-linux-boot'"
}
description = "Validation placeholder. Do not consume as output."
}
output "validate_constellation_initrd" {
@ -33,6 +53,7 @@ output "validate_constellation_initrd" {
condition = var.constellation_boot_mode != "direct-linux-boot" || length(var.constellation_initrd) > 0
error_message = "constellation_initrd must be set if constellation_boot_mode is 'direct-linux-boot'"
}
description = "Validation placeholder. Do not consume as output."
}
output "validate_constellation_cmdline" {
@ -41,12 +62,5 @@ output "validate_constellation_cmdline" {
condition = var.constellation_boot_mode != "direct-linux-boot" || length(var.constellation_cmdline) > 0
error_message = "constellation_cmdline must be set if constellation_boot_mode is 'direct-linux-boot'"
}
}
output "name" {
value = "${var.name}-qemu" // placeholder, as per "uid" output
}
output "ip_cidr_nodes" {
value = local.cidr_vpc_subnet_nodes
description = "Validation placeholder. Do not consume as output."
}

View file

@ -1,3 +1,11 @@
# Variables common to all CSPs
variable "name" {
type = string
default = "constellation"
description = "Name of the Constellation cluster."
}
variable "node_groups" {
type = map(object({
role = string
@ -14,91 +22,88 @@ variable "node_groups" {
description = "A map of node group names to node group configurations."
}
variable "image_id" {
type = string
description = "Path to the OS image for the cluster's nodes."
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes API server. If not set, the default endpoint will be used."
}
# QEMU-specific variables
variable "machine" {
type = string
default = "q35"
description = "machine type. use 'q35' for secure boot and 'pc' for non secure boot. See 'qemu-system-x86_64 -machine help'"
description = "Machine type. Use 'q35' for secure boot and 'pc' for non secure boot. See 'qemu-system-x86_64 -machine help'."
}
variable "libvirt_uri" {
type = string
description = "libvirt socket uri"
description = "URI of the Libvirt socket."
}
variable "constellation_boot_mode" {
type = string
description = "constellation boot mode. Can be 'uefi' or 'direct-linux-boot'"
description = "Constellation boot mode. Can be 'uefi' or 'direct-linux-boot'."
validation {
condition = anytrue([
var.constellation_boot_mode == "uefi",
var.constellation_boot_mode == "direct-linux-boot",
])
error_message = "constellation_boot_mode must be 'uefi' or 'direct-linux-boot'"
error_message = "constellation_boot_mode must be 'uefi' or 'direct-linux-boot'."
}
}
variable "constellation_os_image" {
type = string
description = "constellation OS file path"
}
variable "constellation_kernel" {
type = string
description = "constellation Kernel file path"
description = "Constellation Kernel file path."
default = ""
}
variable "constellation_initrd" {
type = string
description = "constellation initrd file path"
description = "Constellation initrd file path."
default = ""
}
variable "constellation_cmdline" {
type = string
description = "constellation kernel cmdline"
description = "Constellation kernel cmdline."
default = ""
}
variable "image_format" {
type = string
default = "qcow2"
description = "image format"
description = "Image format."
}
variable "firmware" {
type = string
default = "/usr/share/OVMF/OVMF_CODE.fd"
description = "path to UEFI firmware file. Use \"OVMF_CODE_4M.ms.fd\" on Ubuntu and \"OVMF_CODE.fd\" or \"OVMF_CODE.secboot.fd\" on Fedora."
description = "Path to UEFI firmware file. Use \"OVMF_CODE_4M.ms.fd\" on Ubuntu and \"OVMF_CODE.fd\" or \"OVMF_CODE.secboot.fd\" on Fedora."
}
variable "nvram" {
type = string
description = "path to UEFI NVRAM template file. Used for secure boot."
description = "Path to UEFI NVRAM template file. Used for secure boot."
}
variable "metadata_api_image" {
type = string
description = "container image of the QEMU metadata api server"
description = "Container image of the QEMU metadata API server."
}
variable "metadata_libvirt_uri" {
type = string
description = "libvirt uri for the metadata api server"
description = "Libvirt URI for the metadata API server."
}
variable "libvirt_socket_path" {
type = string
description = "path to libvirt socket in case of unix socket"
}
variable "name" {
type = string
default = "constellation"
description = "name prefix of the cluster VMs"
}
variable "custom_endpoint" {
type = string
default = ""
description = "Custom endpoint to use for the Kubernetes apiserver. If not set, the default endpoint will be used."
description = "Path to Libvirt socket in case of unix socket."
}

View file

@ -29,17 +29,17 @@ module "fetch_image" {
}
module "aws" {
source = "../../infrastructure/aws"
name = var.name
node_groups = var.node_groups
iam_instance_profile_worker_nodes = module.aws_iam.worker_nodes_instance_profile
iam_instance_profile_control_plane = module.aws_iam.control_plane_instance_profile
ami = module.fetch_image.image
region = local.region
zone = var.zone
debug = var.debug
enable_snp = var.enable_snp
custom_endpoint = var.custom_endpoint
source = "../../infrastructure/aws"
name = var.name
node_groups = var.node_groups
iam_instance_profile_name_worker_nodes = module.aws_iam.iam_instance_profile_name_worker_nodes
iam_instance_profile_name_control_plane = module.aws_iam.iam_instance_profile_name_control_plane
image_id = module.fetch_image.image
region = local.region
zone = var.zone
debug = var.debug
enable_snp = var.enable_snp
custom_endpoint = var.custom_endpoint
}
module "constellation" {
@ -53,15 +53,15 @@ module "constellation" {
uid = module.aws.uid
clusterEndpoint = module.aws.out_of_cluster_endpoint
inClusterEndpoint = module.aws.in_cluster_endpoint
initSecretHash = module.aws.initSecret
ipCidrNode = module.aws.ip_cidr_nodes
initSecretHash = module.aws.init_secret
ipCidrNode = module.aws.ip_cidr_node
apiServerCertSANs = module.aws.api_server_cert_sans
node_groups = var.node_groups
aws_config = {
region = local.region
zone = var.zone
iam_instance_profile_worker_nodes = module.aws_iam.worker_nodes_instance_profile
iam_instance_profile_control_plane = module.aws_iam.control_plane_instance_profile
region = local.region
zone = var.zone
iam_instance_profile_name_worker_nodes = module.aws_iam.iam_instance_profile_name_worker_nodes
iam_instance_profile_name_control_plane = module.aws_iam.iam_instance_profile_name_control_plane
}
depends_on = [module.aws, null_resource.ensure_yq]
}

View file

@ -19,7 +19,7 @@ module "fetch_image" {
module "azure_iam" {
source = "../../infrastructure/iam/azure"
region = var.location
location = var.location
service_principal_name = var.service_principal_name
resource_group_name = var.resource_group_name
}
@ -47,8 +47,8 @@ module "constellation" {
uid = module.azure.uid
clusterEndpoint = module.azure.out_of_cluster_endpoint
inClusterEndpoint = module.azure.in_cluster_endpoint
initSecretHash = module.azure.initSecret
ipCidrNode = module.azure.ip_cidr_nodes
initSecretHash = module.azure.init_secret
ipCidrNode = module.azure.ip_cidr_node
apiServerCertSANs = module.azure.api_server_cert_sans
node_groups = var.node_groups
azure_config = {
@ -59,7 +59,7 @@ module "constellation" {
userAssignedIdentity = module.azure_iam.uami_id
deployCSIDriver = var.deploy_csi_driver
secureBoot = var.secure_boot
maaURL = module.azure.attestationURL
maaURL = module.azure.attestation_url
networkSecurityGroupName = module.azure.network_security_group_name
loadBalancerName = module.azure.loadbalancer_name
}

View file

@ -41,8 +41,8 @@ resource "null_resource" "aws_config" {
command = <<EOT
./yq eval '.provider.aws.region = "${var.aws_config.region}"' -i constellation-conf.yaml
./yq eval '.provider.aws.zone = "${var.aws_config.zone}"' -i constellation-conf.yaml
./yq eval '.provider.aws.iamProfileControlPlane = "${var.aws_config.iam_instance_profile_control_plane}"' -i constellation-conf.yaml
./yq eval '.provider.aws.iamProfileWorkerNodes = "${var.aws_config.iam_instance_profile_worker_nodes}"' -i constellation-conf.yaml
./yq eval '.provider.aws.iamProfileControlPlane = "${var.aws_config.iam_instance_profile_name_control_plane}"' -i constellation-conf.yaml
./yq eval '.provider.aws.iamProfileWorkerNodes = "${var.aws_config.iam_instance_profile_name_worker_nodes}"' -i constellation-conf.yaml
EOT
}
triggers = {

View file

@ -78,10 +78,10 @@ variable "apiServerCertSANs" {
variable "aws_config" {
type = object({
region = string
zone = string
iam_instance_profile_worker_nodes = string
iam_instance_profile_control_plane = string
region = string
zone = string
iam_instance_profile_name_worker_nodes = string
iam_instance_profile_name_control_plane = string
})
description = "The cluster config for AWS."
default = null

View file

@ -54,16 +54,16 @@ module "constellation" {
uid = module.gcp.uid
clusterEndpoint = module.gcp.out_of_cluster_endpoint
inClusterEndpoint = module.gcp.in_cluster_endpoint
initSecretHash = module.gcp.initSecret
ipCidrNode = module.gcp.ip_cidr_nodes
initSecretHash = module.gcp.init_secret
ipCidrNode = module.gcp.ip_cidr_node
apiServerCertSANs = module.gcp.api_server_cert_sans
node_groups = var.node_groups
gcp_config = {
region = local.region
zone = var.zone
project = var.project
ipCidrPod = module.gcp.ip_cidr_pods
serviceAccountKey = module.gcp_iam.sa_key
ipCidrPod = module.gcp.ip_cidr_pod
serviceAccountKey = module.gcp_iam.service_account_key
}
depends_on = [module.gcp, null_resource.ensure_yq]
}