Building native packages the ansible way

aka meet samu

Features

  • simple. Configuration is done via yaml files.
  • modular. New inputs or outputs can be added writing ansible playbooks.
  • scalable. Can be used for large number of components.
  • convention over configuration.

Arquitecture

Files

├── group_vars
│   ├── all
│   ├── backend-daemon
│   ├── common-web
│   ├── languages
│   ├── web-modules
│   └── web-themes
├── inventory
├── main.yml
└── roles
    └── packaging
        ├── defaults
        │   └── main.yml
        └── tasks
            ├── artifact.yml
            ├── deb.yml
            ├── git.yml
            ├── main.yml
            ├── pkg-conffiles.yml
            ├── pkg-scripts.yml
            └── svn.yml

Data Levels

  • Global
  • Common 
  • Component

Global

group_vars/all

Files:

Global

# package metadata
pkg_vendor: ACME
pkg_license: Apache Licence
pkg_maintainer: <release-team@acme.com>

# fpm temp dir
pkg_tmp_dir: /var/tmp/fpm

# roles/packaging/tasks/pkg-scripts.yml
init_scripts_rootdir: /home/local/git/pkg-scripts/
pkg_scripts_setup: false
pkg_script_opts: --template-scripts
pkg_script_files_opt: { preinst: '--before-install', postinst: '--after-install ', prerm: '--before-remove ', postrm: '--after-remove ' }
fpm_pkg_opts:
# roles/packaging/tasks/pkg-conffiles.yml
pkg_conffiles_setup: false
pkg_conffiles_etcdir: /etc
fpm_scripts_opts:

Common

group_vars/common-*

Examples:
# for components web-themes, web-modules:
group_vars/common-web 
group_vars/common-backend

Files:

Common

pkg:
  rpm:
    base_prefix : /home/httpd/www.acme.com
    user: "--rpm-user httpd"
    group: "--deb-group httpd"
  deb:
    base_prefix : /var/www/www.acme.com
    user: "--deb-user www-data"
    group: "--deb-group www-data"

Component

group_vars/web-themes
group_vars/web-modules
group_vars/languages
group_vars/backend-daemon

Files:

Component

# group_vars/web-frontend
component_input: github

# group_vars/web-translations
component_input: gitlab
#group_vars/input-main_jfrog
jfrog_admin_user: admin
jfrog_admin_password: secret
jfrog_url: jfrog.acme.com.ar/artifactory/simple
input_type: artifact
# group_vars/input-gitlab
input_url: git@git.acme.com.ar
input_type: git

# group_vars/input-github
input_url: git@github.com:acme
input_type: git
# group_vars/web-daemon
component_input: main_jfrog

plugins

components

input Plugins

- include: git.yml
  when: input_type == 'git'

- include: artifact.yml
  when: input_type == 'artifact'

Build

- include: pkg-scripts.yml
  when: pkg_scripts_setup

- include: pkg-conffiles.yml
  when: pkg_conffiles_setup

Mantainer scripts and conf files

Build

- name: deb -  creating package with fpm 
  command: 'fpm -t deb -s {{ pkg_input_type }} \
    --name {{ component_package_name_prefix }}-{{ component_package_name }} \
     --version {{ version }} --iteration {{ branch }}-{{ sha }}-{{ iter }} \
     --architecture {{ component_arch }}  --maintainer "{{ pkg_maintainer }}" \
    --description "{{ component_description }}" --url {{ component_uri }} \
    --vendor {{ pkg_vendor }} --license "{{ pkg_license }}" \
     {{ pkg.deb.user }} {{ pkg.deb.group }} {{ fpm_scripts_opts }} \
     -C src/ . chdir={{ pkg_tmp_dir }}/{{ component }} '
  register: out

- name: deb -  get package name
  set_fact: pkgfile={{ out.stdout_lines[0] | regex_replace('.*path=>"(.*\.deb).*$', '\\1') }}

- hipchat_v2: msg="new package created {{ pkgfile }}" color="{{ pkg_hipchat_color }}" 
    room="{{ pkg_hipchat_room }}" token="{{ pkg_hipchat_token }}"

Create the package and notify it

Output plugins

  - name: include component input vars file 
    include_vars: "group_vars/output-{{ component_output }}"
    when: component_output is defined
    ignore_errors: yes

Mantainer scripts and conf files

Ansible

ansible-playbook -i inventory main.yml -e "component=web-modules version=1.0.2 branch=master sha=646a561"

Executing the playbook

Building native packages the ansible way

By osvaldo

Building native packages the ansible way

  • 488