Skip to content

Commit 27dbb1a

Browse files
Fix review date and update GitOps references
Updated last reviewed date and corrected references to GitOps design document. Changed keys in configuration examples to uppercase for consistency.
1 parent ef2e1ae commit 27dbb1a

1 file changed

Lines changed: 58 additions & 63 deletions

File tree

  • operations-advisory/customer-operations/oracle-database/Oracle Database @ Google Cloud Operations/Oracle Database @ Google Operations Best Practices

operations-advisory/customer-operations/oracle-database/Oracle Database @ Google Cloud Operations/Oracle Database @ Google Operations Best Practices/odgcp-module-handoff-reference.md renamed to operations-advisory/customer-operations/oracle-database/Oracle Database @ Google Cloud Operations/Oracle Database @ Google Operations Best Practices/handoff-reference.md

Lines changed: 58 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# OD@GCP Module Handoff Reference
22

3-
Last reviewed: 2026-05-20
3+
Last reviewed: 2026-05-26
44

55
This runbook is the implementation companion to [Operational Best Practices for Oracle Database@Google Cloud](./README.md). It shows one practical way to wire the OD@GCP Google Cloud-side modules to the OCI Exadata Database module.
66

77
The best-practices document remains the source of truth for control-plane ownership, drift contracts, Day 2 tool selection, and exception rules. This runbook focuses only on the normal implementation path and post-handoff checks.
88

9-
For the recommended GitOps repository, state, and operations model, see [GitOps Repository, State, and Operations Design for Oracle Database@Google Cloud](./odgcp-gitops-repository-state-and-operations-design.md).
9+
For the recommended GitOps repository, state, and operations model, see [GitOps Repository, State, and Operations Design for Oracle Database@Google Cloud](./gitops-design.md).
1010

1111
## Table Of Contents
1212

@@ -37,7 +37,7 @@ This runbook covers the normal handoff path across four steps:
3737

3838
This runbook does not cover patching, upgrades, support procedures, or the OCI Terraform exception path for Infrastructure / VM Cluster updates. Those topics are covered in [Operational Best Practices for Oracle Database@Google Cloud](./README.md).
3939

40-
This runbook also does not define the full GitOps repository and state model. That design is covered in [GitOps Repository, State, and Operations Design for Oracle Database@Google Cloud](./odgcp-gitops-repository-state-and-operations-design.md).
40+
This runbook also does not define the full GitOps repository and state model. That design is covered in [GitOps Repository, State, and Operations Design for Oracle Database@Google Cloud](./gitops-design.md).
4141

4242
## 2. Reference Examples
4343

@@ -46,7 +46,7 @@ This runbook also does not define the full GitOps repository and state model. Th
4646
| [`modules/odb-networking/examples/basic`](https://github.com/oci-landing-zones/terraform-oci-multicloud-google/tree/release-0.2.0/modules/odb-networking/examples/basic) | A standalone networking stack that creates ODB Network and ODB Subnets. |
4747
| [`modules/exadb/examples/cluster`](https://github.com/oci-landing-zones/terraform-oci-multicloud-google/tree/release-0.2.0/modules/exadb/examples/cluster) | A VM Cluster consumer stack that receives dependency maps from upstream stacks. |
4848
| [`modules/exadb/examples/vision`](https://github.com/oci-landing-zones/terraform-oci-multicloud-google/tree/release-0.2.0/modules/exadb/examples/vision) | A single-root local validation example. Useful for labs, not the preferred production split. |
49-
| [`modules/exadb/examples/oci-dbhome-handoff`](https://github.com/oci-landing-zones/terraform-oci-multicloud-google/tree/release-0.2.0/modules/exadb/examples/oci-dbhome-handoff) | A wrapper pattern that resolves `vm_cluster_key` from the Google Cloud-side VM Cluster output and passes the OCI Cloud VM Cluster OCID to the OCI Exadata Database module. |
49+
| [`modules/exadb/examples/oci-dbhome-handoff`](https://github.com/oci-landing-zones/terraform-oci-multicloud-google/tree/release-0.2.0/modules/exadb/examples/oci-dbhome-handoff) | A wrapper pattern that resolves `vm_cluster_id` from the Google Cloud-side VM Cluster output and passes the OCI Cloud VM Cluster OCID to the OCI Exadata Database module. |
5050
| [`terraform-oci-modules-exadata/exadata-database`](https://github.com/oci-landing-zones/terraform-oci-modules-exadata/tree/main/exadata-database) | The OCI module used for DB Homes, CDBs/databases, PDBs, database-level backup configuration where required, and controlled exceptions. |
5151

5252
Executable module references in the examples below use pinned tags. For production, replace those tags with the release tag or commit SHA validated by the customer.
@@ -74,10 +74,10 @@ flowchart LR
7474
NET["<b>01 - gcp-networking state</b><br/>module: modules/odb-networking<br/><br/>Creates:<br/>ODB Network<br/>Client ODB Subnet<br/>Backup ODB Subnet"]
7575
NETOUT["<b>Networking dependency maps</b><br/>gcp_odb_networks_dependency<br/>gcp_odb_subnets_dependency<br/><br/>Passed by orchestration layer"]
7676
EXA["<b>02 - gcp-exadb state</b><br/>module: modules/exadb<br/><br/>Creates:<br/>Cloud Exadata Infrastructure<br/>Cloud VM Cluster"]
77-
EXAOUT["<b>VM Cluster handoff contract</b><br/>gcp_cloud_vm_clusters_dependency<br/><br/>id = Google Cloud resource name<br/>ocid = OCI Cloud VM Cluster OCID<br/>oci_region = OCI region<br/>state = AVAILABLE"]
77+
EXAOUT["<b>VM Cluster handoff contract</b><br/>gcp_cloud_vm_clusters_dependency<br/><br/>id = Google Cloud resource name<br/>ocid = OCI Cloud VM Cluster OCID<br/>state = AVAILABLE"]
7878
CHOICE{"<b>OCI DB layer input</b>"}
7979
DIRECT["<b>Path A - Direct OCID</b><br/>recommended for orchestrated flows<br/><br/>Input:<br/>vm_cluster_id = OCI OCID"]
80-
WRAP["<b>Path B - Handoff wrapper</b><br/>optional adapter<br/><br/>Input:<br/>vm_cluster_key<br/><br/>Resolves OCI OCID"]
80+
WRAP["<b>Path B - Handoff wrapper</b><br/>optional adapter<br/><br/>Input:<br/>vm_cluster_id = dependency key<br/><br/>Resolves OCI OCID"]
8181
OCI["<b>03 - oci-db-layer state</b><br/>module: exadata-database<br/><br/>Creates:<br/>DB Homes<br/>CDBs / Databases<br/>PDBs<br/>Database-level backup config"]
8282
CHECK["<b>04 - Post-handoff checks</b><br/>plan owning stacks<br/>expected drift accepted<br/>unexpected drift visible"]
8383
@@ -103,8 +103,6 @@ flowchart LR
103103

104104
For production, pass dependency maps through the selected orchestration layer, such as Terragrunt dependencies, `terraform_remote_state`, HCP Terraform / Terraform Enterprise workspace outputs, or CI/CD pipeline variables/artifacts.
105105

106-
File-based JSON handoff with `output_path` and `*_dependency_file_path` is useful for local validation, examples, and demos, but it should not be the default production integration contract.
107-
108106
| Stack | Module | Long-lived owner |
109107
|---|---|---|
110108
| `01-gcp-networking` | `modules/odb-networking` | ODB Network and ODB Subnets. |
@@ -126,24 +124,24 @@ module "odb_networking" {
126124
default_gcp_oracle_zone = var.gcp_oracle_zone
127125
128126
gcp_odb_networks_configuration = {
129-
primary = {
127+
PRIMARY = {
130128
odb_network_id = "odbnet-${var.env}"
131129
network = var.shared_vpc_self_link
132130
}
133131
}
134132
135133
gcp_odb_subnets_configuration = {
136-
client = {
137-
odb_subnet_id = "odbsub-client-${var.env}"
138-
cidr_range = var.client_cidr
139-
purpose = "CLIENT_SUBNET"
140-
odb_network_key = "primary"
134+
CLIENT = {
135+
odb_subnet_id = "odbsub-client-${var.env}"
136+
cidr_range = var.client_cidr
137+
purpose = "CLIENT_SUBNET"
138+
odb_network = "PRIMARY"
141139
}
142-
backup = {
143-
odb_subnet_id = "odbsub-backup-${var.env}"
144-
cidr_range = var.backup_cidr
145-
purpose = "BACKUP_SUBNET"
146-
odb_network_key = "primary"
140+
BACKUP = {
141+
odb_subnet_id = "odbsub-backup-${var.env}"
142+
cidr_range = var.backup_cidr
143+
purpose = "BACKUP_SUBNET"
144+
odb_network = "PRIMARY"
147145
}
148146
}
149147
}
@@ -153,23 +151,21 @@ The networking stack publishes the following dependency maps for downstream stac
153151

154152
```hcl
155153
gcp_odb_networks_dependency = {
156-
primary = { id = "<odb-network-resource-name>" }
154+
PRIMARY = { id = "<odb-network-resource-name>" }
157155
}
158156
159157
gcp_odb_subnets_dependency = {
160-
client = {
158+
CLIENT = {
161159
id = "<client-odb-subnet-resource-name>"
162160
purpose = "CLIENT_SUBNET"
163161
}
164-
backup = {
162+
BACKUP = {
165163
id = "<backup-odb-subnet-resource-name>"
166164
purpose = "BACKUP_SUBNET"
167165
}
168166
}
169167
```
170168

171-
For local validation or demos, `output_path` and example-level `*_dependency_file_path` inputs can be used if the selected example supports file-based handoff.
172-
173169
## 6. Step 2 - Google Cloud Exadata Stack
174170

175171
The Exadata stack consumes the networking maps and creates Cloud Exadata Infrastructure plus Cloud VM Cluster. Its key output is the OCI Cloud VM Cluster OCID.
@@ -188,7 +184,7 @@ module "exadb" {
188184
ssh_public_keys_file_path = var.ssh_public_keys_file_path
189185
190186
gcp_cloud_exadata_infrastructures_configuration = {
191-
primary = {
187+
PRIMARY = {
192188
cloud_exadata_infrastructure_id = "exa-${var.env}"
193189
display_name = "exa-${var.env}"
194190
properties = {
@@ -200,13 +196,13 @@ module "exadb" {
200196
}
201197
202198
gcp_cloud_vm_clusters_configuration = {
203-
primary = {
199+
PRIMARY = {
204200
cloud_vm_cluster_id = "vmc-${var.env}"
205201
display_name = "vmc-${var.env}"
206-
exadata_infrastructure_key = "primary"
207-
odb_network_key = "primary"
208-
odb_subnet_key = "client"
209-
backup_odb_subnet_key = "backup"
202+
exadata_infrastructure = "PRIMARY"
203+
odb_network = "PRIMARY"
204+
odb_subnet = "CLIENT"
205+
backup_odb_subnet = "BACKUP"
210206
properties = {
211207
license_type = "BRING_YOUR_OWN_LICENSE"
212208
gi_version = var.gi_version
@@ -225,27 +221,28 @@ module "exadb" {
225221
}
226222
```
227223

228-
Publish a small, sanitized handoff contract. The `ocid` field is the key value consumed by the OCI database layer and OCI-native tools. The `oci_region` field should be used by the OCI provider configuration. The `state` field is used by the optional handoff wrapper for pre-flight validation.
224+
Publish a small, sanitized handoff contract. The `ocid` field is the key value consumed by the OCI database layer and OCI-native tools. The `state` field is used by the optional handoff wrapper for pre-flight validation.
229225

230-
The `oci_region` field is not a direct module output. Derive it from the OCID — it is the fourth dot-separated segment (e.g., `ocid1.cloudvmcluster.oc1.<oci-region>.<unique-id>`) — or resolve it in the orchestration layer. Including it explicitly in the handoff contract prevents the OCI provider configuration from depending on manual region mapping.
226+
The OCI region is not a direct module output. Derive it from the OCID — it is the fourth dot-separated segment (e.g., `ocid1.cloudvmcluster.oc1.<oci-region>.<unique-id>`) — or resolve it in the orchestration layer. Pass it as a separate input to the OCI provider configuration; do not add it to the `gcp_cloud_vm_clusters_dependency` map, which only accepts `id`, `name`, `ocid`, and `state`.
231227

232228
```hcl
229+
# gcp_cloud_vm_clusters_dependency passed to the OCI database stack
233230
gcp_cloud_vm_clusters_dependency = {
234-
primary = {
235-
id = "projects/<project>/locations/<gcp-region>/cloudVmClusters/<name>"
236-
ocid = "ocid1.cloudvmcluster.oc1.<unique-id>"
237-
oci_region = "<oci-region>"
238-
state = "AVAILABLE"
231+
PRIMARY = {
232+
id = "projects/<project>/locations/<gcp-region>/cloudVmClusters/<name>"
233+
ocid = "ocid1.cloudvmcluster.oc1.<unique-id>"
234+
state = "AVAILABLE"
239235
}
240236
}
237+
238+
# oci_region resolved separately from the OCID and passed to the OCI provider
239+
oci_region = "<oci-region>"
241240
```
242241

243242
Useful evidence fields to capture alongside the OCID: VM Cluster state, OCI compartment ID, OCI region, Google Cloud location, Google Cloud Oracle Database zone, SCAN DNS, listener ports, initial capacity, Grid Infrastructure version, and system version.
244243

245244
Do not copy full real outputs into Git or tickets unless they are sanitized.
246245

247-
For local validation or demos, `output_path` and example-level `*_dependency_file_path` inputs can be used if the selected example supports file-based handoff.
248-
249246
## 7. Step 3 - OCI Database Layer
250247

251248
Both paths below deploy the same OCI database layer. In orchestrated production flows, prefer the direct OCID path. Use the handoff wrapper only when the OCI stack should resolve the VM Cluster by logical key, or when no orchestration layer is resolving the OCID before calling the OCI database module.
@@ -258,10 +255,8 @@ Use this path when Terragrunt, `terraform_remote_state`, HCP Terraform / Terrafo
258255
module "oci_db_layer" {
259256
source = "git::https://github.com/oci-landing-zones/terraform-oci-modules-exadata.git//exadata-database?ref=v1.1.0"
260257
261-
default_compartment_id = var.oci_compartment_id
262-
263258
cloud_db_homes_configuration = {
264-
dbhome1 = {
259+
DBHOME1 = {
265260
vm_cluster_id = var.vm_cluster_ocid
266261
display_name = "dbh-cdb1-${var.env}"
267262
db_version = var.db_version
@@ -276,28 +271,29 @@ module "oci_db_layer" {
276271

277272
Do not pass the Google Cloud resource name as `vm_cluster_id`. The OCI module requires the OCI Cloud VM Cluster OCID.
278273

279-
Set the OCI provider region from the validated handoff contract, for example `oci_region`, not from the Google Cloud region.
274+
Set the OCI provider region from the validated handoff contract, for example the `oci_region` value resolved from the OCID, not from the Google Cloud region.
280275

281276
### 7.2 Path B - Handoff Wrapper Optional Adapter
282277

283-
Use this path when the OCI stack should reference the Google Cloud-side VM Cluster by logical key, or when no orchestration layer resolves the OCI Cloud VM Cluster OCID before calling the OCI database module. The wrapper resolves the key from the dependency map and validates the handoff contract before forwarding the OCI Cloud VM Cluster OCID to `exadata-database`.
278+
Use this path when no orchestration layer resolves the OCI Cloud VM Cluster OCID before calling the OCI database module. The wrapper accepts `vm_cluster_id` set to either a direct OCI Cloud VM Cluster OCID or a lookup key from `gcp_cloud_vm_clusters_dependency`. When a lookup key is provided, the wrapper resolves the OCID from the dependency map and validates the handoff contract before forwarding the OCI Cloud VM Cluster OCID to `exadata-database`.
279+
280+
Keys in `gcp_cloud_vm_clusters_dependency` and `cloud_db_homes_configuration` must be uppercase semantic identifiers (e.g., `PRIMARY`, `DBHOME1`).
284281

285282
```hcl
286283
module "oci_dbhome_handoff" {
287284
source = "git::https://github.com/oci-landing-zones/terraform-oci-multicloud-google.git//modules/exadb/examples/oci-dbhome-handoff?ref=release-0.2.0"
288285
289-
tenancy_ocid = var.tenancy_ocid
290-
region = var.oci_region
291-
default_compartment_id = var.oci_compartment_id
286+
tenancy_ocid = var.tenancy_ocid
287+
region = var.oci_region
292288
293289
gcp_cloud_vm_clusters_dependency = var.gcp_cloud_vm_clusters_dependency
294290
295291
cloud_db_homes_configuration = {
296-
dbhome1 = {
297-
vm_cluster_key = "primary"
298-
display_name = "dbh-cdb1-${var.env}"
299-
db_version = var.db_version
300-
source = "VM_CLUSTER_NEW"
292+
DBHOME1 = {
293+
vm_cluster_id = "PRIMARY" # lookup key resolved against gcp_cloud_vm_clusters_dependency
294+
display_name = "dbh-cdb1-${var.env}"
295+
db_version = var.db_version
296+
source = "VM_CLUSTER_NEW"
301297
}
302298
}
303299
@@ -306,18 +302,16 @@ module "oci_dbhome_handoff" {
306302
}
307303
```
308304

309-
For local/demo file handoff, use `gcp_cloud_vm_clusters_dependency_file_path` instead of `gcp_cloud_vm_clusters_dependency`. Do not set both.
310-
311-
If the wrapper pattern is used in production, treat it as approved module code: pin the source to a validated tag or commit SHA, or promote the wrapper into the customer’s approved module repository.
305+
If the wrapper pattern is used in production, treat it as approved module code: pin the source to a validated tag or commit SHA, or promote the wrapper into the customer's approved module repository.
312306

313307
The wrapper validates that:
314308

315-
- only one handoff input style is used;
316-
- each DB Home sets exactly one of `vm_cluster_key` or `vm_cluster_id`;
317-
- direct `vm_cluster_id` values are OCI Cloud VM Cluster OCIDs;
318-
- `vm_cluster_key` exists in the Google Cloud-side VM Cluster dependency map;
319-
- the referenced VM Cluster has an OCI Cloud VM Cluster OCID;
320-
- the referenced VM Cluster is `AVAILABLE` when state is present.
309+
- each DB Home sets `vm_cluster_id` to either an OCI Cloud VM Cluster OCID or a key from `gcp_cloud_vm_clusters_dependency`;
310+
- `vm_cluster_id` values are not empty or whitespace;
311+
- direct `vm_cluster_id` values that match the `ocid1.cloudvmcluster.` prefix use the full `ocid1.cloudvmcluster.{realm}.{region}.{id}` format;
312+
- lookup key values exist in the `gcp_cloud_vm_clusters_dependency` map;
313+
- each referenced VM Cluster dependency includes a non-null OCI Cloud VM Cluster OCID;
314+
- each referenced VM Cluster dependency is `AVAILABLE` when state is present.
321315

322316
## 8. Step 4 - Post-Handoff Checks
323317

@@ -335,8 +329,9 @@ After the database layer is created, and after any OCI-side operation that may a
335329
| Mistake | Why it is a problem |
336330
|---|---|
337331
| Passing the Google Cloud resource name as `vm_cluster_id`. | The OCI module requires the OCI Cloud VM Cluster OCID. |
338-
| Assuming the Google Cloud region is the OCI provider region. | Use the OCI region from the validated handoff contract. The Google Cloud region and OCI region are not the same configuration value. |
339-
| Treating JSON file handoff as the default production pattern. | JSON handoff is useful for local validation, examples, and demos. Production should use the selected orchestration layer. |
332+
| Assuming the Google Cloud region is the OCI provider region. | Use the OCI region derived from the VM Cluster OCID. The Google Cloud region and OCI region are not the same configuration value. |
333+
| Adding `oci_region` to the `gcp_cloud_vm_clusters_dependency` map. | The map type only accepts `id`, `name`, `ocid`, and `state`. Extra attributes cause a Terraform type constraint error. Resolve and pass `oci_region` separately. |
334+
| Using lowercase keys in `gcp_cloud_vm_clusters_dependency` or `cloud_db_homes_configuration` with the handoff wrapper. | The wrapper validates that these keys are uppercase semantic identifiers. Lowercase keys fail the precondition check. |
340335
| Importing Infrastructure or VM Cluster into the normal OCI database-layer stack. | It creates a second long-lived owner for resources that the Google Cloud-side stack owns. |
341336
| Using broad `ignore_changes` blocks. | Broad ignores can hide unknown drift. Keep `ignore_changes` narrow and module-owned. |
342337
| Copying full real outputs into Git or tickets. | Outputs can include sensitive identifiers or operational details. Sanitize first. |

0 commit comments

Comments
 (0)