Skip to content

Commit

Permalink
Updated UpCloud terraform script to use private network and dynamic (k…
Browse files Browse the repository at this point in the history
…ubernetes-sigs#7779)

additional disks
  • Loading branch information
Xartos authored and LuckySB committed Oct 23, 2021
1 parent 703c6f6 commit e78ecef
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 89 deletions.
48 changes: 27 additions & 21 deletions contrib/terraform/upcloud/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,29 @@ The setup looks like following

```text
Kubernetes cluster
+-----------------------+
| +--------------+ |
| | +--------------+ |
| | | | |
| | | Master/etcd | |
| | | node(s) | |
| +-+ | |
| +--------------+ |
| ^ |
| | |
| v |
| +--------------+ |
| | +--------------+ |
| | | | |
| | | Worker | |
| | | node(s) | |
| +-+ | |
| +--------------+ |
+-----------------------+
+--------------------------+
| +--------------+ |
| | +--------------+ |
| --> | | | |
| | | Master/etcd | |
| | | node(s) | |
| +-+ | |
| +--------------+ |
| ^ |
| | |
| v |
| +--------------+ |
| | +--------------+ |
| --> | | | |
| | | Worker | |
| | | node(s) | |
| +-+ | |
| +--------------+ |
+--------------------------+
```

The nodes uses a private network for node to node communication and a public interface for all external communication.

## Requirements

* Terraform 0.13.0 or newer
Expand Down Expand Up @@ -94,13 +96,17 @@ terraform destroy --var-file cluster-settings.tfvars \

## Variables

* `hostname`: A valid domain name, e.g. example.com. The maximum length is 128 characters.
* `prefix`: Prefix to add to all resources, if set to "" don't set any prefix
* `template_name`: The name or UUID of a base image
* `username`: a user to access the nodes
* `username`: a user to access the nodes, defaults to "ubuntu"
* `private_network_cidr`: CIDR to use for the private network, defaults to "172.16.0.0/24"
* `ssh_public_keys`: List of public SSH keys to install on all machines
* `zone`: The zone where to run the cluster
* `machines`: Machines to provision. Key of this object will be used as the name of the machine
* `node_type`: The role of this node *(master|worker)*
* `cpu`: number of cpu cores
* `mem`: memory size in MB
* `disk_size`: The size of the storage in GB
* `additional_disks`: Additional disks to attach to the node.
* `size`: The size of the additional disk in GB
* `tier`: The tier of disk to use (`maxiops` is the only one you can choose atm)
40 changes: 35 additions & 5 deletions contrib/terraform/upcloud/cluster-settings.tfvars
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@

# See: https://developers.upcloud.com/1.3/5-zones/
zone = "fi-hel1"
username = "ubuntu"

inventory_file = "inventory.ini"
# Prefix to use for all resources to separate them from other resources
prefix = "kubespray"

# A valid domain name, e.g. host.example.com. The maximum length is 128 characters.
hostname = "example.com"
inventory_file = "inventory.ini"

# Set the operating system using UUID or exact name
template_name = "Ubuntu Server 20.04 LTS (Focal Fossa)"
Expand All @@ -17,7 +16,7 @@ ssh_public_keys = [
"ssh-rsa public key 2",
]

#check list of available plan https://developers.upcloud.com/1.3/7-plans/
# check list of available plan https://developers.upcloud.com/1.3/7-plans/
machines = {
"master-0" : {
"node_type" : "master",
Expand All @@ -27,6 +26,7 @@ machines = {
"mem" : "4096"
# The size of the storage in GB
"disk_size" : 250
"additional_disks" : {}
},
"worker-0" : {
"node_type" : "worker",
Expand All @@ -36,6 +36,16 @@ machines = {
"mem" : "4096"
# The size of the storage in GB
"disk_size" : 250
"additional_disks" : {
# "some-disk-name-1": {
# "size": 100,
# "tier": "maxiops",
# },
# "some-disk-name-2": {
# "size": 100,
# "tier": "maxiops",
# }
}
},
"worker-1" : {
"node_type" : "worker",
Expand All @@ -45,6 +55,16 @@ machines = {
"mem" : "4096"
# The size of the storage in GB
"disk_size" : 250
"additional_disks" : {
# "some-disk-name-1": {
# "size": 100,
# "tier": "maxiops",
# },
# "some-disk-name-2": {
# "size": 100,
# "tier": "maxiops",
# }
}
},
"worker-2" : {
"node_type" : "worker",
Expand All @@ -54,5 +74,15 @@ machines = {
"mem" : "4096"
# The size of the storage in GB
"disk_size" : 250
"additional_disks" : {
# "some-disk-name-1": {
# "size": 100,
# "tier": "maxiops",
# },
# "some-disk-name-2": {
# "size": 100,
# "tier": "maxiops",
# }
}
}
}
16 changes: 10 additions & 6 deletions contrib/terraform/upcloud/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ provider "upcloud" {
module "kubernetes" {
source = "./modules/kubernetes-cluster"

zone = var.zone
hostname = var.hostname
prefix = var.prefix
zone = var.zone

template_name = var.template_name
username = var.username

private_network_cidr = var.private_network_cidr

machines = var.machines

ssh_public_keys = var.ssh_public_keys
Expand All @@ -30,13 +32,15 @@ data "template_file" "inventory" {
template = file("${path.module}/templates/inventory.tpl")

vars = {
connection_strings_master = join("\n", formatlist("%s ansible_user=ubuntu ansible_host=%s etcd_member_name=etcd%d",
connection_strings_master = join("\n", formatlist("%s ansible_user=ubuntu ansible_host=%s ip=%s etcd_member_name=etcd%d",
keys(module.kubernetes.master_ip),
values(module.kubernetes.master_ip),
values(module.kubernetes.master_ip).*.public_ip,
values(module.kubernetes.master_ip).*.private_ip,
range(1, length(module.kubernetes.master_ip) + 1)))
connection_strings_worker = join("\n", formatlist("%s ansible_user=ubuntu ansible_host=%s",
connection_strings_worker = join("\n", formatlist("%s ansible_user=ubuntu ansible_host=%s ip=%s",
keys(module.kubernetes.worker_ip),
values(module.kubernetes.worker_ip)))
values(module.kubernetes.worker_ip).*.public_ip,
values(module.kubernetes.worker_ip).*.private_ip))
list_master = join("\n", formatlist("%s",
keys(module.kubernetes.master_ip)))
list_worker = join("\n", formatlist("%s",
Expand Down
142 changes: 106 additions & 36 deletions contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
locals {
# Create a list of all disks to create
disks = flatten([
for node_name, machine in var.machines : [
for disk_name, disk in machine.additional_disks : {
disk = disk
disk_name = disk_name
node_name = node_name
}
]
])

# If prefix is set, all resources will be prefixed with "${var.prefix}-"
# Else don't prefix with anything
resource-prefix = "%{ if var.prefix != ""}${var.prefix}-%{ endif }"
}

resource "upcloud_network" "private" {
name = "${local.resource-prefix}k8s-network"
zone = var.zone

ip_network {
address = var.private_network_cidr
dhcp = true
family = "IPv4"
}
}

resource "upcloud_storage" "additional_disks" {
for_each = {
for disk in local.disks: "${disk.node_name}_${disk.disk_name}" => disk.disk
}

size = each.value.size
tier = each.value.tier
title = "${local.resource-prefix}${each.key}"
zone = var.zone
}

resource "upcloud_server" "master" {
for_each = {
Expand All @@ -6,61 +44,93 @@ resource "upcloud_server" "master" {
if machine.node_type == "master"
}

hostname = "${each.key}.${var.hostname}"
cpu = each.value.cpu
mem = each.value.mem
zone = var.zone
hostname = "${local.resource-prefix}${each.key}"
cpu = each.value.cpu
mem = each.value.mem
zone = var.zone

template {
storage = var.template_name
size = each.value.disk_size
size = each.value.disk_size
}

# Public network interface
network_interface {
type = "public"
}

# Network interfaces
network_interface {
type = "public"
}
# Private network interface
network_interface {
type = "private"
network = upcloud_network.private.id
}

network_interface {
type = "utility"
}
# Include at least one public SSH key
login {
user = var.username
keys = var.ssh_public_keys
create_password = false
dynamic "storage_devices" {
for_each = {
for disk_key_name, disk in upcloud_storage.additional_disks :
disk_key_name => disk
# Only add the disk if it matches the node name in the start of its name
if length(regexall("^${each.key}_.+", disk_key_name)) > 0
}

}
content {
storage = storage_devices.value.id
}
}

# Include at least one public SSH key
login {
user = var.username
keys = var.ssh_public_keys
create_password = false
}
}


resource "upcloud_server" "worker" {
for_each = {
for name, machine in var.machines :
name => machine
if machine.node_type == "worker"
}

hostname = "${each.key}.${var.hostname}"
cpu = each.value.cpu
mem = each.value.mem
zone = var.zone
hostname = "${local.resource-prefix}${each.key}"
cpu = each.value.cpu
mem = each.value.mem
zone = var.zone

template {
storage = var.template_name
size = each.value.disk_size
storage = var.template_name
size = each.value.disk_size
}

# Public network interface
network_interface {
type = "public"
}

# Network interfaces
network_interface {
type = "public"
}

# Include at least one public SSH key
login {
user = var.username
keys = var.ssh_public_keys
create_password = false
}
# Private network interface
network_interface {
type = "private"
network = upcloud_network.private.id
}

dynamic "storage_devices" {
for_each = {
for disk_key_name, disk in upcloud_storage.additional_disks :
disk_key_name => disk
# Only add the disk if it matches the node name in the start of its name
if length(regexall("^${each.key}_.+", disk_key_name)) > 0
}

content {
storage = storage_devices.value.id
}
}

# Include at least one public SSH key
login {
user = var.username
keys = var.ssh_public_keys
create_password = false
}
}
10 changes: 8 additions & 2 deletions contrib/terraform/upcloud/modules/kubernetes-cluster/output.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
output "master_ip" {
value = {
for instance in upcloud_server.master :
instance.hostname => instance.network_interface[0].ip_address
instance.hostname => {
"public_ip": instance.network_interface[0].ip_address
"private_ip": instance.network_interface[1].ip_address
}
}
}

output "worker_ip" {
value = {
for instance in upcloud_server.worker :
instance.hostname => instance.network_interface[0].ip_address
instance.hostname => {
"public_ip": instance.network_interface[0].ip_address
"private_ip": instance.network_interface[1].ip_address
}
}
}
Loading

0 comments on commit e78ecef

Please sign in to comment.