Merge pull request #118 from kube-hetzner/automatic-subnets

Automatic subnets creation
This commit is contained in:
Marco Nenciarini 2022-03-12 11:53:21 +01:00 committed by GitHub
commit 900277f645
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 59 deletions

View File

@ -12,11 +12,11 @@ module "agents" {
placement_group_id = hcloud_placement_group.k3s.id placement_group_id = hcloud_placement_group.k3s.id
location = var.location location = var.location
server_type = each.value.server_type server_type = each.value.server_type
ipv4_subnet_id = hcloud_network_subnet.subnet[each.value.subnet].id ipv4_subnet_id = hcloud_network_subnet.subnet[[for i, v in var.agent_nodepools : i if v.name == each.value.nodepool_name][0] + 2].id
# We leave some room so 100 eventual Hetzner LBs that can be created perfectly safely # We leave some room so 100 eventual Hetzner LBs that can be created perfectly safely
# It leaves the subnet with 254 x 254 - 100 = 64416 IPs to use, so probably enough. # It leaves the subnet with 254 x 254 - 100 = 64416 IPs to use, so probably enough.
private_ipv4 = cidrhost(var.network_ipv4_subnets[each.value.subnet], each.value.index + 101) private_ipv4 = cidrhost(local.network_ipv4_subnets[[for i, v in var.agent_nodepools : i if v.name == each.value.nodepool_name][0] + 2], each.value.index + 101)
labels = { labels = {
"provisioner" = "terraform", "provisioner" = "terraform",

View File

@ -11,11 +11,11 @@ module "control_planes" {
placement_group_id = hcloud_placement_group.k3s.id placement_group_id = hcloud_placement_group.k3s.id
location = var.location location = var.location
server_type = var.control_plane_server_type server_type = var.control_plane_server_type
ipv4_subnet_id = hcloud_network_subnet.subnet["control_plane"].id ipv4_subnet_id = hcloud_network_subnet.subnet[1].id
# We leave some room so 100 eventual Hetzner LBs that can be created perfectly safely # We leave some room so 100 eventual Hetzner LBs that can be created perfectly safely
# It leaves the subnet with 254 x 254 - 100 = 64416 IPs to use, so probably enough. # It leaves the subnet with 254 x 254 - 100 = 64416 IPs to use, so probably enough.
private_ipv4 = cidrhost(var.network_ipv4_subnets["control_plane"], count.index + 101) private_ipv4 = cidrhost(local.network_ipv4_subnets[1], count.index + 101)
labels = { labels = {
"provisioner" = "terraform", "provisioner" = "terraform",

View File

@ -1,6 +1,6 @@
locals { locals {
# if we are in a single cluster config, we use the default klipper lb instead of Hetzner LB # if we are in a single cluster config, we use the default klipper lb instead of Hetzner LB
is_single_node_cluster = var.control_plane_count + length(keys(var.agent_nodepools)) == 1 is_single_node_cluster = var.control_plane_count + sum(concat([for v in var.agent_nodepools : v.count], [0])) == 1
ssh_public_key = trimspace(file(var.public_key)) ssh_public_key = trimspace(file(var.public_key))
# ssh_private_key is either the contents of var.private_key or null to use a ssh agent. # ssh_private_key is either the contents of var.private_key or null to use a ssh agent.
ssh_private_key = var.private_key == null ? null : trimspace(file(var.private_key)) ssh_private_key = var.private_key == null ? null : trimspace(file(var.private_key))
@ -23,7 +23,7 @@ locals {
hetzner_cloud_api_ipv4 = "213.239.246.1/32" hetzner_cloud_api_ipv4 = "213.239.246.1/32"
whitelisted_ips = [ whitelisted_ips = [
var.network_ipv4_range, local.network_ipv4_cidr,
local.hetzner_metadata_service_ipv4, local.hetzner_metadata_service_ipv4,
local.hetzner_cloud_api_ipv4, local.hetzner_cloud_api_ipv4,
"127.0.0.1/32", "127.0.0.1/32",
@ -170,14 +170,20 @@ locals {
install_k3s_agent = concat(local.common_commands_install_k3s, ["curl -sfL https://get.k3s.io | INSTALL_K3S_SKIP_START=true INSTALL_K3S_SKIP_SELINUX_RPM=true INSTALL_K3S_CHANNEL=${var.initial_k3s_channel} INSTALL_K3S_EXEC=agent sh -"], local.apply_k3s_selinux) install_k3s_agent = concat(local.common_commands_install_k3s, ["curl -sfL https://get.k3s.io | INSTALL_K3S_SKIP_START=true INSTALL_K3S_SKIP_SELINUX_RPM=true INSTALL_K3S_CHANNEL=${var.initial_k3s_channel} INSTALL_K3S_EXEC=agent sh -"], local.apply_k3s_selinux)
agent_nodepools = merge([ agent_nodepools = merge([
for nodepool_name, nodepool_obj in var.agent_nodepools : { for nodepool_obj in var.agent_nodepools : {
for index in range(nodepool_obj.count) : for index in range(nodepool_obj.count) :
format("%s-%s", nodepool_name, index) => { format("%s-%s", nodepool_obj.name, index) => {
nodepool_name : nodepool_name, nodepool_name : nodepool_obj.name,
server_type : nodepool_obj.server_type, server_type : nodepool_obj.server_type,
subnet : nodepool_obj.subnet,
index : index index : index
} }
} }
]...) ]...)
# The main network cidr that all subnets will be created upon
network_ipv4_cidr = "10.0.0.0/8"
# The first two subnets are respectively the default subnet 10.0.0.0/16 use for potientially anything and 10.1.0.0/16 used for control plane nodes.
# the rest of the subnets are for agent nodes in each nodepools.
network_ipv4_subnets = [for index in range(length(var.agent_nodepools) + 2) : cidrsubnet(local.network_ipv4_cidr, 8, index)]
} }

16
main.tf
View File

@ -10,25 +10,15 @@ resource "hcloud_ssh_key" "k3s" {
resource "hcloud_network" "k3s" { resource "hcloud_network" "k3s" {
name = var.cluster_name name = var.cluster_name
ip_range = var.network_ipv4_range ip_range = local.network_ipv4_cidr
}
# This is the default subnet to be used by the load balancer.
resource "hcloud_network_subnet" "default" {
network_id = hcloud_network.k3s.id
type = "cloud"
network_zone = var.network_region
ip_range = "10.0.0.0/16"
} }
resource "hcloud_network_subnet" "subnet" { resource "hcloud_network_subnet" "subnet" {
for_each = var.network_ipv4_subnets count = length(local.network_ipv4_subnets)
network_id = hcloud_network.k3s.id network_id = hcloud_network.k3s.id
type = "cloud" type = "cloud"
network_zone = var.network_region network_zone = var.network_region
ip_range = each.value ip_range = local.network_ipv4_subnets[count.index]
depends_on = [hcloud_network_subnet.default]
} }
resource "hcloud_firewall" "k3s" { resource "hcloud_firewall" "k3s" {

View File

@ -18,15 +18,6 @@ private_key = "/home/username/.ssh/id_ed25519"
location = "fsn1" # change to `ash` for us-east Ashburn, Virginia location location = "fsn1" # change to `ash` for us-east Ashburn, Virginia location
network_region = "eu-central" # change to `us-east` if location is ash network_region = "eu-central" # change to `us-east` if location is ash
# You can have up to as many subnets as you want (preferably if the form of 10.X.0.0/16),
# their primary use is to logically separate the nodes.
# The control_plane network is mandatory.
network_ipv4_subnets = {
control_plane = "10.1.0.0/16"
agent_big = "10.2.0.0/16"
agent_small = "10.3.0.0/16"
}
# At least 3 server nodes is recommended for HA, otherwise you need to turn off automatic upgrade (see ReadMe). # At least 3 server nodes is recommended for HA, otherwise you need to turn off automatic upgrade (see ReadMe).
# As per rancher docs, it must be always an odd number, never even! See https://rancher.com/docs/k3s/latest/en/installation/ha-embedded/ # As per rancher docs, it must be always an odd number, never even! See https://rancher.com/docs/k3s/latest/en/installation/ha-embedded/
# For instance, 1 is ok (non-HA), 2 not ok, 3 is ok (becomes HA). # For instance, 1 is ok (non-HA), 2 not ok, 3 is ok (becomes HA).
@ -37,28 +28,27 @@ control_plane_server_type = "cpx11"
# As for the agent nodepools, below is just an example, if you do not want nodepools, just use one, # As for the agent nodepools, below is just an example, if you do not want nodepools, just use one,
# and change the name to what you want, it need not be "agent-big" or "agent-small", also give them the subnet prefer. # and change the name to what you want, it need not be "agent-big" or "agent-small", also give them the subnet prefer.
# For single node clusters set this equal to {} # For single node clusters set this equal to [] or just set the counts to 0.
agent_nodepools = { # IMPORTANT: Once the cluster is created, you can change the count, and even set it to 0, but do not remove a nodepool from the list.
agent-big = { # You can add others at the end of the list if you want.
server_type = "cpx21", agent_nodepools = [
count = 1, {
subnet = "agent_big", name = "agent-small",
}
agent-small = {
server_type = "cpx11", server_type = "cpx11",
count = 2, count = 2
subnet = "agent_small", },
{
name = "agent-large",
server_type = "cpx21",
count = 1
} }
} ]
# That will depend on how much load you want it to handle, see https://www.hetzner.com/cloud/load-balancer # That will depend on how much load you want it to handle, see https://www.hetzner.com/cloud/load-balancer
load_balancer_type = "lb11" load_balancer_type = "lb11"
### The following values are fully optional ### The following values are fully optional
# It's best to leave the network range as is, unless you know what you are doing. The default is "10.0.0.0/8".
# network_ipv4_range = "10.0.0.0/8"
# If you want to use a specific Hetzner CCM and CSI version, set them below, otherwise leave as is for the latest versions # If you want to use a specific Hetzner CCM and CSI version, set them below, otherwise leave as is for the latest versions
# hetzner_ccm_version = "" # hetzner_ccm_version = ""
# hetzner_csi_version = "" # hetzner_csi_version = ""

View File

@ -30,17 +30,6 @@ variable "network_region" {
type = string type = string
} }
variable "network_ipv4_range" {
description = "Default IPv4 range for network"
type = string
default = "10.0.0.0/8"
}
variable "network_ipv4_subnets" {
description = "Subnets definition for default network"
type = map(string)
}
variable "control_plane_server_type" { variable "control_plane_server_type" {
description = "Default control plane server type" description = "Default control plane server type"
type = string type = string
@ -64,8 +53,8 @@ variable "load_balancer_disable_ipv6" {
variable "agent_nodepools" { variable "agent_nodepools" {
description = "Number of agent nodes." description = "Number of agent nodes."
type = map(any) type = list(any)
default = {} default = []
} }
variable "hetzner_ccm_version" { variable "hetzner_ccm_version" {