你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 HashiCorp Terraform 预配 Oracle Database@Azure

可以使用 Terraform 工具为 Oracle Database@Azure 预配和管理资源,该工具可用于在 Oracle 云基础结构 (OCI) 中预配和管理基础结构。

Terraform 预配和管理的 OCI 机制通过 JSON 脚本完成。 下面是示例脚本。

注意

本文档介绍通过 Terraform 提供程序 AzAPI 预配和管理 Oracle Database@Azure 资源的示例。 请参阅 AzAPI TF 提供程序资源和数据源

示例中使用的 API 规范版本是“2023-09-01-preview”,如示例中的“type”字段所示。 当公共版本可用时,此版本将更改为公共版本。

创建 Oracle Exadata 基础结构

resource "azapi_resource" "resource_group" {
  type     = "Microsoft.Resources/resourceGroups@2023-07-01"
  name     = "ExampleRG"
  location = "eastus"
}

// OperationId: CloudExadataInfrastructures_CreateOrUpdate, CloudExadataInfrastructures_Get, CloudExadataInfrastructures_Delete
// PUT /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures/{cloudexadatainfrastructurename}
resource "azapi_resource" "cloudExadataInfrastructure" {
  type      = "Oracle.Database/cloudExadataInfrastructures@2023-09-01-preview"
  parent_id = azapi_resource.resource_group.id
  name      = "ExampleName"
  body = jsonencode({
    "location" : "eastus",
    "zones" : [
      "2"
    ],
    "tags" : {
      "createdby" : "ExampleName"
    },
    "properties" : {
      "computeCount" : 2,
      "displayName" : "ExampleName",
      "maintenanceWindow" : {
        "leadTimeInWeeks" : 0,
        "preference" : "NoPreference",
        "patchingMode" : "Rolling"
      },
      "shape" : "Exadata.X9M",
      "storageCount" : 3
    }
  })
  schema_validation_enabled = false
}

按订阅列出 Oracle Exadata 基础结构


data "azapi_resource" "subscription" {
  type                   = "Microsoft.Resources/subscriptions@2020-06-01"
  response_export_values = ["*"]
}

// OperationId: CloudExadataInfrastructures_ListBySubscription
// GET /subscriptions/{subscriptionId}/providers/Oracle.Database/cloudExadataInfrastructures
data "azapi_resource_list" "listCloudExadataInfrastructuresBySubscription" {
  type       = "Oracle.Database/cloudExadataInfrastructures@2023-09-01-preview"
  parent_id  = data.azapi_resource.subscription.id
}

按资源组列出 Oracle Exadata 基础结构


data "azurerm_resource_group" "example" {
  name = "existing"
}

// OperationId: CloudExadataInfrastructures_ListByResourceGroup
// GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures
data "azapi_resource_list" "listCloudExadataInfrastructuresByResourceGroup" {
  type       = "Oracle.Database/cloudExadataInfrastructures@2023-09-01-preview"
  parent_id  = azurerm_resource_group.example.id
}

修补 Oracle Exadata 基础结构

注意

只有资源上的 Microsoft Azure 标记才能通过 AzAPI 提供程序进行更新。


data "azapi_resource" "subscription" {
  type                   = "Microsoft.Resources/subscriptions@2020-06-01"
  response_export_values = ["*"]
}

// OperationId: CloudExadataInfrastructures_Update
// PATCH /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures/{cloudexadatainfrastructurename}
resource "azapi_resource_action" "patch_cloudExadataInfrastructure" {
  type        = "Oracle.Database/cloudExadataInfrastructures@2023-09-01-preview"
  resource_id = azapi_resource.cloudExadataInfrastructure.id
  action      = ""
  method      = "PATCH"
  body = jsonencode({
    "tags" : {
      "updatedby" : "ExampleName"
    }
  })
}

列出 Oracle Exadata 基础结构上的数据库服务器


// OperationId: DbServers_Get
// GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures/{cloudexadatainfrastructurename}/dbServers/{dbserverocid}
data "azapi_resource" "dbServer" {
  type      = "Oracle.Database/cloudExadataInfrastructures/dbServers@2023-09-01-preview"
  parent_id = azapi_resource.cloudExadataInfrastructure.id
  name      = var.resource_name
}

创建 Oracle Exadata 虚拟机群集


resource "azapi_resource" "resource_group" {
  type     = "Microsoft.Resources/resourceGroups@2023-07-01"
  name     = "ExampleRG"  location = "eastus"
}

// OperationId: CloudExadataInfrastructures_CreateOrUpdate, CloudExadataInfrastructures_Get, CloudExadataInfrastructures_Delete
// PUT /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures/{cloudexadatainfrastructurename}
resource "azapi_resource" "cloudExadataInfrastructure" {
  type      = "Oracle.Database/cloudExadataInfrastructures@2023-09-01-preview"
  parent_id = azapi_resource.resource_group.id
  name      = "ExampleName"
  body = jsonencode({
    "location" : "eastus",
    "zones" : [
      "2"
    ],
    "tags" : {
      "createdby" : "ExampleName"
    },
    "properties" : {
      "computeCount" : 2,
      "displayName" : "ExampleName",
      "maintenanceWindow" : {
        "leadTimeInWeeks" : 0,
        "preference" : "NoPreference",
        "patchingMode" : "Rolling"
      },
      "shape" : "Exadata.X9M",
      "storageCount" : 3
    }
  })
  schema_validation_enabled = false
}

//-------------VMCluster resources ------------
// OperationId: CloudVmClusters_CreateOrUpdate, CloudVmClusters_Get, CloudVmClusters_Delete
// PUT GET DELETE /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudVmClusters/{cloudvmclustername}
resource "azapi_resource" "cloudVmCluster" {
  type                      = "Oracle.Database/cloudVmClusters@2023-09-01-preview"
  parent_id                 = azapi_resource.resourceGroup.id
  name                      = local.exa_cluster_name
  schema_validation_enabled = false
  depends_on                = [azapi_resource.cloudExadataInfrastructure]
  body                      = jsonencode({
    "properties": {
        "dataStorageSizeInTbs": 1000,
        "dbNodeStorageSizeInGbs": 1000,
        "memorySizeInGbs": 1000,
        "timeZone": "UTC",
        "hostname": "hostname1",
        "domain": "domain1",
        "cpuCoreCount": 2,
        "ocpuCount": 3,
        "clusterName": "cluster1",
        "dataStoragePercentage": 100,
        "isLocalBackupEnabled": false,
        "cloudExadataInfrastructureId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg000/providers/Oracle.Database/cloudExadataInfrastructures/infra1",
        "isSparseDiskgroupEnabled": false,
        "sshPublicKeys": [
          "ssh-key 1"
        ],
        "nsgCidrs": [
          {
            "source": "10.0.0.0/16",
            "destinationPortRange": {
              "min": 1520,
              "max": 1522
            }
          },
          {
            "source": "10.10.0.0/24"
          }
        ],
        "licenseModel": "LicenseIncluded",
        "scanListenerPortTcp": 1050,
        "scanListenerPortTcpSsl": 1025,
        "vnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg000/providers/Microsoft.Network/virtualNetworks/vnet1",
        "giVersion": "19.0.0.0",
        "subnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg000/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/subnet1",
        "backupSubnetCidr": "172.17.5.0/24",
        "dataCollectionOptions": {
          "isDiagnosticsEventsEnabled": false,
          "isHealthMonitoringEnabled": false,
          "isIncidentLogsEnabled": false
        },
        "displayName": "cluster 1",
        "dbServers": [
          "ocid1..aaaa"
        ]
      },
      "location": "eastus"
    }
})
  response_export_values = ["properties.ocid"]
}

按订阅列出 Oracle Exadata 虚拟机群集


data "azapi_resource" "subscription" {
  type                   = "Microsoft.Resources/subscriptions@2020-06-01"
  response_export_values = ["*"]
}

// OperationId: CloudExadataInfrastructures_ListBySubscription
// GET /subscriptions/{subscriptionId}/providers/Oracle.Database/cloudExadataInfrastructures
data "azapi_resource_list" "listCloudExadataInfrastructuresBySubscription" {
  type       = "Oracle.Database/cloudVmClusters@2023-09-01-preview"
  parent_id  = data.azapi_resource.subscription.id
}

按资源组列出 Oracle Exadata VM 群集

data "azurerm_resource_group" "example" {
  name = "existing"
}

// OperationId: CloudExadataInfrastructures_ListByResourceGroup
// GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures
data "azapi_resource_list" "listCloudExadataInfrastructuresByResourceGroup" {
  type       = "Oracle.Database/cloudVmClusters@2023-09-01-preview"
  parent_id  = azurerm_resource_group.example.id
}

列出 Oracle Exadata VM 群集上的数据库节点


// OperationId: DbNodes_Get
// GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudVmClusters/{cloudvmclustername}/dbNodes/{dbnodeocid}
data "azapi_resource" "dbNode" {
  type      = "Oracle.Database/cloudVmClusters/dbNodes@2023-09-01-preview"
  parent_id = azapi_resource.cloudVmCluster.id. // VM Cluster Id
  name      = var.resource_name
}

将虚拟网络地址添加到 Oracle Exadata VM 群集

// OperationId: VirtualNetworkAddresses_CreateOrUpdate, VirtualNetworkAddresses_Get, VirtualNetworkAddresses_Delete
// PUT GET DELETE /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudVmClusters/{cloudvmclustername}/virtualNetworkAddresses/{virtualnetworkaddressname}
resource "azapi_resource" "virtualNetworkAddress" {
  type                      = "Oracle.Database/cloudVmClusters/virtualNetworkAddresses@2023-09-01-preview"
  parent_id                 = azapi_resource.cloudVmCluster.id
  name                      = var.resource_name
  body = jsonencode({
    "properties": {
        "ipAddress": "192.168.0.1",
        "vmOcid": "ocid1..aaaa"
      }
  })
  schema_validation_enabled = false
}

列出 Oracle Exadata VM 群集上的虚拟网络地址


// OperationId: VirtualNetworkAddresses_ListByCloudVmCluster
// GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudVmClusters/{cloudvmclustername}/virtualNetworkAddresses
data "azapi_resource_list" "listVirtualNetworkAddressesByCloudVmCluster" {
  type       = "Oracle.Database/cloudVmClusters/virtualNetworkAddresses@2023-09-01-preview"
  parent_id  = azapi_resource.cloudVmCluster.id
}

列出 Oracle Exadata 数据库形式


data "azapi_resource_id" "location" {
  type      = "Oracle.Database/locations@2023-12-12"
  parent_id = data.azapi_resource.subscription.id
  name      = "eastus"
}

// OperationId: DbSystemShapes_Get
// GET /subscriptions/{subscriptionId}/providers/Oracle.Database/locations/{location}/dbSystemShapes/{dbsystemshapename}
data "azapi_resource" "dbSystemShape" {
  type      = "Oracle.Database/locations/dbSystemShapes@2023-09-01-preview"
  parent_id = data.azapi_resource_id.location.id
  name      = var.resource_name
}

按位置列出 Oracle Exadata 数据库形式


// OperationId: DbSystemShapes_ListByLocation
// GET /subscriptions/{subscriptionId}/providers/Oracle.Database/locations/{location}/dbSystemShapes
data "azapi_resource_list" "listDbSystemShapesByLocation" {
  type       = "Oracle.Database/locations/dbSystemShapes@2023-09-01-preview"
  parent_id  = data.azapi_resource_id.location.id
}

用于测试示例的 Terraform 脚本

注意

以下脚本使用 AzAPI Terraform 提供程序创建 Oracle Exadata 基础结构和 Oracle Exadata VM 群集,然后使用 OCI Terraform 提供程序 https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/database_db_home 创建 Oracle Database 部署。


terraform {
  required_providers {
    azapi = {
      source = "Azure/azapi"
    }
    oci = {
      source = "oracle/oci"
    }
  }
}

provider "azapi" {
  skip_provider_registration = false
}

provider "oci" {
  user_ocid        = <user_ocid>
  fingerprint      = <user_fingerprint>
  tenancy_ocid     = <oci_tenancy_ocid>
  region           = "us-ashburn-1"
  private_key_path = <Path to API Key>
}

locals {
  resource_group_name = "TestResourceGroup"
  user                = "Username"
  location            = "eastus"
}

resource "azapi_resource" "resource_group" {
  type     = "Microsoft.Resources/resourceGroups@2023-07-01"
  name     = local.resource_group_name
  location = local.location
}

resource "azapi_resource" "virtual_network" {
  type      = "Microsoft.Network/virtualNetworks@2023-04-01"
  name      = "${local.resource_group_name}_vnet"
  location  = local.location
  parent_id = azapi_resource.resource_group.id
  body = jsonencode({
    properties = {
      addressSpace = {
        addressPrefixes = [
          "10.0.0.0/16"
        ]
      }
      subnets = [
        {
          name = "delegated"
          properties = {
            addressPrefix = "10.0.1.0/24"
            delegations = [
              {
                name = "Oracle.Database.networkAttachments"
                properties = {
                  serviceName = "Oracle.Database/networkAttachments"
                }
              }
            ]
          }
        }
      ]
    }
  })
}

data "azapi_resource_list" "listVirtualNetwork" {
  type                   = "Microsoft.Network/virtualNetworks/subnets@2023-09-01"
  parent_id              = azapi_resource.virtual_network.id
  depends_on             = [azapi_resource.virtual_network]
  response_export_values = ["*"]
}

resource "tls_private_key" "generated_ssh_key" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "azapi_resource" "ssh_public_key" {
  type      = "Microsoft.Compute/sshPublicKeys@2023-09-01"
  name      = "${local.resource_group_name}_key"
  location  = local.location
  parent_id = azapi_resource.resource_group.id
  body = jsonencode({
    properties = {
      publicKey = "${tls_private_key.generated_ssh_key.public_key_openssh}"
    }
  })
}

// OperationId: CloudExadataInfrastructures_CreateOrUpdate, CloudExadataInfrastructures_Get, CloudExadataInfrastructures_Delete
// PUT /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures/{cloudexadatainfrastructurename}
resource "azapi_resource" "cloudExadataInfrastructure" {
  type      = "Oracle.Database/cloudExadataInfrastructures@2023-09-01-preview"
  parent_id = azapi_resource.resource_group.id
  name      = "OFake_terraform_deploy_infra_${local.resource_group_name}"
  timeouts {
    create = "1h30m"
    delete = "20m"
  }
  body = jsonencode({
    "location" : "${local.location}",
    "zones" : [
      "2"
    ],
    "tags" : {
      "createdby" : "${local.user}"
    },
    "properties" : {
      "computeCount" : 2,
      "displayName" : "OFake_terraform_deploy_infra_${local.resource_group_name}",
      "maintenanceWindow" : {
        "leadTimeInWeeks" : 0,
        "preference" : "NoPreference",
        "patchingMode" : "Rolling"
      },
      "shape" : "Exadata.X9M",
      "storageCount" : 3
    }

  })
  schema_validation_enabled = false
}

// OperationId: DbServers_ListByCloudExadataInfrastructure
// GET /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudExadataInfrastructures/{cloudexadatainfrastructurename}/dbServers
data "azapi_resource_list" "listDbServersByCloudExadataInfrastructure" {
  type                   = "Oracle.Database/cloudExadataInfrastructures/dbServers@2023-09-01-preview"
  parent_id              = azapi_resource.cloudExadataInfrastructure.id
  depends_on             = [azapi_resource.cloudExadataInfrastructure]
  response_export_values = ["*"]
}

// OperationId: CloudVmClusters_CreateOrUpdate, CloudVmClusters_Get, CloudVmClusters_Delete
// PUT /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Oracle.Database/cloudVmClusters/{cloudvmclustername}
resource "azapi_resource" "cloudVmCluster" {
  type                      = "Oracle.Database/cloudVmClusters@2023-09-01-preview"
  parent_id                 = azapi_resource.resource_group.id
  name                      = "OFake_terraform_deploy_cluster_${local.resource_group_name}"
  schema_validation_enabled = false
  depends_on                = [azapi_resource.cloudExadataInfrastructure]
  timeouts {
    create = "1h30m"
    delete = "20m"
  }
  body = jsonencode({
    "location" : "${local.location}",
    "tags" : {
      "createdby" : "${local.user}"
    },
    "properties" : {
      "subnetId" : "${jsondecode(data.azapi_resource_list.listVirtualNetwork.output).value[0].id}"
      "cloudExadataInfrastructureId" : "${azapi_resource.cloudExadataInfrastructure.id}"
      "cpuCoreCount" : 4
      "dataCollectionOptions" : {
        "isDiagnosticsEventsEnabled" : true,
        "isHealthMonitoringEnabled" : true,
        "isIncidentLogsEnabled" : true
      },
      "dataStoragePercentage" : 80,
      "dataStorageSizeInTbs" : 2,
      "dbNodeStorageSizeInGbs" : 120,
      "dbServers" : [
        "${jsondecode(data.azapi_resource_list.listDbServersByCloudExadataInfrastructure.output).value[0].properties.ocid}",
        "${jsondecode(data.azapi_resource_list.listDbServersByCloudExadataInfrastructure.output).value[1].properties.ocid}"
      ]
      "displayName" : "OFake_terraform_deploy_cluster_${local.resource_group_name}",
      "giVersion" : "19.0.0.0",
      "hostname" : "${local.user}",
      "isLocalBackupEnabled" : false,
      "isSparseDiskgroupEnabled" : false,
      "licenseModel" : "LicenseIncluded",
      "memorySizeInGbs" : 60,
      "sshPublicKeys" : ["${tls_private_key.generated_ssh_key.public_key_openssh}"],
      "timeZone" : "UTC",
      "vnetId" : "${azapi_resource.virtual_network.id}",
      "provisioningState" : "Succeeded"
    }
  })
  response_export_values = ["properties.ocid"]
}

resource "oci_database_db_home" "exa_db_home" {
  source        = "VM_CLUSTER_NEW"
  vm_cluster_id = jsondecode(azapi_resource.cloudVmCluster.output).properties.ocid
  db_version    = "19.20.0.0"
  display_name  = "TFDBHOME"

  database {
    db_name        = "TFCDB"
    pdb_name       = "TFPDB"
    admin_password = "TestPass#2024#"
    db_workload    = "OLTP"
  }
  depends_on = [azapi_resource.cloudVmCluster]
}