Paste sensitive data the ansible way - passwords

Let's suppose i have some applications inside a repository. Sensitive data, like database username+password, are not stored inside the repository but are in a separate encrypted password database. Within the source code are only place-holders like this: %%mysqlpassword%%.
I want to create an ansible-playbook to checkout the code and replace the user-credentials.
I have two ideas to do so:
with a template or
with the replace module.
Is there a best practise way to accomplish this task?
---
- hosts: test
vars_prompt:
- name: "mysqlpassword"
prompt: "Enter mysql password for app"
private: yes
tasks:
- name: copy code from repo
subversion: repo=https://repo.url.local/app dest=/srv/www/app
- name: Replacement of sensitive data by templating
template: src=mysqlconnect.php.j2 dest=/srv/www/app/inc/mysqlconnect.php
- name: Replacement of sensitive data by replacement function
replace: dest=/srv/www/app/inc/mysqlconnect.php regexp='%%mysqlpassword%%' replace='{{ mysqlpassword }}'

The best answer to your question is use ansible-vault.
1- use mysqlpassword as variable {{ mysqlpassword }} inside your template mysqlconnect.php.j2
2- create separate file like my_very_secure.yml(whatever name you want) with all the values of your secure username and password:
---
mysqlpassword: very-secure-password-value
anothervariable: another-secure-value
After that you can encrypt this file with ansible-vault:
ansible-vault encrypt my_very_secure.yml
Then you can store this file into source control server because it's encrypted or leave it on the ansible master server, but once you are ready to run the playbook just include the --ask-vault-pass option like this and path to your secure file:
ansible-playbook -i yourhostfile yourplaybook.yml -e#/path-to-your-file/my_very_secure.yml --ask-vault-pass
Hope this will help you.

Related

Use dotted YAML variables file in Ansible

I'm trying to achieve the following using Ansible:
Define a YAML file with some variables in the dotted format inside it (variables.yml)
database.hosts[0]: "db0"
database.hosts[1]: "db1"
database.hosts[2]: "db2"
foo.bar: 1
foo.baz: 2
Load the variables in variables.yml by using the include_vars module in my playbook (playbook.yml) and print them in a tree structure
- hosts: all
gather_facts: not
tasks:
- name: "Loading vars"
run_once: true
include_vars:
file: 'variables.yml'
- name: "Testing"
debug:
msg: "{{ foo }}"
- name: "Testing"
debug:
msg: "{{ database }}"
Running this results in the following error:
fatal: [host0]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'foo' is undefined\n\nThe error appears to be in '.../playbook.yml': line 9, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: \"Testing\"\n ^ here\n"}
Which makes it clear that each property in the YAML file has been loaded as a separate property and not as properties within two trees rooted in database and foo.
Of course, the playbook works as expected if I specify the properties as follows:
database:
hosts:
- "db0"
- "db1"
- "db2"
foo:
bar: 1
baz: 2
However, I need the YAML variables file to be in the dotted format instead of in the classic indented format. Is there any way to achieve this? E.g.: a module different from include_vars or some configuration that I can add to the ansible.cfg file? I have already tried to use hash_behaviour=merge, but that didn't help.
Q: "I need the YAML variables file to be in the dotted format instead of in the classic indented format. Is there any way to achieve this?"
A: No. It's' not possible. See Creating valid variable names.

Hana Sap B1: Execute query using hdbuserstore - * 10: invalid username or password SQLSTATE: 28000

Actually I'm working in Hana DB and Suse Enterprise Server, my objective is use the Scripting and Cronjob to automatize some tasks.
Using hdbuserstore located in /usr/sap/hdbclient I've created and profile for create a HANA command line secure connection, check this link.
My profile works perfect, I did:
Create a user backup into HanaDB, using
*create user backup password Aa12345678*
Then, I've added BACKUPS PRIVILEGES to it:
*grant BACKUP ADMIN to backup*
Later, I've used ./hdbuserstore to create a profile to use via command line:
./hdbuserstore SET back5prf localhost:30015 backup Aa12345678
Then list the profile: ./hdbuserstore LIST
DATA FILE : /root/.hdb/hanab1/SSFS_HDB.DAT
KEY BACK2PRF
ENV : NDB#hanab1:30015
USER: backups
KEY BACK3PRF
ENV : hanab1:30015
USER: backups
KEY BACK5PRF
ENV : localhost:30015
USER: backup
KEY BACKUPSTORE
ENV : localhost:30015
USER: backups
How you guys can see, the profile is ready. Finally when I tried to use the following command:
./hdbsql -U BACK5PRF "SELECT * FROM SCHEMAS"
The system returns the following message:
* 10: invalid username or password SQLSTATE: 28000
Why I'm getting this error event the user and password are ok?
There is other way to execute HANA SQL query without enter into the hdbsql console to automate via Scripting?
This error message can have several causes:
actual wrong user name/password
user account is locked (you need to unlock it in the user management)
user account is a restricted user and not allowed to connect via ODBC/JDBC or from anywhere "outside" SAP HANA
I suggest you make sure that the user works in SAP HANA studio and then setup the cron job.
I had the same issue, the cause was that I used a $ in my password which gets treated as special character in linux (and there more special characters).
So in this case one solution is not to use any character that a treated as special characters or to escape them which in my case resulted the following command for hdbuserstore:
hdbuserstore SET BKADMIN 1xx.x.x.xx:30015 ADMIN_BACKUP password\$12
Check the thread on answer.sap.com.

How to read the connection string from a file in fitnesse?

I want to test different queries, in fitnesse using dbfit, on a table present in different environment. Each environment has a different connection string. So instead of creating multiple pages for each environment(which is again a tedious task since each time a single change in the query may lead to change in all the test pages), I would like to store the connection string in a single file(may be text or excel sheet) and read the connection string out of it according to the requirement.
Can anyone help me out on how to proceed?
I'm not sure if the following is perfect fit for your requirements but I have an own "configuration" page for each database. Then I simply include the configuration page in the each of the test pages:
!include -c .DbFitSetup.UseDbX
You can switch the database during the test simply by including new configuration as the example below demonstrates:
user272735#dev:~/test/FitNesseRoot$ cat DbFitSetup/UseDbX/content.txt
!path lib/*.jar
!|dbfit.OracleTest|
!|Connect|dbx.example.com:1531|<username>|<password>|dbx|
user272735#dev:~/test/FitNesseRoot$ cat DbFitSetup/UseDbY/content.txt
!path lib/*.jar
!|dbfit.OracleTest|
!|Connect|dby.example.com:1531|<username>|<password>|dby|
user272735#dev:~/test/FitNesseRoot$ cat ExampleTestSuite/ExampleTest/content.txt
!include -c .DbFitSetup.UseDbX
!|inspect query|select sysdate, global_name as db_name from global_name|
!include -c .DbFitSetup.UseDbY
!|inspect query|select sysdate, global_name as db_name from global_name|
user272735#dev:~/test/FitNesseRoot$

Remove quotes from Ansible variable output

I'm using this task to add a line to a file:
lineinfile: "dest={{ ansible_env.HOME }}/{{ deploy_dir }}/config/deploy/{{ stage_name }}.rb
insertbefore='# role-based syntax'
line='server "'{{ ip_addr }}'", user: "'{{ user_name }}'", roles: %w{'{{ role }}'}'"
Which adds this line:
server '172.16.8.11', user: 'vagrant', roles: %w{'api'}
But I don't want the quotes around api. Instead I want this output:
server '172.16.8.11', user: 'vagrant', roles: %w{api}
Actually the quotes do not come from the variable, but are right there in your string:
%w{'{{ role }}'}
Now the solution is little bit tricky though. Because you can not simply remove the quotes like that:
%w{{{ role }}}
This would result into a parse error, since {{ starts an expression...
The solution is to write the outer parentheses, which are meant to be in the string, as an expression themselves.
So to output { you would instead write {{'{'}} and instead of } you would write {{'}'}}. Does that make sense? You're instructing the template engine (Jinja2) to output the parentheses to avoid the parsing error:
%w{{'{'}}{{ role }}{{'}'}}
But since role is an expression already, you just also can group it together into one single expression:
%w{{ '{'+role+'}' }}
Your whole task would then read like this:
- lineinfile:
dest: "{{ ansible_env.HOME }}/{{ deploy_dir }}/config/deploy/{{ stage_name }}.rb"
insertbefore: "# role-based syntax"
line: "server '{{ ip_addr }}', user: '{{ user_name }}', roles: %w{{ '{'+role+'}' }}"
This also is converted into proper YAML syntax because this quoted k=v format is just really hard to read. :)

ansible playbook of playbooks with variables

I'm not even sure if this is possible..
I know you can have a playbook that calls other playbooks..
IE:
---
# MasterPlaybook.yml
- include: playbook1.yml
when: some_var == "true"
- include: playbook2.yml
when: someother_var == "true"
and this will work if I call MasterPlaybook.yml and pass in the Vars..
BUT I want to include the vars from some other yml
for example here is myvars.yml
some_var: "true"
someother_var: "false"
Other_var: "Foo"
So if I want this included in a playbook1.yml I simply add..
---
- name: Script Play use variables to get and push out the code
hosts: somegroup
remote_user: "some user"
vars:
url: 'The url of the build'
buildNumber: 'the build number'
jobName: 'passed in job name'
vars_files:
- ~/myvars.yml
serial: 1
and it will pull in the vars..
My question is how do I do this in the masterplaybook.yml so that I don't have to pass in the vars?
and while we are at it.. are there any good examples of a master playbook? (or a playbook of playbooks)
You can specify vars as part of the include statements. This is what I do for some of my projects.
---
- include: playbook1.yml
vars:
some_var: "true"
someother_var: "false"
Other_var: "Foo"
when: some_var == "true"
- include: playbook2.yml
when: someother_var == "true"
Have a look at roles in ansible. They are a more structured way for the "playbook of playbooks" concept. There you can define global variables in the "master" playbook and variables within the sub-playbooks http://docs.ansible.com/playbooks_roles.html.
You can also have a look at the example playbooks to see how roles are used and structured.