Thursday, March 11, 2021

Ansible - Managing variables and Facts

 Managing variables and Facts
- Working with variable is very userful in ansible.
- You can define variables and also provided in ansible facts

Lets look at an example

$ cat user.yaml
---    # this line is also optional
- name: Create a user using a variable
  hosts: all
  vars:
    user: jay
  tasks:
    - name: create a user {{ user }}    # note double curly braces and sapce
      user:                # We are using user module
        name: "{{ user }}"        # and call variable user.


now, execute this yaml file

$ ansible-playbook user.yaml

carefully look at the output

you see variable is replaced with value

Now, lets talk about different kind of variable, ansible facts

ansible facts are properties of the managed host
lets run ansible with set up module

$ ansible all -m setup
here you see fact gathering results
- lots of parameters

go to ansible facts section and review it
- you see ipv4 addresses, ipv6 info
- architecture, date time, ansible commandline
- ansible devices, properties of devices

lets create a yaml about facts

$ cat facts.yaml
---
- name: show facts
  hosts: all
  tasks:
    - name: print facts
      debug:
        var: ansible_facts

lets run it,
$ ap facts.yaml

you see lots of facts, this play book is basically helping us for fact gathering.
- it is storing the facts in variables.
- it is using debug module to show the content of the variable.
- You see lots of variables, so lets go to parcular one.

$ cat findip.yaml
---
-  hosts: all
   tasks
   - name: show IP address
     debug:     # we have debug module. In debug, we display message
       msg: >
          this hosts uses IP address {{ ansible_facts.default_ipv4.address }}    # this is the message output

lets run it now,
$ ap findip.yaml

now, you see ip address of respective hosts.
What is the usecase of ansible facts
- we are not going to use itself even its easy to display the facts
- ansible facts are going to be use in conditional.

Variables can be provided in multiple ways
- you can include them,
- you can include files,
- you can also connect variables to hosts files.
- You can use inventory file to include variables, but not recommended anymore.

lets review this configuration
- you can create directory vars within your project/workspace directory.
- Group_vars are connected to hosts group .
- Vars are variables assigned to specific hosts.

$ mkdir group_vars; cd group_vars
$ cat lamps
web_package: httpd
web_service: httpd

now, lets update our inventory file

$ cd ..
$ vi hosts
control
ansible1
ansible2

[lamp]  # group them together
ansible1
ansible3

so we have a group lamp with two hosts

lets create a yaml config file to create a web page

$ cat website.yaml
---
- name: configure web services
  hosts: lamp    # our hosts where this job is going to be executed
  task:        # list of tasks
    - name: This is the {{ web_package }} package
      debug:    # debug module display message, so you will know what is going on
        msg: "Installing {{ web_package }}"
    - name: This is the {{ web_service }}  service
      debug:
        msg: "Starting {{ web_service }}"

lets run it

$ ap website.yaml

you can see what is going on with displayed messages

it shows are variables are coming from group_vars directory.

it is not always good idea to have variable in plain text if the information is sensetive.
for eg, password

for this we use ansible vault

Ansible vault
- ansible vault allow you to encript the variable
- we use ansible-vault command to create it

lets take a look by creating it.
here, secret.yaml file is going to be our secret file where we encript our variable
$ ansible-vault create secret.yaml
propmpts for password

username: jay
mypass: password

$ cat secret.yaml
you see encripted message.

lets create a yaml file which helps us to create user with secret password

$ cat create-user.yaml
---
- name: create user
  hosts: all
  vars_files:    # we have reference to var file
    - secret.yaml
  tasks:
    - name: creating user
      user:
        name: "{{ username }}"
        passwd: "{{ mypass }}"

lets run it now
$ ap create-user.yaml

got an error says no vault secret found

what we have to do is to ask ansible vault password since its not able to decrept it.
since this is encripted content, we need to supply password

$ ap --ask-vault-pass create-user.yaml

now, its working .. creating user.

now, verify using ansible ad-hoc command

$ ansible all -m command  "grep jay /etc/shadow"

look at the output, you see the password in plaintext. it should be encripted
its just a string, we will discuss later how to hash it out.

you can keep vault passowd in plain text at root directory with readonly to root

$ echo passwd > vault_pass
$ ap --vault-passwd-file=vault-pass create-user.yaml

it will not prompt you password anymore

this is how you can use secret for sensible data,


Variables
different kind of variables

built-in variables (only limited variables are available)
- groups  (host group)
- hostvars

- you can not over write built-in variables

variable priority
- generic to most specific
- most specific higher priority

you can supply variable in command (cmd)
-> cmd: -e key-value -> always highest priority
-> playbook variables
-> inventory variables


ansible roles
- default variables
- variables variables (variables in variable section)

- these default variables can be overwrite by playbook variables
- variables variable has more priority then playbook variables and
  these variables can be overwriteen by command line variables.

lets look at an example how priority and variables are relevent

$ ansible-playbook website.yaml

lets try again with this play
$ ap website.yaml -e "web_package=apache"
so it has higher priority

so, lets put this variable in playbook


$ cat website.yaml
---
- name: configure web services
  hosts: lamp    
  vars:
    web_packages: nginx
  task:        
    - name: This is the {{ web_package }} package
      debug:    
        msg: "Installing {{ web_package }}"
    - name: This is the {{ web_service }}  service
      debug:
        msg: "Starting {{ web_service }}"


$ ap website.yaml

we see, playbook overwrites the host_group variables

now run with -e
$ ap website.yaml -e "web package=apache"
see the output, command line has higher priority

so command line variable has higher priority, so for higher priority, specify in command line.
second priority, specify in playbook
3rd highest priority specify in host variables


Variables are little confusing, lets google for best practice

"ansible best practices"
- it will basically guides you how to organize stuffs, such as
  - Directory layout
  - Dynamic Inventory
  - Group and host variables and much more

Lets click on directory layout, you will see an example.

at the example, you see


production        # inventory file for production servers
staging            # inventory file for staging environment

group_vars/
   group1.yml                 # here we assign variables to particular groups
   group2.yml
host_vars/
   hostname1.yml        # here we assign variables to particular systems
   hostname2.yml

library/             # if any custom modules, put them here (optional)
module_utils/         # if any custom module_utils to support modules, put them here (optional)
filter_plugins/        # if any custom filter plugins, put them here (optional)

site.yml             # master playbook
webservers.yml     # playbook for webserver tier
dbservers.yml             # playbook for dbserver tier

roles/
    common/               # this hierarchy represents a "role"
        tasks/            #
            main.yml      #  <-- tasks file can include smaller files if warranted
        handlers/         #
            main.yml      #  <-- handlers file
        templates/        #  <-- files for use with the template resource
            ntp.conf.j2   #  <------- templates end in .j2
        files/            #
            bar.txt       #  <-- files for use with the copy resource
            foo.sh        #  <-- script files for use with the script resource
        vars/             #
            main.yml      #  <-- variables associated with this role
        defaults/         #
            main.yml      #  <-- default lower priority variables for this role
        meta/             #
            main.yml      #  <-- role dependencies
        library/          # roles can also include custom modules
        module_utils/     # roles can also include custom module_utils
        lookup_plugins/   # or other types of plugins, like lookup in this case

    webtier/              # same kind of structure as "common" was above, done for the webtier role
    monitoring/           # ""
    fooapp/               # ""












No comments:

Post a Comment

Git branch show detached HEAD

  Git branch show detached HEAD 1. List your branch $ git branch * (HEAD detached at f219e03)   00 2. Run re-set hard $ git reset --hard 3. ...