ansiblefest 2014 - role tips and tricks

31
WRITING ROLES: TIPS & TRICKS James Cammarata (github: jimi-c)

Upload: jimi-c

Post on 29-Nov-2014

2.071 views

Category:

Engineering


5 download

DESCRIPTION

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

TRANSCRIPT

Page 1: AnsibleFest 2014 - Role Tips and Tricks

WRITING ROLES: TIPS & TRICKSJames Cammarata

(github: jimi-c)

Page 2: AnsibleFest 2014 - Role Tips and Tricks

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

Page 3: AnsibleFest 2014 - Role Tips and Tricks

WHAT ARE ROLES?

Page 4: AnsibleFest 2014 - Role Tips and Tricks

GETTING STARTED

Page 5: AnsibleFest 2014 - Role Tips and Tricks

CREATING THE INITIAL ROLE LAYOUT

Page 6: AnsibleFest 2014 - Role Tips and Tricks

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

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

Page 7: AnsibleFest 2014 - Role Tips and Tricks

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`

Page 8: AnsibleFest 2014 - Role Tips and Tricks

USING ROLE DEPENDENCIES

Page 9: AnsibleFest 2014 - Role Tips and Tricks

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!" }

Page 10: AnsibleFest 2014 - Role Tips and Tricks

TAGS & CONDITIONALS WITH ROLE DEPENDENCIES

Page 11: AnsibleFest 2014 - Role Tips and Tricks

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.

Page 12: AnsibleFest 2014 - Role Tips and Tricks

CROSS-PLATFORM ROLESTIPS & TRICKS

Page 13: AnsibleFest 2014 - Role Tips and Tricks

USE GATHERED FACTS + INCLUDE TO TARGETPLATFORMS

Page 14: AnsibleFest 2014 - Role Tips and Tricks

# 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

Page 15: AnsibleFest 2014 - Role Tips and Tricks

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

Page 16: AnsibleFest 2014 - Role Tips and Tricks

Results...

Page 17: AnsibleFest 2014 - Role Tips and Tricks

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.

Page 18: AnsibleFest 2014 - Role Tips and Tricks

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

Page 19: AnsibleFest 2014 - Role Tips and Tricks

DEALING WITH OTHER DIFFERENCES

Page 20: AnsibleFest 2014 - Role Tips and Tricks

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 ...

Page 21: AnsibleFest 2014 - Role Tips and Tricks

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

Page 22: AnsibleFest 2014 - Role Tips and Tricks

ALTERNATIVE METHOD FOR VARIABLES

Page 23: AnsibleFest 2014 - Role Tips and Tricks

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"

Page 24: AnsibleFest 2014 - Role Tips and Tricks

GALAXY BEST PRACTICES

Page 25: AnsibleFest 2014 - Role Tips and Tricks

CREATING ACCURATE METADATA

Page 26: AnsibleFest 2014 - Role Tips and Tricks

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: []

Page 27: AnsibleFest 2014 - Role Tips and Tricks

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

Galaxy roles.

Page 28: AnsibleFest 2014 - Role Tips and Tricks

STEPS TO ADD YOUR ROLE TO GITHUB

Page 29: AnsibleFest 2014 - Role Tips and Tricks

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

Page 30: AnsibleFest 2014 - Role Tips and Tricks

QUESTIONS?

Page 31: AnsibleFest 2014 - Role Tips and Tricks

THANKS!