Crossplane mit Hetzner hcloud verwenden
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:
-
Erstellung von GitHub (oder privates git) Repository auf Basis von https://github.com/crossplane/upjet-provider-template.git
-
Installation der git Submodules
make submodules
-
Einrichtung des Repository
./hack/prepare.sh
-
Anpassung der Terraform Referenz in
Makefile
-
Anpassung der Credentials in
internal/client/{provider}.go
-
Mapping der Ressourcen Identifier in
config/external_name.go
( https://github.com/crossplane/upjet/blob/main/docs/configuring-a-resource.md#external-name ) -
Erzeugung von Konfigurationen pro ressource
mkdir config/{resource}
-
Registrierung der Konfigurationen in
config/provider.go
-
Installation von goimports
go install golang.org/x/tools/cmd/goimports@latest
-
Erzeugung des Providers
make generate
-
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.
$ 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.
$ kubectl create ns crossplane-system
$ kubectl apply -f package/crds
$ make run # benoetigt lokales terraform
Eine passende Konfiguration wird ebenfalls benötigt.
$ 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.