注意:
- 此教程需要访问 Oracle Cloud。要注册免费账户,请参阅开始使用 Oracle Cloud Infrastructure Free Tier 。
- 它使用 Oracle Cloud Infrastructure 身份证明、租户和区间示例值。完成实验室时,请将这些值替换为特定于云环境的值。
使用 Terraform 使用 PostgreSQL 服务部署 OCI 托管数据库
简介
PostgreSQL 是一个广受赞誉的开源对象关系数据库,由于其强大的架构和坚定不移的数据完整性,因此具有突出的地位,使其成为企业景观中的首选。它在 Oracle Cloud Infrastructure (OCI) 上的可用性引入了完全托管的高性能数据库服务,具有智能大小、经济高效的优化和持久性。PostgreSQL 支持企业、中小型企业 (SMB) 和各种开发环境,展示了其适应性和稳健性。
在本教程中,我们将了解如何在 OCI 云租户中部署 OCI 托管 PostgreSQL 数据库系统的三个节点,并使用 Terraform 脚本通过计算实例进行专用连接。
目标
-
部署包含 PostgreSQL 和计算实例的 OCI 托管数据库,以使用 Terraform 脚本私密连接数据库服务。我们将在 OCI 中使用 Terraform 代码部署以下架构。
注:如果所选区域具有单个可用性域,创建高可用性数据库系统将在该区域中的所有故障域中分布所有 PostgreSQL 实例,无论它们是特定于 AD 的子网还是区域子网。
先决条件
-
Oracle Cloud Infrastructure 租户。
-
具有以下权限的用户帐户:创建用户、将用户添加到用户组以及创建安全策略。
-
用户应具有 OCI IAM 权限。有关详细信息,请参阅 OCI Database with PostgreSQL Policies 。
任务 1:在文件夹中创建 Terraform 脚本文件
-
创建
providers.tf
脚本。让我们从创建
providers.tf
文件开始。创建本地文件夹并在创建的文件中复制以下代码。tenancy_id、user_id、region 等的值将在variables.tf
文件中替换,我们将在后面的步骤中创建该文件。要获取 OCI 配置值,请通过访问用户设置在 OCI 中生成 API 密钥,创建 API 密钥对,安全下载私有密钥,然后将其与 Terraform 代码中的用户和租户 OCID 一起使用,以进行身份验证以部署 OCI 资源。有关详细信息,请参阅生成 API 签名密钥。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 }
-
创建
vcn.tf
脚本。我们需要具有专用子网和公共子网的 VCN 网络来部署和访问 OCI PostgreSQL 数据库系统,并记住 PostgreSQL 数据库将仅部署在专用子网上。使用以下代码创建名为
vcn.tf
的文件。该代码将确保只有 VCN CIDR 才能访问 PostgreSQL 的端口 5432,并且允许通过安全列表中的端口 22 上的 SSH 访问计算实例。无需担心在此处替换值,您可以在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] }
-
创建
instance.tf
脚本。要访问 PostgreSQL 数据库,我们需要公共子网中的计算实例。我们将连接到实例,然后访问 PostgreSQL,因为它只能通过专用子网进行访问。为此,请使用以下代码创建一个名为
instance.tf
的文件。以后可以在variables.tf
文件中轻松更新计算变量值。# 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 }
-
创建
postgresql.tf
脚本。让我们通过将 Terraform 代码添加到名为
postgresql.tf
的文件中来设置 OCI PostgreSQL 数据库系统。此代码详细介绍了系统的配置,包括配置、核心和节点。对于优化的设置,请考虑三节点数据库系统:一个主节点和两个跨不同可用性区域的副本。首先创建postgresql.tf
文件并插入提供的代码。可以轻松地在variables.tf
文件中添加 PostgreSQL 数据库的变量值以满足特定要求。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 }
-
创建
variables.tf
脚本。在此部分中,用户需要调整和更新要在 OCI 租户中创建的资源的值。创建
variables.tf
文件并添加以下代码。请记住,这是要在同一文件夹中创建的最后一个文件。根据您的要求仔细查看和修改每个变量。某些值将在每个代码的“值”部分中预先填充,而其他值则需要您输入。在文件中添加或修改了所有值后,继续执行阶段。# 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 = "" }
创建所需文件并使用必要值调整
variables.tf
文件后,文件夹结构将反映以下屏幕截图中显示的设置。
任务 2:执行 Terraform 脚本
使用终端或命令提示符,运行以下命令以初始化 Terraform,并在 OCI 租户中创建资源。这些命令将初始化 Terraform,并在您的 OCI 租户中部署指定的资源。
terraform init
terraform plan
terraform apply
任务 3:连接到 OCI PostgreSQL 数据库
完成后,导航到 OCI 控制台以查找 OCI PostgreSQL 和预加载了 psql 客户端的计算实例。使用公共 IP 通过 SSH 访问计算实例,然后执行提供的命令与 OCI PostgreSQL 数据库系统建立连接(SSH 端口 22
和数据库端口 5432
都通过 vcn.tf
脚本自动创建;端口管理不需要任何操作)。更新可从 OCI PostgreSQL 数据库控制台获取的专用端点 IP,以及您在 variable.tf
文件中指定的用户名和密码。执行该命令后,将提示输入口令进行连接。
psql --version
psql -h endpoint_ip -U admin_username -d postgres
执行以上命令后,用户应能够看到与托管 PostgreSQL 数据库建立的连接。
用户成功部署了 OCI 托管 PostgreSQL 数据库的三个节点,并使用计算实例私下连接它们。
相关链接
确认
- 作者 - Akarsha I K(云架构师)
更多学习资源
浏览 docs.oracle.com/learn 上的其他实验室,或者通过 Oracle Learning YouTube 频道访问更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 以成为 Oracle Learning Explorer。
有关产品文档,请访问 Oracle 帮助中心。
Deploy OCI Managed Database with PostgreSQL Service using Terraform
F91015-01
January 2024
Copyright © 2024, Oracle and/or its affiliates.