Note:
- This tutorial requires access to Oracle Cloud. To sign up for a free account, see Get started with Oracle Cloud Infrastructure Free Tier.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Provision an Oracle Exadata Database Service on Cloud@Customer Virtual Machine Cluster with Ansible
Introduction
This tutorial explains how to use the OCI Ansible collection to provision Oracle Exadata Database Service on Cloud@Customer virtual machine (VM) clusters. To create an Oracle Exadata Database Service on Cloud@Customer VM cluster, it is mandatory to create the corresponding VM cluster network first.
Objectives
- Provision an Oracle Exadata Database Service on Cloud@Customer VM cluster network and VM cluster using Ansible.
Prerequisites
-
An Oracle Cloud Infrastructure (OCI) account with Oracle Exadata Database Service on Cloud@Customer infrastructure available.
-
An SSH keys pair.
-
A control node with the following components already installed and configured properly.
- Ansible.
- OCI Ansible collection.
- Oracle Cloud Infrastructure Command Line Interface (OCI CLI).
For more information, see Prerequisites for Using Ansible with Oracle Cloud Infrastructure.
Task 1: Create an Inventory
-
Connect to the properly configured Ansible control node.
-
Create an inventory file named
inventory_exacc.yml
with the following content.localhost ansible_connection=local
Task 2: Create a Variable File
Create a variable file named variables_exacc.yml
with all variables described in the following content.
# Your variables file
your_region: "eu-frankfurt-1" # The OCI region where your resources will reside - This parameter is optional
your_exa_infra_id: "ocid1.exadatainfrastructure.oc1.eu-frankfurt-1.xxx" # The OCI of your Exadata infrastructure
## Variables related to your VM cluster network
your_vm_net_comp_id: "ocid1.compartment.oc1..xxx" # The compartment OCID of your VM cluster network
your_vm_net_name: "my_vm_cluster_network_name" # The display name of your VM cluster network
your_vm_net_dns: "10.109.10.2" # The list of your DNS server IP addresses. Maximum of 3 allowed.
your_vm_net_ntp: "10.109.10.3" # The list of your NTP server IP addresses. Maximum of 3 allowed.
your_vm_net_scan_ips: ["203.101.10.123", "203.101.10.124", "203.101.10.125"] # The list of your SCAN IP addresses. Three addresses should be provided.
your_vm_net_scan_listener_port_tcp: "1521" # Your SCAN TCPIP port. Default is 1521.
### Variables related to your CLIENT network
your_cli_nodes_hostname_1: "your_1st_hostname" # The hostname of your 1st node on the CLIENT network
your_cli_nodes_ip_1: "203.101.10.101" # The IP address of your 1st node on the CLIENT network
your_cli_nodes_vip_hostname_1: "your_1st_hostname-vip" # The node virtual IP (VIP) host name of your 1st node on the CLIENT network
your_cli_nodes_vip_1: "203.101.10.102" # The node virtual IP (VIP) address of your 1st node on the CLIENT network
your_db_server_ocid_1: "ocid1.dbserver.oc1.eu-frankfurt-1.xxx" # The Db server OCID associated with your 1st node on the CLIENT network
your_cli_nodes_hostname_2: "your_2nd_hostname" # The hostname of your 2nd node on the CLIENT network
your_cli_nodes_ip_2: "203.101.10.103" # The IP address of your 2nd node on the CLIENT network
your_cli_nodes_vip_hostname_2: "your_2nd_hostname-vip" # The node virtual IP (VIP) host name of your 2nd node on the CLIENT network
your_cli_nodes_vip_2: "203.101.10.104" # The node virtual IP (VIP) address of your 2nd node on the CLIENT network
your_db_server_ocid_2: "ocid1.dbserver.oc1.eu-frankfurt-1.yyy" # The Db server OCID associated with your 2nd node on the CLIENT network
your_cli_vm_net_vlan_id: "123" # Your CLIENT network VLAN ID
your_cli_vm_net_netmask: "your_client_netmask" # Your CLIENT network netmask
your_cli_vm_net_gateway: "your_client_gateway_ip" # Your CLIENT network gateway
your_cli_vm_net_domain_name: "your_client_network_domain_name" # Your CLIENT network domain name
### Variables related to your BACKUP network
your_bck_nodes_hostname_1: "your_1st_hostname-bk" # The hostname of your 1st node on the BACKUP network
your_bck_nodes_ip_1: "10.108.10.3" # The IP address of your 1st node on the BACKUP network
your_bck_nodes_hostname_2: "your_2nd_hostname-bk" # The hostname of your 2nd node on the BACKUP network
your_bck_nodes_ip_2: "10.108.10.4" # The IP address of your 2nd node on the BACKUP network
your_bck_vm_net_vlan_id: "456" # Your BACKUP network VLAN ID
your_bck_vm_net_netmask: "your_backup_netmask" # Your BACKUP network netmask
your_bck_vm_net_gateway: "your_backup_gateway_ip" # Your BACKUP network gateway
your_bck_vm_net_domain_name: "your_backup_network_domain_name" # Your BACKUP network domain name
## Variables related to your VM cluster
your_vm_cluster_comp_id: "ocid1.compartment.oc1..yyy" # The compartment OCID of your VM cluster
your_vm_cluster_name: "my_vm_cluster_name"
your_vm_clus_ssh_public_keys: [ "ssh-rsa AAAAB3NzaC...qScP4xMPQ9L5xWsqs" ]
your_license_model: "LICENSE_INCLUDED" # The Oracle license model that applies to the VM cluster. The default is BRING_YOUR_OWN_LICENSE.
Task 3: Create a Playbook to Provision a VM Cluster Network
-
Create a playbook file named
playbook_exacc_vmCluster_network_creation.yml
with the following content.- hosts: localhost collections: - oracle.oci vars_files: - variables_exacc.yml tasks: - name: Create VM cluster network oci_database_vm_cluster_network: region: "{{ your_region }}" compartment_id: "{{ your_vm_net_comp_id }}" exadata_infrastructure_id: "{{ your_exa_infra_id }}" display_name: "{{ your_vm_net_name }}" dns: "{{ your_vm_net_dns }}" ntp: "{{ your_vm_net_ntp }}" scans: - hostname: "{{ your_vm_clus_name }}-scan" ips: "{{ your_vm_net_scan_ips }}" scan_listener_port_tcp: "{{ your_vm_net_scan_listener_port_tcp }}" vm_networks: - network_type: CLIENT nodes: - hostname: "{{ your_cli_nodes_hostname_1 }}" ip: "{{ your_cli_nodes_ip_1 }}" vip_hostname: "{{ your_cli_nodes_vip_hostname_1 }}" vip: "{{ your_cli_nodes_vip_1 }}" db_server_id: "{{ your_db_server_ocid_1 }}" - hostname: "{{ your_cli_nodes_hostname_2 }}" ip: "{{ your_cli_nodes_ip_2 }}" vip_hostname: "{{ your_cli_nodes_vip_hostname_2 }}" vip: "{{ your_cli_nodes_vip_2 }}" db_server_id: "{{ your_db_server_ocid_2 }}" vlan_id: "{{ your_cli_vm_net_vlan_id }}" netmask: "{{ your_cli_vm_net_netmask }}" gateway: "{{ your_cli_vm_net_gateway }}" domain_name: "{{ your_cli_vm_net_domain_name }}" - network_type: BACKUP nodes: - hostname: "{{ your_bck_nodes_hostname_1 }}" ip: "{{ your_bck_nodes_ip_1 }}" vip_hostname: "{{ your_bck_nodes_vip_hostname_1 }}" vip: "{{ your_bck_nodes_vip_1 }}" db_server_id: "{{ your_db_server_ocid_1 }}" - hostname: "{{ your_bck_nodes_hostname_2 }}" ip: "{{ your_bck_nodes_ip_2 }}" vip_hostname: "{{ your_bck_nodes_vip_hostname_2 }}" vip: "{{ your_bck_nodes_vip_2 }}" db_server_id: "{{ your_db_server_ocid_2 }}" vlan_id: "{{ your_bck_vm_net_vlan_id }}" netmask: "{{ your_bck_vm_net_netmask }}" gateway: "{{ your_bck_vm_net_gateway }}" domain_name: "{{ your_bck_vm_net_domain_name }}" wait: true register: new_vmClusterNetwork
Note the task keyword
register
, at the end of the invocation of moduleoci_database_vm_cluster_network
: it means the output of the module will be registered in thenew_vmClusterNetwork
variable. This variable will contain all details of the newly created VM cluster network, including its OCID.Note: For this tutorial, there are only two nodes dictionaries for each network type, because the underlying Exadata infrastructure contains two
db servers
. To create a VM cluster with four or eight nodes, it is necessary to provide the adequate number of nodes dictionaries for each network type. -
In the playbook
playbook_exacc_vmCluster_network_creation.yml
, add the following task to retrieve the OCID of the newly created VM cluster network.- name: Get OCID of newly created VM cluster network set_fact: your_vm_net_ocid: "{{ item.id }}" loop: - "{{ new_vmClusterNetwork.vm_cluster_network }}" loop_control: label: "{{ item.display_name }}"
-
In the playbook,
playbook_exacc_vmCluster_network_creation.yml
, add the following tasks to validate the newly created VM cluster network and to download its configuration.- name: Validate VM cluster network oci_database_vm_cluster_network_actions: exadata_infrastructure_id: "{{ your_exa_infra_id }}" vm_cluster_network_id: "{{ your_vm_net_ocid }}" region: "{{ your_region }}" action: validate - name: Download network configuration file of VM cluster network oci_database_vm_cluster_network_actions: exadata_infrastructure_id: "{{ your_exa_infra_id }}" vm_cluster_network_id: "{{ your_vm_net_ocid }}" action: download_vm_cluster_network_config_file config_file_dest: "/tmp/net_config_my_vm_cluster_network.json" region: "{{ your_region }}"
-
In the playbook
playbook_exacc_vmCluster_network_creation.yml
, add the following tasks to display the details of the newly created VM cluster network after its validation has taken place.- name: Get facts of newly created VM cluster network oci_database_vm_cluster_network_facts: exadata_infrastructure_id: "{{ your_exa_infra_id }}" vm_cluster_network_id: "{{ your_vm_net_ocid }}" region: "{{ your_region }}" register: newly_created_VM_cluster_network_facts - name: Display details of newly created VM cluster network debug: msg : "{{ newly_created_VM_cluster_network_facts.vm_cluster_networks }}"
Task 4: Run the Playbook to Provision a VM Cluster Network
-
Run the VM cluster network creation playbook with the verbose option.
ansible-playbook playbook_exacc_vmCluster_network_creation.yml -i inventory_exacc.yml -vvv
Note: Using the verbose option
-vvv
will increase the verbosity and help you understand all the underlying steps while the playbook is running. -
After a few minutes, a successful execution of the
oci_database_vm_cluster_network
module should return the following output.changed: [localhost] => { [...], "vm_cluster_network": { "compartment_id": "ocid1.compartment.oc1..xxx", "defined_tags": { "Oracle-Tags": { "CreatedBy": "creation_user", "CreatedOn": "2025-01-09T09:30:30.631Z" } }, "display_name": "my_vm_cluster_network_name", "dns": [ "10.109.10.2" ], "dr_scans": null, "exadata_infrastructure_id": "ocid1.exadatainfrastructure.oc1.eu-frankfurt-1.xxx", "freeform_tags": {}, "id": "ocid1.vmclusternetwork.oc1.eu-frankfurt-1.xxx", "lifecycle_details": null, "lifecycle_state": "REQUIRES_VALIDATION", "ntp": [ "10.109.10.3" ], "scans": [ { "hostname": "name_of_your-scan", "ips": [ "203.101.10.123", "203.101.10.124", "203.101.10.125" ], "port": 1521, "scan_listener_port_tcp": 1521, "scan_listener_port_tcp_ssl": 2484 } ], "time_created": "2025-01-09T09:30:30.818000+00:00", "vm_cluster_id": null, "vm_networks": [ { "domain_name": "your_client_network_domain_name", "gateway": "your_client_gateway_ip", "netmask": "your_client_netmask", "network_type": "CLIENT", "nodes": [ { "db_server_id": "ocid_of_your_1st_db_server", "hostname": "your_1st_hostname", "ip": "203.101.10.101", "lifecycle_state": "REQUIRES_VALIDATION", "vip": "203.101.10.102", "vip_hostname": "your_1st_hostname-vip" }, { "db_server_id": "ocid_of_your_2nd_db_server", "hostname": "your_2nd_hostname", "ip": "203.101.10.103", "lifecycle_state": "REQUIRES_VALIDATION", "vip": "203.101.10.104", "vip_hostname": "your_2nd_hostname-vip" } ], "vlan_id": "123" }, { "domain_name": "your_backup_network_domain_name", "gateway": "your_backup_gateway_ip", "netmask": "your_backup_netmask", "network_type": "BACKUP", "nodes": [ { "db_server_id": "ocid_of_your_1st_db_server", "hostname": "your_1st_hostname-bk", "ip": "10.108.10.3", "lifecycle_state": "REQUIRES_VALIDATION", }, { "db_server_id": "ocid_of_your_2nd_db_server", "hostname": "your_2nd_hostname-bk", "ip": "10.108.10.4", "lifecycle_state": "REQUIRES_VALIDATION", } ], "vlan_id": "456" } ] } }
Task 5: Create a Playbook to Provision a VM Cluster
-
Create a playbook file named
playbook_exacc_vmCluster_creation.yml
with the following content.- hosts: localhost collections: - oracle.oci vars_files: - variables_exacc.yml tasks: - name: Get all existing VM cluster networks oci_database_vm_cluster_network_facts: exadata_infrastructure_id: "{{ your_exa_infra_id }}" compartment_id: "{{ your_vm_net_comp_id }}" region: "{{ your_region }}" register: get_all_vmClusterNetworks - name: Get OCID of the newly created VM cluster network set_fact: your_vm_net_ocid: "{{ item.id }}" loop: "{{ get_all_vmClusterNetworks.vm_cluster_networks }}" loop_control: label: "{{ item.display_name }}" when: item.display_name == your_vm_net_name
These 2 tasks are used to retrieve the OCID of the newly created VM cluster network, because it will be necessary for the VM cluster creation.
-
Add the VM cluster creation task in the playbook,
playbook_exacc_vmCluster_creation.yml
.- name: Create VM cluster oci_database_vm_cluster: region: "{{ your_region }}" compartment_id: "{{ your_vm_cluster_comp_id }}" display_name: "{{ your_vm_cluster_name }}" exadata_infrastructure_id: "{{ your_exa_infra_id }}" vm_cluster_network_id: "{{ your_vm_net_ocid }}" gi_version: "19.0.0.0.0" cpu_core_count: "4" ssh_public_keys: "{{ your_vm_clus_ssh_public_keys }}" time_zone: "Europe/Zurich" memory_size_in_gbs: "60" db_node_storage_size_in_gbs: "120" data_storage_size_in_tbs: "2" license_model: "{{ your_license_model }}" is_sparse_diskgroup_enabled: "false" is_local_backup_enabled: "false" data_collection_options: is_diagnostics_events_enabled: "false" is_health_monitoring_enabled: "false" is_incident_logs_enabled: "false" wait: true wait_timeout: 18000
Note that the current accepted values for the
gi_version
parameter are19.0.0.0.0
and23.0.0.0.0
. Otherwise, you will get the following error:Cannot create VM cluster because Oracle Grid Infrastructure version is invalid. Valid versions are: [19.0.0.0.0, 23.0.0.0.0].
Note: The VM cluster creation usually takes up to 3 hours. This is why the
wait: true
andwait_timeout: 18000
instructions are added in the code.
Task 6: Run the Playbook to Provision a VM Cluster
-
Run the VM cluster creation playbook with the verbose option.
ansible-playbook playbook_exacc_vmCluster_creation.yml -i inventory_exacc.yml -vvv
Note: Using the verbose option
-vvv
will increase the verbosity and help you understand all the underlying steps while the playbook is running. -
After a few minutes, a successful execution of the module
oci_database_vm_cluster
should return the following output.changed: [localhost] => { [...], "vm_clusters": [ { "availability_domain": "your_availability_domain", "compartment_id": "ocid1.compartment.oc1..yyy", "cpus_enabled": 4, "data_collection_options": { "is_diagnostics_events_enabled": false, "is_health_monitoring_enabled": false, "is_incident_logs_enabled": false }, "data_storage_size_in_gbs": null, "data_storage_size_in_tbs": 2.0, "db_node_storage_size_in_gbs": 120, "db_servers": [ "ocid1.dbserver.oc1.eu-frankfurt-1.xxx", "ocid1.dbserver.oc1.eu-frankfurt-1.yyy" ], "defined_tags": { "Oracle-Tags": { "CreatedBy": "creation_user", "CreatedOn": "2025-01-09T12:40:17.201Z" } }, "display_name": "my_vm_cluster_name", "exadata_infrastructure_id": "ocid1.exadatainfrastructure.oc1.eu-frankfurt-1.xxx", "file_system_configuration_details": [ { "file_system_size_gb": 15, "mount_point": "/" }, [...], { "file_system_size_gb": 16, "mount_point": "swap" } ], "freeform_tags": {}, "gi_software_image_id": null, "gi_version": "19.24.0.0.0", "id": "ocid1.vmcluster.oc1.eu-frankfurt-1.xxx", "is_local_backup_enabled": false, "is_sparse_diskgroup_enabled": false, "last_patch_history_entry_id": null, "license_model": "your_license_model", "lifecycle_details": null, "lifecycle_state": "AVAILABLE", "memory_size_in_gbs": 60, "ocpus_enabled": null, "shape": "your_ExadataCC_shape", "ssh_public_keys": null, "system_version": "24.1.6.0.0.241115", "time_created": "2025-01-09T12:40:17.256000+00:00", "time_zone": "Europe/Zurich", "vm_cluster_network_id": "your_newly_created_vmCluster_network_OCID" } ] }
Task 7: Create a Playbook to Check the State of the Newly Created VM Cluster
Create a playbook file named playbook_exacc_vmCluster_post_creation_checks.yml
with the following content.
- hosts: localhost
collections:
- oracle.oci
vars_files:
- variables_exacc.yml
tasks:
- name: Get newly created vmCluster facts
oci_database_vm_cluster_facts:
region: "{{ your_region }}"
compartment_id: "{{ your_vm_cluster_comp_id }}"
exadata_infrastructure_id: "{{ your_exa_infra_id }}"
display_name: "{{ your_vm_cluster_name }}"
register: output_cluster_facts
- name: Set vmCluster facts
set_fact:
your_vm_cluster_id: "{{ item.id }}"
your_vm_cluster_state: "{{ item.lifecycle_state }}"
loop: "{{ output_cluster_facts.vm_clusters }}"
loop_control:
label: "{{ item.display_name }}"
when: item.display_name == your_vm_cluster_name
- name: Check VM cluster state
debug:
msg: "The VM cluster your_vm_cluster_name is in lifecycle state your_vm_cluster_state ."
Task 8: Run the Playbook to Check the State of the Newly Created VM Cluster
-
Run the VM cluster check playbook with the verbose option.
ansible-playbook playbook_exacc_vmCluster_post_creation_checks.yml -i inventory_exacc.yml -vvv
Note: Using the verbose option
-vvv
will increase the verbosity and help you understand all the underlying steps while the playbook is running. -
After a few seconds, a successful execution of the playbook
playbook_exacc_vmCluster_post_creation_checks.yml
should return the following output.ok: [localhost] => { "msg": "The VM cluster your_vm_cluster_name is in lifecycle state AVAILABLE." }
Related Links
Acknowledgments
- Authors - Flora Barriele (EMEA Cloud Lift Implementation Technical Lead - Database)
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Provision an Oracle Exadata Database Service on Cloud@Customer Virtual Machine Cluster with Ansible
G27205-01
February 2025
Copyright ©2025, Oracle and/or its affiliates.