ansible

The Show

Automation for everyone

Created by Paweł 'Srebrny' Srebniak / @srebrny_dev

@srebrny_dev

Who I am

Down arrow

Developer with 10 year in PHP ecosystem

Python developer

3 years experience as backend developer

DevOps (1 year) Sys admin (4 years)


Directory structure

I use advenced directory structure

See more at best practices.

Directory structure

                    
inventories/
    production/
        hosts    # inventory file for production servers
        group_vars/
        host_vars/
    ...
library/
filter_plugins/

roles/
    common/
    application/
    ...

deploy_front.yml
                    
                

Inventory


hosts               # inventory file for production servers
group_vars/
    group1           # here we assign variables to particular groups
    group2           # ""
host_vars/
    hostname1        # if systems need specific variables, put them here
    hostname2        # ""
                    

Directory structure

library required for custom modules, eg. do-cli, openstack_ext


                    library/ # (optional)
                     

Directory structure

Put here custom filter for filter inventories. see: do-json-inventory.py


                filter_plugins/ # if any custom filter plugins, put them here (optional)
                

Directory structure

Every roles goes into new directory.

                    
roles/
    common/
    webtier/
    monitoring/
    fooapp/
                    
                

Directory structure

Playbooks names should describe what playbook do!

site.yml

webservers.yml

dbservers.yml

deploy_tools.yml

secure_new_host.yml

deploy_tools.yml

update_balancer_nodes.yml

Role directory structure

                    
        tasks/
            main.yml    # tasks file can include smaller files if warranted
        handlers/
            main.yml    # handlers file notification, restart nginx
        templates/      # files for use with the template resource
        files/          # place here files for uploads
        vars/
            main.yml    # variables associated with this role
        defaults/
            main.yml    # default lower priority variables
        meta/
            main.yml    # role dependencies
        library/        # roles can also include custom modules
        lookup_plugins/ # or other types of plugins
                
                

Variables

Before we start using variables it’s important to know what are valid variable names.

Variable names should be letters, numbers, and underscores. Variables should always start with a letter.

foo-port, foo port, foo.port, 12foo_port, as

foo_port, field1, lbs_balancer_ports

Inventories

Ansible works against multiple systems in your infrastructure at the same time.

Inventories is a standard ini file!

Inventories

Hosts can be grouped


    mail.example.com

    [webservers]
    foo.example.com
    bar.example.com

    [dbservers]
    one.example.com
    two.example.com
    three.example.com
                

Host in inventory

Specific configuration like port, host name or ip

jumper ansible_port=5555 ansible_host=192.0.2.50

Adding a lot of hosts?

Ta dam!

whp[01:50].jupiter.pycode.biz

or

dbs[01:50].node-[a:f].akka.pycode.biz

Group Variables

Variables can also be applied to an entire group at once:


[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.akka.pycode.biz
proxy=proxy.akka.pycode.biz
                

Groups of Groups, and Group Variables

It is also possible to make groups of groups using the :children suffix you can apply variables using :vars:


[atlanta]
host1
host2

[raleigh]
host2
host3

                

Groups of Groups, and Group Variables

It is also possible to make groups of groups using the :children suffix you can apply variables using :vars:


                [southeast:children]
                atlanta
                raleigh
                

Groups of Groups, and Group Variables

It is also possible to make groups of groups using the :children suffix you can apply variables using :vars:


                    [southeast:vars]
                    some_server=whp0.node-a.akka.pycode.biz
                    halon_system_timeout=30
                    self_destruct_countdown=60
                    escape_pods=2

                    [usa:children]
                    southeast
                    northeast
             

Ansible ad hoc command

Just run command without playbook

Simple ad hoc command

Use module ping on all hosts as user bruce

$ ansible all -m ping -u bruce

File Transfer

Transfer a file directly to many servers

                    
                        $ ansible whp-all.node-a.akka.pycode.biz \
                        $ -m copy -a "src=/etc/hosts dest=/tmp/hosts"
                    
                
                    
                        # part of hosts
                        [whp-all.node-a.akka.pycode.biz]
                        whp[01:50].node-[a:f].akka.pycode.biz
                    
                

Update

Transfer a file directly to many servers

                    
                        $ ansible whp-all.node-a.akka.pycode.biz \
                        $ -m copy -a "src=/etc/hosts dest=/tmp/hosts"
                    
                
                    
                        # part of hosts
                        [whp-all.node-a.akka.pycode.biz]
                        whp[01:50].node-[a:f].akka.pycode.biz
                    
                

Install packages on all servers

Transfer a file directly to many servers

                    
                        $ ansible whp-all.jupiter.pycode.biz -m yum \
                        $   -a "name=nginx state=latest"
                    
                
                    
                        # part of hosts
                        [whp-all.jupiter.pycode.biz]
                        whp[01:50].jupiter.pycode.biz
                    
                

Ansible playbook - examples

Copying files in playbook

Generate template

Generate proxy config for all host in group proxy.node-a.akka.pycode.biz


- name: Update nginx configuration
  template:
    src: "roles/nginx_stream/templates/nginx.conf.j2"
    dest: "/etc/nginx/sites-available/{{inventory_hostname}}"
    owner: "{{ AKKA_USER_NAME }}"
    group: "{{ AKKA_GROUP_NAME }}"
    mode: '0600'
  become: yes
  become_user:  "{{ AKKA_USER_NAME }}"
  become_method: "sudo"
  tags: [nginx_proxy]
                

Copy file

Transfer a file directly to many servers

                    
- name: Copying file into server
  copy:
    src: "roles/open_stack/templates/rootwrap.conf.j2"
    dest: /etc/cinder/rootwrap.conf
    owner: foo
    group: foo
    mode: "u=rw,g=r,o=r"
  tags:
    - openstack_blockstorage
                    
                
                    
[DEFAULT]
rootwrap_config=/etc/cinder/rootwrap.conf
sql_connection = mysql://cinder:openstack@198.168.xxx.yyy/cinder
api_paste_config = /etc/cinder/api-paste.ini
                    
                

More info about modules

Copy & Template

Tags

If you have a large playbook it may become useful to be able to run a specific part of the configuration without running the whole playbook.

Example playbook

Set two tags packages and configuration

                    
                      tasks:
                        - yum: name={{ item }} state=installed
                          with_items:
                             - httpd
                             - memcached
                          tags:
                             - packages

                        - template: src=templates/src.j2 dest=/etc/foo.conf
                          tags:
                             - configuration
                    
                

Limit playbook with tags

We can run specific playbook with only job tagged as configuration and packages!

                    
                        $ ansible-playbook deploy_server_proxy.yml \
                        $     --tags "configuration,packages"
                    
                

Skipping tags

We can skip tag!

                    
                        $ ansible-playbook deploy_server_proxy.yml
                        $    --skip-tags "notification"
                    
                

Tag a role

Add role tag

                    
roles:
  - { role: webserver, port: 5000, tags: [ 'web', 'foo' ] }
                    
                

galaxy.ansible.com

Playbook repository

Down arrow

Instalation of role

How install a new roles

                    
                        $ ansible-galaxy install username.rolename
                    
                

Instalation of nginx role

Install nginx role from user jdauphant

                    
                        $ ansible-galaxy install jdauphant.nginx
                    
                

Questions?

Links