<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[cloudexplorers.club]]></title><description><![CDATA[Cloud Explores – Learn • Automate • Secure • Explore the Cloud. 

A hub for cloud trends, hacks &amp; updates across OCI, AWS, Azure, GCP, Terraform &amp; more.]]></description><link>https://cloudexplorers.club</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1757407076170/201c876f-88b7-45a2-a796-ecf8cf5a1959.png</url><title>cloudexplorers.club</title><link>https://cloudexplorers.club</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 13:18:06 GMT</lastBuildDate><atom:link href="https://cloudexplorers.club/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Oracle Database at Azure]]></title><description><![CDATA[Same Exadata. Completely Different Architecture.
If you read our Oracle Database at AWS guide, you already understand the concept: Oracle Exadata hardware physically inside a cloud provider's data cen]]></description><link>https://cloudexplorers.club/oracle-database-at-azure</link><guid isPermaLink="true">https://cloudexplorers.club/oracle-database-at-azure</guid><category><![CDATA[Oracle Cloud]]></category><category><![CDATA[Azure]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[database]]></category><dc:creator><![CDATA[Paresh Zawar]]></dc:creator><pubDate>Tue, 07 Apr 2026 03:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/ea31d3d6-43a7-451e-b16f-15d6a338cd31.svg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>Same Exadata. Completely Different Architecture.</strong></h2>
<p>If you read our Oracle Database at AWS guide, you already understand the concept: Oracle Exadata hardware physically inside a cloud provider's data center, managed by Oracle, connected to your workloads via a private network link.</p>
<p>Oracle Database at Azure (ODP — Oracle Database Service for Azure) follows the same model. But almost everything underneath is different: the networking uses Azure ExpressRoute instead of a VPC endpoint, identity uses Microsoft Entra ID (formerly Azure AD) instead of AWS IAM, billing integrates into your Azure invoice rather than a separate Oracle invoice, and the latency profile, support boundaries, and deployment regions are all distinct.</p>
<p>This guide walks you through the architecture differences, step-by-step provisioning via both Azure Portal and CLI, networking setup with Azure Virtual Network peering, Entra ID integration, pricing comparison against Azure SQL and the AWS equivalent, and an honest assessment of when Oracle Database@Azure beats Oracle Database@AWS and vice versa.</p>
<blockquote>
<p><strong>🎯 Who This Is For</strong></p>
<p>Cloud architects and DBAs evaluating Oracle Database@Azure for workloads already on Microsoft Azure — particularly those running .NET applications, Power BI, Azure Data Factory, or Azure Kubernetes Service that need an Oracle backend.</p>
</blockquote>
<h2><strong>What Is Oracle Database at Azure (ODP)?</strong></h2>
<p>Oracle Database@Azure — formally called Oracle Database Service for Azure or ODP — is a partnership announced in September 2023 and reaching GA in early 2024. Oracle Exadata X9M hardware racks are physically co-located inside Microsoft Azure data centers, connected to your Azure Virtual Network through Azure ExpressRoute at sub-2ms latency.</p>
<p>The key architectural difference from Oracle Database at AWS: on AWS, you connect via a VPC endpoint (a software-defined construct). On Azure, the connection is a dedicated ExpressRoute circuit — a physical-layer private connection provisioned by Microsoft between the Oracle Exadata infrastructure and your Azure VNet. This gives slightly more predictable latency but requires ExpressRoute to be provisioned in your Azure subscription.</p>
<h3><strong>Available Services</strong></h3>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Service</strong></p></td><td><p><strong>Shape</strong></p></td><td><p><strong>Min Config</strong></p></td><td><p><strong>Best For</strong></p></td></tr><tr><td><p>Oracle Autonomous Database Serverless</p></td><td><p>ECPU-based</p></td><td><p>2 ECPUs, 1 TB</p></td><td><p>OLTP, Analytics, JSON, APEX</p></td></tr><tr><td><p>Oracle Autonomous Database on Dedicated Exadata</p></td><td><p>Exadata X9M</p></td><td><p>Quarter Rack</p></td><td><p>Enterprise OLTP, strict isolation</p></td></tr><tr><td><p>Oracle Exadata Database Service</p></td><td><p>Exadata X9M</p></td><td><p>Quarter Rack</p></td><td><p>Custom DB workloads, RAC</p></td></tr><tr><td><p>Oracle Base Database Service</p></td><td><p>VM shapes</p></td><td><p>1 OCPU, 256 GB</p></td><td><p>Dev/Test, SMB workloads</p></td></tr></tbody></table>

<h3><strong>Oracle Database at Azure vs Oracle Database at AWS — Key Differences</strong></h3>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Dimension</strong></p></td><td><p><strong>Oracle DB@Azure (ODP)</strong></p></td><td><p><strong>Oracle DB@AWS</strong></p></td></tr><tr><td><p>Network link</p></td><td><p>Azure ExpressRoute (dedicated circuit)</p></td><td><p>AWS VPC Endpoint (software-defined)</p></td></tr><tr><td><p>Identity</p></td><td><p>Microsoft Entra ID + OCI IAM</p></td><td><p>AWS IAM + OCI IAM</p></td></tr><tr><td><p>Billing</p></td><td><p>Integrated into Azure invoice (MACC eligible)</p></td><td><p>Separate Oracle invoice</p></td></tr><tr><td><p>Management plane</p></td><td><p>Azure Portal + OCI Console</p></td><td><p>OCI Console only</p></td></tr><tr><td><p>Latency to app tier</p></td><td><p>&lt; 2ms (ExpressRoute)</p></td><td><p>&lt; 1ms (VPC Endpoint)</p></td></tr><tr><td><p>Primary GA regions</p></td><td><p>East US, Germany West Central</p></td><td><p>US East (N. Virginia)</p></td></tr><tr><td><p>Azure Marketplace</p></td><td><p>Yes — one-click from Azure Portal</p></td><td><p>No — via OCI Console</p></td></tr><tr><td><p>MACC consumption</p></td><td><p>Yes — counts toward Azure spend commitment</p></td><td><p>No</p></td></tr></tbody></table>

<blockquote>
<p><strong>💡 MACC Is a Big Deal</strong></p>
<p>If your organization has a Microsoft Azure Consumption Commitment (MACC), Oracle Database@Azure spend counts toward it. This means you can use existing Azure budget for Oracle — a significant procurement advantage that Oracle DB@AWS cannot offer.</p>
</blockquote>
<h2><strong>Network Architecture: ExpressRoute Deep Dive</strong></h2>
<p>The network topology for Oracle Database at Azure is more complex than the AWS equivalent because it uses ExpressRoute rather than a VPC endpoint. Understanding this is essential before provisioning.</p>
<p>Layer 1 — Physical co-location: Oracle Exadata X9M racks sit inside Azure data centers on dedicated floor space leased by Oracle. Microsoft provides power, cooling, and physical security. Oracle operates the hardware.</p>
<p>Layer 2 — ExpressRoute circuit: An Azure ExpressRoute circuit is provisioned between the Oracle Exadata infrastructure and Microsoft's network edge. This is a dedicated private circuit — not a shared tunnel, not the public internet. Oracle provisions this on your behalf when you create an ODP resource.</p>
<p>Layer 3 — Virtual Network Gateway: In your Azure subscription, an ExpressRoute Virtual Network Gateway connects your Azure Virtual Network to the ExpressRoute circuit. This gateway must be provisioned in the same region as your ODP resource.</p>
<p>Layer 4 — Your Azure VNet: Your Azure VMs, AKS pods, App Service instances, and Azure Functions connect to Oracle DB through the VNet — same as any other Azure service. No special Oracle client configuration beyond the wallet.</p>
<h3><strong>Latency Profile</strong></h3>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Connection</strong></p></td><td><p><strong>Typical Latency</strong></p></td><td><p><strong>Notes</strong></p></td></tr><tr><td><p>Azure VM → Oracle DB@Azure (same AZ)</p></td><td><p>&lt; 2ms</p></td><td><p>ExpressRoute dedicated circuit</p></td></tr><tr><td><p>Azure VM → Oracle DB@AWS</p></td><td><p>30–80ms</p></td><td><p>Cross-cloud, public internet or FastConnect</p></td></tr><tr><td><p>Azure VM → Azure SQL Managed Instance</p></td><td><p>&lt; 1ms</p></td><td><p>Native Azure, no ExpressRoute needed</p></td></tr><tr><td><p>On-premises → Oracle DB@Azure</p></td><td><p>5–30ms</p></td><td><p>Via your existing ExpressRoute to Azure</p></td></tr><tr><td><p>AKS Pod → Oracle DB@Azure</p></td><td><p>&lt; 2ms</p></td><td><p>Same VNet, standard pod networking</p></td></tr></tbody></table>

<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/3a483aa6-b3cb-498b-b284-2964bfcd7ee2.svg" alt="" style="display:block;margin:0 auto" />

<h2><strong>Prerequisites</strong></h2>
<h3><strong>Azure Requirements</strong></h3>
<p>●      Azure subscription with Owner or Contributor role</p>
<p>●      Azure CLI 2.x installed: az --version</p>
<p>●      An Azure Virtual Network (VNet) in the target region with at least one subnet</p>
<p>●      An ExpressRoute Virtual Network Gateway deployed in your VNet (Standard SKU minimum)</p>
<p>●      Microsoft Entra ID tenant with permissions to create service principals</p>
<p>●      Azure subscription linked to Oracle — done via Azure Marketplace (one-time setup)</p>
<h3><strong>OCI Requirements</strong></h3>
<p>●      An OCI tenancy (trial or paid) — Oracle provisions ODP resources in OCI behind the scenes</p>
<p>●      OCI CLI installed and configured: oci --version</p>
<p>●      Oracle account linked to your Azure subscription via the ODP onboarding flow</p>
<h3><strong>Step 1: Link Azure Subscription to Oracle via Marketplace</strong></h3>
<p>Navigate to Azure Portal → Marketplace → search 'Oracle Database@Azure' → Subscribe. This creates the cross-cloud trust relationship and provisions the ExpressRoute connectivity.</p>
<blockquote>
<p><code>#Verify ODP provider is registered in your Azure subscription</code></p>
<p><code>az provider register --namespace Oracle.Database</code></p>
<p><code>az provider show --namespace Oracle.Database --query "registrationState"</code></p>
<p><code>#Expected: "Registered"</code></p>
</blockquote>
<h3><strong>Step 2: Create ExpressRoute Virtual Network Gateway</strong></h3>
<p>This is the most time-consuming step — provisioning an ExpressRoute gateway takes 20–45 minutes. Do this first.</p>
<blockquote>
<p><code>#Create gateway subnet (required naming — must be GatewaySubnet)</code></p>
<p><code>az network vnet subnet create \</code></p>
<p><code>--resource-group myRG \</code></p>
<p><code>--vnet-name myVNet \</code></p>
<p><code>--name GatewaySubnet \</code></p>
<p><code>--address-prefixes 10.0.255.0/27</code></p>
<p><code>#Create public IP for gateway</code></p>
<p><code>az network public-ip create \</code></p>
<p><code>--resource-group myRG \</code></p>
<p><code>--name oracle-er-gateway-pip \</code></p>
<p><code>--sku Standard \</code></p>
<p><code>--allocation-method Static</code></p>
<p><code>#Create ExpressRoute Virtual Network Gateway (takes 20-45 minutes)</code></p>
<p><code>az network vnet-gateway create \</code></p>
<p><code>--resource-group myRG \</code></p>
<p><code>--name oracle-er-gateway \</code></p>
<p><code>--vnet myVNet \</code></p>
<p><code>--gateway-type ExpressRoute \</code></p>
<p><code>--sku Standard \</code></p>
<p><code>--public-ip-address oracle-er-gateway-pip \</code></p>
<p><code>--no-wait  # Run async, check status with az network vnet-gateway show</code></p>
</blockquote>
<h2><strong>Step-by-Step: Provisioning Oracle Autonomous Database on Azure</strong></h2>
<h3><strong>Step 3: Create ODP Resource via Azure Portal</strong></h3>
<p>Once the ExpressRoute gateway is provisioned, navigate to Azure Portal → Create a resource → Oracle Database@Azure → Autonomous Database.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Field</strong></p></td><td><p><strong>Value</strong></p></td><td><p><strong>Notes</strong></p></td></tr><tr><td><p>Subscription</p></td><td><p>Your Azure subscription</p></td><td><p>Must have ODP registered</p></td></tr><tr><td><p>Resource Group</p></td><td><p>oracle-prod-rg</p></td><td><p>Create new or use existing</p></td></tr><tr><td><p>Name</p></td><td><p>prod-adb-azure-01</p></td><td><p>Display name in Azure Portal</p></td></tr><tr><td><p>Region</p></td><td><p>East US</p></td><td><p>Must match your ExpressRoute gateway region</p></td></tr><tr><td><p>Database Name</p></td><td><p>PRODADB01</p></td><td><p>Uppercase, 1-14 chars</p></td></tr><tr><td><p>Workload Type</p></td><td><p>Transaction Processing</p></td><td><p>Or Data Warehouse / JSON / APEX</p></td></tr><tr><td><p>Database Version</p></td><td><p>23ai</p></td><td><p>Latest — recommended</p></td></tr><tr><td><p>ECPU Count</p></td><td><p>2</p></td><td><p>Minimum; auto-scales if enabled</p></td></tr><tr><td><p>Storage</p></td><td><p>1 TB</p></td><td><p>Minimum; auto-scales</p></td></tr><tr><td><p>Admin Password</p></td><td><p>Use Azure Key Vault reference</p></td><td><p>Never hardcode — see Step 4</p></td></tr><tr><td><p>Virtual Network</p></td><td><p>myVNet</p></td><td><p>Must have ExpressRoute gateway</p></td></tr><tr><td><p>Subnet</p></td><td><p>oracle-subnet</p></td><td><p>Dedicated subnet recommended</p></td></tr><tr><td><p>License Type</p></td><td><p>License Included</p></td><td><p>Or BYOL if you have Oracle licenses</p></td></tr></tbody></table>

<h3><strong>Step 4: Store Credentials in Azure Key Vault</strong></h3>
<p>Unlike Oracle Database@AWS where you download a wallet ZIP, Oracle Database@Azure integrates with Azure Key Vault for credential management.</p>
<blockquote>
<p><code>#Create Key Vault (if not existing)</code></p>
<p><code>az keyvault create \</code></p>
<p><code>--name oracle-prod-kv \</code></p>
<p><code>--resource-group oracle-prod-rg \</code></p>
<p><code>--location eastus \</code></p>
<p><code>--enable-rbac-authorization true</code></p>
<p><code>#Store the ADB admin password</code></p>
<p><code>az keyvault secret set \</code></p>
<p><code>--vault-name oracle-prod-kv \</code></p>
<p><code>--name "adb-admin-password" \</code></p>
<p><code>--value "YourSecurePassword2026!"</code></p>
<p><code>#Grant your app's managed identity access to the secret</code></p>
<p><code>az role assignment create \</code></p>
<p><code>--role "Key Vault Secrets User" \</code></p>
<p><code>--assignee &lt;managed-identity-object-id&gt; \</code></p>
<p><code>--scope /subscriptions/&lt;sub-id&gt;/resourceGroups/oracle-prod-rg/providers/Microsoft.KeyVault/vaults/oracle-prod-kv</code></p>
</blockquote>
<h3><strong>Step 5: Download Wallet and Test Connectivity</strong></h3>
<blockquote>
<p><code>#Download wallet via OCI CLI (ODP resources appear in OCI too)</code></p>
<p><code>oci db autonomous-database generate-wallet \</code></p>
<p><code>--autonomous-database-id &lt;adb-ocid&gt; \</code></p>
<p><code>--password "WalletPassword2026!" \</code></p>
<p><code>--file ~/wallets/</code><a href="http://prod-adb-azure.zip"><code>prod-adb-azure.zip</code></a></p>
<p><code>mkdir -p ~/wallets/prod-adb-azure</code></p>
<p><code>unzip ~/wallets/</code><a href="http://prod-adb-azure.zip"><code>prod-adb-azure.zip</code></a> <code>-d ~/wallets/prod-adb-azure</code></p>
<p><code>#Test connection from an Azure VM in the same VNet</code></p>
<p><code>export TNS_ADMIN=~/wallets/prod-adb-azure</code></p>
<p><code>sql ADMIN/YourSecurePassword2026!@prodadb01_high</code></p>
<p><code>#Verify platform</code></p>
<p><code>SELECT platform_name, version_full FROM v\(database d, v\)instance i;</code></p>
</blockquote>
<h3><strong>Step 6: Connect from .NET / C# Application</strong></h3>
<p>Oracle Database@Azure is designed with Azure-native workloads in mind — particularly .NET applications. Use Oracle.ManagedDataAccess.Core:</p>
<blockquote>
<p><code>// Install NuGet: Oracle.ManagedDataAccess.Core</code></p>
<p><code>// dotnet add package Oracle.ManagedDataAccess.Core</code></p>
<p><code>using Oracle.ManagedDataAccess.Client;</code></p>
<p><code>using Azure.Identity;</code></p>
<p><code>using</code> <a href="http://Azure.Security"><code>Azure.Security</code></a><code>.KeyVault.Secrets;</code></p>
<p><code>// Retrieve password from Key Vault (Managed Identity auth)</code></p>
<p><code>var kvClient = new SecretClient(</code></p>
<p><code>new Uri("</code><a href="https://oracle-prod-kv.vault.azure.net/"><code>https://oracle-prod-kv.vault.azure.net/</code></a><code>"),</code></p>
<p><code>new DefaultAzureCredential()  // Uses Managed Identity in Azure, local creds in dev</code></p>
<p><code>);</code></p>
<p><code>var secret = await kvClient.GetSecretAsync("adb-admin-password");</code></p>
<p><code>// Build connection string</code></p>
<p><code>var connString = $"User Id=ADMIN;Password={secret.Value.Value};" +</code></p>
<p><code>"Data Source=prodadb01_high;" +</code></p>
<p><code>"Connection Timeout=30;Pooling=true;Min Pool Size=5;Max Pool Size=50;";</code></p>
<p><code>// Set wallet location</code></p>
<p><code>OracleConfiguration.TnsAdmin = "/path/to/wallet";</code></p>
<p><code>OracleConfiguration.WalletLocation = "/path/to/wallet";</code></p>
<p><code>using var conn = new OracleConnection(connString);</code></p>
<p><code>await conn.OpenAsync();</code></p>
<p><code>Console.WriteLine($"Connected: {conn.ServerVersion}");</code></p>
</blockquote>
<h2><strong>Microsoft Entra ID Integration</strong></h2>
<p>One of the most compelling features of Oracle Database at Azure is native Microsoft Entra ID (formerly Azure AD) authentication for Oracle DB users. Your employees can log into Oracle using their corporate Entra ID credentials — no separate Oracle passwords to manage.</p>
<h3><strong>Enable Entra ID Authentication on ADB</strong></h3>
<blockquote>
<p><code>-- Connect as ADMIN and enable Entra ID authentication EXEC DBMS_CLOUD_ADMIN.ENABLE_PRINCIPAL_AUTH( provider =&gt; 'AZURE_AD', params =&gt; JSON_OBJECT( 'azure_tenant_id' VALUE '', 'azure_app_id' VALUE '' ) );</code></p>
<p><code>-- Create a mapped Oracle user for an Entra ID user CREATE USER "user@yourdomain.com" IDENTIFIED EXTERNALLY AS 'user@yourdomain.com'; GRANT CONNECT, CREATE TABLE TO "user@yourdomain.com";</code></p>
<p><code>-- Create a mapped Oracle role for an Entra ID group CREATE ROLE "Oracle-DBAs" IDENTIFIED EXTERNALLY AS 'Oracle-DBAs'; -- Now assign permissions to the role; all members of the Entra group inherit them</code></p>
</blockquote>
<blockquote>
<p><strong>🔐 Security Win</strong></p>
<p>With Entra ID auth, DBA offboarding is instant — remove them from the Entra group and they immediately lose Oracle DB access. No hunting for Oracle passwords to revoke. No separate Oracle user lifecycle management.</p>
</blockquote>
<h2><strong>Azure-Native Integrations</strong></h2>
<p>Oracle Database@Azure integrates with the broader Azure ecosystem in ways that Oracle Database@AWS does not — because Azure Portal surfaces ODP as a first-class Azure resource.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Azure Service</strong></p></td><td><p><strong>Integration</strong></p></td><td><p><strong>Use Case</strong></p></td></tr><tr><td><p>Azure Monitor</p></td><td><p>Native metrics forwarding</p></td><td><p>CPU, storage, sessions, latency dashboards</p></td></tr><tr><td><p>Azure Log Analytics</p></td><td><p>Audit log streaming</p></td><td><p>SQL audit, login events, security monitoring</p></td></tr><tr><td><p>Azure Data Factory</p></td><td><p>Built-in Oracle connector</p></td><td><p>ETL pipelines from Oracle to Azure Synapse / Fabric</p></td></tr><tr><td><p>Microsoft Fabric</p></td><td><p>Oracle mirroring (preview)</p></td><td><p>Real-time Oracle data in OneLake for Power BI</p></td></tr><tr><td><p>Azure Backup</p></td><td><p>Policy-based DB backup</p></td><td><p>Backup retention management via Azure Portal</p></td></tr><tr><td><p>Azure Private DNS</p></td><td><p>Auto-registered DNS entries</p></td><td><p>Connect by hostname, no IP management</p></td></tr><tr><td><p>Azure Policy</p></td><td><p>Compliance enforcement</p></td><td><p>Enforce encryption, backup retention, tagging</p></td></tr><tr><td><p>Entra ID</p></td><td><p>Database user authentication</p></td><td><p>SSO and group-based Oracle DB access</p></td></tr></tbody></table>

<h3><strong>Azure Data Factory Oracle Connector</strong></h3>
<p>If you use Azure Data Factory for data movement, the Oracle connector works directly with Oracle Database at Azure — no self-hosted integration runtime needed if your ADF is in the same VNet:</p>
<blockquote>
<p><code>// ADF Linked Service JSON (Oracle Database@Azure)</code></p>
<p><code>{</code></p>
<p>  <code>"name": "OracleADB_LinkedService",</code></p>
<p>  <code>"type": "Oracle",</code></p>
<p>  <code>"typeProperties": {</code></p>
<p>    <code>"connectionString": {</code></p>
<p>      <code>"type": "SecureString",</code></p>
<p>      <code>"value": "Host=&lt;adb-host&gt;;Port=1522;Sid=&lt;service_name&gt;;User Id=adf_user;"</code></p>
<p>    <code>},</code></p>
<p>    <code>"password": {</code></p>
<p>      <code>"type": "AzureKeyVaultSecret",</code></p>
<p>      <code>"store": { "referenceName": "AzureKeyVaultLinkedService", "type": "LinkedServiceReference" },</code></p>
<p>      <code>"secretName": "adb-adf-password"</code></p>
<p>    <code>}</code></p>
<p>  <code>}</code></p>
<p><code>}</code></p>
</blockquote>
<h2><strong>Pricing: Oracle Database at Azure vs Oracle Database at AWS vs Azure SQL</strong></h2>
<table style="min-width:125px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Service</strong></p></td><td><p><strong>Config</strong></p></td><td><p><strong>Monthly Estimate</strong></p></td><td><p><strong>Oracle Support</strong></p></td><td><p><strong>Azure Invoice</strong></p></td></tr><tr><td><p>Oracle ADB@Azure Serverless</p></td><td><p>2 ECPUs, 1 TB, LI</p></td><td><p>~\(800–950/mo</p></td><td><p>Yes</p></td><td><p>Yes (MACC)</p></td></tr><tr><td><p>Oracle ADB@AWS Serverless</p></td><td><p>2 ECPUs, 1 TB, LI</p></td><td><p>~\)800/mo</p></td><td><p>Yes</p></td><td><p>No (OCI invoice)</p></td></tr><tr><td><p>Oracle on Azure VM (DIY)</p></td><td><p>D8s_v5, EE license</p></td><td><p>~\(1,400/mo</p></td><td><p>No (DIY)</p></td><td><p>Yes</p></td></tr><tr><td><p>Azure SQL Managed Instance</p></td><td><p>GP, 8 vCores</p></td><td><p>~\)900/mo</p></td><td><p>Microsoft</p></td><td><p>Yes (MACC)</p></td></tr><tr><td><p>Azure SQL Database (vCore)</p></td><td><p>GP, 8 vCores</p></td><td><p>~$700/mo</p></td><td><p>Microsoft</p></td><td><p>Yes (MACC)</p></td></tr></tbody></table>

<blockquote>
<p><strong>💰 MACC Advantage Calculation</strong></p>
<p>If you have a \(500K MACC and use Oracle DB@Azure at \)900/month, that $10,800/year counts toward your Azure commitment — reducing your at-risk MACC balance. Oracle DB@AWS does NOT count toward MACC. For organizations with large Azure commitments, this can justify a 10–20% price premium over the AWS equivalent.</p>
</blockquote>
<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/265211a1-b3a6-4034-9941-6dc620db35ac.svg" alt="" style="display:block;margin:0 auto" />

<h2><strong>Oracle DB@Azure vs Oracle DB@AWS — When to Use Which</strong></h2>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Scenario</strong></p></td><td><p><strong>Use Azure</strong></p></td><td><p><strong>Use AWS</strong></p></td><td><p><strong>Reason</strong></p></td></tr><tr><td><p>App on Azure (.NET, AKS)</p></td><td><p>✅</p></td><td><p>—</p></td><td><p>Sub-2ms latency via ExpressRoute; native Azure integrations</p></td></tr><tr><td><p>App on AWS (EC2, EKS)</p></td><td><p>—</p></td><td><p>✅</p></td><td><p>Sub-1ms latency via VPC endpoint; no cross-cloud routing</p></td></tr><tr><td><p>Power BI / Fabric reporting</p></td><td><p>✅</p></td><td><p>—</p></td><td><p>Microsoft Fabric Oracle mirroring connects directly</p></td></tr><tr><td><p>Azure Data Factory pipelines</p></td><td><p>✅</p></td><td><p>—</p></td><td><p>Built-in Oracle connector, same VNet, no SHIR needed</p></td></tr><tr><td><p>MACC spend commitment</p></td><td><p>✅</p></td><td><p>—</p></td><td><p>Oracle DB@Azure counts toward Azure MACC spend</p></td></tr><tr><td><p>Entra ID SSO for Oracle users</p></td><td><p>✅</p></td><td><p>—</p></td><td><p>Native Entra ID integration; AWS equivalent is more complex</p></td></tr><tr><td><p>Existing AWS workloads</p></td><td><p>—</p></td><td><p>✅</p></td><td><p>No cross-cloud networking overhead</p></td></tr><tr><td><p>Lowest possible latency</p></td><td><p>—</p></td><td><p>✅</p></td><td><p>VPC endpoint &lt; 1ms vs ExpressRoute ~2ms</p></td></tr><tr><td><p>Multi-cloud / cloud-agnostic</p></td><td><p>Both</p></td><td><p>Both</p></td><td><p>Same OCI Console manages both; data replication between them possible</p></td></tr></tbody></table>

<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/4e06dff9-f951-4478-a22a-f161693c6e4a.svg" alt="" style="display:block;margin:0 auto" />

<h2><strong>Migration Paths to Oracle Database at Azure</strong></h2>
<h3><strong>From On-Premises Oracle (Recommended: GoldenGate)</strong></h3>
<p>If you have existing Oracle on-premises and want to migrate to Oracle DB@Azure with minimal downtime:</p>
<blockquote>
<p><code>-- Source: your on-premises Oracle DB</code></p>
<p><code>-- Target: Oracle ADB@Azure</code></p>
<p><code>-- Step 1: Install GoldenGate on-premises and configure Extract</code></p>
<p><code>-- (GoldenGate Microservices runs on OCI, accessible from on-prem via ExpressRoute)</code></p>
<p><code>-- Step 2: Verify supplemental logging is enabled on source</code></p>
<p><code>ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;</code></p>
<p><code>ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS;</code></p>
<p><code>-- Step 3: Initial load via Data Pump to Oracle Object Storage</code></p>
<p><code>expdp SYSTEM/password SCHEMAS=APP_USER DIRECTORY=DATA_PUMP_DIR \</code></p>
<p>  <code>DUMPFILE=app_%U.dmp PARALLEL=4</code></p>
<p><code>-- Step 4: Start GoldenGate replication (catches changes during load)</code></p>
<p><code>-- Step 5: Validate row counts and data integrity</code></p>
<p><code>-- Step 6: Cutover — stop writes to source, let GoldenGate drain, switch app connection string</code></p>
</blockquote>
<h3><strong>From Oracle on Azure VM (Simplest Path)</strong></h3>
<p>If you're already running Oracle Database on an Azure Virtual Machine, this is the simplest migration — you're in the same VNet, same region, no cross-cloud complexity:</p>
<blockquote>
<p><code>#Direct Data Pump export from Oracle on Azure VM expdp SYSTEM/password@source_vm_db   FULL=Y   DUMPFILE=full_export_%U.dmp   DIRECTORY=DATA_PUMP_DIR   PARALLEL=8</code></p>
<p><code>#Copy dump files to Azure Blob Storage (then Oracle imports from Object Storage)</code></p>
<p><code>azcopy copy "/oracle/datapump/*.dmp" \</code></p>
<p>  <code>"</code><a href="https://mystorageaccount.blob.core.windows.net/migration-container/"><code>https://mystorageaccount.blob.core.windows.net/migration-container/</code></a><code>" \</code></p>
<p>  <code>--recursive</code></p>
<p><code>#Import into ADB@Azure via DBMS_DATAPUMP over DBMS_CLOUD -- (Run this on the ADB@Azure instance as ADMIN) BEGIN DBMS_CLOUD.GET_OBJECT( credential_name =&gt; 'AZURE_BLOB_CRED', object_uri =&gt; 'https://mystorageaccount.blob.core.windows.net/migration-container/full_export_01.dmp', directory_name =&gt; 'DATA_PUMP_DIR' ); END;</code></p>
</blockquote>
<h2><strong>Best Practices for Production</strong></h2>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Category</strong></p></td><td><p><strong>Best Practice</strong></p></td><td><p><strong>Why</strong></p></td></tr><tr><td><p>Networking</p></td><td><p>Deploy ODP in a dedicated subnet with NSG rules</p></td><td><p>Isolate Oracle traffic; NSGs restrict access to app tier only</p></td></tr><tr><td><p>Networking</p></td><td><p>Use Azure Private DNS for Oracle endpoint resolution</p></td><td><p>Auto-registered — no manual /etc/hosts or DNS entries</p></td></tr><tr><td><p>Security</p></td><td><p>Use Azure Managed Identity for app authentication to Key Vault</p></td><td><p>No secrets in code; rotates automatically</p></td></tr><tr><td><p>Security</p></td><td><p>Enable Entra ID authentication for human users</p></td><td><p>Instant offboarding; central identity governance</p></td></tr><tr><td><p>Security</p></td><td><p>Enable Transparent Data Encryption (always-on in ADB)</p></td><td><p>ADB enforces TDE; verify key management policy</p></td></tr><tr><td><p>Cost</p></td><td><p>Enable auto-pause for dev/test (15-min idle)</p></td><td><p>ADB stops billing compute when paused — critical for non-prod</p></td></tr><tr><td><p>Cost</p></td><td><p>Set max_cpu_count to cap auto-scaling</p></td><td><p>Without ceiling, query storm can 10x your monthly bill</p></td></tr><tr><td><p>Operations</p></td><td><p>Forward Oracle audit logs to Azure Log Analytics</p></td><td><p>Centralised SIEM; compliance reporting via Azure Monitor Workbooks</p></td></tr><tr><td><p>Operations</p></td><td><p>Use Azure Data Factory for all Oracle→Azure data movement</p></td><td><p>Managed, monitored, no self-hosted integration runtime needed</p></td></tr><tr><td><p>Reliability</p></td><td><p>Enable Autonomous Data Guard (active standby)</p></td><td><p>RPO &lt; 5 seconds; automatic failover; no extra config in ADB</p></td></tr><tr><td><p>BCDR</p></td><td><p>Configure cross-region ADB clones for DR</p></td><td><p>Oracle ADB supports refreshable clones across ODP regions</p></td></tr></tbody></table>

<h2><strong>Common Issues and Fixes</strong></h2>
<h3><strong>Issue: ExpressRoute Gateway Not Connecting</strong></h3>
<p>If the ODP resource is provisioned but the ExpressRoute circuit shows 'Not Connected', the most common cause is the gateway SKU. ODP requires Standard SKU or higher — the Basic SKU is not supported.</p>
<blockquote>
<p><code>#Check ExpressRoute gateway SKU</code></p>
<p><code>az network vnet-gateway show \</code></p>
<p>  <code>--resource-group myRG \</code></p>
<p>  <code>--name oracle-er-gateway \</code></p>
<p>  <code>--query "</code><a href="http://sku.name"><code>sku.name</code></a><code>"</code></p>
<p><code>#If output is "Basic", you need to delete and recreate with Standard SKU</code></p>
<p><code>#Check circuit provisioning state</code></p>
<p><code>az network express-route list \</code></p>
<p>  <code>--resource-group myRG \</code></p>
<p>  <code>--query "[].{Name:name, State:provisioningState, CircuitState:circuitProvisioningState}"</code></p>
</blockquote>
<h3><strong>Issue: ORA-12541 from Azure VM</strong></h3>
<p>If your Azure VM cannot reach the Oracle endpoint on port 1522, check the Network Security Group (NSG) on both the Oracle subnet and the VM subnet:</p>
<blockquote>
<p><code>#Check NSG rules on the oracle-subnet</code></p>
<p><code>az network nsg rule list \</code></p>
<p>  <code>--resource-group myRG \</code></p>
<p>  <code>--nsg-name oracle-subnet-nsg \</code></p>
<p>  <code>--output table</code></p>
<p><code>#Required: Allow inbound TCP 1522 from your app subnet</code></p>
<p><code>az network nsg rule create \</code></p>
<p>  <code>--resource-group myRG \</code></p>
<p>  <code>--nsg-name oracle-subnet-nsg \</code></p>
<p>  <code>--name Allow-Oracle-TLS \</code></p>
<p>  <code>--priority 100 \</code></p>
<p>  <code>--protocol Tcp \</code></p>
<p>  <code>--destination-port-range 1522 \</code></p>
<p>  <code>--source-address-prefixes 10.0.1.0/24 \</code></p>
<p>  <code>--access Allow</code></p>
</blockquote>
<h3><strong>Issue: Entra ID Authentication Failing (ORA-01017)</strong></h3>
<p>If Entra ID authentication fails, verify the app registration in Entra ID has the correct API permissions and that the Oracle DB user name exactly matches the Entra UPN (case-sensitive):</p>
<blockquote>
<p><code>-- Verify the mapped Oracle user exists and matches UPN exactly</code></p>
<p><code>SELECT username, authentication_type FROM dba_users</code></p>
<p><code>WHERE authentication_type = 'EXTERNAL';</code></p>
<p><code>-- UPN must be ALL CAPS in Oracle user definition</code></p>
<p><code>-- Correct:   CREATE USER "</code><a href="mailto:USER@YOURDOMAIN.COM"><code>USER@YOURDOMAIN.COM</code></a><code>" IDENTIFIED EXTERNALLY</code></p>
<p><code>-- Wrong:     CREATE USER "</code><a href="mailto:user@yourdomain.com"><code>user@yourdomain.com</code></a><code>" IDENTIFIED EXTERNALLY</code></p>
</blockquote>
<hr />
<blockquote>
<p><strong>📌 Subscribe</strong></p>
<p>All posts publish at <a href="http://cloudexplorers.club">cloudexplorers.club</a> — no paywalls, no sponsored content. Independent analysis only.</p>
</blockquote>
<hr />
<h3><strong>Safe Harbour &amp; Disclaimer</strong></h3>
<p>PRICING DISCLAIMER: All prices shown are estimates based on publicly available Oracle Cloud, Microsoft Azure, and AWS pricing pages as of March 2026. Verify current pricing at <a href="http://cloud.oracle.com">cloud.oracle.com</a>, azure.microsoft.com/pricing, and aws.amazon.com/pricing before making purchasing decisions.</p>
<p>SAFE HARBOUR: Oracle Database@Azure (ODP) features, regional availability, MACC eligibility, and pricing may change at any time without notice.</p>
<p>NO AFFILIATION: <a href="http://cloudexplorers.club">cloudexplorers.club</a> is an independent technical blog not affiliated with Oracle Corporation or Microsoft Corporation. License: CC BY 4.0 — share and adapt with attribution to <a href="http://cloudexplorers.club">cloudexplorers.club</a>.</p>
]]></content:encoded></item><item><title><![CDATA[OCI Generative AI Service]]></title><description><![CDATA[Why Oracle Is Quietly Winning the Enterprise AI Infrastructure Race
Most engineers evaluating LLM APIs start with OpenAI, drift to Bedrock for AWS integration, and never look at OCI Generative AI. Tha]]></description><link>https://cloudexplorers.club/oci-generative-ai-service</link><guid isPermaLink="true">https://cloudexplorers.club/oci-generative-ai-service</guid><category><![CDATA[Oracle Cloud]]></category><category><![CDATA[AI]]></category><category><![CDATA[generative ai]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Paresh Zawar]]></dc:creator><pubDate>Fri, 27 Mar 2026 05:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/b3e87790-a7aa-488a-81dd-3ce77b169f81.svg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>Why Oracle Is Quietly Winning the Enterprise AI Infrastructure Race</strong></h2>
<p>Most engineers evaluating LLM APIs start with OpenAI, drift to Bedrock for AWS integration, and never look at OCI Generative AI. That is a mistake — especially if you are already running workloads on Oracle Cloud or need enterprise-grade data residency guarantees.</p>
<p>OCI Generative AI Service went GA in March 2024 with a model lineup that has grown steadily since: Cohere Command R, Command R+, Meta Llama 3, Cohere Embed, and Cohere Rerank. The service runs on dedicated GPU clusters inside OCI regions. Your prompts and completions never leave the region, and Oracle does not use your data to train models.</p>
<p>This guide takes you from zero to production-ready in a single session: OCI Console setup, IAM policies, your first API call via CLI, Python SDK integration, LangChain compatibility, embeddings, RAG pipeline, and an honest pricing comparison against OpenAI GPT-4o and AWS Bedrock.</p>
<blockquote>
<p><strong>Target Audience</strong></p>
<p>Developers, ML engineers, and cloud architects who want to run LLM inference on OCI — either because they are already on Oracle Cloud or need enterprise data residency. No prior OCI AI experience required.</p>
</blockquote>
<h2><strong>What Is OCI Generative AI Service?</strong></h2>
<p>OCI Generative AI is a fully managed inference service. You send a prompt, you get a completion. No GPUs to provision, no model weights to manage, no CUDA drivers. Oracle handles the infrastructure; you pay per token.</p>
<p>The service sits inside OCI as a first-class regional service — same IAM, same VCN networking, same audit logging as any other OCI service. It supports private endpoints, meaning your traffic can stay entirely within your VCN and never traverse the public internet.</p>
<h3><strong>Available Models (March 2026)</strong></h3>
<table style="min-width:125px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Model</strong></p></td><td><p><strong>Provider</strong></p></td><td><p><strong>Type</strong></p></td><td><p><strong>Context</strong></p></td><td><p><strong>Best For</strong></p></td></tr><tr><td><p>cohere.command-r-plus</p></td><td><p>Cohere</p></td><td><p>Chat / Instruction</p></td><td><p>128K tokens</p></td><td><p>RAG, complex reasoning, enterprise Q&amp;A</p></td></tr><tr><td><p>cohere.command-r</p></td><td><p>Cohere</p></td><td><p>Chat / Instruction</p></td><td><p>128K tokens</p></td><td><p>Cost-efficient chat, summarisation</p></td></tr><tr><td><p>meta.llama-3-70b-instruct</p></td><td><p>Meta</p></td><td><p>Chat / Instruction</p></td><td><p>8K tokens</p></td><td><p>Open-weight, code generation — FREE</p></td></tr><tr><td><p>meta.llama-3-8b-instruct</p></td><td><p>Meta</p></td><td><p>Chat / Instruction</p></td><td><p>8K tokens</p></td><td><p>Low latency, lightweight tasks — FREE</p></td></tr><tr><td><p>cohere.embed-english-v3.0</p></td><td><p>Cohere</p></td><td><p>Embeddings</p></td><td><p>512 tokens</p></td><td><p>Semantic search, RAG retrieval</p></td></tr><tr><td><p>cohere.embed-multilingual-v3.0</p></td><td><p>Cohere</p></td><td><p>Embeddings</p></td><td><p>512 tokens</p></td><td><p>100+ language semantic search</p></td></tr><tr><td><p>cohere.rerank-english-v3.0</p></td><td><p>Cohere</p></td><td><p>Reranking</p></td><td><p>N/A</p></td><td><p>RAG result reranking, search quality</p></td></tr></tbody></table>

<blockquote>
<p><strong>Model Selection Rule</strong></p>
<p>For most RAG pipelines: command-r-plus for generation + embed-english-v3.0 for retrieval + rerank-english-v3.0 for reranking. This is a complete Cohere stack on OCI with no external API dependencies and full data residency.</p>
</blockquote>
<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/ab6d7d59-549f-4f38-9fa3-3427e8e835bd.svg" alt="" style="display:block;margin:0 auto" />

<h2><strong>Prerequisites and IAM Setup</strong></h2>
<p>Before writing a single line of code, IAM must be configured correctly. This is the step most tutorials skip — and why most developers hit OCI 401 errors on their first attempt.</p>
<h3><strong>Step 1: Enable OCI Generative AI</strong></h3>
<p>Navigate to OCI Console &gt; Generative AI &gt; Overview. Full model catalog is available in us-chicago-1. Frankfurt (eu-frankfurt-1) and London (uk-london-1) have a limited subset. Verify your tenancy region before starting.</p>
<h3><strong>Step 2: Create IAM Policy</strong></h3>
<p>OCI Generative AI requires explicit IAM policy statements. Without these, all API calls return 404 or 401.</p>
<blockquote>
<p>#<code>Create a group for GenAI users (OCI CLI)</code></p>
<p><code>oci iam group create \</code></p>
<p>  <code>--name genai-users \</code></p>
<p>  <code>--description "Users allowed to invoke OCI Generative AI"</code></p>
<p>#<code>Add your user to the group</code></p>
<p><code>oci iam group add-user \</code></p>
<p>  <code>--group-id &lt;group-ocid&gt; \</code></p>
<p>  <code>--user-id &lt;user-ocid&gt;</code></p>
</blockquote>
<p>Create the policy in OCI Console &gt; Identity &gt; Policies &gt; Create Policy:</p>
<blockquote>
<p>#<code>Minimal policy (tenancy-wide)</code></p>
<p><code>Allow group genai-users to use generative-ai-family in tenancy</code></p>
<p>#<code>Recommended: compartment-scoped for production</code></p>
<p><code>Allow group genai-users to use generative-ai-chat in compartment genai-prod</code></p>
<p><code>Allow group genai-users to use generative-ai-text-generation in compartment genai-prod</code></p>
<p><code>Allow group genai-users to use generative-ai-embed in compartment genai-prod</code></p>
<p><code>Allow group genai-users to use generative-ai-summarize in compartment genai-prod</code></p>
</blockquote>
<h3><strong>Step 3: Install OCI CLI and Python SDK</strong></h3>
<blockquote>
<p>#<code>Install OCI CLI</code></p>
<p><code>bash -c "$(curl -L</code> <a href="https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh"><code>https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh</code></a><code>)"</code></p>
<p><code>oci setup config</code></p>
<p>#<code>Verify Generative AI access</code></p>
<p><code>oci generative-ai model list \</code></p>
<p>  <code>--compartment-id &lt;your-compartment-ocid&gt; \</code></p>
<p>  <code>--output table</code></p>
<p>#<code>Install Python SDK + LangChain</code></p>
<p><code>pip install oci langchain-community</code></p>
<p>#<code>Verify</code></p>
<p><code>python3 -c "import oci; print(oci.__version__)"</code></p>
</blockquote>
<h2><strong>Your First OCI Generative AI API Call</strong></h2>
<p>Let us start simple: a basic chat completion using Cohere Command R+. This verifies credentials, region endpoint, and IAM policy before building anything complex.</p>
<h3><strong>Via OCI CLI — Quickest Verification</strong></h3>
<blockquote>
<p><code>export COMPARTMENT_ID="ocid1.compartment.oc1..xxxxxxxxxxxx"</code></p>
<p><code>oci generative-ai-inference chat \</code></p>
<p>  <code>--compartment-id $COMPARTMENT_ID \</code></p>
<p>  <code>--serving-mode '{"modelId":"cohere.command-r-plus","servingType":"ON_DEMAND"}' \</code></p>
<p>  <code>--chat-request '{</code></p>
<p>    <code>"message": "Explain Oracle Exadata in 2 sentences.",</code></p>
<p>    <code>"maxTokens": 200,</code></p>
<p>    <code>"temperature": 0.7,</code></p>
<p>    <code>"chatHistory": []</code></p>
<p>  <code>}'</code></p>
</blockquote>
<h3><strong>Via Python SDK — Chat Completion</strong></h3>
<blockquote>
<p><code>import oci</code></p>
<p><code>config = oci.config.from_file()</code></p>
<p><code>client = oci.generative_ai_inference.GenerativeAiInferenceClient(</code></p>
<p>    <code>config=config,</code></p>
<p>    <code>service_endpoint="</code><a href="https://inference.generativeai.us-chicago-1.oci.oraclecloud.com"><code>https://inference.generativeai.us-chicago-1.oci.oraclecloud.com</code></a><code>"</code></p>
<p><code>)</code></p>
<p><code>COMPARTMENT_ID = "ocid1.compartment.oc1..xxxxxxxxxxxx"</code></p>
<p>#<code>Build request</code></p>
<p><code>chat_detail = oci.generative_ai_inference.models.CohereChatRequest() chat_detail.message = "What is Oracle Autonomous Database 23ai?" chat_detail.max_tokens = 500 chat_detail.temperature = 0.7</code></p>
<p><code>chat_request = oci.generative_ai_inference.models.ChatDetails() chat_request.serving_mode = oci.generative_ai_inference.models.OnDemandServingMode( model_id="cohere.command-r-plus" ) chat_request.chat_request = chat_detail chat_request.compartment_id = COMPARTMENT_ID</code></p>
<p>#<code>Send and print</code></p>
<p><code>response =</code> <a href="http://client.chat"><code>client.chat</code></a><code>(chat_request)</code></p>
<p><code>print(</code><a href="http://response.data.chat"><code>response.data.chat</code></a><code>_response.text)</code></p>
</blockquote>
<h3><strong>Streaming Response (Production Pattern)</strong></h3>
<blockquote>
<p><code>chat_</code><a href="http://detail.is"><code>detail.is</code></a><code>_stream = True  # Add this to any chat request</code></p>
<p><code>response =</code> <a href="http://client.chat"><code>client.chat</code></a><code>(chat_request)</code></p>
<p><code>for event in</code> <a href="http://response.data.events"><code>response.data.events</code></a><code>():</code></p>
<p>    <code>print(</code><a href="http://event.data"><code>event.data</code></a><code>, end="", flush=True)</code></p>
<p><code>print()</code></p>
</blockquote>
<h2><strong>Embeddings and Semantic Search</strong></h2>
<p>Embeddings convert text into dense vector representations — the foundation of RAG pipelines, semantic search, and document clustering.</p>
<h3><strong>Generate Embeddings</strong></h3>
<blockquote>
<p><code>def get_embeddings(texts: list[str], input_type: str = "search_document") -&gt; list: """ input_type: "search_document" | "search_query" | "classification" | "clustering" Use "search_document" when indexing, "search_query" at query time. """ embed_req = oci.generative_ai_inference.models.EmbedTextDetails() embed_req.serving_mode = oci.generative_ai_inference.models.OnDemandServingMode( model_id="cohere.embed-english-v3.0" ) embed_req.compartment_id = COMPARTMENT_ID embed_req.inputs = texts embed_req.input_type = input_type response = client.embed_text(embed_req) return response.data.embeddings</code></p>
<p>#<code>Example</code></p>
<p><code>docs = [</code></p>
<p>    <code>"Oracle Autonomous Database is a self-managing database service.",</code></p>
<p>    <code>"OCI Object Storage provides durable, scalable object storage.",</code></p>
<p>    <code>"Oracle Exadata delivers extreme database performance.",</code></p>
<p><code>]</code></p>
<p><code>embeddings = get_embeddings(docs)</code></p>
<p><code>print(f"Embeddings: {len(embeddings)} vectors of dim {len(embeddings[0])}")</code></p>
<p>#<code>Output: Embeddings: 3 vectors of dim 1024</code></p>
</blockquote>
<h3><strong>Simple Semantic Search</strong></h3>
<blockquote>
<p><code>import numpy as np</code></p>
<p><code>def cosine_similarity(a, b): a, b = np.array(a), np.array(b) return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))</code></p>
<p><code>query_emb = get_embeddings(["Best service for high-performance DB?"], "search_query")[0] results = sorted([(cosine_similarity(query_emb, e), d) for e, d in zip(embeddings, docs)], reverse=True)</code></p>
<p><code>for score, doc in results: print(f"{score:.4f} — {doc[:60]}")</code></p>
<p><code>#0.8821 — Oracle Exadata delivers extreme database performance...</code></p>
<p><code>#0.7234 — Oracle Autonomous Database is a self-managing...</code></p>
</blockquote>
<h2><strong>LangChain Integration</strong></h2>
<p>OCI Generative AI has first-class support in LangChain — drop it into any existing pipeline as a replacement for OpenAI or Bedrock.</p>
<h3><strong>LangChain Chat + RAG Pipeline</strong></h3>
<blockquote>
<p><code>from langchain_community.chat_models.oci_generative_ai import ChatOCIGenAI from langchain_community.embeddings.oci_generative_ai import OCIGenAIEmbeddings from langchain_community.vectorstores import FAISS from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser</code></p>
<p><code>#LLM llm = ChatOCIGenAI( model_id="cohere.command-r-plus", service_endpoint="https://inference.generativeai.us-chicago-1.oci.oraclecloud.com", compartment_id=COMPARTMENT_ID, model_kwargs={"temperature": 0.7, "max_tokens": 500} )</code></p>
<p><code>#Embeddings embeddings = OCIGenAIEmbeddings( model_id="cohere.embed-english-v3.0", service_endpoint="https://inference.generativeai.us-chicago-1.oci.oraclecloud.com", compartment_id=COMPARTMENT_ID, input_type="search_document" )</code></p>
<p><code>#Build vector store and RAG chain</code></p>
<p><code>docs = ["Oracle ADB auto-scales compute independently from storage.",</code></p>
<p>        <code>"OCI Gen AI supports Cohere and Llama 3 on dedicated GPU clusters.",</code></p>
<p>        <code>"Data Guard provides automatic failover with RPO under 5 seconds."]</code> </p>
<p><code>vectorstore = FAISS.from_texts(docs, embeddings)</code></p>
<p><code>retriever =</code> <a href="http://vectorstore.as"><code>vectorstore.as</code></a><code>_retriever(search_kwargs={"k": 2})</code></p>
<p><code>prompt = ChatPromptTemplate.from_template(</code></p>
<p>    <code>"Answer based only on context:\n{context}\n\nQuestion: {question}"</code></p>
<p><code>)</code></p>
<p><code>chain = ({"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser())</code></p>
<p><code>print(chain.invoke("Does OCI support automatic database failover?"))</code></p>
</blockquote>
<h2><strong>Pricing: OCI vs OpenAI vs AWS Bedrock</strong></h2>
<table style="min-width:125px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Model</strong></p></td><td><p><strong>Platform</strong></p></td><td><p><strong>Input \(/1M</strong></p></td><td><p><strong>Output \)/1M</strong></p></td><td><p><strong>Data Residency</strong></p></td></tr><tr><td><p>Command R+</p></td><td><p>OCI Gen AI</p></td><td><p>\(2.86</p></td><td><p>\)14.28</p></td><td><p>Yes — stays in region</p></td></tr><tr><td><p>Command R+</p></td><td><p>Cohere Direct</p></td><td><p>\(3.00</p></td><td><p>\)15.00</p></td><td><p>Varies</p></td></tr><tr><td><p>GPT-4o</p></td><td><p>OpenAI</p></td><td><p>\(5.00</p></td><td><p>\)15.00</p></td><td><p>US by default</p></td></tr><tr><td><p>Claude 3.5 Sonnet</p></td><td><p>AWS Bedrock</p></td><td><p>\(3.00</p></td><td><p>\)15.00</p></td><td><p>Configurable</p></td></tr><tr><td><p>Llama 3 70B</p></td><td><p>OCI Gen AI</p></td><td><p>\(0.00</p></td><td><p>\)0.00</p></td><td><p>Yes — FREE</p></td></tr><tr><td><p>Llama 3 70B</p></td><td><p>AWS Bedrock</p></td><td><p>\(2.65</p></td><td><p>\)3.50</p></td><td><p>Configurable</p></td></tr><tr><td><p>embed-english-v3.0</p></td><td><p>OCI Gen AI</p></td><td><p>\(0.10/1M</p></td><td><p>—</p></td><td><p>Yes</p></td></tr><tr><td><p>text-embedding-3-large</p></td><td><p>OpenAI</p></td><td><p>\)0.13/1M</p></td><td><p>—</p></td><td><p>US by default</p></td></tr></tbody></table>

<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/3ee3d408-4723-4557-8e97-343f29048bef.svg" alt="" style="display:block;margin:0 auto" />

<blockquote>
<p><strong>Cost Reality Check</strong></p>
<p>OCI Llama 3 70B is currently FREE on On Demand. For production workloads where GPT-4o quality is not required, Llama 3 70B on OCI reduces LLM inference cost to zero at the model layer. You only pay OCI compute for your application server.</p>
</blockquote>
<h2><strong>Best Practices for Production</strong></h2>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Category</strong></p></td><td><p><strong>Best Practice</strong></p></td><td><p><strong>Reason</strong></p></td></tr><tr><td><p>Security</p></td><td><p>Use Instance Principal auth — no API keys in code</p></td><td><p>Auto-rotating credentials; keys in env vars get leaked</p></td></tr><tr><td><p>Security</p></td><td><p>Use private endpoint inside VCN</p></td><td><p>Traffic never leaves OCI network</p></td></tr><tr><td><p>Performance</p></td><td><p>Cache embeddings — compute once, store in Oracle ADB</p></td><td><p>Embedding repeatedly is wasted cost; embed is fast but not free</p></td></tr><tr><td><p>Performance</p></td><td><p>Enable streaming for all UI-facing chat responses</p></td><td><p>First-token latency feels faster; users see progress</p></td></tr><tr><td><p>Cost</p></td><td><p>Set max_tokens conservatively (200–500 for most tasks)</p></td><td><p>Output tokens cost 5x more than input on Command R+</p></td></tr><tr><td><p>Cost</p></td><td><p>Use command-r (not r-plus) for simple summarisation</p></td><td><p>Command R is 3x cheaper; reserve r-plus for complex reasoning</p></td></tr><tr><td><p>Reliability</p></td><td><p>Implement exponential backoff on 429 responses</p></td><td><p>On Demand tier has per-minute token limits</p></td></tr><tr><td><p>Data</p></td><td><p>Never send PII to On Demand; use Dedicated AI Cluster</p></td><td><p>Contractual data protection requires Dedicated for sensitive data</p></td></tr></tbody></table>

<h2><strong>Honest Limitations</strong></h2>
<p>●      No function calling / tool use for Cohere models via OCI SDK — use direct Cohere API for structured tool use workflows</p>
<p>●      Llama 3 context window is 8K tokens — not suitable for long-document tasks (use Command R+ at 128K instead)</p>
<p>●      No image / multimodal support yet — vision models not available on OCI Gen AI Service as of March 2026</p>
<p>●      Region availability: Full model catalog only in us-chicago-1; other regions have limited model selection</p>
<p>●      Rate limits on On Demand tier are per-tenancy, not per-compartment — a spike in one team throttles others</p>
<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/54261180-ffd6-41a1-a171-e6772e064515.svg" alt="" style="display:block;margin:0 auto" />

<blockquote>
<p><strong>When to Choose OCI Gen AI</strong></p>
<p>Use OCI if: already on OCI, need data residency, want Llama 3 for free, or need the full Cohere RAG stack (Command R+ + Embed + Rerank) without external dependencies. Use OpenAI/Bedrock if: you need multimodal, function calling, or the absolute latest frontier models within days of release.</p>
</blockquote>
<hr />
<h3><strong>Safe Harbour &amp; Disclaimer</strong></h3>
<p><em>PRICING DISCLAIMER: All prices are estimates based on publicly available OCI, OpenAI, and AWS pricing pages as of March 2026. Llama 3 free pricing is subject to Oracle pricing policy changes without notice. Verify at</em> <a href="http://cloud.oracle.com"><em>cloud.oracle.com</em></a><em>, openai.com/pricing, and aws.amazon.com/bedrock/pricing before purchasing decisions.</em></p>
<p><em>SAFE HARBOUR: OCI Generative AI model availability, pricing, and features may change at any time without notice.</em></p>
<p><em>NO AFFILIATION:</em> <a href="http://cloudexplorers.club"><em>cloudexplorers.club</em></a> <em>is an independent technical blog not affiliated with Oracle Corporation, Cohere Inc., or Meta Platforms. License: CC BY 4.0 — share and adapt with attribution to</em> <a href="http://cloudexplorers.club"><em>cloudexplorers.club</em></a><em>.</em></p>
]]></content:encoded></item><item><title><![CDATA[Oracle Database@AWS: What It Is and Why It Changes Everything]]></title><description><![CDATA[Why Oracle Finally Partnered With AWS (And Why It Matters)
For decades, Oracle and AWS operated like rival kingdoms — you could run Oracle Database on an EC2 instance, but you were doing it yourself, ]]></description><link>https://cloudexplorers.club/oracle-database-aws-guide</link><guid isPermaLink="true">https://cloudexplorers.club/oracle-database-aws-guide</guid><category><![CDATA[Oracle Cloud]]></category><category><![CDATA[Oracle Database]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Oracle]]></category><category><![CDATA[Databases]]></category><dc:creator><![CDATA[Paresh Zawar]]></dc:creator><pubDate>Sun, 15 Mar 2026 16:02:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/7d5e1069-3fee-4d12-9caf-bb3542adcf75.svg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>Why Oracle Finally Partnered With AWS (And Why It Matters)</strong></h2>
<p>For decades, Oracle and AWS operated like rival kingdoms — you could run Oracle Database on an EC2 instance, but you were doing it yourself, unsupported, with all the infrastructure complexity that entails. In June 2023, that changed dramatically.</p>
<p>Oracle and AWS announced Oracle Database@AWS: a fully managed Oracle Database service running on dedicated Oracle Exadata infrastructure inside AWS data centers — but owned, operated, and supported entirely by Oracle. You manage it through the OCI console. You pay Oracle for the database. AWS never touches it.</p>
<p>This is not a marketing rebrand of RDS for Oracle. This is fundamentally different infrastructure with a fundamentally different support model. This guide explains exactly what it is, how the networking works, how to set it up step by step, and — critically — when you should and should not use it.</p>
<blockquote>
<p><strong>🎯 Who This Post Is For</strong></p>
<p>DBAs, cloud architects, and engineering leads evaluating whether to run Oracle Autonomous Database or Oracle Exadata in AWS environments without re-platforming to PostgreSQL or Aurora.</p>
</blockquote>
<h2><strong>What Is Oracle Database@AWS, Exactly?</strong></h2>
<p>Oracle Database@AWS is a managed service that provisions Oracle Database infrastructure — specifically Oracle Exadata Database Service and Oracle Autonomous Database — inside AWS Availability Zones. The key technical details:</p>
<p><strong>Infrastructure</strong>: Oracle Exadata X9M hardware racks physically located inside AWS data centers</p>
<p><strong>Network connectivity:</strong> Connected to your AWS VPC via a high-speed, low-latency private network link (sub-millisecond latency to EC2)</p>
<p><strong>Management plane:</strong> OCI Console, OCI APIs, and OCI CLI — not the AWS Console</p>
<p><strong>Support:</strong> Oracle Cloud Support — not AWS Support</p>
<p><strong>Billing:</strong> Oracle Cloud billing — appears on your OCI invoice, not your AWS bill</p>
<p><strong>Identity:</strong> OCI IAM for database users; AWS IAM for your applications via cross-service roles</p>
<p><strong>Regions:</strong> Initially US East (N. Virginia), expanding to additional regions</p>
<h3><strong>What Databases Are Available?</strong></h3>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Database Service</strong></p></td><td><p><strong>Shape</strong></p></td><td><p><strong>Use Case</strong></p></td><td><p><strong>Min Config</strong></p></td></tr><tr><td><p>Oracle Autonomous Database Serverless</p></td><td><p>ECPU-based</p></td><td><p>OLTP, Analytics, Mixed</p></td><td><p>2 ECPUs, 1 TB Storage</p></td></tr><tr><td><p>Oracle Autonomous Database on Dedicated Exadata</p></td><td><p>Exadata X9M</p></td><td><p>Enterprise OLTP</p></td><td><p>Quarter Rack</p></td></tr><tr><td><p>Oracle Exadata Database Service</p></td><td><p>Exadata X9M</p></td><td><p>Custom DB workloads</p></td><td><p>Quarter Rack</p></td></tr><tr><td><p>Oracle Base Database Service</p></td><td><p>VM.Standard shapes</p></td><td><p>Dev/Test, SMB</p></td><td><p>1 OCPU, 256 GB</p></td></tr></tbody></table>

<blockquote>
<p><strong>💡 Key Insight</strong></p>
<p>For most teams evaluating Oracle Database@AWS, the answer is Oracle Autonomous Database Serverless — it requires zero Exadata rack commitment, scales by the ECPU, and is the fastest to provision (under 5 minutes).</p>
</blockquote>
<h2><strong>Network Architecture: How It Actually Connects</strong></h2>
<p>Understanding the network topology is critical before you provision anything. Oracle Database@AWS does not create an endpoint inside your VPC in the traditional sense. Instead, it creates an OCI VCN (Virtual Cloud Network) that is peered into your AWS VPC through a dedicated interconnect.</p>
<h3><strong>The Three-Layer Network Model</strong></h3>
<p><strong>Layer 1</strong> — <strong>Physical interconnect:</strong></p>
<p>Oracle and AWS maintain a dedicated high-speed network link between Oracle Exadata racks and AWS network infrastructure within the same data center campus. This is NOT traversing the public internet.</p>
<p><strong>Layer 2</strong> — <strong>OCI VCN:</strong></p>
<p>Your Oracle Database instances live inside an OCI VCN subnet. Oracle manages this entirely. You see it in the OCI Console.</p>
<p><strong>Layer 3</strong> — <strong>AWS VPC endpoint:</strong></p>
<p>Oracle provisions a VPC endpoint in your AWS account. Your EC2 instances, Lambda functions, ECS containers, and EKS pods connect to Oracle DB through this endpoint using standard Oracle Net (TCP/1521 or TCP/2484 for TLS).</p>
<h3><strong>Latency Characteristics</strong></h3>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Connection Type</strong></p></td><td><p><strong>Typical Latency</strong></p></td><td><p><strong>Notes</strong></p></td></tr><tr><td><p>EC2 → Oracle DB@AWS (same AZ)</p></td><td><p>&lt; 1 ms</p></td><td><p>Co-located rack, dedicated interconnect</p></td></tr><tr><td><p>EC2 → Oracle DB@AWS (cross-AZ)</p></td><td><p>1–3 ms</p></td><td><p>Still within same AWS region physical campus</p></td></tr><tr><td><p>EC2 → RDS Oracle</p></td><td><p>&lt; 1 ms</p></td><td><p>Fully within AWS network</p></td></tr><tr><td><p>EC2 → OCI DB (cross-cloud)</p></td><td><p>30–80 ms</p></td><td><p>FastConnect or public internet</p></td></tr><tr><td><p>On-premises → Oracle DB@AWS</p></td><td><p>5–50 ms</p></td><td><p>Via AWS Direct Connect + OCI interconnect</p></td></tr></tbody></table>

<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/ba3fc5b9-ead0-4b51-8a9e-d2fa4cc6e6a9.svg" alt="" style="display:block;margin:0 auto" />

<h2><strong>Prerequisites Before You Start</strong></h2>
<p>Before provisioning Oracle Database@AWS, you need accounts and configurations in both OCI and AWS. This is genuinely the most confusing part for teams new to the service — you're operating across two cloud consoles simultaneously.</p>
<h3><strong>OCI Requirements</strong></h3>
<p>●      An active OCI tenancy (trial or paid)</p>
<p>●      OCI user with tenancy-level privileges (or appropriate IAM policies)</p>
<p>●      OCI CLI installed and configured: oci --version should return 3.x+</p>
<p>●      OCI tenancy subscribed to the US East (Ashburn) or relevant region</p>
<p>●      Credit card or Oracle Universal Credits on file</p>
<h3><strong>AWS Requirements</strong></h3>
<p>●      AWS account with permissions to create VPCs, subnets, security groups</p>
<p>●      AWS CLI configured: aws --version should return 2.x+</p>
<p>●      A VPC in us-east-1 (N. Virginia) with at least one private subnet</p>
<p>●      AWS account linked to OCI via the Oracle Database@AWS integration</p>
<h3><strong>Linking Your AWS Account to OCI</strong></h3>
<p>The linking process is a one-time setup done in the AWS Marketplace. Navigate to AWS Marketplace → find 'Oracle Database@AWS' → subscribe. This creates the cross-account trust relationship.</p>
<blockquote>
<p><code># Verify OCI CLI is configured</code></p>
<p><code>oci iam region list --output table</code></p>
<p><code># Verify AWS CLI is configured</code></p>
<p><code>aws sts get-caller-identity</code></p>
<p><code># Output should show your AWS account ID</code></p>
<p><code># {</code></p>
<p><code>#   "UserId": "AIDAXXXXXXXXXXXXXXXXX",</code></p>
<p><code>#   "Account": "123456789012",</code></p>
<p><code>#   "Arn": "arn:aws:iam::123456789012:user/your-user"</code></p>
<p><code># }</code></p>
</blockquote>
<h2><strong>Step-by-Step: Provisioning Oracle Autonomous Database on AWS</strong></h2>
<p>We'll provision an Oracle Autonomous Database Serverless instance — the quickest path to a running Oracle DB in AWS. The full process takes approximately 10–15 minutes once prerequisites are met.</p>
<h3><strong>Step 1: Create the Oracle Database@AWS Resource in OCI Console</strong></h3>
<p>Navigate to the OCI Console → Oracle Database@AWS → Autonomous Database. Click 'Create Autonomous Database'.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Field</strong></p></td><td><p><strong>Value</strong></p></td><td><p><strong>Notes</strong></p></td></tr><tr><td><p>Display Name</p></td><td><p>prod-adb-aws-01</p></td><td><p>Your choice — use naming convention</p></td></tr><tr><td><p>Database Name</p></td><td><p>PRODADB01</p></td><td><p>Uppercase, 1-14 chars, no spaces</p></td></tr><tr><td><p>Workload Type</p></td><td><p>Transaction Processing</p></td><td><p>Or Data Warehouse / JSON / APEX</p></td></tr><tr><td><p>Deployment Type</p></td><td><p>Serverless</p></td><td><p>Shared Exadata — fastest to start</p></td></tr><tr><td><p>Database Version</p></td><td><p>23ai</p></td><td><p>Latest — use this unless legacy app requires 19c</p></td></tr><tr><td><p>ECPU Count</p></td><td><p>2</p></td><td><p>Minimum; auto-scales if enabled</p></td></tr><tr><td><p>Storage</p></td><td><p>1 TB</p></td><td><p>Minimum; auto-scales if enabled</p></td></tr><tr><td><p>Password</p></td><td><p>OCI#Secure2026!</p></td><td><p>ADMIN user — store in Secrets Manager</p></td></tr><tr><td><p>AWS VPC</p></td><td><p>vpc-xxxxxxxxx</p></td><td><p>Your target VPC in us-east-1</p></td></tr><tr><td><p>AWS Subnet</p></td><td><p>subnet-xxxxxxxxx</p></td><td><p>Private subnet recommended</p></td></tr><tr><td><p>License Type</p></td><td><p>License Included</p></td><td><p>Or BYOL if you have Oracle licenses</p></td></tr></tbody></table>

<h3><strong>Step 2: Retrieve the Connection Endpoint</strong></h3>
<p>After provisioning (3–8 minutes), navigate to your ADB instance → DB Connection → Download Wallet. The wallet contains:</p>
<p>●      tnsnames.ora — connection string definitions</p>
<p>●      sqlnet.ora — network configuration</p>
<p>●      cwallet.sso and ewallet.p12 — SSL certificates</p>
<p>●      <a href="http://ojdbc.properties">ojdbc.properties</a> — JDBC properties file</p>
<blockquote>
<p><code># Unzip wallet to a secure directory</code></p>
<p><code>mkdir -p ~/oracle-wallet/prod-adb</code></p>
<p><code>unzip Wallet_PRODADB01.zip -d ~/oracle-wallet/prod-adb</code></p>
<p><code># Check available connection strings</code></p>
<p><code>cat ~/oracle-wallet/prod-adb/tnsnames.ora</code></p>
<p><code># Output will show connection strings like:</code></p>
<p><code># prodadb01_high = (description=(retry_count=20)(retry_delay=3)</code></p>
<p><code>#   (address=(protocol=tcps)(port=1522)</code></p>
<p><code>#   (host=adb.us-east-1.oraclecloud.com))</code></p>
<p><code>#   (connect_data=(service_name=xxxxx_prodadb01_high.adb.oraclecloud.com))</code></p>
<p><code>#   (security=(ssl_server_dn_match=yes)))</code></p>
</blockquote>
<p><strong>Step 3: Configure Security Groups</strong></p>
<p>Your EC2 instances need outbound access to the Oracle DB endpoint on port 1522 (TLS). Create a security group rule:</p>
<blockquote>
<p><code># Get the VPC endpoint DNS name from OCI Console</code></p>
<p><code># Then create outbound rule for your application security group</code></p>
<p><code>aws ec2 authorize-security-group-egress \</code></p>
<p><code>--group-id sg-xxxxxxxxxxxxxxxxx \</code></p>
<p><code>--ip-permissions '[</code></p>
<p><code>{</code></p>
<p><code>"IpProtocol": "tcp",</code></p>
<p><code>"FromPort": 1522,</code></p>
<p><code>"ToPort": 1522,</code></p>
<p><code>"IpRanges": [{"CidrIp": "10.0.0.0/8", "Description": "Oracle DB@AWS endpoint"}]</code></p>
<p><code>}</code></p>
<p><code>]'</code></p>
<p><code># For mutual TLS (recommended), also allow port 1521</code></p>
<p><code>aws ec2 authorize-security-group-egress \</code></p>
<p><code>--group-id sg-xxxxxxxxxxxxxxxxx \</code></p>
<p><code>--ip-permissions '[{"IpProtocol": "tcp", "FromPort": 1521, "ToPort": 1521,</code></p>
<p><code>"IpRanges": [{"CidrIp": "10.0.0.0/8"}]}]'</code></p>
</blockquote>
<h3><strong>Step 4: Test Connectivity from EC2</strong></h3>
<p>SSH into an EC2 instance in the same VPC and run a connection test using SQLcl or SQL*Plus:</p>
<blockquote>
<p># Install SQLcl on Amazon Linux 2023</p>
<p>sudo dnf install java-21-amazon-corretto -y</p>
<p>wget <a href="https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip">https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip</a></p>
<p>unzip <a href="http://sqlcl-latest.zip">sqlcl-latest.zip</a></p>
<p># Set wallet location in environment</p>
<p>export TNS_ADMIN=~/oracle-wallet/prod-adb</p>
<p># Connect to Autonomous Database</p>
<p>sql ADMIN/'OCI#Secure2026!'@prodadb01_high</p>
<p># Expected output:</p>
<p># SQLcl: Release 24.3 Production on ...</p>
<p># Connected to:</p>
<p># Oracle Database 23ai Enterprise Edition</p>
<p># SQL&gt;</p>
<p># Verify you are on Exadata infrastructure</p>
<p>SELECT platform_name, version_full FROM v\(database d, v\)instance i;</p>
</blockquote>
<h3><strong>Step 5: Connect a Java Application via JDBC</strong></h3>
<p>For production applications, use the Oracle JDBC driver with the wallet. Add the dependency to your pom.xml:</p>
<blockquote>
<p><code>com.oracle.database.jdbc</code></p>
<p><code>ojdbc11</code></p>
<p><code>23.5.0.24.07</code></p>
<p><code>com.oracle.database.security</code></p>
<p><code>oraclepki</code></p>
<p><code>23.5.0.24.07</code></p>
<p><code>// Java connection example with wallet</code></p>
<p><code>import oracle.jdbc.pool.OracleDataSource;</code></p>
<p><code>OracleDataSource ods = new OracleDataSource();</code></p>
<p><code>ods.setURL("jdbc:oracle:thin:@prodadb01_high?TNS_ADMIN=/path/to/wallet");</code></p>
<p><code>ods.setUser("ADMIN");</code></p>
<p><code>ods.setPassword(System.getenv("ORACLE_DB_PASSWORD")); // Never hardcode!</code></p>
<p><code>try (Connection conn = ods.getConnection()) {</code></p>
<p><code>Statement stmt = conn.createStatement();</code></p>
<p><code>ResultSet rs = stmt.executeQuery("SELECT * FROM v$version");</code></p>
<p><code>while (rs.next()) {</code></p>
<p><code>System.out.println(rs.getString(1));</code></p>
<p><code>}</code></p>
<p><code>}</code></p>
</blockquote>
<h2><strong>Pricing: What It Actually Costs</strong></h2>
<p>Oracle Database@AWS pricing has two components: the Oracle database service (ECPU + Storage + Options) and any AWS data transfer charges. There are no Oracle fees for the network interconnect itself.</p>
<h3><strong>Autonomous Database Serverless Pricing (us-east-1, April 2026)</strong></h3>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Component</strong></p></td><td><p><strong>Rate</strong></p></td><td><p><strong>Example (2 ECPU, 1 TB, 730 hrs)</strong></p></td><td><p><strong>Notes</strong></p></td></tr><tr><td><p>ECPU (compute)</p></td><td><p>\(0.2688/ECPU/hr</p></td><td><p>2 × \)0.2688 × 730 = ~\(393/mo</p></td><td><p>Auto-scaling adds ECPUs on demand</p></td></tr><tr><td><p>Storage</p></td><td><p>\)0.0230/GB/mo</p></td><td><p>1,000 × \(0.0230 = \)23/mo</p></td><td><p>Includes backups in same region</p></td></tr><tr><td><p>Exadata Storage</p></td><td><p>Included</p></td><td><p>\(0</p></td><td><p>Smart Scan, Smart Flash Cache included</p></td></tr><tr><td><p>BYOL discount</p></td><td><p>−50%</p></td><td><p>~\)196/mo compute with existing licenses</p></td><td><p>Requires Oracle SE2/EE license</p></td></tr><tr><td><p>AWS Data Transfer</p></td><td><p>\(0.09/GB out</p></td><td><p>Varies</p></td><td><p>EC2→DB in same AZ: \)0 transfer cost</p></td></tr></tbody></table>

<table style="min-width:50px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>⚠️ Important Pricing Note</strong></p></td><td><p>ECPU auto-scaling can significantly increase costs under heavy load. Always set max_cpu_count to cap spending: ALTER DATABASE SET max_cpu_count = 8; Monitor usage in OCI Cost Analysis dashboard.</p></td></tr></tbody></table>

<h3><strong>Oracle Database@AWS vs Alternatives: Cost Comparison</strong></h3>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Service</strong></p></td><td><p><strong>8 OCPU / 64GB / 2TB / Oracle DB</strong></p></td><td><p><strong>Oracle Support</strong></p></td><td><p><strong>Managed?</strong></p></td></tr><tr><td><p>Oracle DB@AWS (ADB Serverless)</p></td><td><p>~\(650–900/mo</p></td><td><p>Yes (Oracle)</p></td><td><p>Yes (Oracle)</p></td></tr><tr><td><p>Oracle DB@AWS (Exadata Qtr Rack)</p></td><td><p>~\)12,000+/mo</p></td><td><p>Yes (Oracle)</p></td><td><p>Yes (Oracle)</p></td></tr><tr><td><p>RDS for Oracle (db.r6g.2xlarge)</p></td><td><p>~\(1,100/mo + license</p></td><td><p>Yes (AWS)</p></td><td><p>Yes (AWS)</p></td></tr><tr><td><p>Oracle on EC2 (r6g.2xlarge)</p></td><td><p>~\)350/mo compute</p></td><td><p>No (DIY)</p></td><td><p>No (DIY)</p></td></tr><tr><td><p>OCI Autonomous Database (native)</p></td><td><p>~$580/mo</p></td><td><p>Yes (Oracle)</p></td><td><p>Yes (Oracle)</p></td></tr></tbody></table>

<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/153a9917-5d0b-495f-971f-87af0517d1f6.svg" alt="" style="display:block;margin:0 auto" />

<h2><strong>When to Use Oracle Database@AWS (And When Not To)</strong></h2>
<p>This is the section most comparison articles skip. Oracle Database@AWS is genuinely excellent for specific scenarios and genuinely wrong for others.</p>
<h3><strong>✅ Use Oracle Database@AWS When:</strong></h3>
<p>●      Your application is already on AWS (ECS, EKS, Lambda, EC2) and you need Oracle DB — no migration, no re-architecture</p>
<p>●      You need Oracle-specific features: Partitioning, Advanced Compression, RAC, Data Guard — features RDS for Oracle supports poorly or not at all</p>
<p>●      Oracle licensing compliance is critical — Oracle Customer Success provides direct support, not AWS</p>
<p>●      You need Oracle 23ai features: JSON Relational Duality Views, True Cache, AI Vector Search</p>
<p>●      Your DBA team knows Oracle but not AWS-native databases — lowest re-training cost</p>
<p>●      Regulatory requirements mandate Oracle as the database (common in banking, healthcare, government)</p>
<h3><strong>❌ Do NOT Use Oracle Database@AWS When:</strong></h3>
<p>●      You are a greenfield project — consider Aurora PostgreSQL or DynamoDB first</p>
<p>●      Cost is the primary constraint — Oracle licensing costs will dominate</p>
<p>●      Your workload is 100% cloud-native and Oracle-agnostic — you are paying for features you will not use</p>
<p>●      You need multi-region active-active — Oracle Data Guard is active-passive; global tables on DynamoDB or Aurora Global are better</p>
<p>●      Your team has no Oracle DBA expertise — managed does not mean zero-knowledge</p>
<p>●      You are evaluating this as a "migration path off Oracle" — this keeps you on Oracle; if you want off, use AWS DMS to PostgreSQL instead</p>
<table style="min-width:50px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>🔑 The Bottom Line</strong></p></td><td><p>Oracle Database@AWS is the best answer for "I need Oracle on AWS" — it is not the answer for "I need a database on AWS." Those are very different questions.</p></td></tr></tbody></table>

<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/aa8e4aea-6908-49e7-ad6b-3e9da61e0c89.svg" alt="" style="display:block;margin:0 auto" />

<h2><strong>Migrating an Existing Oracle Database to Oracle DB@AWS</strong></h2>
<p>If you have Oracle running on-premises or on EC2, here are the three primary migration paths:</p>
<h3><strong>Option A: Oracle Data Pump (Export/Import) — Best for &lt; 500 GB</strong></h3>
<blockquote>
<p><code>-- On source database: export schema</code></p>
<p><code>expdp SYSTEM/password@source_db \</code></p>
<p><code>SCHEMAS=APP_USER \</code></p>
<p><code>DIRECTORY=DATA_PUMP_DIR \</code></p>
<p><code>DUMPFILE=app_export_%U.dmp \</code></p>
<p><code>LOGFILE=app_export.log \</code></p>
<p><code>PARALLEL=4</code></p>
<p><code>-- Upload to OCI Object Storage</code></p>
<p><code>oci os object bulk-upload \</code></p>
<p><code>--bucket-name migration-bucket \</code></p>
<p><code>--src-dir /oracle/datapump/</code></p>
<p><code>-- On target ADB: import</code></p>
<p><code>impdp ADMIN/password@prodadb01_high \</code></p>
<p><code>SCHEMAS=APP_USER \</code></p>
<p><code>DIRECTORY=DATA_PUMP_DIR \</code></p>
<p><code>DUMPFILE=app_export_%U.dmp \</code></p>
<p><code>REMAP_SCHEMA=APP_USER:APP_USER \</code></p>
<p><code>PARALLEL=4</code></p>
</blockquote>
<h3><strong>Option B: Oracle GoldenGate — Best for Zero-Downtime Migration</strong></h3>
<p>GoldenGate provides continuous replication from your source database to ADB, allowing you to cut over with &lt; 1 minute downtime. This is the recommended path for production systems with SLA requirements.</p>
<p>The process: configure GoldenGate Extract on source → configure GoldenGate Replicat on ADB → initial load → catch up CDC → validate data → cutover.</p>
<h3><strong>Option C: AWS Database Migration Service (DMS) + Schema Conversion</strong></h3>
<p>DMS supports Oracle as a source and Oracle as a target. Use this path if you are also evaluating conversion to PostgreSQL — SCT (Schema Conversion Tool) shows you the conversion complexity before you commit.</p>
<table style="min-width:125px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Migration Method</strong></p></td><td><p><strong>Downtime</strong></p></td><td><p><strong>Max Size</strong></p></td><td><p><strong>Complexity</strong></p></td><td><p><strong>Best For</strong></p></td></tr><tr><td><p>Data Pump</p></td><td><p>4–24 hours</p></td><td><p>&lt; 500 GB</p></td><td><p>Low</p></td><td><p>Dev/test, small prod databases</p></td></tr><tr><td><p>GoldenGate</p></td><td><p>&lt; 5 min</p></td><td><p>Any size</p></td><td><p>High</p></td><td><p>Large prod with SLA</p></td></tr><tr><td><p>AWS DMS</p></td><td><p>2–8 hours</p></td><td><p>&lt; 2 TB</p></td><td><p>Medium</p></td><td><p>Oracle → Oracle or Oracle → PostgreSQL</p></td></tr><tr><td><p>RMAN Backup/Restore</p></td><td><p>8–48 hours</p></td><td><p>&lt; 5 TB</p></td><td><p>Medium</p></td><td><p>Infrequent migrations, DR setup</p></td></tr></tbody></table>

<h2><strong>Monitoring &amp; Observability</strong></h2>
<p>Oracle Database@AWS exposes metrics through both OCI Monitoring and — critically — AWS CloudWatch. This dual-plane observability is one of the service's underrated strengths.</p>
<h3><strong>OCI Monitoring Metrics</strong></h3>
<blockquote>
<p><code># Query ADB CPU utilization via OCI CLI</code></p>
<p><code>oci monitoring metric-data summarize-metrics-data \</code></p>
<p><code>--compartment-id ocid1.compartment.oc1..xxxx \</code></p>
<p><code>--namespace oracle_autonomous_database \</code></p>
<p><code>--query-text 'CpuUtilization[1m]{resourceId = "ocid1.autonomousdatabase.oc1..xxxx"}.mean()' \</code></p>
<p><code>--start-time 2026-03-17T00:00:00Z \</code></p>
<p><code>--end-time 2026-03-17T06:00:00Z</code></p>
</blockquote>
<h3><strong>CloudWatch Integration</strong></h3>
<p>Enable CloudWatch metrics publishing from the OCI Console → Autonomous Database → CloudWatch Integration. Metrics appear in CloudWatch under the OracleDatabase namespace within 5 minutes.</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Metric</strong></p></td><td><p><strong>CloudWatch Namespace</strong></p></td><td><p><strong>Alert Threshold (Suggestion)</strong></p></td></tr><tr><td><p>CpuUtilization</p></td><td><p>OracleDatabase</p></td><td><p>&gt; 85% for 5 mins → scale up</p></td></tr><tr><td><p>StorageUtilization</p></td><td><p>OracleDatabase</p></td><td><p>&gt; 75% → expand storage</p></td></tr><tr><td><p>SessionCount</p></td><td><p>OracleDatabase</p></td><td><p>&gt; 80% of max → connection pool alert</p></td></tr><tr><td><p>SQLResponseTime</p></td><td><p>OracleDatabase</p></td><td><p>&gt; 2x baseline → investigate</p></td></tr><tr><td><p>FailedConnections</p></td><td><p>OracleDatabase</p></td><td><p>&gt; 10/min → security alert</p></td></tr></tbody></table>

<h2><strong>Best Practices for Production Deployments</strong></h2>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Category</strong></p></td><td><p><strong>Best Practice</strong></p></td><td><p><strong>Why</strong></p></td></tr><tr><td><p>Security</p></td><td><p>Use mutual TLS (mTLS) with wallet, not clear text</p></td><td><p>Oracle enforces this for ADB; do not disable</p></td></tr><tr><td><p>Security</p></td><td><p>Store wallet and credentials in AWS Secrets Manager</p></td><td><p>Never embed in code or environment variables</p></td></tr><tr><td><p>Security</p></td><td><p>Create application-specific DB users, never use ADMIN</p></td><td><p>Principle of least privilege — ADMIN is your break-glass account</p></td></tr><tr><td><p>Networking</p></td><td><p>Deploy Oracle DB@AWS endpoint in private subnet only</p></td><td><p>No public internet access to database ever</p></td></tr><tr><td><p>Networking</p></td><td><p>Use VPC endpoint policies to restrict access to specific IAM roles</p></td><td><p>Defense in depth</p></td></tr><tr><td><p>Performance</p></td><td><p>Enable connection pooling (UCP or HikariCP)</p></td><td><p>ADB Serverless has per-session overhead; pool amortizes this</p></td></tr><tr><td><p>Performance</p></td><td><p>Use the <em>high connection string for OLTP, </em>low for reporting</p></td><td><p>Different parallelism and priority profiles</p></td></tr><tr><td><p>Cost</p></td><td><p>Set max_cpu_count to prevent runaway auto-scaling costs</p></td><td><p>Without cap, a query storm can 10x your monthly bill</p></td></tr><tr><td><p>Cost</p></td><td><p>Enable auto-pause for dev/test databases (15-min idle threshold)</p></td><td><p>ADB stops billing compute when paused</p></td></tr><tr><td><p>Operations</p></td><td><p>Enable Automatic Indexing — it is a 23ai superpower</p></td><td><p>Oracle ML models identify and create optimal indexes automatically</p></td></tr><tr><td><p>Operations</p></td><td><p>Configure Data Guard (Autonomous Data Guard) for production</p></td><td><p>Automatic failover, RPO &lt; 5 seconds, no extra config</p></td></tr><tr><td><p>Backup</p></td><td><p>Verify backup retention is set to 60 days minimum</p></td><td><p>Default is 60 days; confirm in console</p></td></tr></tbody></table>

<h2><strong>Common Issues and Fixes</strong></h2>
<h3><strong>Issue: ORA-12541: TNS:no listener</strong></h3>
<p>Most common cause: your EC2 security group outbound rules do not allow traffic to port 1522. Secondary cause: TNS_ADMIN environment variable not pointing to the correct wallet directory.</p>
<blockquote>
<p><code># Verify TNS_ADMIN is set</code></p>
<p><code>echo $TNS_ADMIN</code></p>
<p><code># Test port connectivity from EC2</code></p>
<p><code>nc -zv 1522</code></p>
<p><code># If nc fails, check security group egress rules</code></p>
<p><code>aws ec2 describe-security-groups \</code></p>
<p><code>--group-ids sg-xxxxxxxxxxxxxxxxx \</code></p>
<p><code>--query "SecurityGroups[0].IpPermissionsEgress"</code></p>
</blockquote>
<h3><strong>Issue: ORA-28000: Account is locked</strong></h3>
<p>The ADMIN account locks after 10 failed login attempts. Unlock via OCI Console → Autonomous Database → Database Users → ADMIN → Unlock. For application users, unlock via SQL:</p>
<blockquote>
<p><code>-- Connect as ADMIN and unlock application user</code></p>
<p><code>ALTER USER app_user ACCOUNT UNLOCK;</code></p>
<p><code>ALTER USER app_user IDENTIFIED BY "NewSecurePassword2026!";</code></p>
</blockquote>
<h3><strong>Issue: Slow Query Performance vs. On-Premises Oracle</strong></h3>
<p>If queries are slower than expected after migration, the most common causes are: (1) missing indexes that Automatic Indexing hasn't yet identified, (2) stale statistics, (3) using the wrong connection string (_low instead of _high for OLTP).</p>
<blockquote>
<p><code>-- Check and gather fresh statistics</code></p>
<p><code>EXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname =&gt; 'APP_USER', cascade =&gt; TRUE);</code></p>
</blockquote>
<blockquote>
<p><code>-- Check Automatic Indexing recommendations</code></p>
<p><code>SELECT * FROM DBA_AUTO_INDEX_IND_ACTIONS ORDER BY creation_time DESC;</code></p>
</blockquote>
<blockquote>
<p><code>-- Check current connection service level</code></p>
<p><code>SELECT SYS_CONTEXT('USERENV', 'SERVICE_NAME') FROM DUAL;</code></p>
</blockquote>
<hr />
<h3><em><strong>Safe Harbour &amp; Disclaimer</strong></em></h3>
<p><em>PRICING DISCLAIMER: All prices shown are estimates based on publicly available AWS and Oracle pricing pages as of March 2026 and may not reflect current rates, promotional pricing, committed use discounts, or enterprise agreements. Verify current pricing at</em> <a href="http://cloud.oracle.com"><em>cloud.oracle.com</em></a> <em>and aws.amazon.com/pricing before making purchasing decisions.</em></p>
<p><em>SAFE HARBOUR: This post contains forward-looking statements based on current service capabilities. Oracle and AWS may change, discontinue, or alter Oracle Database@AWS features, availability, and pricing at any time without notice.</em></p>
<p><em>NO AFFILIATION:</em> <a href="http://cloudexplorers.club"><em>cloudexplorers.club</em></a> <em>is an independent technical blog. This post is not sponsored by, endorsed by, or affiliated with Oracle Corporation or Amazon Web Services. All opinions are those of the author.</em></p>
<p><em>LICENSE: This post is published under Creative Commons Attribution 4.0 International (CC BY 4.0). You may share and adapt with attribution to</em> <a href="http://cloudexplorers.club"><em>cloudexplorers.club</em></a><em>.</em></p>
]]></content:encoded></item><item><title><![CDATA[OCI vs AWS: An Honest Cost Comparison]]></title><description><![CDATA[Introduction: The Cost Conversation Nobody Has Properly
Most cloud cost comparisons are useless. They compare raw compute prices while ignoring the three things that actually drive enterprise cloud bi]]></description><link>https://cloudexplorers.club/oci-vs-aws-cost-comparison</link><guid isPermaLink="true">https://cloudexplorers.club/oci-vs-aws-cost-comparison</guid><category><![CDATA[Oracle Cloud]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Databases]]></category><category><![CDATA[Oracle]]></category><dc:creator><![CDATA[Paresh Zawar]]></dc:creator><pubDate>Mon, 09 Mar 2026 16:33:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/2a5f4bdc-a9d9-4592-8fa5-71d26d24d6e9.svg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction: The Cost Conversation Nobody Has Properly</h2>
<p>Most cloud cost comparisons are useless. They compare raw compute prices while ignoring the three things that actually drive enterprise cloud bills: Oracle database licensing multipliers, data egress fees that compound every month, and support costs that silently add 3–10% to every invoice.</p>
<p>This post does it differently. We'll compare OCI and AWS across a realistic Oracle database workload — the kind teams actually run in production — using real pricing data, real OCI and AWS CLI commands to query what you're spending, and an honest verdict on where each platform wins.</p>
<p>Spoiler: OCI is dramatically cheaper for Oracle database workloads. But AWS wins in specific scenarios, and we'll cover those too. No vendor spin. Let's look at the numbers.</p>
<blockquote>
<p><strong>🎯  What This Post Covers</strong></p>
<p>Real pricing comparison for: Compute (OCPU vs vCPU), Block Storage (OCI vs EBS), Object Storage egress (10TB/month), Oracle DB Enterprise Edition licensing multipliers on each cloud, enterprise support costs, and a full TCO calculator you can adapt to your own workload.</p>
</blockquote>
<h2>Section 1: How OCI and AWS Price Compute Differently</h2>
<p>Before looking at numbers, you need to understand why compute pricing is fundamentally different between the two clouds — not just in dollars but in the unit of measure.</p>
<h3>OCI: OCPU-Based Flexible Pricing</h3>
<p>OCI prices compute in OCPUs (Oracle CPU units). One OCPU equals two vCPUs (one physical core with hyperthreading). You can also scale OCPUs and memory independently on flexible shapes — pay for exactly what you need, rounded to the nearest OCPU.</p>
<blockquote>
<p><code># Query your current OCI compute instance shapes and hourly costs</code></p>
<p><code>oci compute shape list \</code></p>
<p><code>--compartment-id $COMPARTMENT_OCID \</code></p>
<p><code>--query 'data[?contains(shapeFlex)].{shape:shape,ocpus:"ocpu-options".max,mem:"memory-options".max-in-gbs}' \</code></p>
<p><code>--output table</code></p>
<p><code># Check running instance costs (requires Cost Management service)</code></p>
<p><code>oci usage-api usage-summary request \</code></p>
<p><code>--tenant-id $TENANCY_OCID \</code></p>
<p><code>--time-usage-started 2026-03-01T00:00:00Z \</code></p>
<p><code>--time-usage-ended 2026-03-31T23:59:59Z \</code></p>
<p><code>--granularity MONTHLY \</code></p>
<p><code>--query-type COST \</code></p>
<p><code>--group-by '[{"type":"tag","key":"computeShape"}]'</code></p>
</blockquote>
<h3>AWS: vCPU-Based Fixed Instance Families</h3>
<p>AWS EC2 uses fixed instance families (m6a.xlarge, r6g.2xlarge, etc.) where you buy predefined CPU + memory bundles. You cannot split them. For Oracle licensing, this creates a critical hidden cost: AWS counts each vCPU as 0.5 processor licenses — which means an 8-vCPU instance requires 4 processor licenses. OCI counts OCPUs directly, so an 8-OCPU instance also requires 4 licenses — but those 8 OCPUs deliver 16 vCPUs of compute. You get twice the compute for the same license count.</p>
<blockquote>
<p><code># AWS CLI: List EC2 instance pricing for a specific type</code></p>
<p><code>aws pricing get-products \</code></p>
<p>  <code>--service-code AmazonEC2 \</code></p>
<p>  <code>--region us-east-1 \</code></p>
<p>  <code>--filters \</code></p>
<p>    <code>'Type=TERM_MATCH,Field=instanceType,Value=r6a.2xlarge' \</code></p>
<p>    <code>'Type=TERM_MATCH,Field=operatingSystem,Value=Linux' \</code></p>
<p>    <code>'Type=TERM_MATCH,Field=tenancy,Value=Shared' \</code></p>
<p>  <code>--query 'PriceList[0]' | python3 -m json.tool | grep -A3 'pricePerUnit'</code></p>
<p><code># Result: r6a.2xlarge (8 vCPU, 64GB RAM) = ~\(0.4536/hour = \)332/month</code></p>
</blockquote>
<blockquote>
<p><strong>💡  The Licensing Multiplier — The Biggest Hidden Cost</strong></p>
<p>On AWS: 8 vCPUs = 4 Oracle processor licenses required. On OCI: 8 OCPUs = 4 Oracle processor licenses required — but those 8 OCPUs = 16 vCPUs of compute. Same license cost, double the compute on OCI. At \(47,500/processor/year Oracle EE list price, this alone saves ~\)95,000/year for a moderately sized deployment.</p>
</blockquote>
<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/6f150188-30a3-44db-b84e-a060d64f0d2b.svg" alt="" style="display:block;margin:0 auto" />

<p><em>Figure 1: OCI's flat network fabric vs AWS's layered architecture — fewer hops means lower latency and simpler cost modelling</em></p>
<h2>Section 2: Storage — Where the Price Gap Gets Extreme</h2>
<h3>Block Storage: OCI vs AWS EBS</h3>
<p>OCI Block Volumes use a simple model: you pay for capacity in GB-months and optionally for IOPS/throughput performance units. The baseline Balanced performance tier (60 IOPS/GB) is often more than enough for database workloads and costs a fraction of AWS EBS.</p>
<blockquote>
<p><code># OCI: Create a 2TB high-performance block volume</code></p>
<p><code>oci bv volume create \</code></p>
<p>  <code>--compartment-id $COMPARTMENT_OCID \</code></p>
<p>  <code>--availability-domain $AD \</code></p>
<p>  <code>--display-name 'prod-db-volume' \</code></p>
<p>  <code>--size-in-gbs 2048 \</code></p>
<p>  <code>--vpus-per-gb 20    # 20 VPUs = High Performance (2000 IOPS/GB max)</code></p>
<p><code># Query your block volume costs</code></p>
<p><code>oci bv volume list \</code></p>
<p>  <code>--compartment-id $COMPARTMENT_OCID \</code></p>
<p>  <code>--query 'data[*].{name:"display-name",gb:"size-in-gbs",vpus:"vpus-per-gb"}' \</code></p>
<p>  <code>--output table</code></p>
<p><code># OCI pricing (US East, on-demand):</code></p>
<p><code># Balanced (10 VPUs):  \(0.0255/GB-month  = \)52/month for 2TB</code></p>
<p><code># High Perf (20 VPUs): \(0.0375/GB-month = \)76/month for 2TB</code></p>
</blockquote>
<blockquote>
<p><code># AWS: Equivalent EBS volume for Oracle DB (io2 for production IOPS)</code></p>
<p><code>aws ec2 create-volume \</code></p>
<p>  <code>--region us-east-1 \</code></p>
<p>  <code>--availability-zone us-east-1a \</code></p>
<p>  <code>--size 2048 \</code></p>
<p>  <code>--volume-type io2 \</code></p>
<p>  <code>--iops 50000</code></p>
<p><code># AWS EBS io2 pricing (us-east-1):</code></p>
<p><code># Storage:  \(0.125/GB-month  = \)256/month for 2TB</code></p>
<p><code># IOPS:     \(0.065/IOPS-month = \)3,250/month for 50,000 IOPS</code></p>
<p><code># TOTAL:    ~$3,506/month for comparable performance</code></p>
<p><code># gp3 (cheaper option, lower IOPS ceiling):</code></p>
<p><code># Storage:  \(0.08/GB-month = \)164/month</code></p>
<p><code># IOPS:     \(0.005/IOPS-month beyond 3000 = \)235/month extra for 50k IOPS</code></p>
<p><code># TOTAL:   ~$399/month (but gp3 has 16,000 IOPS limit — not enough for Oracle OLTP)</code></p>
</blockquote>
<blockquote>
<p><strong>💡  OCI Block Volume VPUs Explained</strong></p>
<p>VPUs (Volume Performance Units) let you dial performance up or down on a live volume. 0 VPUs = Lower Cost (2 IOPS/GB), 10 VPUs = Balanced (60 IOPS/GB), 20 VPUs = Higher Performance (up to 225,000 IOPS). AWS requires you to pick gp2, gp3, io1, or io2 at creation — changing types requires a multi-hour migration.</p>
</blockquote>
<h3>Object Storage &amp; Data Egress — Where OCI Wins by a Factor of 13</h3>
<p>This is the line item that shocks most AWS-first architects when they see an OCI bill. OCI includes 10 TB of outbound data transfer per month at no charge across all regions. AWS includes 100 GB — then charges $0.09/GB for the next 9.9 TB.</p>
<blockquote>
<p><code># OCI: Check your egress usage this month</code></p>
<p><code>oci monitoring metric-data summarize-metrics-data \</code></p>
<p>  <code>--compartment-id $COMPARTMENT_OCID \</code></p>
<p>  <code>--namespace oci_objectstorage \</code></p>
<p>  <code>--query-text 'BytesDownloaded[1d].sum()' \</code></p>
<p>  <code>--start-time 2026-03-01T00:00:00Z \</code></p>
<p>  <code>--end-time 2026-03-31T23:59:59Z</code></p>
<p><code># OCI egress pricing:</code></p>
<p><code># First 10 TB/month: FREE</code></p>
<p><code># 10-50 TB/month:    \(0.0085/GB  (vs AWS \)0.09/GB = 10.6x cheaper)</code></p>
<p><code># 50+ TB/month:      \(0.0068/GB  (vs AWS \)0.085/GB = 12.5x cheaper)</code></p>
<p><code># 10 TB per month cost comparison:</code></p>
<p><code># OCI:  $0 (within free tier)</code></p>
<p><code># AWS: (10TB - 100GB) x \(0.09 = 9,900 GB x \)0.09 = $891/month</code></p>
</blockquote>
<blockquote>
<p><code># AWS: Check your data transfer costs (Cost Explorer API)</code></p>
<p><code>aws ce get-cost-and-usage \</code></p>
<p>  <code>--time-period Start=2026-03-01,End=2026-03-31 \</code></p>
<p>  <code>--granularity MONTHLY \</code></p>
<p>  <code>--filter '{"Dimensions":{"Key":"USAGE_TYPE","Values":["DataTransfer-Out-Bytes"]}}' \</code></p>
<p>  <code>--metrics BlendedCost AmortizedCost</code></p>
<p><code># If you're doing 50TB/month outbound (common for analytics/reporting):</code></p>
<p><code># OCI:  first 10TB free + 40TB x \(0.0085 = \)340/month</code></p>
<p><code># AWS:  50TB x \(0.09 (roughly) = \)4,500/month</code></p>
<p><code># Annual delta: (\(4,500 - \)340) x 12 = $49,920/year saved</code></p>
</blockquote>
<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/4f0718f1-0f26-4dcf-845a-d0aecdec43d0.svg" alt="" style="display:block;margin:0 auto" />

<p><em>Figure 2: Full TCO breakdown for an 8 OCPU/64GB Oracle EE BYOL production database — on-demand pricing, US East region</em></p>
<h2>Section 3: Oracle Database Licensing — The Cost Multiplier</h2>
<p>This section is critical and often misunderstood. Oracle's licensing policy directly ties to the physical core count of the underlying hardware in a way that's very different between OCI and AWS.</p>
<h3>The Oracle Processor Core Factor Table</h3>
<p>Oracle publishes a Processor Core Factor Table. For x86-64 processors (which both OCI and AWS use), the factor is 0.5 — meaning each physical core requires 0.5 processor licenses. The critical difference is how each cloud maps your VM to physical cores.</p>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Scenario</strong></p></td><td><p><strong>OCI (8 OCPU)</strong></p></td><td><p><strong>AWS (16 vCPU equivalent)</strong></p></td><td><p><strong>License Diff</strong></p></td></tr><tr><td><p>Physical cores mapped to VM</p></td><td><p>8 physical cores</p></td><td><p>8 physical cores (16 vCPU = 2 threads/core)</p></td><td><p>Same hardware</p></td></tr><tr><td><p>Oracle processor licenses needed</p></td><td><p>4 licenses (8 cores × 0.5)</p></td><td><p>4 licenses (8 cores × 0.5)</p></td><td><p>Same count</p></td></tr><tr><td><p>Compute performance delivered</p></td><td><p>16 vCPUs (2 threads/OCPU)</p></td><td><p>16 vCPUs</p></td><td><p>Same performance</p></td></tr><tr><td><p>AWS pricing for 16 vCPU/64GB</p></td><td><p>N/A</p></td><td><p>r6a.4xlarge: ~\(664/month</p></td><td><p>2x cost vs OCI</p></td></tr><tr><td><p><strong>OCI pricing for 8 OCPU/64GB</strong></p></td><td><p><strong>VM.Standard.E4.Flex: ~\)332/mo</strong></p></td><td><p><strong>N/A</strong></p></td><td><p><strong>Half the cost</strong></p></td></tr></tbody></table>

<p>The same 4 licenses run on AWS cost you double in compute charges because AWS sells by vCPU not OCPU. You pay for the hyperthreading overhead but Oracle doesn't count it as extra compute in their licensing — only OCI makes this efficiency transparent in the pricing.</p>
<blockquote>
<p><code># OCI: Check what OCPU count your DB instance is using</code></p>
<p><code>oci db system get \</code></p>
<p>  <code>--db-system-id $DB_SYSTEM_OCID \</code></p>
<p>  <code>--query 'data.{shape:shape,cpuCoreCount:"cpu-core-count",memory:"data-storage-size-in-gbs"}' \</code></p>
<p>  <code>--output table</code></p>
<p><code># Calculate your Oracle license requirement:</code></p>
<p><code># OCI formula: ceil(OCPU_count * 0.5) = processor licenses needed</code></p>
<p><code># 4 OCPU  → 2 licenses</code></p>
<p><code># 8 OCPU  → 4 licenses</code></p>
<p><code># 16 OCPU → 8 licenses</code></p>
<p><code># AWS formula (for standard EC2 with BYOL):</code></p>
<p><code># ceil(vCPU_count * 0.5) — same math BUT you pay for more vCPUs</code></p>
<p><code># to match OCI 8 OCPU performance you need 16 vCPU instance</code></p>
<p><code># 16 vCPU → 8 processor licenses → double the licensing cost</code></p>
</blockquote>
<blockquote>
<p><strong>💡  Oracle Support Rewards — Free Support for OCI Spend</strong></p>
<p>OCI customers earn \(0.25–\)0.33 in Oracle Support Rewards for every \(1 spent on OCI. These rewards directly offset your Oracle on-premises software support bill — potentially reducing it to zero. AWS customers receive no equivalent benefit. For a team spending \)10,000/month on OCI, that's up to $3,300/month off your Oracle support invoice.</p>
</blockquote>
<h2>Section 4: The Full TCO Calculator — Build Your Own</h2>
<p>Here's a reusable bash script that queries both OCI and does the equivalent AWS pricing calculation for your specific workload. Replace the variables at the top with your actual shapes and usage.</p>
<blockquote>
<p><code>#!/bin/bash</code></p>
<p><code># ── OCI vs AWS TCO Calculator ───────────────────────────────</code></p>
<p><code># Adjust these variables for your workload:</code></p>
<p><code>OCI_OCPUS=8</code></p>
<p><code>OCI_MEM_GB=64</code></p>
<p><code>BLOCK_STORAGE_TB=2</code></p>
<p><code>EGRESS_TB_MONTH=10</code></p>
<p><code>ORACLE_PROC_LICENSES=4    # OCI value; AWS would need 8 for same compute</code></p>
<p><code>ORACLE_EE_SUPPORT_ANNUAL=47500  # Per processor, standard list price</code></p>
<p><code># OCI pricing constants (US East, on-demand, Q1 2026)</code></p>
<p><code>OCI_OCPU_RATE=0.0300        # per OCPU-hour (E4 AMD Flex)</code></p>
<p><code>OCI_MEM_RATE=0.0015         # per GB-hour</code></p>
<p><code>OCI_BLOCK_RATE=0.0255       # per GB-month (Balanced)</code></p>
<p><code>OCI_EGRESS_FREE_TB=10</code></p>
<p><code>OCI_EGRESS_RATE=0.0085      # per GB above free tier</code></p>
<p><code>OCI_SUPPORT_RATE=0          # included</code></p>
<p><code># AWS pricing constants (us-east-1, on-demand, r6a family)</code></p>
<p><code>AWS_VCPU_RATE=0.0567        # r6a.4xlarge per hour (÷16 vCPU)</code></p>
<p><code>AWS_EBS_GP3_RATE=0.08       # per GB-month (gp3)</code></p>
<p><code>AWS_EGRESS_RATE=0.09        # per GB beyond 100GB</code></p>
<p><code>AWS_SUPPORT_PCT=0.03        # 3% of monthly bill (Business tier)</code></p>
<p><code>AWS_LICENSE_MULTIPLIER=2    # Need 2x licenses for equivalent compute</code></p>
<p><code># ── Calculate OCI Monthly Cost ───────────────────────────────</code></p>
<p><code>OCI_COMPUTE=\((echo "\)OCI_OCPUS \(OCI_OCPU_RATE 730 + \)OCI_MEM_GB $OCI_MEM_RATE 730" | bc)</code></p>
<p><code>OCI_BLOCK=\((echo "\)BLOCK_STORAGE_TB 1024 $OCI_BLOCK_RATE" | bc)</code></p>
<p><code>OCI_EGRESS=0  # within free tier</code></p>
<p><code>OCI_LICENSE_MO=\((echo "\)ORACLE_PROC_LICENSES * $ORACLE_EE_SUPPORT_ANNUAL / 12" | bc)</code></p>
<p><code>OCI_TOTAL=\((echo "\)OCI_COMPUTE + \(OCI_BLOCK + \)OCI_EGRESS + $OCI_LICENSE_MO" | bc)</code></p>
<p><code># ── Calculate AWS Monthly Cost ───────────────────────────────</code></p>
<p><code>AWS_VCPUS=$((OCI_OCPUS * 2))  # double vCPUs for same performance</code></p>
<p><code>AWS_COMPUTE=\((echo "\)AWS_VCPUS $AWS_VCPU_RATE 730" | bc)</code></p>
<p><code>AWS_BLOCK=\((echo "\)BLOCK_STORAGE_TB 1024 $AWS_EBS_GP3_RATE" | bc)</code></p>
<p><code>AWS_EGRESS_GB=\((echo "(\)EGRESS_TB_MONTH * 1024) - 100" | bc)</code></p>
<p><code>AWS_EGRESS=\((echo "\)AWS_EGRESS_GB * $AWS_EGRESS_RATE" | bc)</code></p>
<p><code>AWS_LICENSE_MO=\((echo "\)ORACLE_PROC_LICENSES \(AWS_LICENSE_MULTIPLIER \)ORACLE_EE_SUPPORT_ANNUAL / 12" | bc)</code></p>
<p><code>AWS_SUBTOTAL=\((echo "\)AWS_COMPUTE + \(AWS_BLOCK + \)AWS_EGRESS + $AWS_LICENSE_MO" | bc)</code></p>
<p><code>AWS_SUPPORT=\((echo "\)AWS_SUBTOTAL * $AWS_SUPPORT_PCT" | bc)</code></p>
<p><code>AWS_TOTAL=\((echo "\)AWS_SUBTOTAL + $AWS_SUPPORT" | bc)</code></p>
<p><code># ── Print Report ─────────────────────────────────────────────</code></p>
<p><code>echo '============================================'</code></p>
<p><code>echo '   OCI vs AWS TCO COMPARISON (Monthly)'</code></p>
<p><code>echo '============================================'</code></p>
<p><code>printf '%-30s %10s %10s\n' 'Component' 'OCI' 'AWS'</code></p>
<p><code>printf '%-30s %10s %10s\n' '---' '---' '---'</code></p>
<p><code>printf '%-30s %10s %10s\n' 'Compute' "$$OCI_COMPUTE" "$$AWS_COMPUTE"</code></p>
<p><code>printf '%-30s %10s %10s\n' 'Block Storage' "$$OCI_BLOCK" "$$AWS_BLOCK"</code></p>
<p><code>printf '%-30s %10s %10s\n' 'Data Egress' "$$OCI_EGRESS" "$$AWS_EGRESS"</code></p>
<p><code>printf '%-30s %10s %10s\n' 'Oracle Licensing' "$$OCI_LICENSE_MO" "$$AWS_LICENSE_MO"</code></p>
<p><code>printf '%-30s %10s %10s\n' 'Enterprise Support' 'INCL.' "$$AWS_SUPPORT"</code></p>
<p><code>echo '---'</code></p>
<p><code>printf '%-30s %10s %10s\n' 'TOTAL' "$$OCI_TOTAL" "$$AWS_TOTAL"</code></p>
</blockquote>
<img src="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/0f301e96-4bca-4aa7-a9d7-8e4ecf3ecae8.png" alt="" style="display:block;margin:0 auto" />

<p><em>Figure 3: Decision framework — when OCI wins vs when AWS is the right call for your specific workload</em></p>
<h2>Section 5: Where AWS Wins — The Honest Part</h2>
<p>This post would be dishonest if it didn't acknowledge the scenarios where AWS is genuinely the better choice. Here they are:</p>
<h3>GPU Workloads at Small Scale</h3>
<p>For A10-class GPU instances, AWS g5 instances are approximately 33% cheaper than equivalent OCI GPU shapes at small scale (1–2 GPUs). OCI wins significantly for A100 and H100 deployments at scale (4+ GPUs), but if you're running small ML inference, AWS has the edge here.</p>
<h3>Service Breadth and Ecosystem</h3>
<p>AWS has over 200 managed services vs OCI's approximately 80. If your architecture depends on AWS-native services — Kinesis, Step Functions, AWS Glue, EventBridge, SageMaker, or Bedrock — AWS is simply the more integrated choice. Replicating these on OCI requires more custom work.</p>
<h3>Spot Compute for Batch Workloads</h3>
<p>AWS Spot instances offer 70–90% discounts over on-demand pricing for fault-tolerant workloads, and the Spot market is far more mature and liquid than OCI's preemptible instances. If you're running large batch processing jobs that can tolerate interruption, AWS Spot pricing can undercut OCI significantly.</p>
<h3>Developer Tooling and Community Size</h3>
<p>AWS has a larger developer community, more third-party integrations, more StackOverflow answers, and more readily available talent. For new projects where you're not running Oracle workloads and where team expertise matters, AWS's ecosystem advantage is real.</p>
<blockquote>
<p><strong>⚠️  The Real Question to Ask</strong></p>
<p>The right question isn't 'which cloud is cheaper' globally — it's 'which cloud is cheaper for MY workload profile'. OCI wins decisively for Oracle database workloads, egress-heavy architectures, and compute at scale. AWS wins for non-Oracle ecosystems, small GPU inference, and teams deeply invested in AWS-native services. Most enterprise Oracle shops should be running OCI for their database tier and potentially keeping other services on AWS — that's what Oracle@AWS and the multicloud agreements are designed for.</p>
</blockquote>
<h2>Quick Reference: OCI vs AWS Pricing Cheat Sheet</h2>
<table style="min-width:100px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Service</strong></p></td><td><p><strong>OCI Price</strong></p></td><td><p><strong>AWS Price</strong></p></td><td><p><strong>Winner</strong></p></td></tr><tr><td><p>Compute (4 OCPU/8 vCPU, 16GB)</p></td><td><p>~\(122/month</p></td><td><p>~\)260/month (m6a.xlarge)</p></td><td><p>OCI (-53%)</p></td></tr><tr><td><p>Block Storage (1 TB, Balanced)</p></td><td><p>\(26/month</p></td><td><p>\)80/month (gp3)</p></td><td><p>OCI (-68%)</p></td></tr><tr><td><p>Block Storage (1 TB, High Perf)</p></td><td><p>\(38/month</p></td><td><p>\)200–\(400/month (io2)</p></td><td><p>OCI (-81%)</p></td></tr><tr><td><p>Object Storage (standard)</p></td><td><p>\)0.0255/GB-month</p></td><td><p>\(0.023/GB-month</p></td><td><p>AWS (-10%)</p></td></tr><tr><td><p>Data Egress (first 10 TB)</p></td><td><p>\)0 (free)</p></td><td><p>\(891/month</p></td><td><p>OCI (free)</p></td></tr><tr><td><p>Data Egress (10–50 TB)</p></td><td><p>\)0.0085/GB</p></td><td><p>\(0.09/GB</p></td><td><p>OCI (-91%)</p></td></tr><tr><td><p>Oracle DB Enterprise Edition</p></td><td><p>BYOL + licensing efficiency</p></td><td><p>BYOL + 2x licenses needed</p></td><td><p>OCI (-50% licensing)</p></td></tr><tr><td><p>Enterprise Support</p></td><td><p>Included in base</p></td><td><p>3–10% of monthly bill</p></td><td><p>OCI (included)</p></td></tr><tr><td><p>A10 GPU (small scale, 1 GPU)</p></td><td><p>Higher than AWS</p></td><td><p>g5 ~33% cheaper</p></td><td><p>AWS</p></td></tr><tr><td><p>A100 GPU (4+ GPUs)</p></td><td><p>20–58% cheaper</p></td><td><p>Higher total cost</p></td><td><p>OCI</p></td></tr><tr><td><p>Global pricing consistency</p></td><td><p>Same in all regions</p></td><td><p>Varies up to 4x by region</p></td><td><p>OCI</p></td></tr><tr><td><p><strong>Kubernetes (OKE vs EKS)</strong></p></td><td><p><strong>Enhanced: \)0.10/hr cluster</strong></p></td><td><p><strong>$0.10/hr cluster</strong></p></td><td><p><strong>Tie</strong></p></td></tr></tbody></table>

<h2>Conclusion: Run the Numbers for Your Workload</h2>
<p>The headline finding is clear: for Oracle database workloads, OCI delivers approximately 65% lower total cost of ownership than equivalent AWS deployments once you account for compute, storage, egress, licensing, and support costs together.</p>
<p>The key insight most teams miss is that cost comparisons that only look at compute rates are systematically misleading. Data egress costs alone can eclipse compute costs for analytics-heavy Oracle environments. Oracle licensing multipliers can double your licensing spend on AWS vs OCI for identical performance. Enterprise support that's free on OCI costs thousands per month on AWS.</p>
<p>Use the TCO script from Section 4 to run your own numbers. Plug in your actual OCPU counts, storage sizes, and egress volumes. The delta will almost certainly be larger than you expect.</p>
<p>The next post in this series will look at OCI Object Storage vs S3 vs Azure Blob in depth — including lifecycle policies, multipart upload performance benchmarks, and a real cost comparison for a data lake workload pushing 500TB/month.</p>
<hr />
<p><strong>Disclaimer &amp; Safe Harbour Statement</strong> </p>
<p><em>The pricing figures, cost estimates, and comparisons presented in this article are based on publicly available list prices from Oracle Cloud Infrastructure (OCI) and Amazon Web Services (AWS) pricing pages as of Q1 2026. Cloud pricing is subject to change without notice, and actual costs will vary based on your specific configuration, reserved pricing agreements, enterprise discount programmes, committed use contracts, region selection, and usage patterns.</em> <em><strong>This content is provided for informational and educational purposes only.</strong></em> <em>Nothing in this article constitutes financial, procurement, or architectural advice. Readers should conduct their own due diligence and consult directly with Oracle and AWS representatives to obtain pricing tailored to their workloads before making purchasing or migration decisions.</em> </p>
<p><strong>Safe Harbour — Forward-Looking Statements</strong></p>
<p><em>Certain statements in this article regarding future product availability, pricing structures, service levels, or vendor roadmaps may constitute forward-looking statements. These are based on current public information and reasonable assumptions. Actual outcomes may differ materially from any expectations expressed or implied here.</em> <a href="http://cloudexplorers.club"><em>cloudexplorers.club</em></a> <em>assumes no obligation to update such statements.</em> </p>
<p><em><em>No Affiliation</em>:</em>**</p>
<p> <a href="http://cloudexplorers.club"><em>cloudexplorers.club</em></a> <em>is an independent technical blog. The author is not employed by, sponsored by, or affiliated with Oracle, Amazon Web Services, or any other vendor mentioned. No compensation was received for the views expressed in this article. All product names, logos, and trademarks are the property of their respective owners.</em> <em><strong>Accuracy:</strong></em> <em>While every effort has been made to ensure the accuracy of technical information, the author makes no warranties, express or implied, about the completeness, accuracy, or fitness for a particular purpose of the content. Use of any information in this article is at your own risk.</em></p>
<p><em>© 2026</em> <a href="http://cloudexplorers.club"><em>cloudexplorers.club</em></a> <em>— Content published under Creative Commons Attribution 4.0 International (CC BY 4.0). You are free to share and adapt with attribution</em></p>
]]></content:encoded></item><item><title><![CDATA[Terraform on OCI]]></title><description><![CDATA[Introduction: Why Terraform on OCI?
If you've been clicking around the OCI Console to create VMs, networks, and databases — you're not alone. Most people start that way. But once you need to repeat th]]></description><link>https://cloudexplorers.club/terraform-on-oci</link><guid isPermaLink="true">https://cloudexplorers.club/terraform-on-oci</guid><category><![CDATA[Terraform]]></category><category><![CDATA[Oracle Cloud]]></category><category><![CDATA[OCI]]></category><category><![CDATA[Infrastructure as code]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Paresh Zawar]]></dc:creator><pubDate>Tue, 03 Mar 2026 15:57:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/66070b822018a4a9c83bbb3a/39e8400b-f8c6-4a99-b462-649cee6fddb3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Introduction: Why Terraform on OCI?</h2>
<p>If you've been clicking around the OCI Console to create VMs, networks, and databases — you're not alone. Most people start that way. But once you need to repeat that setup for a second environment, hand it off to a colleague, or recover from an accidental deletion, you quickly realize: clicking through a UI is not infrastructure management. It's infrastructure guessing.</p>
<p>That's where Terraform comes in. Terraform is an Infrastructure as Code (IaC) tool that lets you describe your cloud infrastructure in simple text files, then apply, change, or destroy it in a repeatable, auditable way. On Oracle Cloud Infrastructure, Terraform is a first-class citizen — Oracle maintains the official OCI provider, and the latest version (6.x) supports virtually every OCI service.</p>
<p>This guide is for complete beginners. We'll start from zero — what Terraform is, how it thinks, how to connect it to OCI — and build up to a real working example: a fully functional VCN with subnets, an Internet Gateway, and a Compute instance you can SSH into. Every line of code is explained.</p>
<blockquote>
<p><strong>🎯  What You'll Build By the End</strong></p>
<p>A working OCI environment built entirely with Terraform: VCN + Public subnet + Internet Gateway + Route Table + Security list + Ubuntu compute instance with SSH access. Everything destroyed with one command when you're done.</p>
</blockquote>
<h2>Section 1: What Is Terraform and How Does It Work?</h2>
<p>Terraform, built by HashiCorp, is an open-source IaC tool that uses a declarative approach to infrastructure management. That means you tell Terraform what you want — not how to build it. You write configuration files in HashiCorp Configuration Language (HCL), and Terraform figures out the sequence of API calls needed to make reality match your description.</p>
<h3>The Terraform Workflow: Plan, Apply, Destroy</h3>
<p>Terraform operates in a simple three-command loop that you'll use constantly:</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Command</strong></p></td><td><p><strong>What It Does</strong></p></td><td><p><strong>When to Use</strong></p></td></tr><tr><td><p>terraform init</p></td><td><p>Downloads the OCI provider plugin, sets up the working directory</p></td><td><p>First time, or after changing providers</p></td></tr><tr><td><p>terraform plan</p></td><td><p>Shows exactly what will be created, changed, or deleted — no real changes made</p></td><td><p>Before every apply, to review the diff</p></td></tr><tr><td><p>terraform apply</p></td><td><p>Executes the plan and creates/modifies/destroys real OCI resources</p></td><td><p>After reviewing the plan</p></td></tr><tr><td><p>terraform destroy</p></td><td><p>Tears down all resources described in your configuration</p></td><td><p>Cleanup / decommission</p></td></tr><tr><td><p>terraform fmt</p></td><td><p>Auto-formats your .tf files to standard style</p></td><td><p>Before committing code</p></td></tr><tr><td><p>terraform validate</p></td><td><p>Checks configuration syntax without connecting to OCI</p></td><td><p>After writing new config</p></td></tr></tbody></table>

<h3>Terraform State: The Source of Truth</h3>
<p>Terraform maintains a state file (terraform.tfstate) that maps your configuration to real OCI resources. This is how Terraform knows what already exists and what needs to change. By default it's a local file, but for team environments you should store it remotely — OCI Object Storage works perfectly for this.</p>
<blockquote>
<p><strong>⚠️  Never Manually Edit the State File</strong></p>
<p>The terraform.tfstate file is Terraform's internal database. Editing it manually corrupts it. If you need to modify state, use 'terraform state' subcommands. Also — add terraform.tfstate to your .gitignore, as it can contain sensitive values.</p>
</blockquote>
<h3>Key Terraform Concepts at a Glance</h3>
<p>•      <strong>Provider</strong> — A plugin that enables Terraform to talk to a specific platform (in our case, oracle/oci)</p>
<p>•      <strong>Resource</strong> — A cloud object to create (e.g. oci_core_vcn, oci_core_instance)</p>
<p>•      <strong>Data Source</strong> — Read-only query for existing OCI data (e.g. get all availability domains)</p>
<p>•      <strong>Variable</strong> — Parameterize your config so it's reusable across environments</p>
<p>•      <strong>Output</strong> — Print useful values after apply (e.g. the new instance's public IP)</p>
<p>•      <strong>Module</strong> — A reusable group of resources, like a blueprint for a network pattern</p>
<h2>Section 2: Installing Terraform and Connecting to OCI</h2>
<h3>Step 1: Install Terraform</h3>
<p>Terraform is a single binary — no dependencies. Install the latest version for your OS:</p>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>OS</strong></p></td><td><p><strong>Install Method</strong></p></td><td><p><strong>Command / Link</strong></p></td></tr><tr><td><p>macOS</p></td><td><p>Homebrew</p></td><td><p>brew tap hashicorp/tap &amp;&amp; brew install hashicorp/tap/terraform</p></td></tr><tr><td><p>Ubuntu/Debian</p></td><td><p>APT</p></td><td><p>sudo apt-get install terraform (after adding HashiCorp repo)</p></td></tr><tr><td><p>Windows</p></td><td><p>Chocolatey</p></td><td><p>choco install terraform</p></td></tr><tr><td><p>Any</p></td><td><p>Direct download</p></td><td><p>developer.hashicorp.com/terraform/downloads</p></td></tr></tbody></table>

<p>Verify the installation:</p>
<p><code>terraform -version # Expected output: Terraform v1.9.x (or higher)</code></p>
<h3>Step 2: Set Up OCI API Key Authentication</h3>
<p>Terraform authenticates to OCI using an API key pair. You'll create an RSA key, upload the public key to OCI, and configure a local credentials file. This is a one-time setup.</p>
<p>1.     Log into the OCI Console</p>
<p>2.     Click your profile icon (top-right) → My Profile</p>
<p>3.     Scroll to API Keys → Add API Key → Generate API Key Pair</p>
<p>4.     Download the Private Key (.pem file) → click Add</p>
<p>5.     Copy the configuration snippet shown — you'll need these values</p>
<p>Create the OCI credentials file:</p>
<p><code>mkdir -p ~/.oci</code></p>
<p><code># Move your downloaded private key:</code></p>
<p><code>mv ~/Downloads/your-key.pem ~/.oci/oci_api_key.pem</code></p>
<p><code>chmod 400 ~/.oci/oci_api_key.pem</code></p>
<p><code># Create the config file:</code></p>
<p><code>vi ~/.oci/config</code></p>
<p>Paste the following into ~/.oci/config (use the values from the OCI console snippet):</p>
<p>[DEFAULT]</p>
<p><code>user=ocid1.user.oc1..aaaaaaaaxxx          # Your User OCID</code></p>
<p><code>tenancy=ocid1.tenancy.oc1..aaaaaaaaxxx    # Your Tenancy OCID</code></p>
<p><code>region=ap-mumbai-1                         # Your home region</code></p>
<p><code>fingerprint=aa:bb:cc:dd:...               # Key fingerprint from OCI console</code></p>
<p><code>key_file=~/.oci/oci_api_key.pem          # Path to your private key</code></p>
<blockquote>
<p><strong>💡  Finding Your OCIDs</strong></p>
<p>Tenancy OCID: OCI Console → top-right profile → Tenancy. User OCID: Profile → My Profile. Compartment OCID: Identity &amp; Security → Compartments → click your compartment. OCIDs start with 'ocid1.' and are long strings — copy them carefully.</p>
</blockquote>
<h3>Step 3: Verify the OCI CLI Connection</h3>
<p>Before writing any Terraform, confirm your credentials work:</p>
<p><code># Install OCI CLI if not already installed:</code></p>
<p><code>pip install oci-cli --break-system-packages</code></p>
<p><code># Test authentication:</code></p>
<p><code>oci iam region list --output table</code></p>
<p><code># Should list all OCI regions — if it does, credentials are working</code></p>
<h2>Section 3: Your First Terraform Project — File Structure</h2>
<p>Good Terraform projects split configuration across multiple files by concern. Here's the recommended structure for a beginner OCI project:</p>
<blockquote>
<p>oci-terraform-demo/</p>
<p>├── <a href="http://provider.tf">provider.tf</a>       # OCI provider configuration and authentication</p>
<p>├── <a href="http://variables.tf">variables.tf</a>      # Input variable declarations</p>
<p>├── terraform.tfvars  # Variable values (DO NOT commit to Git)</p>
<p>├── <a href="http://main.tf">main.tf</a>           # Core resources: VCN, subnets, gateways</p>
<p>├── <a href="http://compute.tf">compute.tf</a>        # Compute instance resources</p>
<p>└── <a href="http://outputs.tf">outputs.tf</a>       # Output values to display after apply</p>
</blockquote>
<p>Create the project directory and open it:</p>
<table style="min-width:25px"><colgroup><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><code>mkdir oci-terraform-demo &amp;&amp; cd oci-terraform-demo</code></p></td></tr></tbody></table>

<p><a href="http://provider.tf"><strong>provider.tf</strong></a> <strong>— Connecting Terraform to OCI</strong></p>
<p>This file tells Terraform which provider to use and how to authenticate. Create <a href="http://provider.tf">provider.tf</a> with the following content:</p>
<blockquote>
<p><code>terraform {</code></p>
<p>  <code>required_providers {</code></p>
<p>    <code>oci = {</code></p>
<p>      <code>source  = "oracle/oci"</code></p>
<p>      <code>version = "&gt;= 6.0.0"    # Always pin a minimum version</code></p>
<p>    <code>}</code></p>
<p>  <code>}</code></p>
<p>  <code>required_version = "&gt;= 1.9.0"</code></p>
<p><code>}</code></p>
<p><code>provider "oci" {</code></p>
<p>  <code>tenancy_ocid     = var.tenancy_ocid</code></p>
<p>  <code>user_ocid        = var.user_ocid</code></p>
<p>  <code>fingerprint      = var.fingerprint</code></p>
<p>  <code>private_key_path = var.private_key_path</code></p>
<p>  <code>region           = var.region</code></p>
<p><code>}</code></p>
</blockquote>
<blockquote>
<p><strong>🔒  Never Hardcode Credentials</strong></p>
<p>Notice we use variables (var.tenancy_ocid) instead of pasting OCIDs directly. The actual values go in terraform.tfvars which you add to .gitignore. This prevents accidental credential exposure when pushing to GitHub.</p>
</blockquote>
<h3><a href="http://variables.tf">variables.tf</a> — Declaring Input Variables</h3>
<p>Declare all variables your configuration needs. This file is safe to commit — it contains no values, just declarations:</p>
<blockquote>
<p><code># Authentication variables</code></p>
<p><code>variable "tenancy_ocid" {</code></p>
<p>  <code>description = "OCID of your OCI tenancy"</code></p>
<p>  <code>type        = string</code></p>
<p><code>}</code></p>
<p><code>variable "user_ocid" {</code></p>
<p>  <code>description = "OCID of the OCI user for API authentication"</code></p>
<p>  <code>type        = string</code></p>
<p><code>}</code></p>
<p><code>variable "fingerprint" {</code></p>
<p>  <code>description = "Fingerprint of the API key"</code></p>
<p>  <code>type        = string</code></p>
<p><code>}</code></p>
<p><code>variable "private_key_path" {</code></p>
<p>  <code>description = "Local path to the OCI API private key (.pem)"</code></p>
<p>  <code>type        = string</code></p>
<p>  <code>default     = "~/.oci/oci_api_key.pem"</code></p>
<p><code>}</code></p>
<p><code>variable "region" {</code></p>
<p>  <code>description = "OCI region identifier"</code></p>
<p>  <code>type        = string</code></p>
<p>  <code>default     = "ap-mumbai-1"</code></p>
<p><code>}</code></p>
<p><code># Infrastructure variables</code></p>
<p><code>variable "compartment_ocid" {</code></p>
<p>  <code>description = "OCID of the compartment to create resources in"</code></p>
<p>  <code>type        = string</code></p>
<p><code>}</code></p>
<p> <code>variable "ssh_public_key" {</code></p>
<p>  <code>description = "SSH public key to inject into the compute instance"</code></p>
<p>  <code>type        = string</code></p>
<p><code>}</code></p>
</blockquote>
<h3>terraform.tfvars — Your Actual Values (Keep Private)</h3>
<p>This file holds the real values for your variables. <strong>Add it to .gitignore immediately:</strong></p>
<blockquote>
<p><code># terraform.tfvars — DO NOT COMMIT TO GIT</code></p>
<p><code>tenancy_ocid      = "ocid1.tenancy.oc1..aaaaaaaaxxxxxxxxxxx"</code></p>
<p><code>user_ocid         = "ocid1.user.oc1..aaaaaaaaxxxxxxxxxxx"</code></p>
<p><code>fingerprint       = "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99"</code></p>
<p><code>private_key_path  = "/home/yourname/.oci/oci_api_key.pem"</code></p>
<p><code>region            = "ap-mumbai-1"</code></p>
<p><code>compartment_ocid  = "ocid1.compartment.oc1..aaaaaaaaxxxxxxxxxxx"</code></p>
<p><code>ssh_public_key   = "ssh-rsa AAAAB3NzaC1yc2E... your-public-key"</code></p>
</blockquote>
<h3>Create your .gitignore immediately:</h3>
<blockquote>
<p><code># .gitignore</code></p>
<p><code>terraform.tfvars</code></p>
<p><code>*.tfvars</code></p>
<p><code>.terraform/</code></p>
<p><code>terraform.tfstate</code></p>
<p><code>terraform.tfstate.backup</code></p>
<p><code>*.pem</code></p>
</blockquote>
<h2>Section 4: Real Example — Build a Full OCI Network with Terraform</h2>
<p>Now the exciting part. We'll create a <a href="http://main.tf">main.tf</a> that provisions a complete, functional OCI network: a Virtual Cloud Network (VCN), a public subnet, an Internet Gateway, and the route table needed to make it all work.</p>
<h3>Understanding What We're Building</h3>
<p>In OCI, before you can launch a compute instance, you need this networking chain in place:</p>
<p>•      <strong>VCN</strong> → The top-level private network, like an AWS VPC</p>
<p>•      <strong>Subnet</strong> → A subdivision of the VCN where resources live</p>
<p>•      <strong>Internet Gateway</strong> → Allows traffic between the subnet and the public internet</p>
<p>•      <strong>Route Table</strong> → Rules that direct traffic; the subnet must have a route pointing to the IGW</p>
<p>•      <strong>Security List</strong> → Stateful firewall rules (like AWS Security Groups) at the subnet level</p>
<h3><a href="http://main.tf">main.tf</a> — VCN, Subnet, Internet Gateway, and Security</h3>
<blockquote>
<p><code># ── DATA SOURCE: Get Availability Domains ──────────────────────────</code></p>
<p><code># This queries OCI to find the names of availability domains in your region.</code></p>
<p><code># We use it to deploy the subnet into a specific AD.</code></p>
<p><code>data "oci_identity_availability_domains" "ads" {</code></p>
<p>  <code>compartment_id = var.tenancy_ocid</code></p>
<p><code>}</code></p>
<p><code># ── VIRTUAL CLOUD NETWORK (VCN) ─────────────────────────────────────</code></p>
<p><code>resource "oci_core_vcn" "main_vcn" {</code></p>
<p>  <code>compartment_id = var.compartment_ocid</code></p>
<p>  <code>cidr_block     = "10.0.0.0/16"</code></p>
<p>  <code>display_name   = "terraform-demo-vcn"</code></p>
<p>  <code>dns_label      = "tfdemov cn"   # Must be alphanumeric, max 15 chars</code></p>
<p>  <code>freeform_tags = {</code></p>
<p>    <code>"Project"     = "terraform-demo"</code></p>
<p>    <code>"ManagedBy"   = "terraform"</code></p>
<p>    <code>"Environment" = "learning"</code></p>
<p>  <code>}</code></p>
<p><code>}</code></p>
<p><code># ── INTERNET GATEWAY ─────────────────────────────────────────────────</code></p>
<p><code># Required for instances in the public subnet to reach the internet.</code></p>
<p><code>resource "oci_core_internet_gateway" "igw" {</code></p>
<p>  <code>compartment_id = var.compartment_ocid</code></p>
<p>  <code>vcn_id         = oci_core_vcn.main_vcn.id   # Reference the VCN we just defined</code></p>
<p>  <code>display_name   = "terraform-demo-igw"</code></p>
<p>  <code>enabled        = true</code></p>
<p><code>}</code></p>
<p><code># ── ROUTE TABLE ──────────────────────────────────────────────────────</code></p>
<p><code># Directs all outbound internet traffic (0.0.0.0/0) through the IGW.</code></p>
<p><code>resource "oci_core_route_table" "public_rt" {</code></p>
<p>  <code>compartment_id = var.compartment_ocid</code></p>
<p>  <code>vcn_id         = oci_core_vcn.main_vcn.id</code></p>
<p>  <code>display_name   = "public-route-table"</code></p>
<p>  <code>route_rules {</code></p>
<p>    <code>destination       = "0.0.0.0/0"           # All internet traffic</code></p>
<p>    <code>network_entity_id = oci_core_internet_gateway.igw.id</code></p>
<p>  <code>}</code></p>
<p><code>}</code></p>
<p><code># ── SECURITY LIST ─────────────────────────────────────────────────────</code></p>
<p><code># Defines firewall rules: allow SSH in, allow all traffic out.</code></p>
<p><code>resource "oci_core_security_list" "public_sl" {</code></p>
<p>  <code>compartment_id = var.compartment_ocid</code></p>
<p>  <code>vcn_id         = oci_core_vcn.main_vcn.id</code></p>
<p>  <code>display_name   = "public-security-list"</code></p>
<p>  <code># Inbound: Allow SSH from anywhere</code></p>
<p>  <code>ingress_security_rules {</code></p>
<p>    <code>protocol  = "6"         # 6 = TCP</code></p>
<p>    <code>source    = "0.0.0.0/0"</code></p>
<p>    <code>stateless = false</code></p>
<p>    <code>tcp_options {</code></p>
<p>      <code>min = 22</code></p>
<p>      <code>max = 22</code></p>
<p>    <code>}</code></p>
<p>    <code>description = "Allow SSH access"</code></p>
<p>  <code>}</code></p>
<p>  <code># Inbound: Allow ICMP (ping)</code></p>
<p>  <code>ingress_security_rules {</code></p>
<p>    <code>protocol  = "1"         # 1 = ICMP</code></p>
<p>    <code>source    = "0.0.0.0/0"</code></p>
<p>    <code>stateless = false</code></p>
<p>  <code>}</code></p>
<p>  <code># Outbound: Allow all traffic out</code></p>
<p>  <code>egress_security_rules {</code></p>
<p>    <code>protocol    = "all"</code></p>
<p>    <code>destination = "0.0.0.0/0"</code></p>
<p>    <code>stateless   = false</code></p>
<p>  <code>}</code></p>
<p><code>}</code></p>
<p><code># ── PUBLIC SUBNET ─────────────────────────────────────────────────────</code></p>
<p><code>resource "oci_core_subnet" "public_subnet" {</code></p>
<p>  <code>compartment_id    = var.compartment_ocid</code></p>
<p>  <code>vcn_id            = oci_core_vcn.main_vcn.id</code></p>
<p>  <code>cidr_block        = "10.0.1.0/24"</code></p>
<p>  <code>display_name      = "public-subnet"</code></p>
<p>  <code>dns_label         = "public"</code></p>
<p>  <code># Attach the route table and security list we created above</code></p>
<p>  <code>route_table_id    = oci_core_route_table.public_rt.id</code></p>
<p>  <code>security_list_ids = [oci_core_security_list.public_sl.id]</code></p>
<p>  <code># false = allow public IPs on instances in this subnet</code></p>
<p>  <code>prohibit_public_ip_on_vnic = false</code></p>
<p><code>}</code></p>
</blockquote>
<h2>Section 5: Adding a Compute Instance (<a href="http://compute.tf">compute.tf</a>)</h2>
<p>Now let's add a compute instance to the public subnet. Create <a href="http://compute.tf">compute.tf</a>:</p>
<blockquote>
<p><code># ── LOOKUP: Find the Ubuntu 22.04 Image OCID ─────────────────────────</code></p>
<p><code># OCI image OCIDs are region-specific. This data source finds the latest</code></p>
<p><code># Ubuntu 22.04 image automatically — no hardcoding needed.</code></p>
<p><code>data "oci_core_images" "ubuntu_22" {</code></p>
<p>  <code>compartment_id           = var.compartment_ocid</code></p>
<p>  <code>operating_system         = "Canonical Ubuntu"</code></p>
<p>  <code>operating_system_version = "22.04"</code></p>
<p>  <code>shape                    = "VM.Standard.A1.Flex"   # ARM shape</code></p>
<p>  <code>sort_by                  = "TIMECREATED"</code></p>
<p>  <code>sort_order               = "DESC"</code></p>
<p><code>}</code></p>
<p><code># ── COMPUTE INSTANCE ─────────────────────────────────────────────────</code></p>
<p><code>resource "oci_core_instance" "web_server" {</code></p>
<p>  <code>availability_domain = data.oci_identity_availability_domains.ads.availability_domains[0].name</code></p>
<p>  <code>compartment_id      = var.compartment_ocid</code></p>
<p>  <code>display_name        = "terraform-demo-server"</code></p>
<p>  <code># Shape: ARM Always Free tier — 1 OCPU, 6GB RAM</code></p>
<p>  <code>shape = "VM.Standard.A1.Flex"</code></p>
<p>  <code>shape_config {</code></p>
<p>    <code>ocpus         = 1</code></p>
<p>    <code>memory_in_gbs = 6</code></p>
<p>  <code>}</code></p>
<p>  <code># OS Image: Use the latest Ubuntu 22.04 found above</code></p>
<p>  <code>source_details {</code></p>
<p>    <code>source_type             = "image"</code></p>
<p>    <code>source_id               = data.oci_core_images.ubuntu_22.images[0].id</code></p>
<p>    <code>boot_volume_size_in_gbs = 50</code></p>
<p>  <code>}</code></p>
<p>  <code># Network: Place in the public subnet we created</code></p>
<p>  <code>create_vnic_details {</code></p>
<p>    <code>subnet_id        = oci_core_subnet.public_subnet.id</code></p>
<p>    <code>assign_public_ip = true    # Give this instance a public IP</code></p>
<p>    <code>display_name     = "primary-vnic"</code></p>
<p>  <code>}</code></p>
<p>  <code># SSH: Inject your public key so you can log in</code></p>
<p>  <code>metadata = {</code></p>
<p>    <code>ssh_authorized_keys = var.ssh_public_key</code></p>
<p>  <code>}</code></p>
<p>  <code>freeform_tags = {</code></p>
<p>    <code>"ManagedBy"   = "terraform"</code></p>
<p>    <code>"Environment" = "learning"</code></p>
<p>  <code>}</code></p>
<p><code>}</code></p>
</blockquote>
<h3><a href="http://outputs.tf">outputs.tf</a> — See Your Results</h3>
<p>Create <a href="http://outputs.tf">outputs.tf</a> to display useful information after applying:</p>
<blockquote>
<p><code>output "vcn_id" {</code></p>
<p>  <code>description = "OCID of the created VCN"</code></p>
<p>  <code>value       = oci_core_vcn.main_vcn.id</code></p>
<p><code>}</code></p>
<p><code>output "subnet_id" {</code></p>
<p>  <code>description = "OCID of the public subnet"</code></p>
<p>  <code>value       = oci_core_subnet.public_subnet.id</code></p>
<p><code>}</code></p>
<p><code>output "instance_public_ip" {</code></p>
<p>  <code>description = "Public IP address of the compute instance"</code></p>
<p>  <code>value       = oci_core_instance.web_server.public_ip</code></p>
<p><code>}</code></p>
<p><code>output "ssh_command" {</code></p>
<p>  <code>description = "Ready-to-run SSH command to connect to your instance"</code></p>
<p>  <code>value       = "ssh -i ~/.ssh/id_rsa ubuntu@${oci_core_instance.web_server.public_ip}"</code></p>
<p><code>}</code></p>
</blockquote>
<h2>Section 6: Running Terraform — Init, Plan, Apply</h2>
<h3>terraform init</h3>
<p>Initialize the project. This downloads the OCI provider plugin (~200MB) and sets up the working directory:</p>
<blockquote>
<p><code>terraform init</code></p>
<p><code># Expected output:</code></p>
<p><code># Initializing the backend...</code></p>
<p><code># Initializing provider plugins...</code></p>
<p><code># - Finding oracle/oci versions matching "&gt;= 6.0.0"...</code></p>
<p><code># - Installing oracle/oci v6.x.x...</code></p>
<p><code># Terraform has been successfully initialized!</code></p>
</blockquote>
<h3>terraform plan</h3>
<p>Preview exactly what Terraform will create — nothing is changed in OCI yet:</p>
<blockquote>
<p><code>terraform plan</code></p>
<p><code># You'll see output like:</code></p>
<p><code># Terraform will perform the following actions:</code></p>
<p><code>#</code></p>
<p><code>#   + resource "oci_core_vcn" "main_vcn" will be created</code></p>
<p><code>#   + resource "oci_core_internet_gateway" "igw" will be created</code></p>
<p><code>#   + resource "oci_core_route_table" "public_rt" will be created</code></p>
<p><code>#   + resource "oci_core_security_list" "public_sl" will be created</code></p>
<p><code>#   + resource "oci_core_subnet" "public_subnet" will be created</code></p>
<p><code>#   + resource "oci_core_instance" "web_server" will be created</code></p>
<p><code>#</code></p>
<p><code># Plan: 6 to add, 0 to change, 0 to destroy.</code></p>
</blockquote>
<blockquote>
<p><strong>💡  Always Review the Plan</strong></p>
<p>The plan output is your change log before deployment. Read it carefully — especially lines starting with '-' (destroy) or '~' (modify in place). A '+' means create. Getting comfortable reading plans is the single most important Terraform habit.</p>
</blockquote>
<h3>terraform apply</h3>
<p>Apply the plan to create your real OCI resources. Terraform will pause and ask for confirmation:</p>
<blockquote>
<p><code>terraform apply</code></p>
<p><code># Terraform will show the plan again, then prompt:</code></p>
<p><code># Do you want to perform these actions?</code></p>
<p><code>#   Terraform will perform the actions described above.</code></p>
<p><code>#   Only 'yes' will be accepted to approve.</code></p>
<p><code>#</code></p>
<p><code># Enter a value: yes</code></p>
<p><code># ... Terraform creates resources, then shows outputs:</code></p>
<p><code># Outputs:</code></p>
<p><code># instance_public_ip = "130.61.xxx.xxx"</code></p>
<p><code># ssh_command = "ssh -i ~/.ssh/id_rsa ubuntu@130.61.xxx.xxx"</code></p>
<p><code># subnet_id = "ocid1.subnet.oc1..."</code></p>
<p><code># vcn_id = "ocid1.vcn.oc1..."</code></p>
</blockquote>
<p>Copy the ssh_command output and connect to your new instance:</p>
<blockquote>
<p><code>ssh -i ~/.ssh/id_rsa ubuntu@130.61.xxx.xxx</code></p>
<p><code># You should be logged in to your brand new OCI VM!</code></p>
<p><code># ubuntu@terraform-demo-server:~$</code></p>
</blockquote>
<h2>Section 7: Terraform Lifecycle — Modify and Destroy</h2>
<h3>Making Changes</h3>
<p>Terraform's real power is in how it handles changes. Edit your configuration — for example, add port 80 to the security list — then re-run terraform plan. Terraform shows exactly what will change, and terraform apply makes it so. <strong>No manual clicking, no forgetting a step.</strong></p>
<blockquote>
<p><code># Add this inside the security list resource in main.tf:</code></p>
<p>  <code>ingress_security_rules {</code></p>
<p>    <code>protocol  = "6"</code></p>
<p>    <code>source    = "0.0.0.0/0"</code></p>
<p>    <code>stateless = false</code></p>
<p>    <code>tcp_options { min = 80; max = 80 }</code></p>
<p>    <code>description = "Allow HTTP access"</code></p>
<p>  <code>}</code></p>
</blockquote>
<blockquote>
<p><code># Then:</code></p>
<p><code>terraform plan    # Shows: 1 to change</code></p>
</blockquote>
<blockquote>
<p><code>terraform apply  # Updates the security list in place</code></p>
</blockquote>
<h3>Destroying Everything</h3>
<p>When you're done experimenting, destroy all resources with a single command. This is one of Terraform's most powerful features — clean teardown with no orphaned resources:</p>
<blockquote>
<p><code>terraform destroy</code></p>
<p><code># Terraform shows everything it will delete, then prompts:</code></p>
<p><code># Enter a value: yes</code></p>
<p><code># All 6 resources are deleted cleanly.</code></p>
<p><code># Destroy complete! Resources: 6 destroyed.</code></p>
</blockquote>
<blockquote>
<p><strong>⚠️  Destroy is Irreversible</strong></p>
<p>terraform destroy permanently deletes real OCI resources including any data on them. Always review the destroy plan carefully. For production environments, consider using Terraform's prevent_destroy lifecycle argument on critical resources to add a safety net.</p>
</blockquote>
<h2>Section 8: Best Practices for Terraform on OCI</h2>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>Practice</strong></p></td><td><p><strong>Why It Matters</strong></p></td><td><p><strong>How to Implement</strong></p></td></tr><tr><td><p>Use remote state</p></td><td><p>Local state breaks in teams; gets lost if disk fails</p></td><td><p>OCI Object Storage backend or Terraform Cloud</p></td></tr><tr><td><p>Always run plan first</p></td><td><p>Prevents surprises; builds discipline</p></td><td><p>terraform plan -out=plan.out &amp;&amp; terraform apply plan.out</p></td></tr><tr><td><p>Use consistent tagging</p></td><td><p>Cost tracking, ownership, automation targeting</p></td><td><p>Add freeform_tags to every resource</p></td></tr><tr><td><p>Pin provider versions</p></td><td><p>Prevents unexpected breaking changes on upgrade</p></td><td><p>version = "&gt;= 6.0.0, &lt; 7.0.0"</p></td></tr><tr><td><p>Use modules for patterns</p></td><td><p>Avoid copy-pasting the same network config everywhere</p></td><td><p>Create ./modules/vcn/ and call it from <a target="_self" rel="noopener noreferrer nofollow" class="text-primary underline underline-offset-2 hover:text-primary/80 cursor-pointer" href="http://main.tf" style="pointer-events:none">main.tf</a></p></td></tr><tr><td><p>Store secrets in OCI Vault</p></td><td><p>Passwords in tfvars files are risky</p></td><td><p>Reference OCI Vault secrets using data sources</p></td></tr><tr><td><p>Use workspaces for environments</p></td><td><p>Reuse same code for dev/staging/prod</p></td><td><p>terraform workspace new staging</p></td></tr><tr><td><p>Format and validate always</p></td><td><p>Catches syntax errors before they reach plan</p></td><td><p>terraform fmt &amp;&amp; terraform validate</p></td></tr></tbody></table>

<h2>Bonus: Storing Terraform State in OCI Object Storage</h2>
<p>For any serious usage — especially if you're working with a team or in a CI/CD pipeline — move your state file to OCI Object Storage. This prevents state file conflicts and ensures everyone works from the same source of truth.</p>
<blockquote>
<p># First, create an OCI bucket manually (or via Terraform in a separate root module)</p>
<p># Then update <a href="http://provider.tf">provider.tf</a> to add a backend block:</p>
</blockquote>
<blockquote>
<p><code>terraform {</code></p>
<p>  <code>required_providers {</code></p>
<p>    <code>oci = { source = "oracle/oci", version = "&gt;= 6.0.0" }</code></p>
<p>  <code>}</code></p>
<p>  <code>backend "http" {</code></p>
<p>    <code># OCI Object Storage pre-authenticated request URL for state</code></p>
<p>    <code>address        = "https://objectstorage.ap-mumbai-1.oraclecloud.com/..."</code></p>
<p>    <code>update_method  = "PUT"</code></p>
<p>  <code>}</code></p>
<p><code>}</code></p>
</blockquote>
<blockquote>
<p><code># After updating the backend, re-initialize to migrate local state:</code></p>
<p><code>terraform init -migrate-state</code></p>
</blockquote>
<h2>Quick Reference: Common OCI Terraform Resources</h2>
<table style="min-width:75px"><colgroup><col style="min-width:25px"></col><col style="min-width:25px"></col><col style="min-width:25px"></col></colgroup><tbody><tr><td><p><strong>OCI Resource</strong></p></td><td><p><strong>Terraform Resource Type</strong></p></td><td><p><strong>What It Creates</strong></p></td></tr><tr><td><p>Virtual Cloud Network</p></td><td><p>oci_core_vcn</p></td><td><p>Private network for your resources</p></td></tr><tr><td><p>Subnet</p></td><td><p>oci_core_subnet</p></td><td><p>Sub-division of VCN for resource placement</p></td></tr><tr><td><p>Internet Gateway</p></td><td><p>oci_core_internet_gateway</p></td><td><p>Public internet access for a VCN</p></td></tr><tr><td><p>NAT Gateway</p></td><td><p>oci_core_nat_gateway</p></td><td><p>Outbound-only internet for private subnets</p></td></tr><tr><td><p>Route Table</p></td><td><p>oci_core_route_table</p></td><td><p>Traffic routing rules</p></td></tr><tr><td><p>Security List</p></td><td><p>oci_core_security_list</p></td><td><p>Subnet-level firewall rules</p></td></tr><tr><td><p>Network Security Group</p></td><td><p>oci_core_network_security_group</p></td><td><p>Instance-level firewall rules</p></td></tr><tr><td><p>Compute Instance</p></td><td><p>oci_core_instance</p></td><td><p>Virtual machine</p></td></tr><tr><td><p>Block Volume</p></td><td><p>oci_core_volume</p></td><td><p>Persistent block storage disk</p></td></tr><tr><td><p>Object Storage Bucket</p></td><td><p>oci_objectstorage_bucket</p></td><td><p>S3-compatible object storage</p></td></tr><tr><td><p>Autonomous Database</p></td><td><p>oci_database_autonomous_database</p></td><td><p>Managed Oracle DB</p></td></tr><tr><td><p>OKE Cluster</p></td><td><p>oci_containerengine_cluster</p></td><td><p>Managed Kubernetes cluster</p></td></tr><tr><td><p>Load Balancer</p></td><td><p>oci_load_balancer_load_balancer</p></td><td><p>HTTP/TCP load balancer</p></td></tr><tr><td><p>IAM Compartment</p></td><td><p>oci_identity_compartment</p></td><td><p>Resource organization unit</p></td></tr></tbody></table>

<hr />
<p><em><strong>Safe Harbour:</strong></em> <em>This site may contain forward-looking statements regarding cloud architectures, infrastructure strategies, product roadmaps, performance benchmarks, or emerging technologies that are subject to change without notice. Actual results may vary due to technical, operational, or market factors. All content is provided for informational and educational purposes only and does not constitute professional, legal, financial, or investment advice. We undertake no obligation to update such statements.</em></p>
]]></content:encoded></item></channel></rss>