Deploy Oracle
DB System 21c on Oracle Cloud Infrastructure using Terraform
This article describes how to deploy a Database System
on Oracle Cloud Infrastructure (OCI), including a Virtual Cloud Network
including Network sub components. To achieve this lab, you must have an Oracle
Cloud account.
Acknowledgements:
-
Author:
Donatien Mbadi Oum, Oracle Database Cloud Architect, Senior Database
Administrator
-
Last
update: September 2023
1. What is Terraform?
Terraform is an infrastructure as code tool that lets
you define both cloud and on-premise resources in readable files that you can version,
reuse and share. You can use Terraform to provision and manage all or part of
your infrastructure throughout its lifecycle.
Terraform creates and manages resources on cloud
platforms like Oracle Cloud Infrastructure through their Application
Programming Interfaces (APIs)
The core Terraform workflow consists of three stages:
-
Write:
you define resources, which may be across multiple cloud providers and
services.
-
Plan:
Terraform creates an execution plan describing the infrastructure it will
create, update or destroy bases on the existing infrastructure and
configuration.
-
Apply:
Terraform performs the proposed operations in the correct order, respecting any
resource dependencies.
For more knowledge go to https://developer.hashicorp.com/terraform
2. Terraform Setup
On
Windows:
o
Go to the Download Terraform page (https://www.terraform.io/downloads.html)
o
Select the Windows tab under the
operating system heading and select the latest version. Eg. Version 1.5.3
o
Unzip and place terroform.exe
somewhere in your path; Ex. c:\
terraform_1.5.3_windows_386 depending to your terraform version.
o
Edit system environment variables,
select Path in the system variables or alternatively in the user variables and Edit
it.
o
Enter the location of the terraform
folder
o
To check the terraform global path
configuration, open a new command-prompt window and enter the command : terraform –version
On
Linux:
o
Go to the Download Terraform page (https://www.terraform.io/downloads.html)
o
Select the Linux tab under the
operating system heading and select the latest version. Ex. Version 1.5.3
o
You may use wget tool to
download the file wget https://releases.hashicorp.com/terraform/1.5.3/terraform_1.5.3_linux_386.zip
o
Unzip and move terraform to
/usr/local/bin folder
o
Enter the command : terraform –version
CloudShell:
For this lab, we are using Oracle Cloud Shell which is
integrated in Oracle Cloud Infrastructure Interface with the latest Terraform
version already configured. To start the Oracle Cloud Shell
o
Log on OCI Console
o
Click Cloud Shell at the top right of
the page
3. Generate SSH Keys
Generate a
Secure Shell (SSH) keys to allow a secure remote login or secure file transfers
to your cloud host.
o
Open the Cloud Shell terminal
o
Create .ssh directory
mkdir .ssh
o
Run the following commands
cd .ssh
ssh-keygen -b 2048 -t rsa -f cloudkey
o
Ignore the passphrase
o
You will have two files created : cloudkey and cloudkey.pub
4. Generate API Keys
o
Open Cloud Shell
o
Create directory .oci
mkdir .oci
o
Run the following commands to
generate API keys
openssl genrsa -out .oci/oci_api_key.pem
2048
openssl
rsa -pubout -in .oci/oci_api_key.pem -out
.oci/oci_api_key_public.pem
o
Copy the content of oci_api_key_public.pem
file including
the ----Begin Public Key--- and ----End Public Key---- lines
cat oci_api_key_public.pem
o
Navigate to and click on your user
profile in the top right of the OCI console
o
Select Click on API Keys and Add API
Keys
o
Choose Paste Public Key option and Paste
your public OCI API Keys file copied above
o
Click Add and copy the content of
configuration file
o
Back in your .oci directory and
create the config file
vi config
o
Insert the content of configuration
file copied above.
o
Save and quit
:x or :wq
5. Overview and Topology
In this lab, we will create the following resources:
-
VCN (Virtual Cloud Network) à
-
1x Internet Gateway
-
1x Subnets
o
DB Subnet : Private / Linked to
Default Route Table
-
1x Route Tables
o
Default Route Table / Routes to NAT
Gateway and Service Gateway
-
1x Security Lists
o
The Database Security List Ports:
Ingress 22 and 1521 from App Subnet
-
Linux Virtual Machine
-
DB System 21c with PDB
6. Create Compartment
Before creating resources, you must create first a
compartment. It’s required to have permission to create and delete
compartments.
o
Log to OCI console
o
Open the navigation menu and click
Identity & Security
o
Under Identity, click Compartments. A
list of compartments in your tenancy is displayed
o
Select the compartment in which you
want to create your resources or create a new compartment
o
To create a new compartment, click Create Compartment
o
Enter the following:
§
Name: A name that is unique across all
compartment in your tenancy. Eg. dbcs-comp
§
Description: Description for this
compartment
§
Tags: Enter tags to organize and list
resources based on your business needs
o
Click Create Compartment
o
Once a compartment is created, you
must copy a compartment OCID.
7. Get Availability domain
o
Log to OCI console
o
Open the navigation menu and click on
Instances
o
Copy the availability domain name
(E.g: CA-MONTREAL-1-AD-1)
8. Terraform files
To create a DB Systems including the network
resources, create a database system folder which contents all the files needed
for Terraform. These files are:
Files |
Description |
terraform.tfvars |
Parameters
for authentication on your tenancy and DB System |
variables.tf |
Resource
variables for the deploy |
outputs.tf |
Displays
the DBCS resources detail after the deploy |
database.tf |
Db
System resources for the deploy |
datasources.tf |
|
vcn.tf |
Networking
declaration code |
8.1. Terraform Config Content
Adjust all the required information:
o
tenancy_ocid
o
user_ocid
o
compartment_ocid
o
fingerprint
o
private_key_path
o
ssh_public_key
o
region
o
availability_domain
o
db_admin_password
Those information must be updated on the terraform.tfvars file
# Oracle Cloud
Infrastructure Authentication
tenancy_ocid = "ocid1.tenancy.oc1.." # CHANGE ME
user_ocid = "ocid1.user.oc1.." # CHANGE ME
fingerprint = "1c:" # CHANGE ME
private_key_path =
"~/oci_api_key.pem" #
CHANGE ME
ssh_public_key = "~/ssh/id_rsa.pub" # CHANGE ME
compartment_ocid =
"ocid1.compartment.oc1." #
CHANGE ME
# Region
region = " ca-montreal-1" # CHANGE ME
# AD
availability_domain = " CA-MONTREAL-1-AD-1" # CHANGE ME
# Database Admin Password
db_admin_password = " WELcome_1234U##"
The terraform.tfvars looks like:
8.2. Terraform Variables Content
Adjust all the required information
on the variables.tf file.
variable
"compartment_ocid" {}
variable
"tenancy_ocid" {}
variable "region"
{}
variable
"fingerprint" {}
variable
"user_ocid" {}
#variable
"public_key_path" {}
variable
"private_key_path" {}
variable
"availability_domain" {
default = "CA-MONTREAL-1-AD-1"
}
# CHANGE ME
variable
"vcn_display_name" {
default = "DBCSVCN"
}
variable
"vcn_cidr" {
default = "10.0.0.0/16"
}
variable
"vcn_dns_label" {
default = "terravcn"
}
# SUBNET INFO
variable
"subnet_db_dns_label" {
default = "dbsubnet"
}
variable
"subnet_db_display_name" {
default = "lab-tf-db-subnet"
}
variable
"subnet_cidr" {
default = "10.0.1.0/24"
}
variable
"subnet_cidr2" {
default = "10.0.2.0/24"
}
provider "oci" {
tenancy_ocid = var.tenancy_ocid
region
= var.region
}
#################
# DB System
#################
variable "db_system_shape"
{
default =
"VM.Standard.E4.Flex"
#"VM.Standard2.4"
}
variable
"db_edition" {
default = "ENTERPRISE_EDITION"
}
# VNIC INFO
variable
"db_system_private_ip" {
default = "10.0.1.50"
}
variable
"db_admin_password" {
}
variable "db_name"
{
default = "CDB01"
}
variable
"db_version" {
default = "21.9.0.0"
}
/*
valid list :
11.2.0.4 or 11.2.0.4.201020
or 11.2.0.4.210119 or 11.2.0.4.210420 or 12.1.0.2 or 12.1.0.2.210420 or
12.1.0.2.210720 or
12.1.0.2.211019 or 12.2.0.1
or 12.2.0.1.210420 or 12.2.0.1.210720 or 12.2.0.1.211019 or 18.0.0.0 or
18.13.0.0 or
18.14.0.0 or 18.16.0.0 or
19.0.0.0 or 19.11.0.0 or 19.12.0.0 or 19.13.0.0 or 21.0.0.0 or 21.3.0.0 or
21.X.0.0.
*/
variable
"db_home_display_name" {
default = "DBHome21"
}
variable "db_disk_redundancy"
{
default = "HIGH"
}
variable
"db_system_display_name" {
default = "DBSYS01"
}
variable
"hostname" {
default = "dbcs-host"
}
variable
"host_user_name" {
default = "opc"
}
variable
"n_character_set" {
default = "AL16UTF16"
}
variable
"character_set" {
default = "AL32UTF8"
}
variable
"db_workload" {
default = "OLTP"
}
variable
"pdb_name" {
default = "PDB01"
}
variable
"data_storage_size_in_gb" {
default = "256"
}
variable
"license_model" {
default = "LICENSE_INCLUDED"
}
variable
"node_count" {
default = "1"
}
variable
"db_system_cpu_core_count" {
default = "2"
}
variable
"data_storage_percentage" {
default = "40"
}
variable
"db_auto_backup_enabled" {
default = "true"
}
variable
"db_auto_backup_window" {
default = "SLOT_TWO"
}
variable
"db_recovery_window_in_days" {
default = "45"
}
variable
"ssh_public_key" {
# default = "~/id_rsa_oci.pub"
}
# Dictionary Locals
locals {
}
8.3. Terraform Database Content
Adjust all the required information
on the database.tf file.
resource
"oci_database_db_system" "MYDBSYS" {
availability_domain =
data.oci_identity_availability_domains.ad1.availability_domains[0].name
compartment_id = var.compartment_ocid
#cpu_core_count =
data.oci_database_db_system_shapes.db_system_shapes.db_system_shapes[0]["minimum_core_count"]
database_edition = var.db_edition
db_home {
database {
admin_password = var.db_admin_password
db_name = var.db_name
pdb_name = var.pdb_name
character_set = var.character_set
ncharacter_set = var.n_character_set
db_workload = var.db_workload
db_backup_config {
auto_backup_enabled = var.db_auto_backup_enabled
auto_backup_window = var.db_auto_backup_window
recovery_window_in_days =
var.db_recovery_window_in_days
}
}
db_version = var.db_version
}
shape = var.db_system_shape
license_model = var.license_model
subnet_id = oci_core_subnet.terraDB.id
private_ip = var.db_system_private_ip
ssh_public_keys = [file(var.ssh_public_key),]
hostname = var.hostname
data_storage_size_in_gb =
var.data_storage_size_in_gb
node_count = data.oci_database_db_system_shapes.db_system_shapes.db_system_shapes[0]["minimum_node_count"]
display_name = var.db_system_display_name
cpu_core_count = var.db_system_cpu_core_count
# defined_tags =
{"${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}"
= var.release }
}
8.4. Terraform Datasource Content
Adjust all the required information
on the datasource.tf file.
## Copyright © 2020, Oracle
and/or its affiliates.
## All rights reserved. The
Universal Permissive License (UPL), Version 1.0 as shown at
http://oss.oracle.com/licenses/upl
# Get the latest Oracle
Linux image
# Get DB node list
data
"oci_database_db_nodes" "db_nodes1" {
compartment_id = var.compartment_ocid
db_system_id
= oci_database_db_system.MYDBSYS.id
}
## Get DB node details
data
"oci_database_db_node" "db_node_details1" {
db_node_id =
data.oci_database_db_nodes.db_nodes1.db_nodes[0]["id"]
}
# Gets the OCID of the first
(default) vNIC
data
"oci_core_vnic" "db_node_vnic1" {
vnic_id =
data.oci_database_db_node.db_node_details1.vnic_id
}
data
"oci_database_db_homes" "db_homes1" {
compartment_id = var.compartment_ocid
db_system_id
= oci_database_db_system.MYDBSYS.id
}
data
"oci_database_databases" "databases1" {
compartment_id = var.compartment_ocid
db_home_id
=
data.oci_database_db_homes.db_homes1.db_homes[0].db_home_id
}
data
"oci_database_db_system_patches" "patches1" {
db_system_id =
oci_database_db_system.MYDBSYS.id
}
data
"oci_database_db_system_patch_history_entries"
"patches_history1" {
db_system_id =
oci_database_db_system.MYDBSYS.id
}
data
"oci_database_db_home_patches" "patches1" {
db_home_id =
data.oci_database_db_homes.db_homes1.db_homes[0].db_home_id
}
data
"oci_database_db_home_patch_history_entries"
"patches_history1" {
db_home_id =
data.oci_database_db_homes.db_homes1.db_homes[0].db_home_id
}
data
"oci_database_db_versions"
"test_db_versions_by_db_system_id1" {
compartment_id = var.compartment_ocid
db_system_id
= oci_database_db_system.MYDBSYS.id
}
data "oci_database_db_system_shapes"
"db_system_shapes" {
availability_domain = var.availability_domain
compartment_id = var.compartment_ocid
filter {
name
= "shape"
values = [var.db_system_shape]
}
}
8.5. Terraform VCN Content
Adjust all the required information
on the vcn.tf file.
terraform {
required_version = ">= 0.12.0"
}
#################
# VCN
#################
resource
"oci_core_virtual_network" "vcnterra" {
dns_label
= var.vcn_dns_label
cidr_block = var.vcn_cidr
compartment_id = var.compartment_ocid
display_name
= var.vcn_display_name
}
######################
# Internet Gateway
######################
resource
"oci_core_internet_gateway" "igtw" {
compartment_id = var.compartment_ocid
vcn_id
= oci_core_virtual_network.vcnterra.id
display_name
= "tf-igw"
enabled
= "true"
}
#####################
# NAT Gateway
#####################
resource
"oci_core_nat_gateway" "natgw" {
compartment_id = var.compartment_ocid
display_name
= "${lower(var.vcn_display_name)}-natgw"
vcn_id
= oci_core_virtual_network.vcnterra.id
#
defined_tags =
{"${oci_identity_tag_namespace.ArchitectureCenterTagNamespace.name}.${oci_identity_tag.ArchitectureCenterTag.name}"
= var.release }
}
######################
# Route Tables
######################
#default
resource
"oci_core_default_route_table" "rt" {
manage_default_resource_id =
oci_core_virtual_network.vcnterra.default_route_table_id
route_rules {
destination = "0.0.0.0/0"
network_entity_id =
oci_core_internet_gateway.igtw.id
}
}
######################
# Security Lists
######################
resource
"oci_core_security_list" "terra_sl" {
compartment_id = var.compartment_ocid
vcn_id
= oci_core_virtual_network.vcnterra.id
display_name
= "tf-sl"
egress_security_rules {
protocol
= "all"
destination = "0.0.0.0/0"
}
# ingress_security_rules {
#
protocol = "6"
#
source = "0.0.0.0/0"
#
tcp_options {
#
min = 80
#
max = 80
# }
# }
ingress_security_rules {
protocol = "6"
source
= "0.0.0.0/0"
tcp_options {
min = 22
max = 22
}
}
ingress_security_rules {
protocol = "6"
source
= var.subnet_cidr2
tcp_options {
max = 1521
min = 1521
}
}
}
######################
# Availability Domains
######################
data
"oci_identity_availability_domains" "ad1" {
compartment_id = var.compartment_ocid
}
######################
#
Subnet
######################
resource
"oci_core_subnet" "terraDB" {
availability_domain = data.oci_identity_availability_domains.ad1.availability_domains[0].name
cidr_block = var.subnet_cidr
display_name = var.subnet_db_display_name
prohibit_public_ip_on_vnic = false
dns_label = var.subnet_db_dns_label
#"${var.subnet_dns_label}${count.index + 1}"
compartment_id = var.compartment_ocid
vcn_id =
oci_core_virtual_network.vcnterra.id
route_table_id =
oci_core_default_route_table.rt.id
security_list_ids =
["${oci_core_security_list.terra_sl.id}"]
dhcp_options_id =
oci_core_virtual_network.vcnterra.default_dhcp_options_id
#security_list_ids =
["${oci_core_virtual_network.vcnterra.default_security_list_id}"]
}
9. Terraform commands
9.1. terraform init
The terraform init command initialize a working
directory containing Terraform configuration files. Using Cloud Shell, you may
have to run terraform init -upgrade command
the first time.
9.2. terraform plan
The terraform plan command enables you to preview any
changes before you apply them
…
…
9.3. terraform apply
The terraform apply command makes the changes defined by
your terraform configuration to create, update or destroy resources.
…
…
…
…
10.Connect to the Database instance
As you can
see at the end of output, the DB host named dbcs-host is created with 10.0.1.50
as private Ip. Now you must try to connect using the public Ip.
o
Log to the OCI Console
o
Open the navigation menu and click Oracle
Database
o
Click on Oracle Base Database Service
o
Select the right compartment
o
Click on your DB System (E.g: DBSYS01),
Your will see the CDB under Databases
o
Under Resources, click on Nodes(1)
o
Copy the Public IP address
o
Launch the Cloud Shell
o
Make connection to the dbcs node
using SSH and RSA Key generated
ssh -i .ssh/<RSA Private Key> opc@<Public IP
adress>
o
Switch to oracle user
sudo su –
oracle
o
Connect to the database as sysdba
sqlplus / as
sysdba
o
Display pdbs
SQL> show
pdbs
o
Check the listener status
11.Conclusion
-
In this lab, we described how to
deploy a Database instance using Terraform in OCI and leverage along with all necessary
network resources. We used Cloud Shell as terminal but you can also use other
terminal like Windows Command, PowerShell, Putty etc.
-
All the attributes uses in yhis lab
can be modified in the variables.tf file
-
From this stack, you can safely add
new components or new resources in the .tf files. For exemple, you can add a
Bastion host service on the top on the stack, you can add a block storage using
Service gateway.