Oracle bietet viele Möglichkeiten, den Lebensyzklus von Oracle Datenbanken jeder Couleur im hauseigenen Cloud Stack zu automatisieren, egal wo dieser läuft – ob OCI, Azure, AWS, Google oder in einer privaten bzw. souveränen Cloud. Welcher Resource Manager passt am besten zu Ihnen ? Nach einer möglichst kurzen Liste mit Beschreibungen möchte ich auf ein Beispiel mit dem neuesten CrossPlane Provider for OCI eingehen, der unter Kubernetes läuft.

Infrastruktur als Code, Zustandsverwaltung mit Soll-ist-Vergleich, standardisiert oder quasi-standard, das ist bei fast allen Teilnehmern der nachfolgenden Liste gegeben. Verwenden Sie einfach die Methode, die Ihnen am meisten liegt, mit der Sie am vertrautesten sind oder die am vielversprechendsten klingt.

  • Terraform und Terraform Provider für OCI:
    Der von Oracle stammende Provider ist herunterladbar von github als OpenSource Projekt. Der Terraform-Kern und Provider für OCI sind als kostenloser “Resource Manager” Service in OCI enthalten, benötigen also keine weiteren Vorbedingungen wie eine separate VM oder eine Container Umgebung. Der Kern des Terraform Resource Managers stammt von Hashicorp bzw. RedHat / IBM.
    Der Terraform Provider für OCI nutzt intern die REST API der Oracle Cloud (OCI).
    Ein Update des Providers erfolgt mehrmals monatlich, sobald sich Änderungen oder Erweiterungen in Teilen der OCI REST API ergeben.
Terraform
  • OpenTofu und Provider für OCI:
    Freier Spin-off branch von Terraform , Verfügbar auf opentofu.org
    Benötigt eine separate Installation, ist nicht als “Resource Manager Service” in OCI enthalten.
    Ein Update des Providers erfolgt mehrmals monatlich, sobald sich Änderungen oder Erweiterungen in Teilen der OCI REST API ergeben.
    Der Provider ist nahezu genauso aktuell wie der für Terraform, die Ressourcendefinitionen können übernommen werden bzw. werden zeitnah in das opentofu Repository übernommen.
Opentofu
OpenTF – opentofu
  • OCI REST API (und Ansible):
    Ansible benötigt ebenfalls eine separate Installation. Die OCI REST Services könnten bei Bedarf alternativ direkt aus der Cloud Shell oder mittels oci-cli Kommandozeile aufgerufen werden.
    Ein direkter Zugriff auf die OCI REST API darf über gängige Werkzeuge wie curl erfolgen, die Erzeugung notwendiger Header für den URL Aufruf erfordert meist separate Werkzeuge und JavaScript APIs zur Datenverschlüsselung oder Vorverarbeitung. Eine Beschreibung mit Beispielen finden Sie beispielsweise in diesem Blog.
Ansible / oci-cli
  • Oracle Autonomous Database PL/SQL API DBMS_CLOUD_OCI_*
    Die Oracle Database als Resource Manager nutzen.
    Benötigt eine Oracle Autonomous Database, es könnte auch eine dedizierte Instanz oder PDB sein ohne weitere Nutzdaten darin.
    Datenbank Packages, Funktionen und Datentypen rufen die OCI REST API auf.
    Tipp: Die Oracle Database kann auch GIT repositories nutzen und anbinden über das DBMS_CLOUD_REPO package.
Oracle Autonomous Database
  • KI gestützt durch den Oracle OCI MCP Server
    Benötigt eine separate Installation des OCI MCP servers (bzw. hier der Link zum github Projekt) und Einbindung in KI Tools wie Cline, Copilot oder Oracle Private Agent Factory.
    Unterstützt nicht alle Cloud Services in OCI und auch nicht alle Lifecycle Operationen, aber bestehende Dienste können eingesehen und ausgewertet , gestartet und gestoppt werden.
MCP Server / Private Agent Factory
  • KI gestützt durch in-Database Agents für OCI
    Benötigt eine Oracle Autonomous Database als steuerndes Element und Zugriff auf ein Large Language Model, lokal oder im Internet.
    In der Datenbank definierte Agenten nutzen die PL/SQL API für den Zugriff auf OCI. Diese API existiert momentan nur in einer Autonomous Database.
    Es werden aktuell nicht alle Services der OCI durch Agenten abgedeckt. Die von github herunterladbaren Agenten dienen als Beispiele für die Verwaltung von Autonomous Database, OCI Vault, Object Storage und Load Balancer.
    Die Agenten können mittels SQL API gestartet werden oder abermals in die Private Agent Factory eingebunden und dort in Chats integriert werden. Alternativ ist die Einbindung in die freie APEX Anwendung “Ask Oracle” möglich.
In-Database Agents
  • Oracle Database Operator for Kubernetes (OraOperator)
    Ist in ein bestehendes Kubernetes Cluster (AKS, GKS, OKE, OpenShift…) zu installieren, kann als plugin beim Anlegen eines OKE clusters in OCI ausgewählt werden. Unterstützt zahlreiche Oracle Database Varianten in clouds, on-Premise und auch innerhalb des Kubernetes Clusters. Die im April 2026 aktuelle Version 2.1 unterstützt neben Data Guard nun auch mit RAC abgesicherte Datenbanken, die innerhalb des Kubernetes Clusters betrieben werden sollen. Mehrere Datenbank-Komponenten, die es nicht als Cloud Service gibt wie z.B. ORDS oder Private AI Services Container, können innerhalb von Kubernetes verwaltet werden. OraOperator unterstützt jedoch keine Infrastruktur-Services von OCI.
    Updates müssen daher nicht so häufig erfolgen wie bei Providern, die den Anspruch erheben alle (200+) OCI services zu unterstützen.
OraOperator
  • CrossPlane Provider for OCI
    Ein weiterer Kubernetes Operator, der Kubernetes als Resource Manager nutzt. In diesem Fall wird die Automatisierung von Services in unterschiedlichen Clouds ermöglicht. Crossplane ist erweiterbar um Plugins für verschiedene Clouds wie AWS, Azure und Google sowie um eigene, selbstdefinierte Services, die sich auf irgendeine Weise per REST Protokoll aufrufen lassen (z.B. ansible skripte über einen generischen HTTP provider). Die im April 2026 aktuelle Version 1.0.1 des Crossplane Providers für OCI unterstützt erstmalig neben allen Infrastruktur Diensten der OCI auch alle Plattform-Dienste wie Postgres und mySQL Datenbanken, Oracle Database in allen Ausprägungen wie Autonomous, Exadata, Base Database und auch neue Dienste wie die AI Data Platform.
    Der Crossplane Provider nutzt intern ebenfalls die REST API der Oracle Cloud Infrastruktur (OCI). Die für Kubernetes typischen Ressourcen-Definitionen (CRDs bzw. XRDs im CrossPlane-slang) werden per cross-compiler aus den bestehenden aktuellen Terraform-Strukturen übersetzt und aktuell gehalten.
Crossplane
CrossPlane Provider for OCI


Erste Erfahrungen mit dem CrossPlane Provider for OCI

Installation und Einrichtung gehen recht flott vonstatten und sind im README des github Repository gut beschrieben: einfach das CrossPlane Helm Chart Repository laden und die Installation per helm Kommando anstoßen.
Nach dem Download und Start der CrossPlane Kern-Komponenten (mindestens Version 1.1, besser Version 2.0) sind weitere Container für Teilbereiche der OCI von der github container registry (ghcr.io) herunterzuladen. Nicht benötigte Anteile können weggelassen werden und reduzieren den Wust an zu unterstützenden Kubernetes Ressourcen.
Kleiner Hinweis: der CrossPlane Provider für OCI wurde mit CrossPlane 1.1 übersetzt, funktioniert aber gut mit dem CrossPlane 2.0 und 2.1 Kern zusammen. Er nutzt noch keine CrossPlane 2.x Features, aber die aktuelle Roadmap umfaßt CrossPlane 2.x support, der auch kurzfristig implementiert werden soll.

Um einen Datenbank-Service in OCI zu provisionieren sind mindestens folgende Sub-Provider nötig:

  • oracle-provider-family-oci , bietet Kernfunktionen für OCI an
  • provider-oci-identity, für den Zugriff auf Orga-Strukturen wie Compartments
  • provider-oci-networking, um ein Netzwerk zu definieren oder einzubinden
  • provider-oci-database, der alle denkbaren Oracle Database Service Varianten unterstützt

Die Registrierung der neuen Provider funktioniert nach Kubernetes-Art, indem neue Ressourcen angelegt werden, hier vom Typ pkg.crossplane.io.Provider. Der CrossPlane-Kern kümmert sich dann um die Einrichtung der neuen Provider. Ein “kubectl apply -f” Kommando auf folgende Datei richtet die oben genannten Sub-Provider ein:

apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: oracle-provider-family-oci
spec:
  package: ghcr.io/oracle/provider-family-oci:v1.0.1
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-oci-database
spec:
  package: ghcr.io/oracle/provider-oci-database:v1.0.1
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-oci-identity
spec:
  package: ghcr.io/oracle/provider-oci-identity:v1.0.1
---
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-oci-networking
spec:
  package: ghcr.io/oracle/provider-oci-networking:v1.0.1

Die zugehörigen Container sollten auch bald in Ihrem crossplane-system namespace sichtbar sein:

$ kubectl get pod -n crossplane-system
NAME                                                       READY   STATUS    RESTARTS      AGE
crossplane-794b6bd899-2sgx8                                1/1     Running   0             28d
crossplane-rbac-manager-b6885667b-pmb65                    1/1     Running   1 (41h ago)   28d
oracle-provider-family-oci-2b3022a67775-dbcdddcf9-2d22p    1/1     Running   0             10d
provider-oci-database-a1e1af7fc7ff-5d8cfcd8cd-fnmvw        1/1     Running   0             10d
provider-oci-identity-4492f61491db-6c596cb84c-86n86        1/1     Running   0             9d
provider-oci-networking-1aa2e0844a70-7554546646-gfs45     1/1     Running   0             47h

Nun können wir die Provider mit dem existierenden Tenant in der OCI auf verschiedene Weisen verknüpfen, wie auch im README beschrieben. Ich wählte der Kürze halber den Weg über meinen eigenen Cloud Benutzer und dort hinterlegte API Keys, aber auch sogenannte Instance Principals wären möglich gewesen ohne über einen technischen “dummy user” wie den meinen in OCI zu gehen. Eine oci.m.upbound.io.ProviderConfig Ressource ist anzulegen, die vom CrossPlane Kern interpretiert wird und den Providern die später nötigen Security-Daten übermittelt:

apiVersion: oci.m.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: oci-provider-config
  namespace: crossplane-demo
spec:
  credentials:
    source: Secret
    secretRef:
      name: oci-creds
      namespace: crossplane-demo
      key: credentials

Sie sehen richtig, die Security-Konfiguration wird in einem Kubernetes Secret hinterlegt. In dem Secret sollte sich unter dem genannten key credentials eine JSON Struktur befinden, welche die OCIDs (Oracle Cloud Identifier) und den privaten Schlüssel des OCI Tenants und des Benutzers mit entsprechenden Cloud Berechtigungen enthält. Beispielswiese könnte das Secret wie folgt aussehen, hier als Shell Skript mit verfälschten Daten:

kubectl create secret generic oci-creds \
--namespace=crossplane-demo \
--from-literal=credentials='{
"tenancy_ocid": "ocid1.tenancy.oc1..aaaaaaaanaj36xpawsehrgeheimercontentr7frjixy3lshllsa",
"user_ocid": "ocid1.user.oc1..aaaaaaaajofbzcepdv6jsuperadminuser46uz44uu5ivu6p3ximja",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5fYiOpY0/qUwj\nMXag3Ee3DkD6I.....\n-----END PRIVATE KEY-----\n",
"fingerprint": "9b:f5:18:cf:b1:06:db:hh:ho:ho:he:he:15:ee:a7:ee",
"region": "eu-frankfurt-1",
"auth": "ApiKey"
}'

Ich hatte mich entschlossen, alle neuen Ressourcen in einem eigenen Kubernetes Namespace namens “crossplane-demo” abzulegen. Solche nach Namespace gegliederten Ressourcen sind erst seit Version 1.0 des Providers für OCI möglich, aber funktionieren soweit ich testen konnte.

Ob die Sicherheits-Informationen korrekt waren sehen wir recht schnell, wenn wir versuchen eine bestehende Cloud Ressource einzubinden oder eine neue Ressource anzulegen. Im Status der Ressource finden wir entsprechende Hinweise. Es muß nicht unbedingt im Log des Provider-Containers nachgesehen werden (kubectl logs …..), was aber mitunter hilfreich sein kann.
Zunächst erzeugen wir ein neues Compartment (oder verbinden uns mit einem bestehenden Compartment) in welchem wir einen neuen Database Service erzeugen möchten. Die neue mit kubectl apply anzulegende Kubernetes Ressource sieht in etwa wie folgt aus:

apiVersion: identity.oci.m.upbound.io/v1alpha1
kind: Compartment
metadata:
  labels:
    testing.upbound.io/object-name: compartment-marcel2
  name: marcel2
  namespace: crossplane-demo
spec:
  providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig
  forProvider:
    compartmentId: "ocid1.compartment.oc1..aaaaaaaarq642bv46bdclhgtj3oxp2nuvtp42sqa"
    description: "Marcels Test Compartment"
    name: Marcel2

In Kubernetes heißt die neue Ressource also “marcel2” im Namespace “crossplane-demo” vom Typ “identity.oci.m.upbound.io.Compartment“. Im Oracle Cloud Stack würde ein neues Compartment “Marcel2” angelegt wenn noch nicht vorhanden, oder angebunden wenn bereits existent. Die hier anzugebende OCID bzw. compartmentID ist diejenige des darüberliegenden(!) Compartments, das bereits existieren muss. Im Zweifelsfalle das immer existierende Root-Compartment. Das ist auch in der OCI REST API ganz genau so notwendig wie beispielsweise auch in Terraform.

Das ist beinahe die einzige Stelle, an der in unserer Konfiguration eine OCID in der Cloud Oberfläche nachgeschlagen werden muss (z.B. mittels oci iam compartment list Kommando). Beinahe alle anderen Ressourcen lassen sich ab hier über sogenannte Selektoren, prinzipiell Kubernetes-Pointer oder Namens-Filter, referenzieren. Dafür ist ein stets angegebenes, frei wählbares Label notwendig. Es trägt in unserem Beispiel den Namen “testing.upbound.io/object-name” und den Wert “compartment-marcel2“.

Wurde das Compartment korrekt eingebunden ? Das sehen wir am Status, der sowohl bei SYNCED als auch bei READY nach einer kleinen Weile ein TRUE liefern sollte:

$ kubectl get compartment -n crossplane-demo
NAME      SYNCED   READY   EXTERNAL-NAME                                                                         AGE
marcel2   True     True    ocid1.compartment.oc1..aaaaaaaawy7rmmvmuv42nsagx4cqe5yd6kxrb6vgkc6e73zblexr56br5d4q   2d4h
marcelb   True     True    ocid1.compartment.oc1..aaaaaaaarq642bv46bdumvfvebgsg2b7ci6m2ycclhgtj3oxp2nuvtp42sqa   2d4h

In meiner persönlichen Umgebung habe ich sowohl ein bestehendes Compartment “marcelb” eingebunden als auch ein neues Compartment “marcel2” gleich darunter angelegt.

Übrigens, wenn ich die Compartment-Ressourcen aus Kubernetes lösche (kubectl delete…), dann verschwinden die Compartments NICHT aus der Oracle Cloud. Das ist gewollt so gelöst und in der Dokumentation der OCI REST API auch so erklärt. Viele anderen Ressourcen werden beim Löschen aus Kubernetes allerdings auch aus der Oracle Cloud entfernt wenn möglich, wie z.B. Netzwerke oder Datenbanken.

Kommen wir nun zu einem eher länglichen Teil, dem Anlegen eines neuen Netzwerkes (VCN) mit leider notwendigen Routing Regeln und Zugriff auf den Cloud Storage Dienst, damit die spätere Datenbank auch irgendwo ihre Daten ablegen kann. Hier ein ganzer Block mit Ressourcen-Beschreibungen für ein privates VCN mit Storage Zugriff, alles im Compartment “marcel2” angelegt:

apiVersion: networking.oci.m.upbound.io/v1alpha1
kind: Vcn
metadata:
  labels:
    testing.upbound.io/object-name: vcn-testvcn
  name: testvcn
  namespace: crossplane-demo
spec:
  forProvider:
    cidrBlocks:
      - 10.0.0.0/16
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/object-name: compartment-marcel2
    displayName: testvcn
  providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig
---
apiVersion: networking.oci.m.upbound.io/v1alpha1
kind: ServiceGateway
metadata:
  labels:
    testing.upbound.io/object-name: servicegateway-service1
  name: service1
  namespace: crossplane-demo
spec:
  forProvider:
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/object-name: compartment-marcel2
    displayName: service1
    services:
      # "All FRA Services In Oracle Services Network"
    - serviceId: "ocid1.service.oc1.eu-frankfurt-1.aaaaaaaa7ncsqkj6lkz36dehifizupyn6qjqsmtepsegs23yyntnsy7qrvea"
    vcnIdSelector:
      matchLabels:
        testing.upbound.io/object-name: vcn-testvcn
  providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig
---
apiVersion: networking.oci.m.upbound.io/v1alpha1
kind: NatGateway
metadata:
  labels:
    testing.upbound.io/object-name: natgateway-nat1
  name: nat1
  namespace: crossplane-demo
spec:
  forProvider:
    blockTraffic: false
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/object-name: compartment-marcel2
    displayName: nat1
    vcnIdSelector:
      matchLabels:
        testing.upbound.io/object-name: vcn-testvcn
  providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig
---
apiVersion: networking.oci.m.upbound.io/v1alpha1
kind: RouteTable
metadata:
  labels:
    testing.upbound.io/object-name: routetable-table1
  name: table1
  namespace: crossplane-demo
spec:
  forProvider:
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/object-name: compartment-marcel2
    displayName: table1
    routeRules:
      - destination: 0.0.0.0/0
        destinationType: CIDR_BLOCK
        networkEntityIdSelector:
          matchLabels:
            testing.upbound.io/object-name: natgateway-nat1
      - destinationType: SERVICE_CIDR_BLOCK
        destination: "all-fra-services-in-oracle-services-network"
        networkEntityId:
         matchLabels:
           testing.upbound.io/object-name: servicegateway-service1
    vcnIdSelector:
      matchLabels:
        testing.upbound.io/object-name: vcn-testvcn
  providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig
---
apiVersion: networking.oci.m.upbound.io/v1alpha1
kind: Subnet
metadata:
  labels:
    testing.upbound.io/object-name: subnet-dbsubnet
  name: dbsubnet
  namespace: crossplane-demo
spec:
  forProvider:
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/object-name: compartment-marcel2
    vcnIdSelector:
      matchLabels:
        testing.upbound.io/object-name: vcn-testvcn
    routeTableIdSelector:
      matchLabels:
        testing.upbound.io/object-name: routetable-table1
    displayName: dbsubnet
    cidrBlock: "10.0.2.0/24"
    prohibitInternetIngress: true
    prohibitPublicIpOnVnic: true
  providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig
---
apiVersion: networking.oci.m.upbound.io/v1alpha1
kind: SecurityList
metadata:
  labels:
    testing.upbound.io/object-name: securitylist-testvcn
  name: testvcnlist
  namespace: crossplane-demo
spec:
  forProvider:
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/object-name: compartment-marcel2
    displayName: testvcnlist
    egressSecurityRules:
      - destination: 0.0.0.0/0
        protocol: all
    ingressSecurityRules:
      - protocol: "6"
        source: 10.0.0.0/16
        tcpOptions:
          - max: 2050
            min: 2048
      - protocol: "6"
        source: 10.0.0.0/16
        tcpOptions:
          - sourcePortRange:
              - max: 2050
                min: 2048
      - protocol: "6"
        source: 10.0.0.0/16
        tcpOptions:
          - max: 111
            min: 111
      - protocol: "6"
        source: 0.0.0.0/0
        tcpOptions:
          - max: 22
            min: 22
    vcnIdSelector:
      matchLabels:
        testing.upbound.io/object-name: vcn-testvcn
  providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig

Wie bereits beschrieben funktionieren alle Ressourcen und ihre Abhängigkeiten durch Selektoren, eine Art von Namens-Filtern, die hier umfassend bemüht wurden. Lediglich eine weitere OCID und ein hardcodierter Name mußte nachgeschlagen werden, nämlich die OCID des Storage-Dienstes in Frankfurt sowie sein interner Name all-fra-services-in-oracle-services-network. Das Kommando oci network services list in der Cloud Shell gibt Auskunft über vorhandene Netzwerk-Dienste und ihre IDs.

Und schon kommen wir zum letzten Schritt, wir legen ein “Database System” an. Es umfaßt einen Database Cloud Service mit Storage, VM Knoten, Default Backup, Database Software Image, Patchsets und vielem mehr. Die Details lassen sich nachträglich anlegen und abrufen, es genügt bei der Provisionierung allein das Database System, ohne zu viele Details und Sub-Ressourcen angeben zu müssen:

apiVersion: database.oci.m.upbound.io/v1alpha1
kind: DbSystem
metadata:
  labels:
    testing.upbound.io/object-name: dbsystem-testdb
  name: test-db-system
  namespace: crossplane-demo
spec:
  forProvider:
    availabilityDomain: "hnNp:EU-FRANKFURT-1-AD-1"
    compartmentIdSelector:
      matchLabels:
        testing.upbound.io/object-name: compartment-marcel2
    cpuCoreCount: 1
    dataStorageSizeInGb: 256
    databaseEdition: ENTERPRISE_EDITION
    dbHome:
      - database:
          - adminPasswordSecretRef:
              key: admin-key
              name: dbadmin-secret
            characterSet: AL32UTF8
            dbName: testdb
            dbWorkload: OLTP
            freeformTags:
              Department: Finance
            ncharacterSet: AL16UTF16
            pdbName: boermann
        dbVersion: 23.26.1.0.0
        displayName: DBHome
    dbSystemOptions:
      - storageManagement: LVM
    diskRedundancy: NORMAL
    displayName: DBSystem
    domain: dbsubnet.testvcn.oraclevcn.com
    faultDomains:
      - FAULT-DOMAIN-1
    freeformTags:
      Department: Finance
    hostname: OracleDB
    licenseModel: LICENSE_INCLUDED
    nodeCount: 1
    shape: VM.Standard2.1
    sshPublicKeys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDuS+RSSqBKfakefakefakeJyZtLconRznC/XCqCjQNeZbjni/dadada3KkkebEaSYoLdyk7Mr/EsFxgssG7mS5aKE+DUd6HOOixCaDsfh+5I1WDgLeylrO6psc41NrAJl/jO4WQ+93nspt2abababaYl73rz8+AwfT2jpTIiSlXTcaBHfgs0q3tC5BebqbdJNFvQ9y6CQvzcGCxS1C6UviaxistnichtechtDm2DVp8epbSs6GUZeB+aBMi19fM1gApLXrRogEIwp
    subnetIdSelector:
      matchLabels:
        testing.upbound.io/object-name: subnet-dbsubnet
   providerConfigRef:
    name: oci-provider-config
    kind: ProviderConfig

Für das zu vergebende Admin-Kennwort der Datenbank wurde auch hier ein Kubernetes Secret dbadmin-secret bemüht, damit keine Klartext-Kennwörter verwendet werden. Bis dieser Service sich mit “READY: TRUE” meldet können verständlicherweise mehrere Minuten verstreichen, da nun im Hintergrund eine VM mit Datenbank eingerichtet werden:

$ kubectl get dbsystem -n crossplane-demo
NAME             SYNCED   READY   EXTERNAL-NAME                                                                                    AGE
test-db-system   True     True    ocid1.dbsystem.oc1.eu-frankfurt-1.antheljshycylkyaftsdo5ueox4zyzgn5xurp6ukngji5wx35z7sghjm3jna   46h

Aber auch in der Oracle Cloud Console selbst sollte der neue Datenbank Dienst unter dem Display-Namen DBSystem bald zu sehen sein, zunächst noch im Status “Provisioning” . Auch in meiner Umgebung war die Provisionierung irgendwann erfolgreich:

Ich bin sehr gespannt auf Ihre Erfahrungsberichte, wenn Sie sich mitteilen möchten !

Fazit und Ausblick:

Es gibt viele Möglichkeiten, Oracle Datenbanken automatisiert zu verwalten. KI bietet freilich interessante neue Möglichkeiten, an die man sich aber erst noch herantasten muss. Wenn Sie in einer Kubernetes- und Container-Welt unterwegs sind dann werden Sie mit CrossPlane in die Lage versetzt, auf Ihnen bekannte und übliche Weise neben Kubernetes-Diensten nun auch beliebige Cloud-Dienste zu verwalten und zu konfigurieren. Das gilt auch Cross-Cloud mit Oracle@Azure und co, oder mit den entsprechenden herunterladbaren Providern für reine AWS, Azure und Google Dienste.
Mit den üblichen DevOps Werkzeugen wie GIT und ArgoCD können Sie nun ganze IT Landschaften erzeugen, nicht nur einzelne Container-Anwendungen hochfahren. Mir hat das ehrlich gesagt viel mehr Spaß gemacht als Terraform, aber das ist meine persönliche Entscheidung: Sie haben immer die Wahl, dafür sorgt Oracle sehr gerne !

Links:
Viele weitere Beispiele gleicher Art für den Crossplane Provider für OCI auf github (Storage Buckets, Postgres Database, AI Data Platform,…)
Announcement des Oracle Product Managements zum neuen CrossPlane Provider für OCI