How to set condition for single option of ansible module alone - conditional-statements

Is that possible to set conditions for a single option of the ansible module.
Using set_fact we can set condition aand use that variable in the ansible module. Alternatively is there any other option to set the condition using if loop in jinja or something like that.
E.g:
- name: Simple PUT operation
s3:
bucket: mybucket
object: /my/desired/key.txt
src: /usr/local/myfile.txt
mode: put
I want to add s3_url option if it satifies the condition sample_var= myapp.If it doesnot satify it wont have to add s3_url
- name: Simple PUT operation
s3:
bucket: mybucket
object: /my/desired/key.txt
src: /usr/local/myfile.txt
mode: put
s3_url: "s3my url"------if it satisfies sample_var=myapp
How can i use jinja here when it satisfies my condition it needs to add this option to the ansible module?
Thanks in advance..

You may want to read about omitting parameters:
- name: Simple PUT operation
s3:
bucket: mybucket
object: /my/desired/key.txt
src: /usr/local/myfile.txt
mode: put
s3_url: "{{ 's3my_url' if sample_var == 'myapp' else omit }}"

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.

Ansible variable list span

When adding a variable list in Ansible how would one achieve a span of similar values? For instance "000-100" - in an Ansible hosts file this can be done by listing like so, "hostname-[a:v].com". Would this process be the similar in a variable list?
My use case is to provision many VM's within oVirt in a single go without having to make a line by line list.
---
- name: Create VM based on template
hosts: ovirt-engine
become: yes
become_method: sudo
vars:
- temp: '{{temp_fedora25}}'
- iname:
- db-aa
- db-ab
- db-ac
tasks:
- name: Giving Birth to lil Baby VM's
ovirt:
user: '{{ovirt_usr}}'
password: '{{ovirt_pass}}'
url: '{{engine_url}}'
instance_name: "{{item}}"
instance_nic: ovirtmgmt
resource_type: template
image: '{{temp}}'
zone: superblade-a
disk_alloc: preallocated
with_items: "{{iname}}"
You can use sequence lookup:
- name: numeric
debug:
msg: "{{ item }}"
with_sequence: start=1 count=10 format=server-%0d
- name: characters from small 'a'
debug:
msg: "{{ item }}"
with_sequence: start=0x61 count=10 format=server-%c
- name: save for future use
set_fact:
my_seq: "{{ lookup('sequence','start={} count={} format={}{}'.format(beg,cnt,pref,fmt),wantlist=True) }}"
vars:
beg: 1
cnt: 10
pref: host-
fmt: '%0d'
You can skip set_fact and define my_seq in vars section, but if you use my_seq much, list generation will be done internally every time. With set_fact list is generated once.
With respect to the correct answer from Konstantin, I'm adding the full solution as per my case....
My goal is to be able to reuse the sequenced values as registered variables in order to pass the instance name to host name. This works so far but Im sure it can be streamlined by nesting variables perhaps?
---
- name: Create VM based on template
hosts: ovirt-engine
become: yes
become_method: sudo
vars:
- temp: '{{temp_fedora25}}'
- host_pre: db
- host_seq: a%c
- host_cnt: 3
- host_srt: 0x61
tasks:
- name: Giving Birth to lil Baby VM's
ovirt:
user: '{{ovirt_usr}}'
password: '{{ovirt_pass}}'
url: '{{engine_url}}'
instance_name: "{{item}}"
instance_nic: ovirtmgmt
resource_type: template
image: '{{temp}}'
zone: superblade-a
disk_alloc: preallocated
with_sequence: start="{{host_srt}}" count="{{host_cnt}}" format="{{host_pre}}-{{host_seq}}"

Paste sensitive data the ansible way

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.

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.