Skip to content

Commit

Permalink
feat: setup initial module
Browse files Browse the repository at this point in the history
Co-authored-by: Julian Tölle <[email protected]>
  • Loading branch information
jooola and apricote committed Jun 27, 2024
1 parent cdefe1b commit 79c14ce
Show file tree
Hide file tree
Showing 17 changed files with 669 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Lint

on:
push:
branches: [main]
pull_request:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: opentofu/setup-opentofu@v1
with:
tofu_version: v1.7.2 # renovate: datasource=github-releases depName=opentofu/opentofu
tofu_wrapper: false

- run: |
tofu validate
tofu fmt
- name: Check uncommitted changes
run: git diff --exit-code

- if: failure()
run: echo "::error::Check failed, please run 'tofu validate; tofu fmt' and commit the changes."
64 changes: 64 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Test

on:
push:
branches: [main]
pull_request:

jobs:
example:
runs-on: ubuntu-latest

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
id-token: write # Required by hetznercloud/tps-action

defaults:
run:
working-directory: example

steps:
- uses: actions/checkout@v4

- uses: opentofu/setup-opentofu@v1
with:
tofu_version: v1.7.2 # renovate: datasource=github-releases depName=opentofu/opentofu
tofu_wrapper: false

- uses: yokawasa/[email protected]
with:
setup-tools: |
kubectl
skaffold
kubectl: v1.29.6 # renovate: datasource=github-releases depName=kubernetes/kubernetes
skaffold: v2.12.0 # renovate: datasource=github-releases depName=GoogleContainerTools/skaffold

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

- uses: hetznercloud/tps-action@main

- name: Swap module source
run: sed -i -e 's|source = ".*"|source = ".."|' main.tf

- name: Setup environment
run: make up

- name: Verify environment
run: |
source files/env.sh
kubectl wait --for=condition=Ready --all node
kubectl wait --for=condition=Ready --all --all-namespaces deployment
kubectl wait --for=condition=Ready --all --all-namespaces pod
skaffold run ../test-app
kubectl wait --for=condition=Ready --all pod -l app=test-app
- name: Cleanup
if: always()
run: make down
30 changes: 30 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-executables-have-shebangs
- id: check-shebang-scripts-are-executable
- id: check-symlinks
- id: destroyed-symlinks

- id: check-json
- id: check-yaml
- id: check-toml

- id: check-merge-conflict
- id: end-of-file-fixer
- id: mixed-line-ending
args: [--fix=lf]
- id: trailing-whitespace

- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier
files: \.(md|ya?ml)$
exclude: ^CHANGELOG.md$
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,39 @@ This repository contains a terraform module used to setup a Kubernetes developme

> [!WARNING]
> This project is not an official Hetzner Cloud Integration and is intended to be used internally. There is no backwards-compatibility promise.
## Usage

To setup a development environment, make sure you installed the following tools:

- [tofu](https://opentofu.org/)
- [k3sup](https://github.com/alexellis/k3sup)

1. Configure a `HCLOUD_TOKEN` in your shell session.

> [!WARNING]
> The development environment runs on Hetzner Cloud servers which will induce costs.
2. Deploy the development cluster:

```sh
make -C dev up
```

3. Load the generated configuration to access the development cluster:

```sh
source files/env.sh
```

4. Check that the development cluster is healthy:

```sh
kubectl get nodes -o wide
```

⚠️ Do not forget to clean up the development cluster once are finished:

```sh
make -C dev down
```
9 changes: 9 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.terraform*
terraform.tfstate
terraform.tfstate.backup
*.auto.tfvars

files/*
!files/.gitkeep

.env
27 changes: 27 additions & 0 deletions example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
SHELL = bash
.ONESHELL:

ENV ?= dev
K3S_CHANNEL ?= stable

env.auto.tfvars:
@echo 'name = "$(ENV)"' > "$@"
@echo 'hcloud_token = "$(HCLOUD_TOKEN)"' >> "$@"
@echo 'k3s_channel = "$(K3S_CHANNEL)"' >> "$@"

.terraform:
tofu init

up: .terraform env.auto.tfvars
tofu apply -auto-approve
$(MAKE) port-forward

down: .terraform env.auto.tfvars
tofu destroy -auto-approve

port-forward:
source files/env.sh
bash files/registry-port-forward.sh

clean:
rm -Rf files/* .terraform* terraform.tfstate* env.auto.tfvars
8 changes: 8 additions & 0 deletions example/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module "dev" {
source = "github.com/hetznercloud/terraform-k8s-dev?ref=0.1.0"

name = "k8s-dev-${replace(var.name, "/[^a-zA-Z0-9-_]/", "-")}"
hcloud_token = var.hcloud_token

k3s_channel = var.k3s_channel
}
10 changes: 10 additions & 0 deletions example/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
variable "name" {
type = string
}
variable "hcloud_token" {
type = string
sensitive = true
}
variable "k3s_channel" {
type = string
}
102 changes: 102 additions & 0 deletions main-infra.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Setup the infrastructure

provider "hcloud" {
token = var.hcloud_token
}

locals {
labels = {
env = var.name
}
}

# SSH Key

resource "tls_private_key" "ssh" {
algorithm = "ED25519"
}

resource "local_sensitive_file" "ssh" {
content = tls_private_key.ssh.private_key_openssh
filename = abspath("${path.root}/files/id_ed25519")
}

resource "hcloud_ssh_key" "default" {
name = var.name
public_key = tls_private_key.ssh.public_key_openssh
labels = local.labels
}

# Network

resource "hcloud_network" "cluster" {
name = var.name
ip_range = "10.0.0.0/8"
labels = local.labels
}

resource "hcloud_network_subnet" "cluster" {
network_id = hcloud_network.cluster.id
network_zone = "eu-central"
type = "cloud"
ip_range = "10.0.0.0/24"
}

# Control Plane Node

resource "hcloud_server" "control" {
name = "${var.name}-control"
server_type = var.hcloud_server_type
location = var.hcloud_location
image = var.hcloud_image
ssh_keys = [hcloud_ssh_key.default.id]
labels = local.labels

connection {
host = self.ipv4_address
private_key = tls_private_key.ssh.private_key_openssh
}

provisioner "remote-exec" {
inline = ["cloud-init status --wait || test $? -eq 2"]
}
}

resource "hcloud_server_network" "control" {
server_id = hcloud_server.control.id
subnet_id = hcloud_network_subnet.cluster.id
}

# Worker / Agent Nodes

variable "worker_count" {
type = number
default = 3
}

resource "hcloud_server" "worker" {
count = var.worker_count

name = "${var.name}-worker-${count.index}"
server_type = var.hcloud_server_type
location = var.hcloud_location
image = var.hcloud_image
ssh_keys = [hcloud_ssh_key.default.id]
labels = local.labels

connection {
host = self.ipv4_address
private_key = tls_private_key.ssh.private_key_openssh
}

provisioner "remote-exec" {
inline = ["cloud-init status --wait || test $? -eq 2"]
}
}

resource "hcloud_server_network" "worker" {
count = var.worker_count

server_id = hcloud_server.worker[count.index].id
subnet_id = hcloud_network_subnet.cluster.id
}
Loading

0 comments on commit 79c14ce

Please sign in to comment.