Задача – запустить ansible-playbook
, которому необходимо передать RSA ключ для EC2 и файл с паролем для ansible-vault
, т.к. в задачах плейбука используются зашифрованные переменные.
Для этого используем Jenkins credentials, где сохраним два файла, а потом через Credentials Binding Plugin – передадим их в контейнер с задачей.
Содержание
Secret file в Credentials
Сначала добавляем файлы в Jenkins.
Переходим в Credentials > Add сredentials, выбираем тип Secret file и загружаем RSA-ключ:
ID нам потребуется в Jenkins-файле для передачи в Binding plugin.
Аналогично – загружаем файл с паролем для ansbile-vault
:
Jenkinsfile и Credentials Binding Plugin
Задача описывается в дух файлах – main.groovy
с функциями, тут пример только одной функции ansibleApply()
:
def ansibleApply(tags='1', limit='2', playbookFile='3', connection='4') { docker.image('bm/bm-ansible:1.0').inside('-v /var/run/docker.sock:/var/run/docker.sock') { stage('Ansible apply') { withCredentials([ file(credentialsId: 'bm-backend-dev-pem', variable: 'RSA'), file(credentialsId: 'backend-ansible-vault-pass', variable: 'PASSFILE') ]) { sh "ansible-playbook --private-key ${RSA} --tags ${tags} --limit=${limit} ${playbookFile} --vault-password-file ${PASSFILE} --extra-vars ansible_connection=${connection}" } } } }
Собственно тут мы и используем Credentials Binding Plugin – в вызове withCredentials()
задаём два файла, разделяя их запятой и используя их ID из Credentials:
... file(credentialsId: 'be-example-rsa', variable: 'RSA'), file(credentialsId: 'bm-ansible-pass-file', variable: 'PASSFILE') ...
Путь к первому сохраняем в переменной RSA
, путь ко второму – в переменной PASSFILE
, а затем обе переменные передаём ansible-playbok
:
... sh "ansible-playbook --private-key ${RSA} --tags ${tags} --limit=${limit} ${playbookFile} --vault-password-file ${PASSFILE} --extra-vars ansible_connection=${connection}" ...
Второй файл – mobilebackend-provision.groovy
, импортирует main.groovy
и вызывает ansibleApply()
:
#!/usr/bin/env groovy node { git branch: "${BACKEND_REPO_BRANCH}", url: "${BACKEND_REPO_URL}", credentialsId: "jenkins-dev-ci-github" dir ('projects/mobilebackend') { def provision = load 'ci/main.groovy' provision.ansibleRolesInstall() provision.ansbileSyntaxCheck() //from the Jenkins Credentials Parameter // RSA = set in withCredentials() // infra for CloudFormation // from Jenkins job's parameters TAGS = "${env.TAGS}" // limit for hosts.ini LIMIT = "mobilebackend-dev" // playbook to run PLAYBOOK = "mobilebackend.yml" // file with ansible vault password // PASSFILE = set in withCredentials() // ansible_connection parameter // local for CloudFormation job // ssh for Ansible if ("${env.TAGS}" == "infra") { CONN = "local" } else { CONN = "ssh" } // ansibleApply(tags='1', limit='2', playbookFile='3', connection='4') provision.ansibleApply("${TAGS}", "${LIMIT}", "${PLAYBOOK}", "${CONN}") } }
Переменная $TAGS
используется для выбора ролей для запуска – infra будет применена к роли cloudformation, app – ко всем остальным ролям, см. пост Ansible: теги, include_vars и приоритеты переменных.
На время билда – Jenkins добавит эти Secret files из своего хранилища в контейнер, а после билда – удалит их из workspace.
Запускаем:
Готово.