Hinweis:

OCI Managed Database mit dem PostgreSQL-Service mit Terraform bereitstellen

Einführung

PostgreSQL, eine weithin anerkannte objektrelationale Open-Source-Datenbank, hat aufgrund seiner robusten Architektur und der unerschütterlichen Datenintegrität eine herausragende Position und ist somit eine bevorzugte Wahl in Unternehmenslandschaften. Durch die Verfügbarkeit auf Oracle Cloud Infrastructure (OCI) wird ein vollständig verwalteter und leistungsstarker Datenbankservice mit intelligenter Größe, kostengünstiger Optimierung und Dauerhaftigkeit eingeführt. PostgreSQL unterstützt Unternehmen, kleine und mittlere Unternehmen (KMU) sowie eine Vielzahl von Entwicklungsumgebungen und demonstriert deren Anpassungsfähigkeit und Robustheit.

In diesem Tutorial erfahren Sie, wie wir drei Knoten eines von OCI verwalteten PostgreSQL-Datenbanksystems in einem OCI-Cloud-Mandanten bereitstellen und eine private Verbindung über eine Compute-Instanz mit dem Terraform-Skript herstellen können.

Ziele

Hinweis: Wenn die ausgewählte Region eine einzelne Availability-Domain aufweist, verteilt das Erstellen eines hochverfügbaren Datenbanksystems alle PostgreSQL-Instanzen über alle Faultdomains in der Region, unabhängig davon, ob es sich um ein AD-spezifisches oder regionales Subnetz handelt.

Voraussetzungen

Aufgabe 1: Terraform-Skriptdateien in einem Ordner erstellen

  1. Erstellen Sie das Skript providers.tf.

    Beginnen wir mit dem Erstellen einer providers.tf-Datei. Erstellen Sie einen lokalen Ordner, und kopieren Sie den folgenden Code in die erstellte Datei. Die Werte für tenancy_id, user_id, Region usw. werden in der Datei variables.tf ersetzt. Dies wird in einem späteren Schritt erstellt. Um die OCI-Konfigurationswerte abzurufen, generieren Sie API-Schlüssel in OCI, indem Sie auf Benutzereinstellungen zugreifen, ein API-Schlüsselpaar erstellen, den Private Key sicher herunterladen und ihn dann zusammen mit den Benutzer- und Mandanten-OCIDs im Terraform-Code zur Authentifizierung zum Deployment von OCI-Ressourcen verwenden. Weitere Informationen finden Sie unter API-Signaturschlüssel generieren.

    terraform {
        required_providers {
        oci =  {
            source = "oracle/oci"
            version = "5.22.0"
        }
      }
    }
    # Provider configuration for Tenancy
    provider "oci" {
    tenancy_ocid          = var.tenancy_id
    user_ocid             = var.user_id
    fingerprint           = var.api_fingerprint
    private_key_path      = var.api_private_key_path
    region                = var.region
    }
    
    
  2. Erstellen Sie das Skript vcn.tf.

    Für das Deployment und den Zugriff auf das OCI-Datenbanksystem PostgreSQL benötigen wir ein VCN-Netzwerk mit privaten und öffentlichen Subnetzen. Dabei wird daran erinnert, dass die PostgreSQL-Datenbank nur in einem privaten Subnetz bereitgestellt wird. Erstellen Sie eine Datei mit dem Namen vcn.tf mit dem folgenden Code. Der Code stellt sicher, dass nur das VCN-CIDR auf Port 5432 für PostgreSQL zugreifen kann. Er ermöglicht den Zugriff auf die Compute-Instanz über SSH auf Port 22 in der Sicherheitsliste. Sie müssen sich keine Sorgen machen, die Werte hier zu ersetzen. Sie können dies in der Datei variables.tf tun.

    resource oci_core_vcn psql_vcn_tf {
        #Required
        compartment_id = var.compartment_id
    
        #Optional
        cidr_block = var.vcn_cidr_block
        display_name = var.vcn_display_name
    }
    
    resource oci_core_subnet public_subnet {
        #Required
        cidr_block = var.public_subnet_cidr_block
        compartment_id = var.compartment_id
        vcn_id = oci_core_vcn.psql_vcn_tf.id
    
        #Optional
        display_name = var.public_subnet_display_name
        route_table_id = oci_core_route_table.tf_public_route_table.id
    }
    
    resource oci_core_subnet private_subnet {
        #Required
        cidr_block = var.private_subnet_cidr_block
        compartment_id = var.compartment_id
        vcn_id = oci_core_vcn.psql_vcn_tf.id
    
        display_name = var.private_subnet_display_name
        route_table_id = oci_core_route_table.tf_private_route_table.id
        prohibit_internet_ingress = true
        security_list_ids = [oci_core_security_list.tf_private_security_list.id]
    }
    
    resource oci_core_internet_gateway vcntf_igw {
      vcn_id       = oci_core_vcn.psql_vcn_tf.id
      compartment_id = var.compartment_id
      display_name = var.internet_gateway_name
    }
    
    resource oci_core_nat_gateway tf_nat_gateway {
      vcn_id       = oci_core_vcn.psql_vcn_tf.id
      compartment_id = var.compartment_id
      display_name = example-ngw
      # Add route tables to direct traffic through this NAT gateway
    }
    
    data oci_core_services test_services {
    }
    
    variable create_service_gateway {
      description = whether to create a service gateway. If set to true, creates a service gateway.
      default     = true
      type        = bool
    }
    
    data oci_core_services all_oci_services {
      filter {
        name   = name
        values = [All .* Services In Oracle Services Network]
        regex  = true
      }
      count = var.create_service_gateway == true ? 1 : 0
    }
    
    resource oci_core_service_gateway service_gateway {
      compartment_id = var.compartment_id
      display_name   = var.service_gateway_displayname
      services {
        service_id = lookup(data.oci_core_services.all_oci_services[0].services[0], id)
      }
      vcn_id = oci_core_vcn.psql_vcn_tf.id
      count = var.create_service_gateway == true ? 1 : 0
    }
    
    resource oci_core_security_list tf_public_security_list {
      vcn_id         = oci_core_vcn.psql_vcn_tf.id
      compartment_id = var.compartment_id
      display_name   = var.public_subnet_security_list_display_name
    
      ingress_security_rules {
        protocol    = 6  # TCP protocol for SSH
        source      = 0.0.0.0/0  # Allow inbound traffic from all sources
        tcp_options {
                #Optional
                max = 22
                min = 22
            }
        description = Allow SSH from all sources
      }
    }
    
    resource oci_core_security_list tf_private_security_list {
      vcn_id         = oci_core_vcn.psql_vcn_tf.id
      compartment_id = var.compartment_id
      display_name   = var.private_subnet_security_list_disply_name
    
      ingress_security_rules {
        protocol    = 6  # TCP protocol to connect Postgress service from compute instance in public subnet
        source      = oci_core_vcn.psql_vcn_tf.cidr_block  # Allow inbound traffic from CIDR Block of VCN sources
        tcp_options {
                #Optional
                max = 5432
                min = 5432
            }
        description = Allow psql service connections from all ranges cidr vcn
      }
    }
    
    resource oci_core_route_table tf_public_route_table {
      vcn_id     = oci_core_vcn.psql_vcn_tf.id
      compartment_id = var.compartment_id
      display_name = var.public_subnet_route_table_display_name
      route_rules {
        // Define route rules for public subnet
        network_entity_id = oci_core_internet_gateway.vcntf_igw.id
        destination = 0.0.0.0/0
        destination_type = CIDR_BLOCK
      }
    }
    
    resource oci_core_route_table tf_private_route_table {
      vcn_id     = oci_core_vcn.psql_vcn_tf.id
      compartment_id = var.compartment_id
      display_name = var.private_subnet_route_table_display_name
      route_rules {
        // Define route rules for private subnet
        network_entity_id = oci_core_nat_gateway.tf_nat_gateway.id
        destination = 0.0.0.0/0
        destination_type = CIDR_BLOCK
      }
      route_rules {
        network_entity_id = oci_core_service_gateway.service_gateway.0.id
        destination = all-iad-services-in-oracle-services-network
        destination_type  = SERVICE_CIDR_BLOCK
      }
      }
    
    resource oci_core_route_table_attachment public_route_table_attachment {
      #Required
      subnet_id = oci_core_subnet.public_subnet.id
      route_table_id =oci_core_route_table.tf_public_route_table.id
    }
    
    resource oci_core_route_table_attachment private_route_table_attachment {
      #Required
      subnet_id = oci_core_subnet.private_subnet.id
      route_table_id =oci_core_route_table.tf_private_route_table.id
      depends_on = [oci_core_service_gateway.service_gateway]
    }
    
  3. Erstellen Sie das Skript instance.tf.

    Für den Zugriff auf die Datenbank PostgreSQL benötigen Sie eine Compute-Instanz im öffentlichen Subnetz. Wir stellen eine Verbindung zur Instanz her und greifen dann auf PostgreSQL zu, weil nur über das private Subnetz darauf zugegriffen werden kann. Erstellen Sie dazu eine Datei namens instance.tf mit dem folgenden Code. Sie können die Compute-Variablenwerte in der Datei variables.tf später einfach aktualisieren.

    
    # Resources
    data "oci_identity_availability_domains" "ads" {
      compartment_id = var.compartment_id
    }
    
    resource "oci_core_instance" "tf_compute" {
      # Required
      availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name
      compartment_id      = var.compartment_id
      shape               = var.compute_shape
      source_details {
        source_id         = var.source_operating_system_image_id
        source_type       = "image"
      }
      display_name        = var.compute_instance_display_name
      shape_config {
        ocpus         = var.compute_cpus
        memory_in_gbs = var.compute_memory_in_gbs
      }
      create_vnic_details {
        subnet_id = oci_core_subnet.public_subnet.id
        assign_public_ip  = true
      }
      metadata = {
        ssh_authorized_keys = file(var.compute_ssh_authorized_keys)
      }
      preserve_boot_volume = false
      provisioner "remote-exec" {
        inline = [
          "sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm",
          "sudo dnf -qy module disable postgresql",
          "sudo dnf install -y postgresql16-server",
          "sudo /usr/pgsql-16/bin/postgresql-16-setup initdb",
          "sudo systemctl enable postgresql-16",
          "sudo systemctl start postgresql-16"
        ]
        connection {
          type        = "ssh"
          host        = self.public_ip
          user        = "opc"
          private_key = file(var.api_private_key_for_ssh)
        }
      }
    
    }
    
    # Outputs
    output "compute_id" {
      value = oci_core_instance.tf_compute.id
    }
    
    output "compute_state" {
      value = oci_core_instance.tf_compute.state
    }
    
    output "compute_public_ip" {
      value = oci_core_instance.tf_compute.public_ip
    }
    
    
    
  4. Erstellen Sie das Skript postgresql.tf.

    Richten Sie das OCI PostgreSQL-Datenbanksystem ein, indem Sie den Terraform-Code in eine Datei mit dem Namen postgresql.tf einfügen. Dieser Code enthält Details zur Systemkonfiguration, einschließlich Ausprägung, Cores und Knoten. Für ein optimiertes Setup sollten Sie ein Datenbanksystem mit drei Knoten in Betracht ziehen: einen primären Knoten und zwei Replikate über verschiedene Verfügbarkeitszonen hinweg. Erstellen Sie zunächst die Datei postgresql.tf, und fügen Sie den angegebenen Code ein. Sie können die Variablenwerte der Datenbank PostgreSQL einfach in der Datei variables.tf hinzufügen, um Ihre spezifischen Anforderungen zu erfüllen.

    resource "oci_psql_db_system" "test_db_system" {
        #Required
        compartment_id = var.compartment_id
        db_version = var.db_system_db_version
        display_name = var.db_system_display_name
        network_details {
            #Required
            subnet_id = oci_core_subnet.private_subnet.id
        }
        shape = var.db_system_shape
        storage_details {
            #Required
            is_regionally_durable = var.db_system_storage_details_is_regionally_durable
            system_type = var.db_system_storage_details_system_type
            #Optional
            # availability_domain = var.db_system_storage_details_availability_domain
            # iops = var.db_system_storage_details_iops
        }
        credentials {
            #Required
            password_details {
                #Required
                password_type = var.db_system_credentials_password_details_password_type
                #Optional
                password = var.db_system_credentials_password_details_password
            }
            username = var.db_system_credentials_username
        }
        instance_count = var.db_system_instance_count
        instance_memory_size_in_gbs = var.db_system_instance_memory_size_in_gbs
        instance_ocpu_count = var.db_system_instance_ocpu_count
    
    }
    
    
    
  5. Erstellen Sie das Skript variables.tf.

    In diesem Abschnitt muss der Benutzer die Werte für die Ressourcen anpassen und aktualisieren, die in seinem OCI-Mandanten erstellt werden sollen. Erstellen Sie eine variables.tf-Datei, und fügen Sie den folgenden Code hinzu. Denken Sie daran, dass dies die letzte Datei ist, die im selben Ordner erstellt werden soll. Prüfen und ändern Sie jede Variable sorgfältig nach Ihren Anforderungen. Einige Werte werden im Abschnitt "Wert" jedes Codes vorausgefüllt, während andere, die speziell auf Ihre Bedürfnisse zugeschnitten sind, Ihre Eingabe erfordern. Nachdem alle Werte in der Datei hinzugefügt oder geändert wurden, fahren Sie mit der Ausführungsphase fort.

    
    # Provider identity parameters - Replace these values from API Key Values from OCI User
    
    variable "api_fingerprint" {
      description = "Fingerprint of OCI API private key for Requestor Tenancy"
      type        = string
      default     = ""
    }
    
    variable "api_private_key_path" {
      description = "Path to OCI API private key used for Requestor Tenancy"
      type        = string
      default     = ""
    }
    
    variable "tenancy_id" {
      description = "Tenancy ID where to create resources for Requestor Tenancy"
      type        = string
      default     = ""
    }
    
    variable "user_id" {
      description = "User ID that Terraform will use to create resources for Requestor Tenancy"
      type        = string
      default     = ""
    }
    
    variable "region" {
      description = "OCI region where resources will be created for Requestor Tenancy"
      type        = string
      default     = "us-ashburn-1"  # example value
      # check this document, if you want to use different region - https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm#About
    }
    
    
    # compartment OCID - Replace these values
    
    variable "compartment_id" {
      description = "Compartment ID where to create resources for Requestor Tenancy"
      type        = string
      default     = ""
    }
    
    variable "db_system_db_version" {
      description = "Version"
      type = number
      default = 14
    }
    
    variable "db_system_display_name" {
      description = "postgress db service name"
      type = string
      default = "psqlfromterraform" # example value
    }
    
    
    variable "db_system_shape" {
        description = "shape"
        type = string
        default = "PostgreSQL.VM.Standard.E4.Flex.4.64GB"  # example value
        #change the shape value as per your requirements
    }
    
    variable "db_system_instance_count" {
      description = "instance count"
      type = number
      default = 3  # example value
    }
    
    variable "db_system_instance_memory_size_in_gbs" {
      description = "RAM"
      type = number
      default = 64  # example value
    }
    
    variable "db_system_instance_ocpu_count" {
      description = "OCPU count"
      type = number
      default = 4  # example value
    }
    
    variable "db_system_storage_details_is_regionally_durable" {
      description = "regional"
      type = bool
      default = true
    }
    variable "db_system_credentials_password_details_password_type" {
        description = "type"
        type = string
        default = "PLAIN_TEXT"
    
    }
    
    variable "db_system_credentials_password_details_password" {
      description = "password"
      type = string
      default = ""
    }
    
    variable "db_system_credentials_username" {
      description = "username"
      type = string
      default = "admin" # example value
    }
    
    variable "db_system_storage_details_system_type" {
      description = "type"
      type = string
      default = "OCI_OPTIMIZED_STORAGE"
    }
    
    
    
    # OCI VCN parameters - psql instance deployed on this
    
    variable "vcn_cidr_block" {
      description = "vcn cidr"
      type = string
      default = "172.16.0.0/16" # example value
    }
    
    variable "vcn_display_name" {
      description = "vcn name"
      type = string
      default = "vcn-from-tf-psql" # example value
    }
    
    variable "public_subnet_cidr_block" {
        description = "subnet cidr range"
        type = string
        default = "172.16.1.0/24" # example value
    }
    
    variable "private_subnet_cidr_block" {
        description = "subnet cidr range"
        type = string
        default = "172.16.2.0/24" # example value
    }
    
    variable "public_subnet_display_name" {
      description = "public subnet name"
      type = string
      default = "public-subnet" # example value
    
    }
    
    variable "private_subnet_display_name" {
      description = "public subnet name"
      type = string
      default = "private-subnet" # example value
    
    }
    
    variable "internet_gateway_name" {
      description = "internet gateway name"
      type = string
      default = "internetgateway" # example value
    }
    
    variable "service_gateway_displayname" {
      description = "Service Gateway Display Name"
      type = string
      default = "servicegateway" # example value
    }
    
    variable "public_subnet_security_list_display_name" {
      description = "Public Subnet Security List Display Name"
      type = string
      default = "public_subnet_security_list" # example value
    }
    
    variable "private_subnet_security_list_display_name" {
      description = "Public Subnet Security List Display Name"
      type = string
      default = "public_subnet_security_list" # example value
    }
    
    variable "public_subnet_route_table_display_name" {
      description = "Public Subnet Route table Display Name"
      type = string
      default = "public_subnet_route_table" # example value
    }
    
    variable "private_subnet_route_table_display_name" {
      description = "Public Subnet Route table Display Name"
      type = string
      default = "private_subnet_route_table" # example value
    }
    
    
    # OCI Compute Instance parameters - We will use this instance to connect postgreSQL db instance
    
    variable "compute_shape" {
      type    = string
      default = "VM.Standard.E4.Flex" # example value
    }
    
    variable "compute_cpus" {
      type    = string
      default = "1" # example value
    }
    
    variable "compute_memory_in_gbs" {
      type    = string
      default = "1" # example value
    }
    
    variable "compute_ssh_authorized_keys" {
      type = string
      default = ""
    }
    
    variable "api_private_key_for_ssh" {
      type = string
      default = ""
    }
    
    variable "source_operating_system_image_id" {
      description = "Oracle Linux 8 image ocid"
      type = string
      default = "ocid1.image.oc1.iad.aaaaaaaaszr5wpipg6qskiol3fhbitm56qdmumpbcpv6irzxuofi2nfmlhma" # example value
      # if you change the region , then change the default value from the region you have selected from this document -https://docs.oracle.com/en-us/iaas/images/image/998f1273-d4fd-4e16-8673-dd2517ddd724/
    }
    
    variable "compute_instance_display_name" {
      description = "display name of the compute name"
      type = string
      default = ""
    }
    
    

    Nachdem Sie die erforderlichen Dateien erstellt und die Datei variables.tf mit den erforderlichen Werten angepasst haben, spiegelt Ihre Ordnerstruktur das Setup wider, das im folgenden Screenshot angezeigt wird.

    TF-Ordner

Aufgabe 2: Terraform-Skripte ausführen

Führen Sie mit Ihrem Terminal oder Ihrer Eingabeaufforderung die folgenden Befehle aus, um Terraform zu initialisieren und Ressourcen in Ihrem OCI-Mandanten zu erstellen. Diese Befehle initialisieren Terraform und stellen die angegebenen Ressourcen in Ihrem OCI-Mandanten bereit.

terraform init

terraform plan

terraform apply

postgreSQLdb_oci_console

Aufgabe 3: Verbindung zur OCI PostgreSQL-Datenbank herstellen

Navigieren Sie nach Abschluss zur OCI-Konsole, um OCI PostgreSQL und eine mit dem psql-Client vorab geladene Compute-Instanz zu suchen. Greifen Sie über SSH über die öffentliche IP auf die Compute-Instanz zu, und führen Sie dann den angegebenen Befehl aus, um eine Verbindung zum OCI-Datenbanksystem PostgreSQL herzustellen (sowohl SSH-Port 22 als auch Datenbankport 5432 werden automatisch mit dem Skript vcn.tf erstellt. Für die Portverwaltung ist keine Aktion erforderlich). Aktualisieren Sie die IP des privaten Endpunkts, die von der OCI PostgreSQL-Datenbankkonsole abgerufen werden kann, zusammen mit dem Benutzernamen und Kennwort, die Sie in der Datei variable.tf angegeben haben. Nachdem Sie den Befehl ausgeführt haben, werden Sie zur Eingabe des Kennworts aufgefordert, um eine Verbindung herzustellen.

psql --version
psql -h endpoint_ip -U admin_username -d postgres

Nach Ausführung der oben genannten Befehle sollten Benutzer die Verbindung zur verwalteten PostgreSQL-Datenbank sehen können.

psqldb_access_from_instance

Der Benutzer hat erfolgreich drei Knoten der OCI-verwalteten PostgreSQL-Datenbank bereitgestellt und sie privat mit einer Compute-Instanz verbunden.

Danksagungen

Weitere Lernressourcen

Lernen Sie andere Übungen auf docs.oracle.com/learn kennen, oder greifen Sie auf weitere kostenlose Lerninhalte im Oracle Learning YouTube Channel zu. Besuchen Sie außerdem education.oracle.com/learning-explorer, um Oracle Learning Explorer zu werden.

Produktdokumentation finden Sie im Oracle Help Center.