вторник, 26 февраля 2019 г.

Jenkins: Интерактивный выбор хостов для обработки в ansible с выборкой инстанцев по тэгам в AWS

Задачи специфичны, но идея может быть пригодится на будущее.
AWS + Spotinst. Приложение Java требует обновление порой на всех инстанцах, которых может быть несколько десятков. Люди привыкли обновлять приложения при помощи ansible и делать это так - снчала на один ставят обновление и смотрят как оно идет. Если хорошо то на пару следующих. Если все нормально то далее по пять штук обновляют. Для этого собирается список инстанцев и создается руками файлик hosts, заливается в git и оттуда уже этот файлик приезжает к ansible сценариям.

Вот не переделывая сложно структуру и привычки сделал Jenkins Job на базе Active Choise Plugin + Groovy.
Скрипт Groovy:
---------------------------------------
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def command = 'aws ec2 describe-instances --filters Name=tag:Name,Values=production-instances Name=instance-state-name,Values=running --query Reservations[].Instances[].{release:State.Name,ip:PrivateIpAddress,name:Tags[?Key==\'BName\']|[0].Value}'

def proc = command.execute()
proc.waitFor()
def output = proc.in.text
def exitcode= proc.exitValue()
def error = proc.err.text
if (error) {
println "Std Err: ${error}"
println "Process exit code: ${exitcode}"
return exitcode
}

def object = jsonSlurper.parseText(output)
def names = object.name

def sm = []
object.each { entry ->
    def html = jsonSlurper.parseText("http://$entry.ip:8110/info".toURL().text)
    String rel = html.get("build.version")   
    entry.release = rel
    sm.add("$entry.name ($entry.ip): $rel")
}

return(sm)

------------------------------------
Здесь идея в том, что бы запросить все инстанцы со статусом Running и тэгом Name = production-instances, получить IP и значение тэга BName (в нем уникальные имена с цифрами в конце). Далее вернуть массив строк BName (IP) - ReleaseVersion
Этот массив строк выдется в виде Checkbox параметра для выбора тех инстанцев, которые будем обновлять. 

Шаг сборки - shell script:
--------------------------
#!/bin/bash
IFS=",";

bidderArray=($bidders);
hosts=""

for ((i=0; i<${#bidderArray[@]}; ++i)); do    
    IFS=" ";
    Bidders=(${bidderArray[$i]})
    name=$(echo ${Bidders[0]} | sed 's/-/_/g')
    hosts="${hosts}tag_BName_$name,"
done

hosts=$(echo ${hosts}|sed s/,$//)
ansible-playbook -i /usr/local/bin/ec2.py ping.yml --extra-vars "hosts=$hosts"
-------------------------------

Здесь парсинг массива строк и передача в переменную hosts для playbook.


Комментариев нет: