Reputation: 43
I am using playboooks to run my modules. i have a doubt, whether i can put my common variables outside playbook due to following reasons
Right now my playbook looks like some thing below:
- hosts: localhost
tasks:
- name: Get all Storage Service Levels
StorageServiceLevelModule: host=<ip> port=<port> user=admin password=<password>
action=get name='my_ssl'
register: jsonResultforSSLs
- name: print the SSL key
debug: msg="{{ jsonResultforSSLs.meta.result.records[0].key}}"
- name: Get all Storage VMs
StorageVMModule: host=<ip> port=<port> user=admin password=<password>
action=get name=my_svm
register: jsonResultforSVMs
I want to put
host=<ip> port=<port> user=admin password=<password>
outside playbook and use it in all tasks of my playbooks. How can I do this ?
Please let me know if any clarification is required.
Upvotes: 2
Views: 4071
Reputation: 15273
To second Vinny -
Roles. Roles, roles, roles.
The default structure for roles includes a defaults
directory in which you can define default values in defaults/main.yml
. This is about the lowest priority setting you can use, so I like it better than vars/main.yml
for setting reasonable values that can be easily overridden at runtime, but as long as you pick a consistent structure you're good.
I don't personally like the idea of a "common" role just for variables everything uses, but if your design works well with that, you should be sure to prefix all the variable names with "virtual namespace" strings. for example, don't call it repo
, call it common_git_repo
or common_artifactory
, or something more specific if you can.
Once you include that role in a playbook, make certain the default file is statically loaded before the values are called, but if it is you don't have to worry so much about it. Just use your {{ common_git_repo }}
where you need it. It will be there...which is why you want to use virtual namespacing to avoid collisions with effectively global names.
When you need to override values, you can stage them accordingly. We write playbook-specific overrides of role defaults in the vars:
section of a playbook, and then dynamically write last-minute overrides into a Custom.yml
file that gets loaded in the vars_files:
section. Watch your security, but it's very flexible.
We also write variables right into the inventory. If you use a dynamic inventory you can embed host- and/or group-specific variables there. This works very well. For the record, you can use YAML output instead of JSON. Here's a simplistic template - we sometimes use the shell script that runs the ansible as the inventory:
case $# in
0) # execute the playbook
ansible-playbook -i Jenkins.sh -vv site.yml
;;
*) case $1 in
# ansible-playbook will call the script with --list for hosts
--list)
printf "%s\n\n" ---
for group in someGroup otherGroup admin managed each all
do printf "\n$group:\n hosts:\n"
for s in $Servers
do printf " - $s\n"
done
printf " vars:\n"
printf " ansible_ssh_user: \"$USER\"\n"
printf " ansible_ssh_pass: \"$PSWD\"\n\n"
done
;;
esac
;;
esac
You can also use --extra-vars
as a last-minute, highest-priority override.
Upvotes: 0
Reputation: 291
You can specify your own variables to all or certain hosts in the Inventory file or in the sub-directories related to it (like ./group_vars
). Go to this webpage. There you can see an example of a file in that directory, which must have the name of a group and be written in yaml). The ./group_vars
directory must be in the same directory of your hosts file. For example, if your hosts file is in ./inventory/hosts
, then the files with variables should be ./inventory/group_vars/<group_name>
. Keep in mind that the variables defined in those files will only apply to the members of the group. Example of the content of a file in that directory:
---
ip=1.1.1.1
port=420
password='password1' # should be encrypted with Ansible Vault
...
And then you would use them like normally:
- name: Get all Storage VMs
StorageVMModule: host='{{ip}}' port='{{port}}' user=admin action=get name=my_svm
register: jsonResultforSVMs
Upvotes: 2
Reputation: 6793
To specify things as you describe you'd be best using a secret store for your secrets so something like hashicorp vault but luckily ansible also has a way of encrypting secret information called Ansible vault, which operates at a file level.
What you should never do is put secrets in plain text files then commit them to a source control system. Ansible vault will encrypt stuff to get around this.
Ansible vault isn't complicated but has very good documentation here
You can create a new encrypted file like this:
ansible-vault create filename.yml
You can edit the file with this:
ansible-vault edit filename.yml
You can encrypt an unencrypted file like this:
ansible-vault encrypt filename.yml
You can decrypt with ansible-vault decrypt
You can then use these in playbooks and commit to src control with them protected.
Another approach is to store it in an external secret store (vault) then export to environmental variables. Then read in the environmental variables and assign to ansible variables. This way nothing ever goes into source control at all, this is my preferred approach.
That's secrets taken care of.
For common structures you can use group_vars and set different values for different roles this is explained here
Upvotes: 0
Reputation: 11280
variables
can be loaded in different ways. You can define a file named all
inside vars/
directory, and these are available through the whole playbook.
Also, you can define it in a file and provide it when execution the playbook with -e @filename
. I found this most convinient way.
Check this link from the docs, I think you might find it very useful
I strongly suggest you to use roles. There, in each role you have a vars
folder where you can put relevant variables to the role. Then, you can provide their values using the OS environment variables.
Upvotes: 0