Skip to content

Commit

Permalink
☄️ Add Terraform support to deploy Kapsule clusters
Browse files Browse the repository at this point in the history
  • Loading branch information
jpetazzo committed Oct 3, 2021
1 parent fb8efbe commit 47766be
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
*.pyc
*.swp
*~

prepare-vms/tags
prepare-vms/infra
prepare-vms/www

prepare-scw/.terraform*
prepare-scw/terraform.*
prepare-scw/stage2/*.tf
prepare-scw/stage2/kubeconfig.*
prepare-scw/stage2/wildcard_dns.*

slides/*.yml.html
slides/autopilot/state.yaml
slides/index.html
Expand Down
15 changes: 15 additions & 0 deletions prepare-scw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
This directory contains a Terraform configuration to deploy
a bunch of Kubernetes clusters on Scaleway, using their managed
Kubernetes (Kapsule).

To use it:

```bash
scw init
terraform init
terraform apply
cd stage2
terraform apply
```

Edit `variables.tf` to change the number of clusters.
18 changes: 18 additions & 0 deletions prepare-scw/kapsule_cluster/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
resource "scaleway_k8s_cluster" "my_cluster" {
name = var.cluster_name
tags = var.common_tags
version = var.k8s_version
cni = var.cni
}

resource "scaleway_k8s_pool" "my_pool" {
cluster_id = scaleway_k8s_cluster.my_cluster.id
name = "pool-0"
tags = var.common_tags
node_type = var.node_type
size = var.pool_size
min_size = var.pool_min_size
max_size = var.pool_max_size
autoscaling = true
autohealing = true
}
11 changes: 11 additions & 0 deletions prepare-scw/kapsule_cluster/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "kubeconfig" {
value = scaleway_k8s_cluster.my_cluster.kubeconfig
}

output "cluster_id" {
value = scaleway_k8s_cluster.my_cluster.id
}

output "wildcard_dns" {
value = scaleway_k8s_cluster.my_cluster.wildcard_dns
}
17 changes: 17 additions & 0 deletions prepare-scw/kapsule_cluster/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
terraform {
required_providers {
scaleway = {
source = "scaleway/scaleway"
version = "2.0.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.0.3"
}
local = {
source = "hashicorp/local"
version = "2.1.0"
}
}
required_version = ">= 0.14"
}
39 changes: 39 additions & 0 deletions prepare-scw/kapsule_cluster/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
variable "cluster_name" {
type = string
default = "deployed-with-terraform"
}

variable "cni" {
type = string
default = "cilium"
}

variable "common_tags" {
type = list(string)
default = []
}

variable "k8s_version" {
type = string
default = "1.22.2"
}

variable "node_type" {
type = string
default = "DEV1-M"
}

variable "pool_size" {
type = number
default = 2
}

variable "pool_min_size" {
type = number
default = 1
}

variable "pool_max_size" {
type = number
default = 5
}
6 changes: 6 additions & 0 deletions prepare-scw/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
locals {
# Common tags to be assigned to all resources
common_tags = [
"created-by=terraform"
]
}
29 changes: 29 additions & 0 deletions prepare-scw/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module "kapsule_cluster" {
count = var.how_many_clusters
source = "./kapsule_cluster"
cluster_name = format("tf-%03d", count.index + 101)
}

output "kubectl_config" {
value = format("scw k8s kubeconfig install %s", split("/", module.kapsule_cluster.0.cluster_id)[1])
}

resource "local_file" "stage2" {
filename = "${path.module}/stage2/main.tf"
content = templatefile(
"${path.module}/stage2.tmpl",
{ count = var.how_many_clusters }
)
}

resource "local_file" "kubeconfig" {
count = var.how_many_clusters
filename = format("%s/stage2/kubeconfig.%03d", path.module, count.index + 101)
content = module.kapsule_cluster[count.index].kubeconfig.0.config_file
}

resource "local_file" "wildcard_dns" {
count = var.how_many_clusters
filename = format("%s/stage2/wildcard_dns.%03d", path.module, count.index + 101)
content = trimprefix(module.kapsule_cluster[count.index].wildcard_dns, "*.")
}
16 changes: 16 additions & 0 deletions prepare-scw/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
terraform {
required_providers {
scaleway = {
source = "scaleway/scaleway"
version = "2.0.0"
}
}
required_version = ">= 0.14"
}

provider "scaleway" {
#zone = "nl-ams-1"
#region = "nl-ams"
#project_id = "7ee16446-7711-4171-a7c2-4bb6f0d4c4c8"
}

136 changes: 136 additions & 0 deletions prepare-scw/stage2.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "2.0.3"
}
}
required_version = ">= 0.14"
}


%{ for index in range(101, 101+count) ~}

provider "kubernetes" {
alias = "kapsule_cluster_${index}"
config_path = "$${path.module}/kubeconfig.${index}"
}

resource "kubernetes_namespace" "sshpod_${index}" {
provider = kubernetes.kapsule_cluster_${index}
metadata {
name = "sshpod"
}
}

resource "kubernetes_deployment" "sshpod_${index}" {
provider = kubernetes.kapsule_cluster_${index}
metadata {
name = "sshpod"
namespace = kubernetes_namespace.sshpod_${index}.metadata.0.name
}
spec {
selector {
match_labels = {
app = "sshpod"
}
}
template {
metadata {
labels = {
app = "sshpod"
}
}
spec {
service_account_name = "sshpod"
container {
image = "jpetazzo/sshpod"
name = "sshpod"
env {
name = "PASSWORD"
value = random_string.sshpod_${index}.result
}
lifecycle {
post_start {
exec {
command = [ "sh", "-c", "curl http://myip.enix.org/REMOTE_ADDR > /etc/HOSTIP || true" ]
}
}
}
resources {
limits = {
cpu = "2"
memory = "100M"
}
requests = {
cpu = "100m"
memory = "100M"
}
}
}
}
}
}
}

resource "kubernetes_service" "sshpod_${index}" {
provider = kubernetes.kapsule_cluster_${index}
metadata {
name = "sshpod"
namespace = kubernetes_namespace.sshpod_${index}.metadata.0.name
}
spec {
selector = {
app = "sshpod"
}
port {
port = 22
target_port = 22
node_port = 32222
}
type = "NodePort"
}
}

resource "kubernetes_service_account" "sshpod_${index}" {
provider = kubernetes.kapsule_cluster_${index}
metadata {
name = "sshpod"
namespace = kubernetes_namespace.sshpod_${index}.metadata.0.name
}
}

resource "kubernetes_cluster_role_binding" "sshpod_${index}" {
provider = kubernetes.kapsule_cluster_${index}
metadata {
name = "sshpod"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "cluster-admin"
}
subject {
kind = "ServiceAccount"
name = "sshpod"
namespace = "sshpod"
}
}

resource "random_string" "sshpod_${index}" {
length = 6
special = false
upper = false
}

output "ssh_${index}" {
value = format(
"ssh -l %s -p %s ssh.%s # password=%s",
"k8s",
"32222",
file(format("%s/wildcard_dns.%03d", path.module, ${index})),
random_string.sshpod_${index}.result
)
}

%{ endfor ~}
1 change: 1 addition & 0 deletions prepare-scw/stage2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This directory will only contain generated files.
4 changes: 4 additions & 0 deletions prepare-scw/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variable "how_many_clusters" {
type = number
default = 2
}

0 comments on commit 47766be

Please sign in to comment.