Browse Source
Terraform support for UpCloud (#7360)
Terraform support for UpCloud (#7360)
* terraform support for UpCloud * terraform support for UpCloud * terraform support for UpCloud * terraform support for UpCloud * terraform support for UpCloud * terraform support for UpCloud * terraform support for UpCloud * Updates to README.md and main.tf files * formatting and updating readme * added a .terraform_validate CI job * fixed format issue * added sample inventory * added symbolic link to group_vars * added missing tf variables and minor fixes * added text formatting * minor formatting fixespull/7376/head
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 475 additions and 0 deletions
Split View
Diff Options
-
14.gitlab-ci/terraform.yml
-
106contrib/terraform/upcloud/README.md
-
58contrib/terraform/upcloud/cluster-settings.tfvars
-
55contrib/terraform/upcloud/main.tf
-
66contrib/terraform/upcloud/modules/kubernetes-cluster/main.tf
-
14contrib/terraform/upcloud/modules/kubernetes-cluster/output.tf
-
25contrib/terraform/upcloud/modules/kubernetes-cluster/variables.tf
-
10contrib/terraform/upcloud/modules/kubernetes-cluster/versions.tf
-
8contrib/terraform/upcloud/output.tf
-
56contrib/terraform/upcloud/sample-inventory/cluster.tfvars
-
1contrib/terraform/upcloud/sample-inventory/group_vars
-
17contrib/terraform/upcloud/templates/inventory.tpl
-
35contrib/terraform/upcloud/variables.tf
-
10contrib/terraform/upcloud/versions.tf
@ -0,0 +1,106 @@ |
|||
# Kubernetes on UpCloud with Terraform |
|||
|
|||
Provision a Kubernetes cluster on [UpCloud](https://upcloud.com/) using Terraform and Kubespray |
|||
|
|||
## Overview |
|||
|
|||
The setup looks like following |
|||
|
|||
```text |
|||
Kubernetes cluster |
|||
+-----------------------+ |
|||
| +--------------+ | |
|||
| | +--------------+ | |
|||
| | | | | |
|||
| | | Master/etcd | | |
|||
| | | node(s) | | |
|||
| +-+ | | |
|||
| +--------------+ | |
|||
| ^ | |
|||
| | | |
|||
| v | |
|||
| +--------------+ | |
|||
| | +--------------+ | |
|||
| | | | | |
|||
| | | Worker | | |
|||
| | | node(s) | | |
|||
| +-+ | | |
|||
| +--------------+ | |
|||
+-----------------------+ |
|||
``` |
|||
|
|||
## Requirements |
|||
|
|||
* Terraform 0.13.0 or newer |
|||
|
|||
## Quickstart |
|||
|
|||
NOTE: Assumes you are at the root of the kubespray repo. |
|||
|
|||
For authentication in your cluster you can use the environment variables. |
|||
|
|||
```bash |
|||
export TF_VAR_UPCLOUD_USERNAME=username |
|||
export TF_VAR_UPCLOUD_PASSWORD=password |
|||
``` |
|||
|
|||
To allow API access to your UpCloud account, you need to allow API connections by visiting [Account-page](https://hub.upcloud.com/account) in your UpCloud Hub. |
|||
|
|||
Copy the cluster configuration file. |
|||
|
|||
```bash |
|||
CLUSTER=my-upcloud-cluster |
|||
cp -r inventory/sample inventory/$CLUSTER |
|||
cp contrib/terraform/upcloud/cluster-settings.tfvars inventory/$CLUSTER/ |
|||
export ANSIBLE_CONFIG=ansible.cfg |
|||
cd inventory/$CLUSTER |
|||
``` |
|||
|
|||
Edit `cluster-settings.tfvars` to match your requirement. |
|||
|
|||
Run Terraform to create the infrastructure. |
|||
|
|||
```bash |
|||
terraform init ../../contrib/terraform/upcloud |
|||
terraform apply --var-file cluster-settings.tfvars \ |
|||
-state=tfstate-$CLUSTER.tfstate \ |
|||
../../contrib/terraform/upcloud/ |
|||
``` |
|||
|
|||
You should now have a inventory file named `inventory.ini` that you can use with kubespray. |
|||
You can use the inventory file with kubespray to set up a cluster. |
|||
|
|||
It is a good idea to check that you have basic SSH connectivity to the nodes. You can do that by: |
|||
|
|||
```bash |
|||
ansible -i inventory.ini -m ping all |
|||
``` |
|||
|
|||
You can setup Kubernetes with kubespray using the generated inventory: |
|||
|
|||
```bash |
|||
ansible-playbook -i inventory.ini ../../cluster.yml -b -v |
|||
``` |
|||
|
|||
## Teardown |
|||
|
|||
You can teardown your infrastructure using the following Terraform command: |
|||
|
|||
```bash |
|||
terraform destroy --var-file cluster-settings.tfvars \ |
|||
-state=tfstate-$CLUSTER.tfstate \ |
|||
../../contrib/terraform/upcloud/ |
|||
``` |
|||
|
|||
## Variables |
|||
|
|||
* `hostname`: A valid domain name, e.g. example.com. The maximum length is 128 characters. |
|||
* `template_name`: The name or UUID of a base image |
|||
* `username`: a user to access the nodes |
|||
* `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 |
@ -0,0 +1,58 @@ |
|||
|
|||
# See: https://developers.upcloud.com/1.3/5-zones/ |
|||
zone = "fi-hel1" |
|||
username = "ubuntu" |
|||
|
|||
inventory_file = "inventory.ini" |
|||
|
|||
# A valid domain name, e.g. host.example.com. The maximum length is 128 characters. |
|||
hostname = "example.com" |
|||
|
|||
# Set the operating system using UUID or exact name |
|||
template_name = "Ubuntu Server 20.04 LTS (Focal Fossa)" |
|||
|
|||
ssh_public_keys = [ |
|||
# Put your public SSH key here |
|||
"ssh-rsa public key 1", |
|||
"ssh-rsa public key 2", |
|||
] |
|||
|
|||
#check list of available plan https://developers.upcloud.com/1.3/7-plans/ |
|||
machines = { |
|||
"master-0" : { |
|||
"node_type" : "master", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
}, |
|||
"worker-0" : { |
|||
"node_type" : "worker", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
}, |
|||
"worker-1" : { |
|||
"node_type" : "worker", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
}, |
|||
"worker-2" : { |
|||
"node_type" : "worker", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
} |
|||
} |
@ -0,0 +1,55 @@ |
|||
|
|||
terraform { |
|||
required_version = ">= 0.13.0" |
|||
} |
|||
provider "upcloud" { |
|||
# Your UpCloud credentials are read from environment variables: |
|||
username = var.UPCLOUD_USERNAME |
|||
password = var.UPCLOUD_PASSWORD |
|||
} |
|||
|
|||
module "kubernetes" { |
|||
source = "./modules/kubernetes-cluster" |
|||
|
|||
zone = var.zone |
|||
hostname = var.hostname |
|||
|
|||
template_name = var.template_name |
|||
username = var.username |
|||
|
|||
machines = var.machines |
|||
|
|||
ssh_public_keys = var.ssh_public_keys |
|||
} |
|||
|
|||
# |
|||
# Generate ansible inventory |
|||
# |
|||
|
|||
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", |
|||
keys(module.kubernetes.master_ip), |
|||
values(module.kubernetes.master_ip), |
|||
range(1, length(module.kubernetes.master_ip) + 1))) |
|||
connection_strings_worker = join("\n", formatlist("%s ansible_user=ubuntu ansible_host=%s", |
|||
keys(module.kubernetes.worker_ip), |
|||
values(module.kubernetes.worker_ip))) |
|||
list_master = join("\n", formatlist("%s", |
|||
keys(module.kubernetes.master_ip))) |
|||
list_worker = join("\n", formatlist("%s", |
|||
keys(module.kubernetes.worker_ip))) |
|||
} |
|||
} |
|||
|
|||
resource "null_resource" "inventories" { |
|||
provisioner "local-exec" { |
|||
command = "echo '${data.template_file.inventory.rendered}' > ${var.inventory_file}" |
|||
} |
|||
|
|||
triggers = { |
|||
template = data.template_file.inventory.rendered |
|||
} |
|||
} |
@ -0,0 +1,66 @@ |
|||
|
|||
resource "upcloud_server" "master" { |
|||
for_each = { |
|||
for name, machine in var.machines : |
|||
name => machine |
|||
if machine.node_type == "master" |
|||
} |
|||
|
|||
hostname = "${each.key}.${var.hostname}" |
|||
cpu = each.value.cpu |
|||
mem = each.value.mem |
|||
zone = var.zone |
|||
|
|||
template { |
|||
storage = var.template_name |
|||
size = each.value.disk_size |
|||
} |
|||
|
|||
# Network interfaces |
|||
network_interface { |
|||
type = "public" |
|||
} |
|||
|
|||
network_interface { |
|||
type = "utility" |
|||
} |
|||
# 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 |
|||
|
|||
template { |
|||
storage = var.template_name |
|||
size = each.value.disk_size |
|||
} |
|||
|
|||
# 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 |
|||
} |
|||
} |
@ -0,0 +1,14 @@ |
|||
|
|||
output "master_ip" { |
|||
value = { |
|||
for instance in upcloud_server.master : |
|||
instance.hostname => instance.network_interface[0].ip_address |
|||
} |
|||
} |
|||
|
|||
output "worker_ip" { |
|||
value = { |
|||
for instance in upcloud_server.worker : |
|||
instance.hostname => instance.network_interface[0].ip_address |
|||
} |
|||
} |
@ -0,0 +1,25 @@ |
|||
variable "zone" { |
|||
type = string |
|||
} |
|||
|
|||
variable "hostname"{ |
|||
default ="example.com" |
|||
} |
|||
|
|||
variable "template_name"{} |
|||
|
|||
variable "username"{} |
|||
|
|||
variable "machines" { |
|||
description = "Cluster machines" |
|||
type = map(object({ |
|||
node_type = string |
|||
cpu = string |
|||
mem = string |
|||
disk_size = number |
|||
})) |
|||
} |
|||
|
|||
variable "ssh_public_keys" { |
|||
type = list(string) |
|||
} |
@ -0,0 +1,10 @@ |
|||
|
|||
terraform { |
|||
required_providers { |
|||
upcloud = { |
|||
source = "UpCloudLtd/upcloud" |
|||
version = "~>2.0.0" |
|||
} |
|||
} |
|||
required_version = ">= 0.13" |
|||
} |
@ -0,0 +1,8 @@ |
|||
|
|||
output "master_ip" { |
|||
value = module.kubernetes.master_ip |
|||
} |
|||
|
|||
output "worker_ip" { |
|||
value = module.kubernetes.worker_ip |
|||
} |
@ -0,0 +1,56 @@ |
|||
# See: https://developers.upcloud.com/1.3/5-zones/ |
|||
zone = "fi-hel1" |
|||
username = "ubuntu" |
|||
|
|||
inventory_file = "inventory.ini" |
|||
|
|||
# A valid domain name, e.g. host.example.com. The maximum length is 128 characters. |
|||
hostname = "example.com" |
|||
|
|||
# Set the operating system using UUID or exact name |
|||
template_name = "Ubuntu Server 20.04 LTS (Focal Fossa)" |
|||
ssh_public_keys = [ |
|||
# Put your public SSH key here |
|||
"ssh-rsa I-did-not-read-the-docs", |
|||
"ssh-rsa I-did-not-read-the-docs 2", |
|||
] |
|||
|
|||
check list of available plan https://developers.upcloud.com/1.3/7-plans/ |
|||
machines = { |
|||
"master-0" : { |
|||
"node_type" : "master", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
}, |
|||
"worker-0" : { |
|||
"node_type" : "worker", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
}, |
|||
"worker-1" : { |
|||
"node_type" : "worker", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
}, |
|||
"worker-2" : { |
|||
"node_type" : "worker", |
|||
#number of cpu cores |
|||
"cpu" : "2", |
|||
#memory size in MB |
|||
"mem" : "4096" |
|||
# The size of the storage in GB |
|||
"disk_size" : 250 |
|||
} |
|||
} |
@ -0,0 +1 @@ |
|||
../../../../inventory/sample/group_vars/ |
@ -0,0 +1,17 @@ |
|||
|
|||
[all] |
|||
${connection_strings_master} |
|||
${connection_strings_worker} |
|||
|
|||
[kube-master] |
|||
${list_master} |
|||
|
|||
[etcd] |
|||
${list_master} |
|||
|
|||
[kube-node] |
|||
${list_worker} |
|||
|
|||
[k8s-cluster:children] |
|||
kube-master |
|||
kube-node |
@ -0,0 +1,35 @@ |
|||
|
|||
variable "zone" { |
|||
description = "The zone where to run the cluster" |
|||
} |
|||
|
|||
variable "hostname" { |
|||
default = "example.com" |
|||
} |
|||
|
|||
variable "template_name" {} |
|||
|
|||
variable "username" {} |
|||
|
|||
variable "machines" { |
|||
description = "Cluster machines" |
|||
type = map(object({ |
|||
node_type = string |
|||
cpu = string |
|||
mem = string |
|||
disk_size = number |
|||
})) |
|||
} |
|||
|
|||
variable "ssh_public_keys" { |
|||
description = "List of public SSH keys which are injected into the VMs." |
|||
type = list(string) |
|||
} |
|||
|
|||
variable "inventory_file" { |
|||
description = "Where to store the generated inventory file" |
|||
} |
|||
|
|||
variable "UPCLOUD_USERNAME" {} |
|||
|
|||
variable "UPCLOUD_PASSWORD" {} |
@ -0,0 +1,10 @@ |
|||
|
|||
terraform { |
|||
required_providers { |
|||
upcloud = { |
|||
source = "UpCloudLtd/upcloud" |
|||
version = "~>2.0.0" |
|||
} |
|||
} |
|||
required_version = ">= 0.13" |
|||
} |
Write
Preview
Loading…
Cancel
Save