master_hemant
master_hemant

Reputation: 43

Where i can put common variable outside playbook in ansible

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

  1. Security reason like username and password
  2. To reduce the repetitive code by using putting global variabble at common place and loc of playbook.

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

Answers (4)

Paul Hodges
Paul Hodges

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

David
David

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

krystan honour
krystan honour

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

Chen A.
Chen A.

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

Related Questions