Neuigkeiten von trion.
Immer gut informiert.

Crossplane mit Hetzner hcloud verwenden

Kubernetes

Im Beitrag Crossplane Tutorial wurde Crossplane als Werkzeug zur Infrastrukturautomatisierung vorgestellt. In diesem Beitrag wird der Einsatz von Crossplane für die Hetzner Cloud gezeigt. Dabei wird auch betrachtet, wie neue Provider für Crossplane durch Wiederverwendung bestehender Terraform Plugins bereitgestellt werden können.

Crossplane Upjet

Crossplane ist relativ gesehen ein junges Projekt. Entsprechend viel Ressourcen wären erforderlich, um für das umfangreiche Ökosystem an Cloudprodukten individuell Provider zu programmieren und zu warten. Für die meisten Cloudprodukte gibt es jedoch bereits Libraries, sei es für Ansible oder dem Platzhirsch Terraform.
Crossplane hat mit dem Upjet (ehemals "Terrajet") Projekt eine Bridge geschaffen, mit der sich Terraform Plugins für Crossplane nutzbar machen.

Die prinzipielle Verwendung gestaltet sich dabei wie folgt:

  1. Erstellung von GitHub (oder privates git) Repository auf Basis von https://github.com/crossplane/upjet-provider-template.git

  2. Installation der git Submodules make submodules

  3. Einrichtung des Repository ./hack/prepare.sh

  4. Anpassung der Terraform Referenz in Makefile

  5. Anpassung der Credentials in internal/client/{provider}.go

  6. Mapping der Ressourcen Identifier in config/external_name.go ( https://github.com/crossplane/upjet/blob/main/docs/configuring-a-resource.md#external-name )

  7. Erzeugung von Konfigurationen pro ressource mkdir config/{resource}

  8. Registrierung der Konfigurationen in config/provider.go

  9. Installation von goimports go install golang.org/x/tools/cmd/goimports@latest

  10. Erzeugung des Providers make generate

  11. Test des Providers mit make run

Eine genaue Anleitung ist unter https://github.com/crossplane/upjet/blob/main/docs/generating-a-provider.md zu finden. Mehr Informationen zu Crossplane Upjet finden sich auf der Projekthomepage und in diesem Blogpost: https://blog.crossplane.io/deep-dive-terrajet-part-i/

Crossplane Hetzner hcloud Beispiel

Bei Hetzner handelt es sich um einen deutschen Anbieter, der insbesondere durch preiswerte Infrastruktur bekannt ist. Hetzner hat dabei kontinuierlich in den Ausbau der eigenen Infrastruktur als auch in Automatisierung investiert. Seit einigen Jahren bietet Hetzner neben physischen Servern auch eine Cloud auf Basis virtueller Maschinen an.
Inzwischen ist Hetzner auch in anderen europäischen Ländern und sogar den USA mit Rechenzentren vertreten. Im Vergleich zu Amazon, Azure oder der Google Cloud handelt es sich bei Hetzner um einen kleinen Anbieter. Dennoch existiert eine Integration für Ansible und auch Terraform.

Um die Hetzner hcloud mit Crossplane zu nutzen wird ein entsprechender Provider benötigt. Hier kann Upjet als Bridge für den existierenden Terraform Provider aushelfen.

Mit Upjet gibt es verschiedene Integrationen der Hetzner hcloud:

Die Installation des Upjet basierten Providers erfolgt vergleichbar mit anderen Providern. Alternativ kann auch ein eigener Provider basierend auf dem Upjet-Template verwendet werden.

Übersicht der Konfiguration
$ git clone https://github.com/crossplane/upjet-provider-template.git provider-hetzner-hcloud
$ cd provider-hetzner-hcloud
$ ./hack/prepare.sh
+ read -r -p 'Lower case provider name (ex. github): ' PROVIDER_NAME_LOWER
Lower case provider name (ex. github): hetzner-hcloud
+ read -r -p 'Normal case provider name (ex. GitHub): ' PROVIDER_NAME_NORMAL
Normal case provider name (ex. GitHub): Hetzner hcloud
+ read -r -p 'Organization (ex. upbound, my-org-name): ' ORGANIZATION_NAME
Organization (ex. upbound, my-org-name): trion-development
+ read -r -p 'CRD rootGroup (ex. upbound.io, crossplane.io): ' CRD_ROOT_GROUP
CRD rootGroup (ex. upbound.io, crossplane.io): crossplane.io
$ nano Makefile

export TERRAFORM_PROVIDER_SOURCE := hetznercloud/hcloud
export TERRAFORM_PROVIDER_REPO := https://github.com/hetznercloud/terraform-provider-hcloud
export TERRAFORM_PROVIDER_VERSION := 1.44.1
export TERRAFORM_PROVIDER_DOWNLOAD_NAME := https://github.com/hetznercloud/terraform-provider-hcloud/releases/download/v1.44.1
export TERRAFORM_NATIVE_PROVIDER_BINARY := https://releases.hashicorp.com/terraform-provider-hcloud/1.44.1/
export TERRAFORM_DOCS_PATH := website/docs/r

$ nano internal/clients/hetzner-hcloud.go

const (
	keyToken        = "token"
	keyEndpoint     = "endpoint"
	keyPollInterval = "poll_interval"
)
...
        // set provider configuration
		ps.Configuration = map[string]interface{}{
            "token":         creds[keyToken],
			"endpoint":      creds[keyEndpoint],
			"poll_interval": creds[keyPollInterval],
		}

$ nano config/external_name.go

"hcloud_server": config.NameAsIdentifier,

$ mkdir config/hcloud_server
$ nano config/hcloud_server/config.go

package hcloud_server

import "github.com/crossplane/upjet/pkg/config"

func Configure(p *config.Provider) {
    p.AddResourceConfigurator("hcloud_server", func(r *config.Resource) {
        r.ShortGroup = "hcloud-server" // API Group Namensvorgaben beachten
    })
}

$ nano config/provider.go
import (
...
	"github.com/trion-development/provider-hetzner-hcloud/config/hcloud_server"
)
...
for _, configure := range []func(provider *ujconfig.Provider){
		hcloud_server.Configure,
	} {
...
$ go install golang.org/x/tools/cmd/goimports@latest
$ make generate

Verwendung des Providers

Um den frisch erstellten Provider zu testen sollte zunächst ein Testprojekt bei Hetzner erzeugt werden. Das Projekt könnte zum Beispiel crossplane heißen. In dem Projekt wird dann ein Access-Token mit Lese- und Schreibrechten erzeugt. In unserem Beispiel ist der Wert LgoO42jrifaJS8YrSCEXDxzHu2Cph1qTLebMsSPZSXlSbQzwfECDvLmtNn63qmfp.

Der Provider kann nun lokal zusammen mit einem Kubernetes Cluster getestet werden.

Lokaler Start des Providers
$ kubectl create ns crossplane-system
$ kubectl apply -f package/crds
$ make run # benoetigt lokales terraform

Eine passende Konfiguration wird ebenfalls benötigt.

Beispielkonfiguration mit Secret, ProviderConfig und einer Hetzner Server Ressource
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  namespace: crossplane-system
  name: hcloud-token
type: Opaque
stringData:
  credentials: |
    {
      "token": "LgoO42jrifaJS8YrSCEXDxzHu2Cph1qTLebMsSPZSXlSbQzwfECDvLmtNn63qmfp"
    }
EOF

$ cat <<EOF | kubectl apply -f -
apiVersion: hetzner-hcloud.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
  name: staging
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: hcloud-token
      key: credentials
EOF

$ cat <<EOF | kubectl apply -f -
apiVersion: hcloud-server.crossplane.io/v1alpha1
kind: Server
metadata:
  annotations:
    meta.upbound.io/example-id: hcloud-server/v1alpha1/server
  labels:
    testing.upbound.io/example-name: node1
  name: node1
spec:
  providerConfigRef:
    name: staging
  forProvider:
    image: "ubuntu-22.04"
    location: "fsn1"
    publicNet:
    - ipv4Enabled: true
      ipv6Enabled: true
    serverType: cx11
    keepDisk: false
    backups: false
    rebuildProtection: false
    deleteProtection: false
    shutdownBeforeDeletion: false
    ignoreRemoteFirewallIds: true
    allowDeprecatedImages: false
EOF

Das funktioniert soweit, der Server wird erzeugt und kann auch wieder gelöscht werden.
Damit ist der Provider natürlich noch nicht fertig, da Hetzner viele weitere Resourcen neben virtuellen Servern anbietet.

Der nächste Schritt wäre es, SSH Keys bereitzustellen, damit der Server auch nutzbar wird. Auch gibt es noch eine Issue, die die Referenzierung von Hetzner Resourcen aktuell verhinder, da diese eine Zahl statt String als Typen verwenden: https://github.com/crossplane/upjet/issues/91

Fazit Crossplane Provider Hetzner hcloud

Dank Upjet ist es möglich die Hetzner hcloud auf einfache Weise durch Crossplane anzusteuern. Im Vergleich zu Terraform oder Ansible kann Kubernetes als Abstraktion genutzt werden, so dass eine automatische Ausführung und Trennung der Verantwortlichkeiten möglich ist. In der Praxis können vergleichbare Lösungen auf Basis von CI Jobs, Ansible Tower oder der Terraform Cloud vorgefunden werden. Keine der anderen Lösungen bietet im Vergleich zu Crossplane dabei eine so einfach anzubindende API, mit der sich höherwertige Lösungen schaffen lassen.




Zu den Themen Kubernetes, Docker und Cloudarchitektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:

Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.

Feedback oder Fragen zu einem Artikel - per Twitter @triondevelop oder E-Mail freuen wir uns auf eine Kontaktaufnahme!

Los geht's!

Bitte teilen Sie uns mit, wie wir Sie am besten erreichen können.