ansiblefest 2014 - role tips and tricks

Post on 29-Nov-2014

2.071 Views

Category:

Engineering

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

My presentation on Role Tips & Tricks from AnsibleFest San Francisco, 2014.

TRANSCRIPT

WRITING ROLES: TIPS & TRICKSJames Cammarata

(github: jimi-c)

ABOUT MESTL Native, previously worked for Savvis/CenturyLink and

Scottrade

Started contributing to Cobbler in September of 2008, and tookover the project leadership in 2010

Joined Ansible in July, 2013

WHAT ARE ROLES?

GETTING STARTED

CREATING THE INITIAL ROLE LAYOUT

BAD!$ mkdir -p roles/myrole/{tasks,vars}$ touch roles/myrole/{tasks,vars}/main.yml

This is a very manual process, and completely unnecessary...

A MUCH BETTER WAY ™$ ansible-galaxy init roles/myrole

Benefits include:

Creates ALL of the directory structure for youStubs out some of the YAML files like `meta/main.yml`

USING ROLE DEPENDENCIES

SPECIFYING DEPENDENCIES IN METADATADependencies are specified in the `meta/main.yml` role file:

dependencies: - foo - { role: foo } - { role: /path/to/some/dir/bar } - { role: bam, some_var: "hello world!" }

TAGS & CONDITIONALS WITH ROLE DEPENDENCIES

When applying a tag or conditional statemtent to a roledefinition, they are appended to those specified on any tasks

within the role. For example:

# main yaml fileroles:- { role: foo, tags: 'foo', when: some_var == 'foo' }

# roles/foo/meta/main.ymldependencies:- { role: bar }

All tasks defined within 'bar' will also have the above tags and'when' statement applied to them, in addition to any other tags or

conditionals defined on the task.

CROSS-PLATFORM ROLESTIPS & TRICKS

USE GATHERED FACTS + INCLUDE TO TARGETPLATFORMS

# apache/tasks/main.yml- include: redhat.yml when: ansible_os_family == 'RedHat'- include: debian.yml when: ansible_os_family == 'Debian'

# apache/tasks/redhat.yml- name: install apache packages yum: name=httpd state=present

# apache/tasks/debian.yml- name: install apache packages apt: name=apache2 state=present

HANDLERS AND SERVICE NAME DIFFERENCESLets use the same method of conditional includes for handlers!

Results...

WHY DOESN'T THIS WORK?1. Handler names in Ansible must be unique.2. Included files are always read and parsed at load time, BUT the

conditionals are not evaluated until the task is executed...3. Result - the last handler defined with the name "wins", and the

wrong handler may be run.

THE SOLUTION: SET_FACT# apache/tasks/redhat.yml- name: install apache packages yum: name=httpd state=present- name: set the name of the service set_fact: apache_service_name=httpd

# apache/tasks/debian.yml- name: install apache packages apt: name=apache2 state=present- name: set the name of the service set_fact: apache_service_name=apache2

# apache/handlers/main.yml- name: restart apache service service: name={{apache_service_name}} state=restarted

DEALING WITH OTHER DIFFERENCES

We can use set_fact again in the platform-specific includes:

# apache/tasks/redhat.yml- name: set variables for this OS set_fact: apache_service_name: httpd apache_user: apache apache_httpd_conf_path: /etc/httpd/conf/httpd.conf apache_httpd_confd_path: /etc/httpd/conf.d ...

# apache/tasks/debian.yml- name: set the name of the service set_fact: apache_service_name: apache2 apache_user: www-data apache_httpd_conf_path: /etc/apache2/apache2.conf apache_httpd_confd_path: /etc/apache2/conf-available ...

And in our updated common tasks/main.yml:

# apache/tasks/main.yml# (continued)- name: deploy apache configuration template: src: httpd.conf.j2 dest: "{{apache_httpd_conf_path}}" owner: "{{apache_user}}" mode: "0640" notify: restart apache service

- name: make sure service is running and enabled service: name: "{{apache_service_name}}" state: running enabled: yes

ALTERNATIVE METHOD FOR VARIABLES

It is possible to use the include_vars and with_first_found lookupto include the distro-specific variables file, and to fall back to a

default set of variables:

# apache/tasks/main.yml- include_vars: "{{ item }}" with_first_found: - "{{ ansible_os_family }}.yml" - "default.yml"

GALAXY BEST PRACTICES

CREATING ACCURATE METADATA

When you use the ansible-galaxy CLI command to init a new role,a sample meta/main.yml is automatically created for you:

---galaxy_info: author: your name description: company: your company (optional) license: BSD min_ansible_version: 1.2 #platforms: #- name: EL # versions: # - all # - 5 # - 6 # - 7 ... #categories: #- cloud ... #- webdependencies: []

LISTING SANE DEPENDENCIESDependencies listed in the metadata should only point to other

Galaxy roles.

STEPS TO ADD YOUR ROLE TO GITHUB

AFTER CREATING YOUR REPO ON GITHUB:$ ansible-galaxy init foo$ cd foo/$ git init-(edit your files here)-$ git add *$ git commit -m "initial commit for my role"$ git remote add origin https://github.com/yourname/your-ansible-role$ git push origin master

QUESTIONS?

THANKS!

top related