Running Oracle SQL scripts with Ansible playbook - oracle

A look at the core database modules in Ansible documentation shows no signs of a module for Oracle. What is the best way to handle SQL/PLSQL deployments via Ansible for Oracle databases?
Are we expected to use roles from Ansible Galaxy to handle this? Very few people seem to have downloaded roles listed on Galaxy for Oracle.

I have created a role to install apex 5 (where I first uninstall apex 4). I use modules like 'script' and 'shell'. I am not too happy about environment initialization but I am still learning. For any SQL/PLSQL task, sqlplus is the right tool. (perhaps SQLcl can do better..?)
- name: Determine apex version
become: yes
become_user: oracle
shell: source /etc/profile && sqlplus -S / as sysdba #"{{ temp_dir }}/apexver.sql"
register: apexver
args:
executable: /bin/bash
changed_when: "'APEX_040000' in apexver.stdout"
- name: oracle apex remove
become: yes
become_user: oracle
script: apex_remove.sh {{ item }}
with_items:
- 'XE'
ignore_errors: yes
register: result
when: "'APEX_040000' in apexver.stdout"
22:18 $ cat apex_remove.sh
#!/bin/sh
# set oracle environment
. /u01/app/oracle/product/11.2.0/xe/bin/oracle_env.sh
ORACLE_SID=$1
sqlplus -s /nolog <<EOF
connect / as sysdba
#?/apex/apxremov.sql
exit
EOF

I'm not sure if this is related to your question, but I originally was looking for Ansible modules to Start/Stop and get the Status of an Oracle database. I couldn't find anything suitable so I wrote my own ansible modules. Modules give you the power to define a standard interface, with OK/Failed/Changed responses to tasks, while performing as much low-level activity/commands as you need (in this way they are much more flexible than the simple shell/command modules). I wrote the modules to be idempotent -- they won't attempt to start databases that are already started, and won't attempt to stop databases that are already stopped. And if a stop/stop function isn't successful, it returns Failed with stdout/stderr.
Along with Oracle databases, I've also written modules to provide interfaces for Business Objects and Weblogic services. The modules are significant up-front work, but once they are stable they can be used in a wide range of playbooks.
I haven't looked at Galaxy to see if there is anything else like this, and unfortunately due to the nature of my client/contract I'm not sure that I can share the modules that we have developed. I just thought I'd offer this as a possible avenue for you to explore.

Related

SOLVED - IBM AIX : NFS: Value too large to be stored in data type

I've got an issue on Continous Deployement step with Ansible playbook for by AIX server.
One tasks on this Ansible playbook is to remove file on NAS with mounted point.
This is the code I used :
- name: "Remove NAS files"
file:
path: "path_to_remove"
state: absent
However, tasks failed caused : rmtree failed: [Errno 127] Value too large to be stored in data type which issue is detailed in https://www.ibm.com/support/pages/nfs-value-too-large-be-stored-data-type.
My NAS was in 32 bits before and now is in 64bits that why my playbook failed.
I don't understand the solution of IBM support and how to use it in ansible playbook (perhaps shell module and rm -rf command)
Can you help me to find a solution please ?

Weird behavior in ansible regarding executing scripts via win_shell

I have a powershell script for installing MS SQL 2014 to a Windows Server 2016 (manually tested and confirmed working properly).
powershell script abbreviated:
$sqlInstanceName = {{ sqlInstance }}
$localAdminPword = {{ localAdminPword }}
### Some more variables here declared the same as above
echo [OPTIONS] > $SQLServerInstallerPath\SQLServerConfigurationFile
### more echo lines like the above.
& $SQLServerInstallerPath\setup /SAPWD=$localAdminPword /ConfigurationFile=$SQLServerInstallerPath\SQLServerConfigurationFile
My playbook is simple just hosts for the target host and two tasks, I just generate the script using win_template, and then execute it with win_shell. something like:
---
- name: Install SQL
hosts: "{{ newhost }}"
tasks:
- name: generate script
win_template:
src: "scriptName"
dest: "{{ path }}//scriptName.ps1"
- name: run script
win_shell: ./scriptName.ps1
args:
chdir: "{{ path }}"
Here's a rundown of the scenarios:
Scenario 1:
I use Ansible tower to run the job targeting a server newly provisioned with vRealize Automation.
Output says it's successful, no problems.
I login to the new server and see that MS SQL wasn't installed, the powershell script didn't work... weird,
so I logged off the server and I ran the same job again, no changes, just rerun it.
I logged in the server again, this time, MS SQL was installed properly.
Scenario 2:
I repeated scenario 1 completely, everything the same, this time, I ran the job twice in succession.
I logged in the server, saw the MS SQL wasn't installed.
Logged off, then ran the job again, Logged in, saw MS SQL installed
Scenario 3:
I provision a new server, exactly the same as the previous scenarios, but this time, I logged into it to just look at the desktop, take a peek at the start menu, then logged off.
I now run the same job again once, on this new server I provisioned.
After the job completed successfully, I logged into the server and MS SQL was properly installed.
It seems that it won't work, unless I do a first Login on to the new server before running this job. Which defeats the purpose of automating it... Does anyone have an idea about this? Is there some sort of setting or flag I should look into? (note: the server doesn't have the "change password on first login" thing, as far as I'm aware, I didn't specify any first login things on that server.) I need this to work without doing a first login.

LDAP Client installation using ansible

We need to install LDAP client over 156 machines. So we want to use ansible to complete this task.
apt-get install ldap-utils libpam-ldapd libnss-ldapd nscd
But when we install it asked lot of question in response (popup box) and we are facing issue how we can handle those response in playbook.
I have used expect module but it was working well when we see question/response on screen not in popup box like below:
- name: run command to install rubyencoder
expect:
chdir: /home/ubuntu/rubyencoder-evaluation/bin
command: /home/ubuntu/rubyencoder-evaluation/bin/rubyencoder
responses:
'.*Press return key to continue.*': ""
'.*type \"I AGREE\".*': "I AGREE"
'.*Your RubyEncoder profile e-mail.*': "abc#xyz.com"
'.*Your RubyEncoder profile password.*': ""
Above config handle response properly but same method is not working in ldap client installation.
I am using below playbook:
---
- hosts: test1
become: true
# remote_user: dagar
# sudo: yes
tasks:
- name: install ldap client packages
expect:
command: apt-get install ldap-utils libpam-ldapd libnss-ldapd nscd
responses:
'.*Do you want to continue?.*': ""
'.*LDAP server URI.*': "Ok"
'.*LDAP server search base.*': "Ok"
'.*Name servives to configure.*': "Ok"
'.*Restart services during package upgrades without asking?.*': "No"
'.*Services to restart to make them use the new libraries.*': "Ok"
Can anybody please help me on above issue.
Any help or guidance will be appriciated.
Thanks.
This accepted answer may help: How to do an initial setup of slapd OLC with ldapmodify
It uses slapd and a heredoc to define the answers for debconf-set-selections to consume.
I run a one line command to join nodes to ldap (assuming the packages are installed and relevant services started. I use nslcd)
authconfig --enableldapauth --ldapserver="ldapserver.example.com" --ldapbasedn="dc=example,dc=com" --update
So Ansible method would be:
- name: This command will join a node to an LDAP server
ansible.builtin.shell:
cmd: authconfig --enableldapauth --ldapserver="ldapserver.example.com" --ldapbasedn="dc=example,dc=com" --update
That should also update /etc/nsswitch.conf, but if not, you can always replace the file with ansible
I'm not sure how to do this with only ansible, but since you are already using expect for automating script responses you could use something like autohotkeys or sikuli to answer popups. You could have ansible run your expect script to answer the scripted responses and run the autohotkeys script to answer the popup. Or perhaps you can just modify whatever script you are running for the install in order to not make a popup.
You can see more info:
https://github.com/sikuli/sikuli
https://www.autohotkey.com/docs/Hotkeys.htm

yum database corruption check/fix module

I'm looking for an Ansible module to identify Red Hat or CentOS yum database errors for "rpmdb open failed"? I'm looking to proactively identify servers we patch regularly to know ahead of patching and report for us when this error occurs. And then have Ansible fix the error. Has anyone seen this type of module/fix?
Thank you.
Such a module does not exist, however you could use the list parameter for the yum module. It won't perform any task other than a yum list on the package you provide, and the result will be successful whether or not the package is installed, unless of course you run into an rpmdb error.
You will need to ignore errors and register the result, like so:
- yum:
list: kernel
ignore_errors: yes
register: result
- debug: var=result
The result variable will include failed=true, msg, and stderr, which together you should be able to use to identify an rpmdb error. Based on this identification, you can kick off a conditional shell task to fix the error.

Migrating ansible version 1.5.4 to latest ansible version

I have been using ansible 1.5.4 for 8 month. Yesterday I found that login_port of mysql_repilcation module is not supported in 1.5.4 version.
It is a bug in that version, but they supported in latest version (>= 1.8 I think). But I already have more than 50 ansible script running in 1.5.4
which has been used in production side
What is the best possible scenario:
If I move 1.5.4 to latest version , will it impact on any existing
ansible script
Is it possible to achieve the desire outout by shell command.
I am stuck in the middle of ocean. please help me to out of this
problem
If I move 1.5.4 to latest version , will it impact on any existing
ansible script
This highly depends on your playbook/roles, but I'm pretty sure it won't just work without changes. For example I read many times now that users have problems with sudo on role level:
- roles:
- role: whatever
sudo: yes
That was broken in 1.9.1. Officially it is fixed but I have read users have still problems. Generally sudo has been replaced with become. Even though the documentation claims sudo is still supported, it clearly isn't completely.
Another change I remember was related to ssh transport but you should only stumble about this issue if you reboot your host during play with Ansible.
I think the sudo/become change was the biggest one. If you want to avoid the hassle and do not necessarily need the very recent version you might just upgrade to a version before 1.9 and will have better chances of getting through without changes.
If you have the time though, I recommend you make your play compatible with the recent version. The Ansible 2.0 release is ahead and will introduce many new very useful features.
Is it possible to achieve the desire outout by shell command.
You mean to automatically convert your playbook/roles? No, not unless you find out exactly about the problems and write that script yourself. :)
I am stuck in the middle of ocean. please help me to out of this problem
Generally you should test every new version of Ansible on a testing/staging environment first. If you do not have testing hosts you can set up local VM's. There you can test and fix your play.
Since login_port of mysql_repilcation module is not supported in ansible 1.7 version. I found a way to achieve the result.
- name: "stop slaves of existing database server"
shell: >
mysql -uroot -p{{ mysql_exist_slave_database_password }} \
-P{{ default_port }} -h{{ default_host }} -e "stop slave" -s
- name: "Retrieve the Position and binary file number using slave
status"
shell: >
mysql -uroot -p{{ mysql_exist_slave_database_password }} \
-P{{ default_port }} -h{{ default_host }} -e "show slave
status\G" -s
register: output
- name: "start slaves of existing database server"
shell: >
mysql -uroot -p{{ mysql_exist_slave_database_password }} -P{{
default_port }} -h{{ default_host }} -e "start slave" -s

Resources