Using Ansible to configure an Oracle Linux 7.1 server with Oracle 12c R1 Enterprise Edition Database

Chris Vezalis Ansible, DEVOPS, Linux, Oracle Database, Oracle Linux, Vagrant 23 Comments

Ansible is the leading tool for configuring software and various parameters on servers. It does not require agents and other software installed on nodes like other popular tools (puppet or chef). Also, it is modular and already has hundreds of modules that help us configure our servers in several ways. In this article I will demonstrate how we can install an Oracle 12c R1 Database ( in CentOS 7.1 server. The same Ansible playbook can be used with Redhat Enterprise Linux 7.1 and Oracle Linux 7.1. You can download the code from Github at:


Source code also includes configuration for automatically provision a virtual machine using Vagrant.

Download from Oracle support the Oracle installation files:
and put them into the folder roles/oracle-install/files inside checkout folder

After that, go into checkout folder and execute :

$ vagrant up 

After a few minutes a virtual machine with Oracle Database installed will be ready, without any further configuration. You can access the Enterprise Manager Express using sys/sysdba and “oracle” as password.


You can shutdown the virtual machine using:

$ vagrant halt

You can destroy it (delete it from disk) using:

$ vagrant destroy

Playbook in details

The main playbook is oracle-db.yml. You can execute it using:

$ ansible-playbook oracle-db.yml

If you do not use Vagrant you need a RHEL/CentOS/Oracle Linux 7.1 server with minimal installation, basic network configuration (ip/gateway/hostname/hosts/dns) and the root password. You can configure your host settings (hostname/ip, private key, username etc) in ansible.cfg and hosts files. Check Ansible documentation for more information about how to configure your inventory for one or more servers.

Playbook has 2 main sections:

1. vars_files. Is the section for configuring all installation parameters.

  - infra-vars.yml
  - db-vars.yml
  - secrets.yml

In secrets.yml you can put the passwords used through playbook. db-vars.yml contains variables in the sense of constants and you may not change them. The infra-vars.yml file contains the infrastructure parameters which can be configured to adapt to your needs. The following table lists the variables you can configure:

oracle_user: The user that will run the software and the user who will perform the installation and configuration. Default value: oracle
oracle_install_group: The group that owns the software. Default value: oinstall
extra_groups: By default dba and oper
oracle_base: The base directory that hosts installation and software and data. Default is /oracle/app. Another example from Oracle documentation is /u01/app
installer_archives: The location of the installer files. You can change them if you download other version of R1 database
dbhome_name: The folder name of the database instance that installer will create
oracle_edition: The Edition of the database that will be installed. EE (Enterprise edition) by default
oracle_dba_group: The operating system group with dba role
oracle-oper_group: The operating system group with oper role
oracle_database_type: GENERAL_PURPOSE by default
oracle_globalname: The database global name
oracle_sid: The sid of the database
oracle_conf_as_container_db: True/false. If database will be a container database
oracle_pdb_name: The pluggable database name
oracle-charset: The character set of database. Default value is: AL32UTF8
oracle_memory_option: Boolean. Enable or disable Automatic Memory Management
oracle_memory_mb: Memory target for database in MB.
oracle_install_samples: Boolean. Install sample schemas when configuring the database
oracle_management_option: DEFAULT for Database Express and CLOUD_CONTROL for Enterprise Manager Cloud Control
oracle_enable_recovery: Boolean. Enable or disable database recovery
oracle_storage_type: FILE_SYSTEM_STORAGE for filesystem storage type. ASM is not supported in this playbook. I will add in a future release
oracle_dataloc: Full path to a folder that Oracle will be storing datafiles
oracle_recoveryloc: Full path to a folder that Oracle will be storing the fast recovery area
oracle_decline_security_updates: Yes by default for playbook. Installer will not install security updates from internet
hugepages_nr: Number of hugepages for the operating system. Consult documentation on how to find the correct value.

Oracle installation response files include more parameters, that i will add in a future release a playbook.
The second section contains the roles playbook will execute:

  - role: linux-oracle
  - role: oracle-install
    sudo_user: '{{ oracle_user }}'

Playbook role: linux-oracle

This is the role for preparing the operating system for oracle installation. Lets examine the sections of linux-oracle role:

# ==> Configure Linux
- name: Install required libraries
  yum: name={{ item }} state=present
  with_items: packages_list
- name: Disable SELinux
  selinux: state=disabled
- name: Disable Firewall Deamon (firewalld)
  service: name=firewalld state=stopped enabled=no
- name: Change kernel parameters
  sysctl: name="{{ item.key }}" value="{{ item.value }}" state=present
  with_dict: kernel_params

The first section will install the required libraries the minimal Oracle Linux 7 is required for support Oracle Database 12c installation. Variables for this section is from roles/linux-oracle/vars/main.yml. The next modules disable the Security-Enhanced Linux and firewall. If you need firewall enabled you can enable it with this module but you also need to open the required ports for firewall using an Ansible module like firewalld. Consult Oracle Documentation for required ports and Ansible documentation for opening ports on Oracle Linux 7.1. The final section configures linux kernel parameters for Oracle Database.

Next, the role has a couple of tasks for creating oracle user and group:

# ==> Create users and groups
- name: Create groups
  group: name={{ oracle_install_group }} state=present
- name: add extra groups
  group: name={{ item }} state=present
  with_items: extra_groups
- name: Create user
  user: name={{ oracle_user }} group={{ oracle_install_group }}   password={{ oracle_os_user_pass }}
- name: Add extra groups
  user: name={{ oracle_user }} groups={{ item }} append=yes
  with_items: extra_groups

Then, the role creates user limits for oracle user:

- name: Add oracle user limits
  lineinfile: dest=/etc/security/limits.conf line='{{ oracle_user }} {{ item.limit }} {{ item.type}} {{ item.value }}'
    - { limit: 'soft', type: nofile, value: '{{ soft_no_file }}' }
    - { limit: 'hard', type: nofile, value: '{{ hard_no_file }}' }
    - { limit: 'soft', type: nproc, value: '{{ soft_nproc }}' }
    - { limit: 'hard', type: nproc, value: '{{ hard_nproc }}' }
    - { limit: 'soft', type: stack, value: '{{ soft_stack }}' }
    - { limit: 'hard', type: stack, value: '{{ hard_stack }}' }
    - { limit: 'soft', type: memlock, value: '{{ soft_memlock }}' }
    - { limit: 'hard', type: memlock, value: '{{ hard_memlock }}' }

These limits refer to the number of open files, number of processes, stack size and memlock for huge pages.
Subsequently playbook creates the main folder for oracle installation.

# ==> Create Base directories
- name: Create Oracle Base directory
  file: state=directory path={{ oracle_base }} owner={{ oracle_user }} group={{ oracle_install_group }}

Transparent HugePages can cause memory allocation delays at runtime according to the Oracle Database documentation here

The following section disables them:

# ==> Disable transparent hugepages
- name: Copy script
  copy: dest='~/' mode=755
- name: Disable Transparent Huge Pages
  shell: '~/'

It executes a script that disables transparent huge pages using rc.local file.
Finally the role enables huge pages on Oracle Linux:

# ==> Configure huge pages
- name: configure kernel for hugepages
  sysctl: name="vm.nr_hugepages" value="{{ hugepages_nr }}" state=present
    - hugepages

A restart is required for system to set the correct value of huge pages. You can verify the settings using:

cat /proc/meminfo | grep HugePages

or in Oracle 12c you can view the alert log. At the beginning it has a nice informational message about huge pages and how Oracle Database uses them:

Wed Oct 21 12:53:19 2015
Dump of system resources acquired for SHARED GLOBAL AREA (SGA) 

Wed Oct 21 12:53:19 2015
 Per process system memlock (soft) limit = 1843M
Wed Oct 21 12:53:19 2015
 Expected per process system memlock (soft) limit to lock
 SHARED GLOBAL AREA (SGA) into memory: 1154M
Wed Oct 21 12:53:19 2015
 Available system pagesizes:
  4K, 2048K 
Wed Oct 21 12:53:19 2015
 Supported system pagesize(s):
Wed Oct 21 12:53:19 2015
Wed Oct 21 12:53:19 2015
        4K       Configured               2               2        NONE
Wed Oct 21 12:53:19 2015
     2048K              578             577             577        NONE
Wed Oct 21 12:53:19 2015

The above is a sample output from database alert log the playbook created using vagrant with my default settings. You can see that system has 578 available huge pages and database utilizes 577 of them and 1 is left for the operating system.

Playbook role: oracle-install

This role installs the Oracle Database 12c (, creates the listener and the database. Let’s focus on some details.

- name: Create folder for installation files
  file: state=directory path={{ installation_folder }}
# ==> Copy installer files
- name: Copy installer files
  copy: src={{ item }} dest='{{ installation_folder }}/'
  with_items: '{{ installer_archives }}'
# ==> extract files
- name: Extract installation files
  command: 'unzip {{ installation_folder }}/{{ item }} -d {{ installation_folder }}/'
  with_items: '{{ installer_archives }}'

This part of playbook creates the installation folder, copies the installation archives and extract them.
In the next section we do the actual installation using a response file:

# ==> generate response file
- name: Gerenerate the response file for software only installation
  template: src=db_install.rsp.j2 dest={{ installation_folder }}/db_install.rsp
# ==> execute installation
- name: Install Product
  command: '{{ installation_folder}}/database/runInstaller -silent -ignorePrereq -ignoreSysPrereqs -waitforcompletion -responseFile {{ installation_folder }}/db_install.rsp'
# ==> execute Inventory command as root
- name: Execute Inventoty root command
  command: '{{ inventory_location }}/'
  sudo_user: root
# ==> execute DB home command as root
- name: Execute DB home rfoot command
  command: '{{ oracle_home }}/'
  sudo_user: root

At first we generate the response file using j2 templates and copy the result to the installation folder. After the creation of the response file we execute Oracle Database installer using some parameters for not loading the graphical user interface and get the parameters to perform silent installation. This is a first time installation and oracle needs us to run 2 commands as root. The two command modules do the following.

- name: copy listener response file
  template: src=netca.rsp.j2 dest={{ installation_folder }}/netca.rsp
- name: Create listener using netca
  command: '{{ oracle_home }}/bin/netca -silent -responseFile {{ installation_folder }}/netca.rsp'

In this part we create the oracle listener using the default settings and network configuration assistant (netca). First we generate the response template for listener installer, then we copy it to installation folder and finally we execute it for creating the listener.
After listener creation we can execute the database configuration assistant (dbca) for creating a database instance.

- name: copy response file for dbca
  template: src=dbca.rsp.j2 dest={{ installation_folder }}/dbca.rsp
- name: create database
  command: '{{ oracle_home }}/bin/dbca -silent -responseFile {{ installation_folder }}/dbca.rsp'

The next section will create environment variables for Oracle user:

- name: create oracle home variable
  lineinfile: dest='/home/{{ oracle_user }}/.bashrc' line='export ORACLE_HOME={{ oracle_home }}'
- name: create oracle sid variable
  lineinfile: dest='/home/{{ oracle_user }}/.bashrc' line='export ORACLE_SID={{ oracle_sid }}'
- name: add oracle home bin folder
  lineinfile: dest='/home/{{ oracle_user }}/.bashrc' line='export PATH=$PATH:$ORACLE_HOME/bin'

This contains useful database tools like sqlplus and lsnrctl.

- name: change oratab
  lineinfile: dest='/etc/oratab' regexp='^{{ oracle_sid }}:{{ oracle_home }}:N' line='{{ oracle_sid }}:{{ oracle_home }}:Y'
  sudo_user: root
- name: copy init.d oracle script to /etc/init.d
  template: src=oradb.j2 dest=/etc/init.d/oradb mode=750
  sudo_user: root
- name: enable oradb script to run at startup
  command: 'chkconfig --add oradb'
  sudo_user: root

At the end we make some configuration for Oracle Database to autostart after a system restart. To do that we enable the instance we created in oratab and create a startup script for the database that will be execute every time the server starts.

This is in short the way my playbook will install Oracle Database 12c ( In the next weeks I will improve it and add more parameters for installation and support for RAC and ASM. Stay tuned with my blog!

My github account also contains an Ansible playbook to provision and configure a WebLogic with Fusion Middleware infrastructure software. You can combine the two playbooks and create the database for storing WebLogic and Fusion Middleware repositories and have the full stack, database plus application server with software installed and running with zero configuration in zero time.

You can find more of my posts at my blog at

Chris Vezalis

Senior Software Engineer at Nodalpoint
Active in IT since 2000.
My areas of expertise are Oracle Middleware Products (WebLogic, ADF, SOA Suite), Linux, JAVA, JavaScript and DevOps.
Chris Vezalis

Leave a Reply

10 Comment threads
13 Thread replies
Most reacted comment
Hottest comment thread
15 Comment authors
mickyRajMaxPrajwalScott Recent comment authors
newest oldest most voted
Notify of

Thanks for sharing. However, this error pops up:The box ‘boxcutter/oel71’ could not be found or could not be accessed in the remote catalog.


Nice article. I’m wondering once the Oracle server is installed and running, can you use ansible to start and stop specific databases on the server thereafter. I see this as the more common daily task, as databases need to be redeployed with as new features are developed and tested. I’d be interested in seeing a second post on this aspect.

Mikael Fransson
Mikael Fransson

Thanks! This is just brilliant. Never had such an easy install of the database. Made a few smaller notes / changes along the way. The Centos box needed some updates and would not load the Shared folders. I also needed to install ansible and for that I needed epel. Listing my changes below: – Install ansible and epel was needed. After the below sequence the GuestAdditions installed properly and you could run the ansible playbooks. – yum install epel-release – yum install ansible – yum update -y – Edit Hosts file to map to – Edit infra-vars.yml – oracle_globalname:… Read more »


I have no idea, but I am observing:
I am guessing something with network is incorrect
Totally new to all of this!

fatal: [oradb]: FAILED! => {“changed”: true, “cmd”: [“/oracle/app/oracle/product/12102/dbhome_1/bin/dbca”, “-silent”, “-responseFile”, “/oracle/app/installation/dbca.rsp”], “delta”: “0:00:02.833544”, “end”: “2016-03-23 17:22:05.382078”, “failed”: true, “rc”: 1, “start”: “2016-03-23 17:22:02.548534”, “stderr”: “”, “stdout”: “Copying database files\n1% complete\n3% complete\nDBCA Operation failed.\nLook at the log file \”/oracle/app/cfgtoollogs/dbca/orcl/orcl.log\” for further details.”, “stdout_lines”: [“Copying database files”, “1% complete”, “3% complete”, “DBCA Operation failed.”, “Look at the log file \”/oracle/app/cfgtoollogs/dbca/orcl/orcl.log\” for further details.”], “warnings”: []}

Chris Noffsinger
Chris Noffsinger

This is pretty fantastic thanks for sharing.


Hy Chris, thanks for such a nice ansible code. However while running the playbook iam getting an error while changing the kernel_parameters “with_dict expects a dict”!. Iam not sure what is the real issue, can anyone help me with this.?



Hi Chris, Nice article. Thanks for sharing. I am trying to use it without vagrant as want to directly run playbooks and install Oracle on RHEL remote machine. After running oracle-db.yml, I get below error while executing task for the role linux-oracle: # ==> Configure Linux – name: Install required libraries yum: name={{ item }} state=present with_items: packages_list Error: “msg”: “No package matching ‘packages_list’ found available, installed or updated”, “rc”: 126, “results”: [ “No package matching ‘packages_list’ found available, installed or updated” ] My guess is its unable to read the packages_list from main.yml of “vars”. Do I need to… Read more »


Chris, I am trying to install this to an Oracle VM instead of using Virtual Box. when I try to run the oracle-db.yml, it gets stuck when attempting to find the installation files. I have them in /roles/oracle-install/files but I keep getting the following TASK [linux-oracle : Install required libraries] ******************************************************************************************************************************************************************* failed: [oradb] (item=[u’packages_list’]) => {“changed”: false, “failed”: true, “item”: [“packages_list”], “msg”: “No package matching ‘packages_list’ found available, installed or updated”, “rc”: 126, “results”: [“No package matching ‘packages_list’ found available, installed or updated”]} to retry, use: –limit @/ansible/oracledb-ansible/oracle-db.retry I’ve only recently started using ansible, and I don’t know what I’m… Read more »


I am getting error Error: [db] : FAILED! => {“failed”: true, “msg”: “with_dict expects a dict”}, Not sure where I need to alter to make this work for Ansible 2 as I feel this is the reason it’s failing for the later error of the response file?


Hi Chris, I am trying to run this with Ansible 2.1, will that still be valid or need to make changes ? I have set up Vagrant but also trying to run using ansbile-playbook. I get the following errors: When run with Vagarant: Bringing machine ‘default’ up with ‘virtualbox’ provider… There are errors in the configuration of this machine. Please fix the following errors and try again: Vagrant: * Unknown configuration section ‘hostmanager’. When run with ansible-playbook: atal: [oradb]: UNREACHABLE! => {“changed”: false, “msg”: “Failed to connect to the host via ssh: no such identity: /etc/ansible/oracledb/oracledb-ansible-master/.vagrant/machines/default/virtualbox/private_key: No such file or… Read more »


hey Chris, I’m getting ORA-12547: TNS: lost contact fatal: [oradb]: FAILED! => {“changed”: true, “cmd”: [“/oracle/app/oracle/product/12102/dbhome_1/bin/dbca”, “-silent”, “-responseFile”, “/oracle/app/installation/dbca.rsp”], “delta”: “0:00:04.151253”, “end”: “2018-07-24 11:21:18.664456”, “msg”: “non-zero return code”, “rc”: 1, “start”: “2018-07-24 11:21:14.513203”, “stderr”: “”, “stderr_lines”: [], “stdout”: “Cleaning up failed steps\n4% complete\nCopying database files\n5% complete\n7% complete\nDBCA Operation failed.\nLook at the log file \”/oracle/app/cfgtoollogs/dbca/orcl/orcl0.log\” for further details.”, “stdout_lines”: [“Cleaning up failed steps”, “4% complete”, “Copying database files”, “5% complete”, “7% complete”, “DBCA Operation failed.”, “Look at the log file \”/oracle/app/cfgtoollogs/dbca/orcl/orcl0.log\” for further details.”]} nano /oracle/app/cfgtoollogs/dbca/orcl/orcl0.log ”’ ERROR: ORA-12547: TNS:lost contact ”’ how can I get rid to that! database software… Read more »