Infrastructure Playbook
OCI Build Playbook for Oracle PeopleSoft Archive
A practical enterprise build guide for the OCI foundation behind an Oracle PeopleSoft archive: Oracle Autonomous AI Database with a private endpoint, Oracle APEX, Object Storage, IAM Identity Domains, Bastion, IPSec VPN or FastConnect, DRG routing, DNS, SSO, security monitoring, and validation.
Who This Playbook Is For
This playbook is for infrastructure, network, database platform, and IAM engineers building the cloud landing zone for an Oracle PeopleSoft archive. It explains the manual console path and Terraform path, the required inputs, the order of resources, and the validation checks that prove private archive access works.
It does not cover Data Pump export/import details or APEX report development. Use the DBA Data Pump playbook for migration commands, and use the next application playbook for APEX reports, attachments, SSO behavior, and module authorization.
Target Architecture
Corporate Access
On-prem users
-> IPSec VPN / FastConnect
-> OCI DRG
-> VCN private subnet
-> Autonomous Database private endpoint
Optional Implementation Access
Admin / contractor
-> OCI Bastion
-> Autonomous Database private endpoint
-> SQLcl or SQL Developer
PeopleSoft Authorization Design
PeopleSoft roles and permission lists should be reviewed as security-design inputs, but they do not automatically transfer to the archive. Define archive authorization by module, Business Unit, SetID, department, employee-data domain, payroll-document access, and other customer-specific security dimensions.
The APEX layer must enforce both page and report authorization and row-level data
filtering. Keep PS_PAYROLL_DOCUMENTS
separate because W-2, T4, ACA, pay statements, and employee attachments are more
sensitive than general payroll reporting.
Attachment Repository Discovery
Before sizing Object Storage, inventory PeopleSoft attachment URL definitions and identify whether each repository uses database records, file storage, FTP, SFTP, or another mechanism. Only attachments selected for separate extraction should be included in the archive bucket design.
Compartment Structure Best Practice
Design the compartment model before creating archive resources. OCI compartments are the boundary for organizing resources, applying policies, separating duties, using quotas, and making cost/security ownership visible. Avoid building directly in the tenancy root.
| Layer | Recommended Use | Why It Matters |
|---|---|---|
| Parent compartment |
One parent such as peoplesoftarchive for the archive program.
|
Gives IAM, budgets, quotas, tags, and security monitoring a clean boundary. |
| Environment compartments |
Separate dev, test, and prod
when more than one environment exists.
|
Prevents test imports, temporary access, and relaxed policies from mixing with production. |
| Functional subcompartments |
Use optional network, database, storage, and
security
subcompartments for larger enterprises.
|
Lets network, DBA, storage, and security teams administer only what they own. |
| Tag defaults and quotas | Apply owner, cost center, environment, data classification, and lifecycle tags. | Supports chargeback, retention, automated governance, and capacity control. |
Keep the first version simple. A single production archive compartment can be enough for a small implementation; use deeper hierarchy only when it improves ownership, policy scope, or audit clarity.
Manual Console Build
Use this path when your team wants to build from the OCI Console. The order is the same as the Terraform path so infrastructure, network, database, and IAM engineers can troubleshoot one layer at a time.
| Step | Build | Why | Watch For |
|---|---|---|---|
| 1 | Confirm region, naming, tags, VCN CIDR, on-prem CIDRs, CPE public IP, Bastion source CIDRs, DNS owner, and IAM owners. | Locks the required inputs before resources are created. | CIDR overlap and unknown DNS ownership cause late failures. |
| 2 | Create the archive compartment structure, naming standard, tag defaults, and any required quotas. | Gives the archive clean ownership, policy, cost, and security boundaries. | Avoid building in the tenancy root; keep hierarchy shallow unless ownership requires more separation. |
| 3 | Create IAM groups and compartment-scoped policies for infrastructure, database, storage, deployment, and read-only access. | Keeps administration least-privilege and auditable. | Broad tenancy policies are hard to defend later. |
| 4 | Create the VCN, private database endpoint subnet, route table, and optional Service Gateway. | Creates the private network for Autonomous Database and Oracle service access. | Keep public IP assignment disabled on private subnets. |
| 5 | Create Object Storage buckets for Data Pump migration files, validation evidence, generated report extracts, and attachments that are extracted separately from PeopleSoft repositories. | Provides the staging and retention area for migration files, evidence, extracts, and separately extracted attachment files. | Set encryption, lifecycle, retention, and access policy before production data lands. Many PeopleSoft attachments remain in imported database attachment tables and do not need to be copied separately to Object Storage. |
| 6 | Create the Autonomous Database NSG and allow only approved sources to HTTPS port 443 and TCPS port 1522. | Controls browser and SQL access to the private Autonomous Database endpoint. | Use TCP 443 for APEX and Autonomous Database web access. Use TCP 1522 for SQLcl, SQL Developer, and Data Pump administration. |
| 7 | Provision Autonomous Database with APEX enabled and a private endpoint in the private subnet. | Hosts archive schemas, APEX applications, and reporting data. | Confirm the selected Autonomous Database configuration supports private endpoints. |
| 8 | Choose the admin path: corporate VPN/FastConnect, temporary OCI Bastion, or a temporary admin VM. | Lets DBAs import, validate, and troubleshoot without public database access. | Bastion should be temporary and restricted to approved public /32 CIDRs. |
| 9 | Configure corporate connectivity: DRG, CPE, IPSec VPN or FastConnect, route tables, and NSG rules for each on-prem CIDR. | Allows corporate users and source systems to reach private OCI resources. | OCI-side VPN is only half the work; your firewall must be configured too. |
| 10 | Configure DNS forwarding from corporate DNS to the OCI inbound resolver for Autonomous Database private names. | Lets SQL Developer, SQLcl, and APEX access resolve private endpoints correctly. | Routing can be correct while client connections fail because DNS is missing. |
| 11 | Create the user access layer: friendly DNS name, TLS certificate, Load Balancer or enterprise reverse proxy if required. | Gives business users a stable archive URL. | Do not make users depend on raw database or temporary URLs. |
| 12 | Create the OCI IAM confidential application for APEX OpenID Connect. | Lets APEX redirect users to OCI IAM and receive login tokens. | The APEX redirect URI must exactly match the allowlisted OCI IAM URL. |
| 13 | Federate OCI IAM with your IdP using SAML, such as Azure AD, Okta, or ADFS. | Lets users authenticate with corporate identity. | Collect IdP metadata, entity ID, SSO URL, signing certificate, NameID format, and group claim name. |
| 14 | Create or synchronize PeopleSoft archive groups such as PS_HCM, PS_BENEFITS, PS_PAYROLL, PS_PAYROLL_DOCUMENTS, PS_GL, PS_AP, PS_AR, PS_BILLING, PS_ASSET_MANAGEMENT, PS_PURCHASING, PS_INVENTORY, PS_ORDER_MANAGEMENT, PS_PROJECT_COSTING, PS_AUDIT, and PS_ARCHIVE_ADMIN. | APEX uses archive groups for navigation, report authorization, document access, and administration boundaries. | Group names must match what APEX parses from the OpenID Connect token. |
| 15 | Configure APEX Web Credentials, OpenID Connect authentication, group parsing, and authorization schemes. | Turns identity groups into application access control. | Apply authorization to navigation entries and individual report pages, and add row-level data filtering for Business Unit, SetID, department, employee-data domain, payroll-document access, and other required dimensions. |
| 16 | Enable OCI Cloud Guard in the reporting region and monitor the archive compartment. | Adds security monitoring for risky configuration, exposed resources, broad IAM access, public buckets, and policy drift. | Confirm the security team owns detector findings and response workflow. |
| 17 | Validate VPN status, DNS resolution, TCP 443 for APEX, TCP 1522 for SQL access, Autonomous Database wallet connection, SQLcl/SQL Developer login, APEX SSO, group-based report access, and row-level archive data filtering. | Proves the build works from infrastructure through application access. | Test from the same network path the users will use. |
Terraform Build: Configure tfvars First
Start here before running any Terraform command. Most failures come from missing inputs, overlapping CIDRs, wrong Identity Domain URLs, or placeholder redirect URLs.
| tfvars Input | What To Set | Why It Matters |
|---|---|---|
| tenancy_ocid | Root OCI tenancy OCID. | Tells Terraform where the stack belongs. |
| user_ocid | OCI API user OCID. | Identifies the user signing OCI API calls. |
| fingerprint | Fingerprint of the uploaded API public key. | Must match the private key used by Terraform. |
| private_key_path | Local path to the OCI API private key. | Lets the provider sign requests. |
| region | OCI region, such as us-ashburn-1. |
Creates resources in the intended region. |
| project_name | Short name such as peoplesoftarchive. |
Prefixes resource names consistently. |
| environment |
Environment such as dev, test, or prod.
|
Separates stacks by lifecycle. |
| vcn_cidr_block | Approved VCN CIDR. | Must not overlap with on-premises or peered networks. |
| private_db_endpoint_subnet_cidr_block | CIDR inside the VCN for the private database endpoint subnet. | Hosts the Autonomous Database private endpoint and private access path. |
| enable_service_gateway |
true when private subnet access to Oracle services is required.
|
Supports private access patterns to services such as Object Storage. |
| archive_db_name | Autonomous Database database name, for example PSARCH. |
Names the archive database. |
| adw_admin_password | Strong Autonomous Database ADMIN password. | Required to create Autonomous Database; keep it out of Git. |
| enable_bastion |
true only when temporary admin access is needed.
|
Creates OCI Bastion for controlled private access. |
| bastion_client_cidr_blocks | Approved public /32 source CIDRs. |
Prevents Bastion access from being open to the internet. |
| enable_ipsec_vpn | true when building OCI-side VPN. |
Creates DRG, CPE, IPSec, routes, and NSG rules. |
| customer_cpe_public_ip | VPN device public IP. | OCI uses this to build the CPE/IPSec connection. |
| customer_on_prem_cidr_blocks | On-prem private CIDRs reachable over VPN. | Drives routes and Autonomous Database NSG ingress rules. |
| enable_dns_resolver_endpoint |
true when corporate DNS must resolve private Autonomous Database hostnames.
|
Creates the OCI inbound resolver target for conditional forwarding. |
| enable_sso |
true when creating OCI IAM app/groups for APEX.
|
Turns on SSO resources. |
| identity_domain_url |
Identity Domain base URL, for example https://idcs-example.identity.oraclecloud.com.
|
Terraform uses this endpoint for Identity Domains APIs. |
| identity_domain_app_template_id | Usually CustomWebAppTemplateId. |
Creates a confidential web/OIDC app. |
| apex_oidc_redirect_uris | APEX OIDC callback URL list. | OCI IAM only redirects users to allowlisted URLs. |
| apex_post_logout_redirect_uris | APEX post-logout URL list. | Controls where users land after logout. |
| apex_oidc_allowed_grants |
authorization_code and refresh_token.
|
Enables the browser login flow APEX uses. |
| peoplesoft_archive_groups |
Groups such as PS_HCM, PS_GL, PS_AP,
PS_PAYROLL_DOCUMENTS, and PS_ARCHIVE_ADMIN.
|
APEX uses these groups for navigation, report authorization, sensitive document access, and archive administration. |
Terraform Step-By-Step Rollout
Apply one layer at a time while building or troubleshooting. Once the design is proven,
use normal terraform plan
and terraform apply
for production changes.
1. Compartment
Creates the ownership and policy boundary for the archive.
terraform plan -target=oci_identity_compartment.peoplesoftarchive
terraform apply -target=oci_identity_compartment.peoplesoftarchive
2. VCN And Private Subnet
Creates the private network where Autonomous Database private endpoint and access paths live.
terraform plan -target=oci_core_vcn.main -target=oci_core_subnet.private_db_endpoint
terraform apply -target=oci_core_vcn.main -target=oci_core_subnet.private_db_endpoint
3. Storage And IAM
Creates the archive bucket plus least-privilege storage administration.
terraform plan -target=oci_objectstorage_bucket.archive -target=oci_identity_policy.archive_admins_object_storage
terraform apply -target=oci_objectstorage_bucket.archive -target=oci_identity_policy.archive_admins_object_storage
4. Autonomous Database NSG And Private Database Endpoint
Allows TCPS 1522 and creates Autonomous Database with a private endpoint in the subnet.
terraform plan -target=oci_core_network_security_group.archive_db -target=oci_database_autonomous_database.archive
terraform apply -target=oci_core_network_security_group.archive_db -target=oci_database_autonomous_database.archive
5. Optional Bastion
Creates temporary controlled access for implementation teams without corporate VPN.
terraform plan -target=oci_bastion_bastion.admin
terraform apply -target=oci_bastion_bastion.admin
6. VPN, Routing, And On-Prem NSG Rules
Creates the OCI side of corporate connectivity and allows on-prem users to reach Autonomous Database.
terraform plan -target=oci_core_ipsec.customer -target=oci_core_route_table.private_db_endpoint -target=oci_core_network_security_group_security_rule.adbsql_from_on_prem
terraform apply -target=oci_core_ipsec.customer -target=oci_core_route_table.private_db_endpoint -target=oci_core_network_security_group_security_rule.adbsql_from_on_prem
7. DNS Resolver
Creates the OCI resolver endpoint corporate DNS forwards private Autonomous Database queries to.
terraform plan -target=oci_dns_resolver_endpoint.inbound
terraform apply -target=oci_dns_resolver_endpoint.inbound
8. SSO Foundation
Creates the OCI IAM confidential app and PeopleSoft archive groups for APEX authorization.
terraform plan -target=oci_identity_domains_app.apex_archive -target=oci_identity_domains_group.peoplesoft_archive_group
terraform apply -target=oci_identity_domains_app.apex_archive -target=oci_identity_domains_group.peoplesoft_archive_group
Terraform File Reference
Create these files under infra/oci.
Use the step-by-step rollout above as the main build path. These reference blocks create
the core reference foundation. Enterprise DNS, corporate firewall changes,
identity-provider federation, certificates, APEX configuration, monitoring ownership,
and retention controls require additional customer-specific implementation.
Pin the OCI provider version tested with this playbook, record that version in the
article, and upgrade only after running
terraform validate, reviewing
the plan, and testing in a nonproduction compartment. The OCI Terraform resource remains
oci_database_autonomous_database.
versions.tf, provider.tf, variables.tf
# versions.tf
terraform {
required_version = ">= 1.6.0"
required_providers {
oci = {
source = "oracle/oci"
# Pin the tested OCI provider version for your implementation.
version = "~> 6.0"
}
}
}
# provider.tf
provider "oci" {
tenancy_ocid = var.tenancy_ocid
user_ocid = var.user_ocid
fingerprint = var.fingerprint
private_key_path = var.private_key_path
region = var.region
}
# variables.tf
variable "tenancy_ocid" { type = string }
variable "user_ocid" { type = string }
variable "fingerprint" { type = string }
variable "private_key_path" { type = string }
variable "region" { type = string }
variable "project_name" {
type = string
default = "peoplesoftarchive"
}
variable "environment" {
type = string
default = "prod"
}
variable "vcn_cidr_block" {
type = string
default = "10.20.0.0/16"
}
variable "private_db_endpoint_subnet_cidr_block" {
type = string
default = "10.20.10.0/24"
}
variable "archive_db_name" {
type = string
default = "PSARCH"
}
variable "adw_admin_password" {
type = string
sensitive = true
}
variable "enable_service_gateway" {
type = bool
default = false
}
variable "enable_bastion" {
type = bool
default = false
}
variable "bastion_client_cidr_blocks" {
type = list(string)
default = []
}
variable "enable_ipsec_vpn" {
type = bool
default = false
}
variable "customer_cpe_public_ip" {
type = string
default = ""
}
variable "customer_on_prem_cidr_blocks" {
type = list(string)
default = []
}
variable "enable_dns_resolver_endpoint" {
type = bool
default = false
}
variable "enable_sso" {
type = bool
default = false
}
variable "identity_domain_url" {
description = "OCI Identity Domain base URL, for example https://idcs-...identity.oraclecloud.com."
type = string
default = ""
}
variable "identity_domain_app_template_id" {
type = string
default = "CustomWebAppTemplateId"
}
variable "apex_oidc_redirect_uris" {
type = list(string)
default = []
}
variable "apex_post_logout_redirect_uris" {
type = list(string)
default = []
}
variable "apex_oidc_allowed_grants" {
type = list(string)
default = ["authorization_code", "refresh_token"]
}
variable "peoplesoft_archive_groups" {
type = list(string)
default = [
"PS_HCM",
"PS_BENEFITS",
"PS_PAYROLL",
"PS_PAYROLL_DOCUMENTS",
"PS_GL",
"PS_AP",
"PS_AR",
"PS_ASSET_MANAGEMENT",
"PS_PURCHASING",
"PS_BILLING",
"PS_INVENTORY",
"PS_ORDER_MANAGEMENT",
"PS_PROJECT_COSTING",
"PS_AUDIT",
"PS_ARCHIVE_ADMIN"
]
}
main.tf
resource "oci_identity_compartment" "peoplesoftarchive" {
compartment_id = var.tenancy_ocid
name = "${var.project_name}-${var.environment}"
description = "PeopleSoft Archive ${var.environment} resources"
enable_delete = false
}
resource "oci_core_vcn" "main" {
compartment_id = oci_identity_compartment.peoplesoftarchive.id
cidr_block = var.vcn_cidr_block
display_name = "${var.project_name}-${var.environment}-vcn"
dns_label = "peoplesoftarchive"
}
resource "oci_core_subnet" "private_db_endpoint" {
compartment_id = oci_identity_compartment.peoplesoftarchive.id
vcn_id = oci_core_vcn.main.id
cidr_block = var.private_db_endpoint_subnet_cidr_block
display_name = "${var.project_name}-${var.environment}-private-db-endpoint-subnet"
dns_label = "psdbpriv"
prohibit_public_ip_on_vnic = true
route_table_id = var.enable_ipsec_vpn ? oci_core_route_table.private_db_endpoint[0].id : null
}
resource "oci_core_network_security_group" "archive_db" {
compartment_id = oci_identity_compartment.peoplesoftarchive.id
vcn_id = oci_core_vcn.main.id
display_name = "${var.project_name}-${var.environment}-archive-db-nsg"
}
resource "oci_core_network_security_group_security_rule" "adbsql_from_vcn" {
network_security_group_id = oci_core_network_security_group.archive_db.id
direction = "INGRESS"
protocol = "6"
source = var.vcn_cidr_block
source_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = 1522
max = 1522
}
}
}
resource "oci_core_network_security_group_security_rule" "adb_https_from_vcn" {
network_security_group_id = oci_core_network_security_group.archive_db.id
direction = "INGRESS"
protocol = "6"
source = var.vcn_cidr_block
source_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = 443
max = 443
}
}
}
resource "oci_database_autonomous_database" "archive" {
compartment_id = oci_identity_compartment.peoplesoftarchive.id
db_name = var.archive_db_name
display_name = "${var.project_name}-${var.environment}-adb"
db_workload = "DW"
admin_password = var.adw_admin_password
data_storage_size_in_tbs = 1
compute_model = "ECPU"
compute_count = 2
license_model = "LICENSE_INCLUDED"
subnet_id = oci_core_subnet.private_db_endpoint.id
nsg_ids = [oci_core_network_security_group.archive_db.id]
private_endpoint_label = "psarchiveadb"
is_mtls_connection_required = true
}
sso.tf
resource "oci_identity_domains_app" "apex_archive" {
count = var.enable_sso ? 1 : 0
idcs_endpoint = var.identity_domain_url
schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:App"]
display_name = "${var.project_name}-${var.environment}-apex-archive"
description = "Confidential OIDC application for PeopleSoft Archive APEX authentication."
active = true
is_oauth_client = true
client_type = "confidential"
based_on_template {
value = var.identity_domain_app_template_id
}
allowed_grants = var.apex_oidc_allowed_grants
redirect_uris = var.apex_oidc_redirect_uris
post_logout_redirect_uris = var.apex_post_logout_redirect_uris
}
resource "oci_identity_domains_group" "peoplesoft_archive_group" {
for_each = var.enable_sso ? toset(var.peoplesoft_archive_groups) : toset([])
idcs_endpoint = var.identity_domain_url
schemas = ["urn:ietf:params:scim:schemas:core:2.0:Group"]
display_name = each.value
}
storage_iam.tf
data "oci_objectstorage_namespace" "current" {
compartment_id = var.tenancy_ocid
}
resource "oci_objectstorage_bucket" "archive" {
compartment_id = oci_identity_compartment.peoplesoftarchive.id
namespace = data.oci_objectstorage_namespace.current.namespace
name = "${var.project_name}-${var.environment}-archive"
access_type = "NoPublicAccess"
storage_tier = "Standard"
}
resource "oci_identity_group" "archive_admins" {
compartment_id = var.tenancy_ocid
name = "${var.project_name}-${var.environment}-archive-admins"
description = "Admins who can manage PeopleSoft Archive storage resources."
}
resource "oci_identity_policy" "archive_admins_object_storage" {
compartment_id = oci_identity_compartment.peoplesoftarchive.id
name = "${var.project_name}-${var.environment}-object-storage-admins"
description = "Allow archive admins to manage Object Storage resources."
statements = [
"Allow group ${oci_identity_group.archive_admins.name} to manage object-family in compartment ${oci_identity_compartment.peoplesoftarchive.name}"
]
}
bastion_vpn_dns.tf
resource "oci_bastion_bastion" "admin" {
count = var.enable_bastion ? 1 : 0
compartment_id = oci_identity_compartment.peoplesoftarchive.id
target_subnet_id = oci_core_subnet.private_db_endpoint.id
bastion_type = "STANDARD"
name = "${var.project_name}-${var.environment}-admin-bastion"
client_cidr_block_allow_list = var.bastion_client_cidr_blocks
max_session_ttl_in_seconds = 10800
}
resource "oci_core_drg" "main" {
count = var.enable_ipsec_vpn ? 1 : 0
compartment_id = oci_identity_compartment.peoplesoftarchive.id
display_name = "${var.project_name}-${var.environment}-drg"
}
resource "oci_core_drg_attachment" "vcn" {
count = var.enable_ipsec_vpn ? 1 : 0
drg_id = oci_core_drg.main[0].id
vcn_id = oci_core_vcn.main.id
display_name = "${var.project_name}-${var.environment}-drg-vcn-attachment"
}
resource "oci_core_cpe" "customer" {
count = var.enable_ipsec_vpn ? 1 : 0
compartment_id = oci_identity_compartment.peoplesoftarchive.id
ip_address = var.customer_cpe_public_ip
display_name = "${var.project_name}-${var.environment}-customer-cpe"
}
resource "oci_core_ipsec" "customer" {
count = var.enable_ipsec_vpn ? 1 : 0
compartment_id = oci_identity_compartment.peoplesoftarchive.id
cpe_id = oci_core_cpe.customer[0].id
drg_id = oci_core_drg.main[0].id
static_routes = var.customer_on_prem_cidr_blocks
display_name = "${var.project_name}-${var.environment}-ipsec"
}
resource "oci_core_route_table" "private_db_endpoint" {
count = var.enable_ipsec_vpn ? 1 : 0
compartment_id = oci_identity_compartment.peoplesoftarchive.id
vcn_id = oci_core_vcn.main.id
display_name = "${var.project_name}-${var.environment}-private-db-endpoint-routes"
dynamic "route_rules" {
for_each = var.customer_on_prem_cidr_blocks
content {
destination = route_rules.value
destination_type = "CIDR_BLOCK"
network_entity_id = oci_core_drg.main[0].id
}
}
}
resource "oci_core_network_security_group_security_rule" "adbsql_from_on_prem" {
for_each = var.enable_ipsec_vpn ? toset(var.customer_on_prem_cidr_blocks) : toset([])
network_security_group_id = oci_core_network_security_group.archive_db.id
direction = "INGRESS"
protocol = "6"
source = each.value
source_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = 1522
max = 1522
}
}
}
resource "oci_core_network_security_group_security_rule" "adb_https_from_on_prem" {
for_each = var.enable_ipsec_vpn ? toset(var.customer_on_prem_cidr_blocks) : toset([])
network_security_group_id = oci_core_network_security_group.archive_db.id
direction = "INGRESS"
protocol = "6"
source = each.value
source_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = 443
max = 443
}
}
}
data "oci_core_vcn_dns_resolver_association" "main" {
vcn_id = oci_core_vcn.main.id
}
resource "oci_dns_resolver_endpoint" "inbound" {
count = var.enable_dns_resolver_endpoint ? 1 : 0
resolver_id = data.oci_core_vcn_dns_resolver_association.main.dns_resolver_id
name = "${var.project_name}-${var.environment}-inbound-dns"
subnet_id = oci_core_subnet.private_db_endpoint.id
is_listening = true
is_forwarding = false
}
terraform.tfvars.example and outputs.tf
# terraform.tfvars.example
tenancy_ocid = "ocid1.tenancy.oc1..example"
user_ocid = "ocid1.user.oc1..example"
fingerprint = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00"
private_key_path = "~/.oci/oci_api_key.pem"
region = "us-phoenix-1"
project_name = "peoplesoftarchive"
environment = "prod"
vcn_cidr_block = "10.20.0.0/16"
private_db_endpoint_subnet_cidr_block = "10.20.10.0/24"
archive_db_name = "PSARCH"
# Do not put the real ADMIN password in this file.
# Pass it with TF_VAR_adw_admin_password, OCI Vault, or your approved secret manager.
enable_bastion = false
bastion_client_cidr_blocks = ["203.0.113.10/32"]
enable_ipsec_vpn = true
customer_cpe_public_ip = "203.0.113.20"
customer_on_prem_cidr_blocks = ["10.50.0.0/16"]
enable_dns_resolver_endpoint = true
enable_sso = true
identity_domain_url = "https://idcs-example.identity.oraclecloud.com"
identity_domain_app_template_id = "CustomWebAppTemplateId"
apex_oidc_redirect_uris = [
"https://archive.example.com/ords/apex_authentication.callback"
]
apex_post_logout_redirect_uris = [
"https://archive.example.com/ords/"
]
apex_oidc_allowed_grants = [
"authorization_code",
"refresh_token"
]
peoplesoft_archive_groups = [
"PS_HCM",
"PS_BENEFITS",
"PS_PAYROLL",
"PS_PAYROLL_DOCUMENTS",
"PS_GL",
"PS_AP",
"PS_AR",
"PS_BILLING",
"PS_ASSET_MANAGEMENT",
"PS_PURCHASING",
"PS_INVENTORY",
"PS_ORDER_MANAGEMENT",
"PS_PROJECT_COSTING",
"PS_AUDIT",
"PS_ARCHIVE_ADMIN"
]
# outputs.tf
output "peoplesoftarchive_compartment_id" { value = oci_identity_compartment.peoplesoftarchive.id }
output "vcn_id" { value = oci_core_vcn.main.id }
output "private_db_endpoint_subnet_id" { value = oci_core_subnet.private_db_endpoint.id }
output "archive_bucket_name" { value = oci_objectstorage_bucket.archive.name }
output "archive_db_id" { value = oci_database_autonomous_database.archive.id }
output "archive_db_private_endpoint" { value = oci_database_autonomous_database.archive.private_endpoint }
output "bastion_id" { value = try(oci_bastion_bastion.admin[0].id, null) }
output "drg_id" { value = try(oci_core_drg.main[0].id, null) }
output "ipsec_connection_id" { value = try(oci_core_ipsec.customer[0].id, null) }
output "inbound_dns_resolver_ip" { value = try(oci_dns_resolver_endpoint.inbound[0].listening_address, null) }
output "apex_oidc_client_id" { value = try(oci_identity_domains_app.apex_archive[0].name, null) }
Secrets and Terraform State
Do not place the real ADMIN password in
terraform.tfvars. Pass it as
TF_VAR_adw_admin_password
through the deployment pipeline, OCI Vault, or an approved enterprise secret manager.
Do not commit credentials to Git.
Protect Terraform state as sensitive infrastructure data. Use encrypted remote state, restrict state-bucket access, enable Object Storage versioning, use state locking or a controlled deployment pipeline, define backup and recovery for state, and prohibit emailing or locally sharing state files.
Avoid outputting secrets such as an APEX OIDC client secret. Marking an output sensitive hides normal display, but the value can still exist in Terraform state.
Rollout Commands
Use targeted commands only while learning or walking through the architecture. For
production rollout, review a normal
terraform plan
and apply through your change process.
terraform init
terraform validate
terraform plan
terraform apply
Failure Checklist
Authentication
A 401-NotAuthenticated
usually means the API key, fingerprint, user OCID, or tenancy OCID is wrong.
CIDR Overlap
Confirm the OCI VCN CIDR does not overlap with on-premises networks or peered VCNs.
Private Database Endpoint
Use an enterprise Autonomous Database configuration that supports private endpoints before applying the database resource.
VPN Tunnel
Terraform creates the OCI side. Your network team must configure the CPE device before tunnels come up.
DNS
Corporate DNS must forward Autonomous Database private hostname queries to the OCI inbound resolver endpoint.
APEX SSO
Terraform creates the OCI IAM app and groups. APEX still needs Web Credentials, OpenID Connect authentication, and group-based authorization schemes.
Destroy
Do not run terraform destroy
casually. Autonomous Database destruction can delete archive data.
SAML Federation Steps
Keep the two trust relationships separate. Your IdP federation uses SAML into OCI IAM. APEX uses OpenID Connect against OCI IAM.
Your IdP -> OCI IAM Identity Domain: SAML federation
APEX -> OCI IAM Identity Domain: OpenID Connect confidential app
IAM Inputs To Collect
- SAML metadata URL or XML
- IdP entity ID and SSO URL
- IdP signing certificate
- NameID format
- Group attribute or claim name
- Test user assigned to PeopleSoft archive groups
Configure In OCI IAM
- Add SAML Identity Provider
- Import IdP metadata
- Map NameID and user attributes
- Map or synchronize groups
- Activate IdP and sign-on policy
- Give OCI SP metadata back to your IAM team
Test Runbook
Check Terraform outputs:
terraform output
From the corporate network or VPN, confirm DNS resolves the Autonomous Database private hostname:
nslookup <adw-private-hostname>
dig <adw-private-hostname>
Confirm Autonomous Database port reachability:
nc -vz <adw-private-hostname> 1522
Connect with SQLcl after downloading and unzipping the Autonomous Database wallet:
export TNS_ADMIN=~/adw-wallet
sql admin/<password>@ebsarch_high
Connect with SQL Developer:
Connection Type: Cloud Wallet
Configuration File: Wallet_PSARCH.zip
Username: ADMIN
Password: <password>
Service: ebsarch_high
If using Bastion, create a port-forwarding session to Autonomous Database private IP port 1522 and keep the SSH tunnel open:
ssh -i ~/.ssh/id_rsa \
-N \
-L 1522:<adw-private-ip>:1522 \
<bastion-session-user>@<bastion-session-host>
Test APEX SSO and module authorization:
Expected:
- APEX redirects to OCI IAM or your federated IdP
- User returns to APEX after login
- Group claims include the expected PeopleSoft archive groups, and APEX authorization correctly restricts modules, reports, documents, Business Units, SetIDs, departments, and sensitive employee information
- APEX HTTPS access works on TCP 443
- SQL access works on TCP 1522
- Employee and payroll-document restrictions are enforced
- Business Unit and SetID filtering returns only authorized rows
- Unauthorized direct-page access is blocked
- Attachment download authorization is enforced
- Session timeout and logout behave as designed
- Navigation entries and report pages honor group authorization