Ansible: ansible-galaxy – репозиторий ролей и Jenkins VM provision

Автор: | 25/09/2017

Продолжаем сетап системы мониторинга.

Предыдущие части:

Для NGINX роль я писал руками, далее – используем Ansible Galaxy.

Основная идея использования Galaxy – иметь постоянно обновлённые роли во время сетапа серверов.

Т.е., вместо того, что бы просто сделать git clone роли к себе в репозиторий и через полгода узнать, что она уже не работает – можно выполнять импорт ролей прямо во время провижена из Jenkins-а.

Сначала выполним локально, на примере unattended-upgrades, потом – добавим импорт списка ролей через requirements.yml. и в конце – добавим их установку в Jenkins-файл.

Импорт роли

roles_path

По умолчанию – роли будут импортироваться в каталог /etc/ansible/roles.

Переопределить путь можно с помощью переменной ANSIBLE_ROLES_PATH:

[simterm]

$ mkdir ~/.ansible/roles
$ export ANSIBLE_ROLES_PATH=/home/setevoy/.ansible/roles

[/simterm]

Другой вариант – использовать опцию --roles-path для ansible-galaxy.

Импортируем роль:

[simterm]

$ ansible-galaxy install jnv.unattended-upgrades
- downloading role 'unattended-upgrades', owned by jnv
- downloading role from https://github.com/jnv/ansible-role-unattended-upgrades/archive/v1.3.0.tar.gz
- extracting jnv.unattended-upgrades to /home/setevoy/.ansible/roles/jnv.unattended-upgrades
- jnv.unattended-upgrades (v1.3.0) was installed successfully

[/simterm]

Проверяем:

[simterm]

$ ls -l ~/.ansible/roles/jnv.unattended-upgrades/
total 76
-rw-rw-r-- 1 setevoy setevoy    62 Jul 24  2016 ansible.cfg
drwxr-xr-x 2 setevoy setevoy  4096 Sep 25 11:49 defaults
drwxr-xr-x 2 setevoy setevoy  4096 Sep 25 11:49 files
drwxr-xr-x 2 setevoy setevoy  4096 Sep 25 11:49 handlers
...

[/simterm]

Или используем --roles-path, что бы загрузить роль в каталог проекта:

[simterm]

$ ansible-galaxy install jnv.unattended-upgrades --roles-path /home/setevoy/Work/BER.jm/azure-infrastructure/monitoring/ansible/monitoring/roles
- downloading role 'unattended-upgrades', owned by jnv
- downloading role from https://github.com/jnv/ansible-role-unattended-upgrades/archive/v1.3.0.tar.gz
- extracting jnv.unattended-upgrades to /home/setevoy/Work/BER.jm/azure-infrastructure/monitoring/ansible/monitoring/roles/jnv.unattended-upgrades
- jnv.unattended-upgrades (v1.3.0) was installed successfully

[/simterm]

Теперь эту роль можно добавить в provision.yml:

- hosts: all
  become:
    true
  roles:
   - nginx
   - jnv.unattended-upgrades

И выполняем --check:

[simterm]

$ ansible-playbook --inventory-file=hosts --check --limit=dev --private-key ../../.ssh/monitoring provision.yml
PLAY [all] ****

TASK [Gathering Facts] ****
ok: [dev.monitor.domain.ms]
 
TASK [nginx : Install Nginx] ****
ok: [dev.monitor.domain.ms] 
 
TASK [nginx : Replace NGINX config] ****
ok: [dev.monitor.domain.ms] 
 
TASK [nginx : Add NGINX virtualhost config] ****
ok: [dev.monitor.domain.ms] 
 
TASK [jnv.unattended-upgrades : add distribution-specific variables] ****
ok: [dev.monitor.domain.ms] 
 
TASK [jnv.unattended-upgrades : add Debian Wheezy workaround] ****
skipping: [dev.monitor.domain.ms] 
 
TASK [jnv.unattended-upgrades : install unattended-upgrades] ****
ok: [dev.monitor.domain.ms] 
 
TASK [jnv.unattended-upgrades : install update-notifier-common] ****
skipping: [dev.monitor.domain.ms] 
 
TASK [jnv.unattended-upgrades : create APT auto-upgrades configuration] ****
changed: [dev.monitor.domain.ms] 
 
TASK [jnv.unattended-upgrades : create unattended-upgrades configuration] ****
changed: [dev.monitor.domain.ms] 
 
PLAY RECAP ****
dev.monitor.domain.ms         : ok=8    changed=2    unreachable=0    failed=0

[/simterm]

Хорошо – всё работает.

requirements.yml

Далее, что бы хранить список всех нужных ролей и устанавливать их одной командой – в корне репозитория создаём файл requirements.yml.

Пока он будет содержать только одну роль, потом сюда же добавим Docker, Docker-Compose etc:

- src: jnv.unattended-upgrades
  name: unattended-upgrades

С помощью name – указываем под каким именем импортировать роль.

Удаляем уже импортированную роль:

[simterm]

$ rm -rf roles/jnv.unattended-upgrades/

[/simterm]

Обновляем имя в provision.yml: и добавляем переменные для настройки unattended-upgrades:

- hosts: all
  become:
    true
  roles:
    - role: nginx
    - role: unattended-upgrades
      unattended_mail: [email protected]
      unattended_automatic_reboot: true
      unattended_automatic_reboot_time: 03:00

Меняем ANSIBLE_ROLES_PATH на каталог проекта:

[simterm]

$ export ANSIBLE_ROLES_PATH=/home/setevoy/Work/BER.Jm/azure-infrastructure/monitoring/ansible/monitoring/roles/

[/simterm]

Вызываем ansible-galaxy, через --role-file (-r) указываем файл со списком ролей:

[simterm]

$ ansible-galaxy install -r requirements.yml 
- downloading role 'unattended-upgrades', owned by jnv
- downloading role from https://github.com/jnv/ansible-role-unattended-upgrades/archive/v1.3.0.tar.gz
- extracting unattended-upgrades to /home/setevoy/Work/BER.jm/azure-infrastructure/monitoring/ansible/monitoring/roles/unattended-upgrades
- unattended-upgrades (v1.3.0) was installed successfully

[/simterm]

Проверяем роли:

[simterm]

$ ls -l roles/
total 8
drwxr-xr-x 6 setevoy setevoy 4096 Sep 20 17:31 nginx
drwxr-xr-x 9 setevoy setevoy 4096 Sep 25 12:16 unattended-upgrades

[/simterm]

Всё готово.

Jenkins

Последним шагом – надо добавить вызов установки ролей в Jenkins.

Для этого добавим ещё одну функцию в файл monitoring-ansible.groovy:

#!/usr/bin/env groovy

def ansibleRolesInstall() {

    docker.image('williamyeh/ansible:master-ubuntu16.04').inside('-v /var/run/docker.sock:/var/run/docker.sock') {

        git branch: "${BRANCH}", credentialsId: 'github', url: "${INFRA_URL}"

        stage('Roles install') {

            sh "ansible-galaxy install --roles-path ${WORKDIR}/roles --role-file ${WORKDIR}/requirements.yml"
        }
    }
}
...

И её вызов во втором скрипте – monitoring-ansible-provision.groovy (до вызова provision.ansibleVmProvisionValidate() и provision.ansibleVmProvisionApply()):

#!/usr/bin/env groovy

node {
    
    // 'dev' or 'production'
    ENV="${ENV}"
    
    TAG = "${env.BUILD_TAG}"
    
    // Ansible playbooks repo URL
    INFRA_URL = "${INFRA_URL}"
    
    // Jenkins build script repo URL
    BUILD_REPO_URL = "${BUILD_REPO_URL}"
    
    // expor variable to path to Ansible dir in Infra repo
    WORKDIR='monitoring/ansible/monitoring'
    
    // clone $BUILD_REPO_URL to dedicated directory ./buildscripts/
    dir('buildscripts') {
        git branch: 'master', credentialsId: 'github', url: "${BUILD_REPO_URL}"
    }
    
    def provision = load 'buildscripts/monitoring/monitoring-ansible.groovy'
    
    provision.ansibleRolesInstall()
    provision.ansibleVmProvisionValidate("${ENV}")
    provision.ansibleVmProvisionApply("${ENV}")
}

Коммитим и пушим изменения в обоих репозиториях (кроме каталога roles – можно его вообще в .gitignore добавить, правда там собственная роль nginx).

Репозиторий Jenkins-файлов:

[simterm]

$ git add -A && git commit -m "Roles install funct()" && git push

[/simterm]

Ansbile репозиторий:

[simterm]

$ git add provision.yml requirements.yml && git commit -m "unattended-upgrades added" && git push

[/simterm]

Запускаем билд, и – он фейлится:


[monitoring-azure-VM-DEV-provisioning@2] Running shell script
+ ansible-galaxy install –roles-path roles –role-file monitoring/ansible/monitoring/requirements.yml
[WARNING]: – unattended-upgrades was NOT installed successfully: Failed to get
data from the API server (https://galaxy.ansible.com/api/): <urlopen error
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>
ERROR! – you can use –ignore-errors to skip failed roles and finish processing the list.

Как вариант решения – добавляем --ignore-certs:

...
        stage('Roles install') {

            sh "ansible-galaxy install --ignore-certs --roles-path ${WORKDIR}/roles --role-file ${WORKDIR}/requirements.yml"
        }
...

Запускаем ещё раз – всё ОК.

Импорт ролей:

И установка unattended-upgrades на Dev:

Проверяем настройки на сервере:

[simterm]

root@monitoring-dev-vm:~# cat /etc/apt/apt.conf.d/50unattended-upgrades | grep Reboot
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";

[/simterm]

Готово.