Nota

Distribuire il database gestito OCI con il servizio PostgreSQL utilizzando Terraform

Introduzione

PostgreSQL, un database relazionale di oggetti open-source ampiamente acclamato, occupa una posizione di rilievo grazie alla sua solida architettura e all'integrità dei dati incrollabile, rendendola una scelta preferita negli scenari aziendali. La sua disponibilità su Oracle Cloud Infrastructure (OCI) introduce un servizio di database completamente gestito e ad alte prestazioni con il suo dimensionamento intelligente, l'ottimizzazione e la durabilità a costi contenuti. PostgreSQL supporta le imprese, le piccole e medie imprese (PMI) e una vasta gamma di ambienti di sviluppo, dimostrando la sua adattabilità e robustezza.

In questa esercitazione verrà descritto come distribuire tre nodi di un sistema di database PostgreSQL gestito da OCI in una tenancy cloud OCI e connettersi privatamente tramite un'istanza di computazione utilizzando lo script Terraform.

Obiettivi

Nota: se l'area selezionata dispone di un singolo dominio di disponibilità, la creazione di un sistema di database ad alta disponibilità distribuirà tutte le istanze PostgreSQL in tutti i domini di errore nell'area, indipendentemente dal fatto che una subnet specifica di AD o regionale.

Prerequisiti

Task 1: Creare file di script Terraform in una cartella

  1. Creare lo script providers.tf.

    Iniziamo con la creazione di un file providers.tf. Creare una cartella locale e copiare il codice riportato di seguito nel file creato. I valori per tenancy_id, user_id, area e così via verranno sostituiti nel file variables.tf, che verrà creato in un passo successivo. Per ottenere i valori delle configurazioni OCI, genera le chiavi API in OCI accedendo alle impostazioni utente, crea una coppia di chiavi API, scarica in modo sicuro la chiave privata, quindi usala insieme agli OCID utente e tenancy nel codice Terraform per l'autenticazione per distribuire le risorse OCI. Per ulteriori informazioni, vedere Generate an API Signing Key.

    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. Creare lo script vcn.tf.

    Abbiamo bisogno di una rete VCN con subnet private e pubbliche per distribuire e accedere al sistema di database PostgreSQL OCI, ricordando che il database PostgreSQL verrà distribuito solo in una subnet privata. Creare un file denominato vcn.tf utilizzando il codice seguente. Il codice assicurerà che solo il CIDR VCN possa accedere alla porta 5432 per PostgreSQL e consentirà l'accesso all'istanza di computazione tramite SSH sulla porta 22 all'interno della lista di sicurezza. Non è necessario preoccuparsi di sostituire i valori qui, è possibile farlo nel file variables.tf.

    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. Creare lo script instance.tf.

    Per accedere al database PostgreSQL, abbiamo bisogno di un'istanza di computazione nella subnet pubblica. Ci connetteremo all'istanza e quindi accederemo a PostgreSQL perché è accessibile solo tramite la subnet privata. A tale scopo, creare un file denominato instance.tf utilizzando il codice seguente. È possibile aggiornare facilmente i valori delle variabili di computazione nel file variables.tf in un secondo momento.

    
    # 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. Creare lo script postgresql.tf.

    Di seguito viene descritto come impostare il sistema di database PostgreSQL OCI aggiungendo il codice Terraform in un file denominato postgresql.tf. Questo codice descrive in dettaglio la configurazione del sistema, inclusi forma, memorie centrali e nodi. Per una configurazione ottimizzata, considera un sistema di database a tre nodi: un nodo primario e due repliche nelle diverse zone di disponibilità. Iniziare creando il file postgresql.tf e inserendo il codice fornito. È possibile aggiungere facilmente i valori delle variabili del database PostgreSQL nel file variables.tf per soddisfare i requisiti specifici.

    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. Creare lo script variables.tf.

    In questa sezione, l'utente deve adeguare e aggiornare i valori delle risorse da creare all'interno della propria tenancy OCI. Creare un file variables.tf e aggiungere il codice seguente. Ricorda, questo è il file finale da creare nella stessa cartella. Esaminare e modificare attentamente ogni variabile in base alle proprie esigenze. Alcuni valori verranno precompilati nella sezione "valore" di ciascun codice, mentre altri, specifici per le tue esigenze, richiederanno il tuo input. Dopo aver aggiunto o modificato tutti i valori nel file, passare alla fase di esecuzione.

    
    # 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 = ""
    }
    
    

    Dopo aver creato i file richiesti e regolato il file variables.tf con i valori necessari, la struttura delle cartelle rifletterà l'impostazione visualizzata nello screenshot seguente.

    cartella tf

Task 2: Esegui script Terraform

Utilizzando il terminale o il prompt dei comandi, eseguire i comandi riportati di seguito per inizializzare Terraform e creare risorse all'interno della tenancy OCI. Questi comandi inizializzeranno Terraform e distribuiranno le risorse specificate nella tenancy OCI.

terraform init

terraform plan

terraform apply

postgreSQLdb_oci_console

Task 3: connettersi al database PostgreSQL OCI

Al termine, passare a OCI Console per individuare OCI PostgreSQL e un'istanza di computazione precaricata con il client psql. Accedere all'istanza di computazione tramite SSH utilizzando il relativo IP pubblico, quindi eseguire il comando fornito per stabilire una connessione con il sistema di database PostgreSQL OCI (sia la porta SSH 22 che la porta di database 5432 vengono create automaticamente tramite lo script vcn.tf; non è necessaria alcuna azione per la gestione delle porte). Aggiornare l'IP dell'endpoint privato, ottenibile dalla console del database PostgreSQL OCI, insieme al nome utente e alla password specificati nel file variable.tf. Una volta eseguito il comando, verrà richiesto di connettere la password.

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

Dopo l'esecuzione dei comandi riportati di seguito, gli utenti devono essere in grado di visualizzare la connessione stabilita al database PostgreSQL gestito.

psqldb_access_from_instance

L'utente ha distribuito correttamente tre nodi del database PostgreSQL gestito da OCI e li ha connessi privatamente utilizzando un'istanza di computazione.

Conferme

Altre risorse di apprendimento

Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti gratuiti sulla formazione su Oracle Learning YouTube channel. Inoltre, visita education.oracle.com/learning-explorer per diventare Oracle Learning Explorer.

Per la documentazione del prodotto, visitare Oracle Help Center.