Опыт построения Infrastructure-as-Code в VMware. Часть 1.1: Динамическая инвентаризация

    image

    Приветствую, дорогой читатель! В предыдущей серии я рассказывал об опыте, сыне ошибок трудных, и обещал продолжить с модификацией Powershell скрипта.

    К сожалению, проект по этому направлению заморожен до следующего года, и чтобы не томить тебя ожиданиями, я решил поделиться своим «исследованием» в области динамической инвентаризации Vmware, что является промежуточной фазой для нашего проекта. Если твой парк виртуалок часто изменяется, то я настоятельно рекомендую ознакомиться с материалом.

    Первым делом, что я сделал, когда обнаружил этот коммент, это побежал к нашим инфраструктурщикам с вопросом «оно мне надо, велосипед пилить?». Ребята пояснили, что Vcloud это:

    • Дорого.
    • Окупается, когда у тебя распределенные датацентры на разных континентах.
    • Овер9000 изменений в инфраструктуре и столько же виртуалок.
    • Да и вообще, мы в AWS переезжаем, зачем нам.

    Зарядившись мотивацией («нам никто не поможет, кроме нас самих»), я полез в дебри изучения динамики. Не пойми меня неправильно, дорогой читатель, статичный инвентарь в Ansible штука очень удобная, да и вооружившись echo и sed в него тоже можно «писать динамически», но зачем?

    Ищем нужный скрипт


    На данный момент на Github в разделе contrib представлены следующие реализации динамического инвентаря: тот и этот.

    На просторах интернета еще нашелся такой вариант. Я его отбросил сразу — он тупо выгребает список всех машинок (без внутренностей), работает долго, логин и пароль для соединения с варей надо хардкодить. Иными словами — здорово чтобы поиграть, но не более.

    vmware.py тоже отпал, поскольку работает долго даже с кэшем (на моей машинке 30 минут без кэша, и 8 с кэшем), да и «глубина» погружения во внутренности виртуалки тоже не нравится.

    Так что мой выбор пал vmware_inventory.py — он очень гибок, с кэшем работает 2 секунды и дает мне возможность группировать по параметрам машинки.

    В первую очередь, большой и длинный INI файлик — конфигурация для работы с варей.

    vmware_inventory.ini
    # Ansible VMware external inventory script settings
    
    [vmware]
    
    # The resolvable hostname or ip address of the vsphere
    server=virtualcenter.example.com
    
    # The port for the vsphere API
    #port=443
    
    # The username with access to the vsphere API
    username=example\vmware_reader
    
    # The password for the vsphere API
    password=supersecurepassword
    
    # Verify the server's SSL certificate
    validate_certs = False
    
    # Specify the number of seconds to use the inventory cache before it is
    # considered stale.  If not defined, defaults to 0 seconds.
    cache_max_age = 86400
    
    
    # Specify the directory used for storing the inventory cache.  If not defined,
    # caching will be disabled.
    cache_path = ~/.cache/ansible
    
    
    # Max object level refers to the level of recursion the script will delve into
    # the objects returned from pyvomi to find serializable facts. The default 
    # level of 0 is sufficient for most tasks and will be the most performant. 
    # Beware that the recursion can exceed python's limit (causing traceback),
    # cause sluggish script performance and return huge blobs of facts.
    # If you do not know what you are doing, leave this set to 1.
    max_object_level=2
    
    
    # Lower the keynames for facts to make addressing them easier.
    lower_var_keys=True
    
    
    # Host alias for objects in the inventory. VMWare allows duplicate VM names
    # so they can not be considered unique. Use this setting to alter the alias
    # returned for the hosts. Any atributes for the guest can be used to build 
    # this alias. The default combines the config name and the config uuid and 
    # expects that the ansible_host will be set by the host_pattern.
    alias_pattern={{ config.name }}
    
    
    # Host pattern is the value set for ansible_host and ansible_ssh_host, which
    # needs to be a hostname or ipaddress the ansible controlhost can reach.
    #host_pattern={{ guest.ipaddress }}
    
    
    # Host filters are a comma separated list of jinja patterns to remove 
    # non-matching hosts from the final result.
    # EXAMPLES:
    #   host_filters={{ config.guestid == 'rhel7_64Guest' }}
    #   host_filters={{ config.cpuhotremoveenabled != False }},{{ runtime.maxmemoryusage >= 512 }}
    #   host_filters={{ config.cpuhotremoveenabled != False }},{{ runtime.maxmemoryusage >= 512 }}
    # The default is only gueststate of 'running'
    host_filters={{ guest.gueststate == "running" }}
    
    
    # Groupby patterns enable the user to create groups via any possible jinja
    # expression. The resulting value will the groupname and the host will be added
    # to that group. Be careful to not make expressions that simply return True/False
    # because those values will become the literal group name. The patterns can be
    # comma delimited to create as many groups as necessary
    groupby_patterns={{ guest.guestid }},{{ 'templates' if config.template else 'guests'}}
    
    # The script attempts to recurse into virtualmachine objects and serialize
    # all available data. The serialization is comprehensive but slow. If the
    # vcenter environment is large and the desired properties are known, create
    # a 'properties' section in this config and make an arbitrary list of
    # key=value settings where the value is a path to a specific property. If 
    # If this feature is enabled, be sure to fetch every property that is used
    # in the jinja expressions defined above. For performance tuning, reduce
    # the number of properties to the smallest amount possible and limit the 
    # use of properties that are not direct attributes of vim.VirtualMachine
    #[properties]
    prop01=name
    prop04=config.instanceUuid
    prop05=config.hardware.numCPU
    prop06=config.template
    prop07=config.name
    prop08=guest.hostName
    prop09=guest.ipAddress
    prop11=guest.guestState
    prop12=runtime.maxMemoryUsage


    В первую очередь я рекомендую завести отдельного юзера для работы с варей. По сути нам нужен обычный пользователь, который может читать данные машинок, ресурспулов, папок и датасторов. Никаких прав на включение/выключение, создание/удаление виртуалок у него нет и не должно быть. Least privilege principle!

    Допольнительно подчеркиваю:

    1. Срок жизни кэша (cache_max_age) в секундах. Я выставил на сутки, но каждый раз когда будет создаваться машинка, кэш будет обновляться (запуск скрипта с опцией --refresh-cache). Также обновление будет раз в сутки ночью (точно также)
    2. Глубину рекурсии (max_object_level). Двойка здесь самый оптимальный вариант, чтобы получить ЕЩЕ больше метаданных о машинке. Больше метаданных — больше игр с группировками и фильтрацией. Но — больше json и больше времени работы скрипта.
    3. Паттерн машинки (alias_pattern) — по умолчанию идет {{ config.name + '_' + config.uuid }}, что делает название машинки нечитабельным, так что я убрал config.uuid
    4. Паттерны группировки (groupby_patterns) — вот это самая прелесть в скрипте. Позволяет группировать машины на основе метаданных. Группировать можно по всему от слова «совсем». Ресурспул, кастомный вар в нотах, сетка, location, даже название датастора. По умолчанию группируется по гестам (читай — по установленной ОС)

    Всякие очевидные вещи типа валидации сертификатов описывать не буду, но если попал в беду со скриптом — пиши в комментариях.

    Пробуем запустить.

    $ time ./vmware_inventory.py > fact_from_vm_py.json
    
    real	27m59.970s
    user	8m33.334s
    sys	0m7.841s

    Повторюсь, читатель, будь осторожен обновлением кэша, а то плейбуки будут медленнее черепашки!

    С кэшем весь инвентарь подгружается за секунду, и основное время работы скрипта занимает сканирование вари. Я не буду приводить весь выхлоп скрипта, приведу один единичный хост:

    Данных очень много
    "edin_host": {
            "resourcepool": {
              "_moId": "resgroup-14510", 
              "name": "example-BI"
            }, 
            "customvalue": [], 
            "permission": [], 
            "storage": {
              "timestamp": {
                "hour": 7, 
                "min": {}, 
                "max": {}, 
                "month": 12, 
                "second": 20, 
                "microsecond": 859999, 
                "year": 2016, 
                "tzinfo": {}, 
                "resolution": {}, 
                "day": 22, 
                "minute": 45
              }, 
              "perdatastoreusage": []
            }, 
            "configissue": [], 
            "parentvapp": null, 
            "tag": [], 
            "recenttask": [], 
            "resourceconfig": {
              "changeversion": null, 
              "lastmodified": null, 
              "memoryallocation": {
                "overheadlimit": 63, 
                "reservation": 0, 
                "limit": -1, 
                "shares": {}, 
                "expandablereservation": false
              }, 
              "cpuallocation": {
                "overheadlimit": null, 
                "reservation": 0, 
                "limit": -1, 
                "shares": {}, 
                "expandablereservation": false
              }, 
              "entity": {
                "resourcepool": {
                  "_moId": "resgroup-14510", 
                  "name": "example-BI"
                }, 
                "alarmactionsenabled": true, 
                "configissue": [], 
                "tag": [], 
                "resourceconfig": {}, 
                "datastore": [], 
                "triggeredalarmstate": [], 
                "layout": {}, 
                "guest": {}, 
                "effectiverole": [], 
                "storage": {}, 
                "layoutex": {}, 
                "config": {}, 
                "customvalue": [], 
                "permission": [], 
                "parentvapp": null, 
                "recenttask": [], 
                "availablefield": [], 
                "overallstatus": "green", 
                "network": [], 
                "guestheartbeatstatus": "green", 
                "name": "edin_host", 
                "rootsnapshot": [], 
                "configstatus": "green", 
                "value": [], 
                "summary": {}, 
                "capability": {}, 
                "snapshot": null, 
                "runtime": {}
              }
            }, 
            "availablefield": [
              {
                "fieldinstanceprivileges": null, 
                "fielddefprivileges": null, 
                "name": "Service", 
                "key": 101
              }, 
              {
                "fieldinstanceprivileges": null, 
                "fielddefprivileges": null, 
                "name": "Group", 
                "key": 301
              }, 
              {
                "fieldinstanceprivileges": null, 
                "fielddefprivileges": null, 
                "name": "Role", 
                "key": 103
              }, 
              {
                "fieldinstanceprivileges": null, 
                "fielddefprivileges": null, 
                "name": "Owner", 
                "key": 104
              }, 
              {
                "fieldinstanceprivileges": null, 
                "fielddefprivileges": null, 
                "name": "Environment", 
                "key": 102
              }
            ], 
            "datastore": [
              {
                "_moId": "datastore-57683", 
                "name": "mydatastore"
              }
            ], 
            "summary": {
              "customvalue": [], 
              "guest": {
                "toolsstatus": "toolsOk", 
                "toolsversionstatus": "guestToolsUnmanaged", 
                "hostname": "edin_host.example.com", 
                "toolsrunningstatus": "guestToolsRunning", 
                "guestid": "centos64Guest", 
                "ipaddress": "192.168.1.1", 
                "toolsversionstatus2": "guestToolsUnmanaged", 
                "guestfullname": "CentOS 4/5/6/7 (64-bit)"
              }, 
              "config": {
                "memoryreservation": 0, 
                "product": null, 
                "instanceuuid": "502c6c2d-8b58-a01c-4ce0-a18e0a65ac3a", 
                "name": "edin_host", 
                "numethernetcards": 1, 
                "numcpu": 1, 
                "installbootrequired": false, 
                "guestid": "centos64Guest", 
                "memorysizemb": 2048, 
                "vmpathname": "[mydatastore] edin_host/edin_host.vmx", 
                "template": false, 
                "ftinfo": null, 
                "uuid": "422c78f0-7401-3dbc-2790-9708af08bd03", 
                "cpureservation": 0, 
                "annotation": null, 
                "numvirtualdisks": 2, 
                "guestfullname": "CentOS 4/5/6/7 (64-bit)"
              }, 
              "storage": {
                "timestamp": {}, 
                "uncommitted": 1064, 
                "unshared": 85899345920, 
                "committed": 88272314106
              }, 
              "vm": {
                "resourcepool": {
                  "_moId": "resgroup-14510", 
                  "name": "example-BI"
                }, 
                "alarmactionsenabled": true, 
                "configissue": [], 
                "tag": [], 
                "resourceconfig": {}, 
                "datastore": [], 
                "triggeredalarmstate": [], 
                "layout": {}, 
                "guest": {}, 
                "effectiverole": [], 
                "storage": {}, 
                "layoutex": {}, 
                "config": {}, 
                "customvalue": [], 
                "permission": [], 
                "parentvapp": null, 
                "recenttask": [], 
                "availablefield": [], 
                "overallstatus": "green", 
                "network": [], 
                "guestheartbeatstatus": "green", 
                "name": "edin_host", 
                "rootsnapshot": [], 
                "configstatus": "green", 
                "value": [], 
                "summary": {}, 
                "capability": {}, 
                "snapshot": null, 
                "runtime": {}
              }, 
              "quickstats": {
                "ftsecondarylatency": -1, 
                "privatememory": 1877, 
                "compressedmemory": 0, 
                "consumedoverheadmemory": 37, 
                "swappedmemory": 0, 
                "ftlatencystatus": "gray", 
                "uptimeseconds": 1898839, 
                "ssdswappedmemory": 0, 
                "guestheartbeatstatus": "green", 
                "distributedmemoryentitlement": 602, 
                "staticcpuentitlement": 1905, 
                "balloonedmemory": 0, 
                "guestmemoryusage": 81, 
                "overallcpuusage": 0, 
                "overallcpudemand": 0, 
                "staticmemoryentitlement": 2111, 
                "ftlogbandwidth": -1, 
                "distributedcpuentitlement": 0, 
                "sharedmemory": 47, 
                "hostmemoryusage": 1916
              }, 
              "runtime": {
                "powerstate": "poweredOn", 
                "featuremask": [], 
                "onlinestandby": false, 
                "cleanpoweroff": null, 
                "featurerequirement": [], 
                "question": null, 
                "boottime": {}, 
                "maxmemoryusage": 2048, 
                "offlinefeaturerequirement": [], 
                "minrequiredevcmodekey": "intel-sandybridge", 
                "toolsinstallermounted": false, 
                "suspendinterval": 0, 
                "memoryoverhead": null, 
                "needsecondaryreason": null, 
                "vflashcacheallocation": 0, 
                "host": {}, 
                "maxcpuusage": 1999, 
                "device": [], 
                "suspendtime": null, 
                "recordreplaystate": "inactive", 
                "consolidationneeded": false, 
                "connectionstate": "connected", 
                "dasvmprotection": {}, 
                "faulttolerancestate": "notConfigured", 
                "nummksconnections": 0
              }, 
              "overallstatus": "green"
            }, 
            "overallstatus": "green", 
            "ansible_host": "192.168.1.1", 
            "triggeredalarmstate": [], 
            "network": [
              {
                "configstatus": "green", 
                "customvalue": [], 
                "name": "bi-acceptatie", 
                "effectiverole": [], 
                "permission": [], 
                "configissue": [], 
                "alarmactionsenabled": true, 
                "vm": [], 
                "value": [], 
                "summary": {}, 
                "host": [], 
                "tag": [], 
                "recenttask": [], 
                "availablefield": [], 
                "overallstatus": "green", 
                "triggeredalarmstate": []
              }
            ], 
            "configstatus": "green", 
            "guestheartbeatstatus": "green", 
            "layout": {
              "logfile": [
                "vmware-10.log", 
                "vmware-11.log", 
                "vmware-12.log", 
                "vmware-13.log", 
                "vmware-8.log", 
                "vmware-9.log", 
                "vmware.log"
              ], 
              "configfile": [
                "edin_host.nvram", 
                "edin_host.vmsd"
              ], 
              "disk": [], 
              "snapshot": [], 
              "swapfile": "[mydatastore] edin_host/edin_host-60ee652b.vswp"
            }, 
            "guest": {
              "appheartbeatstatus": "appStatusGray", 
              "interactiveguestoperationsready": false, 
              "toolsversion": "2147483647", 
              "toolsversionstatus": "guestToolsUnmanaged", 
              "toolsrunningstatus": "guestToolsRunning", 
              "ipaddress": "192.168.1.1", 
              "screen": {
                "width": 1280, 
                "height": 768
              }, 
              "guestfamily": "linuxGuest", 
              "generationinfo": [], 
              "ipstack": [], 
              "gueststate": "running", 
              "hostname": "edin_host.example.com", 
              "guestid": "centos64Guest", 
              "toolsstatus": "toolsOk", 
              "net": [], 
              "disk": [], 
              "appstate": "none", 
              "guestoperationsready": true, 
              "toolsversionstatus2": "guestToolsUnmanaged", 
              "guestfullname": "CentOS 4/5/6/7 (64-bit)"
            }, 
            "effectiverole": [
              -2
            ], 
            "rootsnapshot": [], 
            "alarmactionsenabled": true, 
            "value": [], 
            "name": "edin_host", 
            "capability": {
              "quiescedsnapshotssupported": true, 
              "cpufeaturemasksupported": true, 
              "consolepreferencessupported": false, 
              "vpmcsupported": true, 
              "featurerequirementsupported": true, 
              "snapshotconfigsupported": true, 
              "bootoptionssupported": true, 
              "changetrackingsupported": true, 
              "vmnpivwwnupdatesupported": true, 
              "poweredonmonitortypechangesupported": true, 
              "nestedhvsupported": true, 
              "poweredoffsnapshotssupported": true, 
              "settingvideoramsizesupported": true, 
              "settingscreenresolutionsupported": false, 
              "virtualmmuusagesupported": true, 
              "sesparsedisksupported": true, 
              "s1acpimanagementsupported": true, 
              "reverttosnapshotsupported": true, 
              "disksharessupported": true, 
              "vmnpivwwndisablesupported": true, 
              "disablesnapshotssupported": false, 
              "swapplacementsupported": true, 
              "bootretryoptionssupported": true, 
              "memoryreservationlocksupported": true, 
              "recordreplaysupported": true, 
              "settingdisplaytopologysupported": false, 
              "vmnpivwwnsupported": true, 
              "npivwwnonnonrdmvmsupported": true, 
              "toolsautoupdatesupported": false, 
              "multiplecorespersocketsupported": true, 
              "guestautolocksupported": true, 
              "multiplesnapshotssupported": true, 
              "snapshotoperationssupported": true, 
              "toolssynctimesupported": true, 
              "hostbasedreplicationsupported": true, 
              "locksnapshotssupported": true, 
              "memorysnapshotssupported": true
            }, 
            "snapshot": null, 
            "ansible_uuid": "39d641a6-9b9e-4ce0-b1f8-a4e8e38c9743", 
            "layoutex": {
              "timestamp": {
                "hour": 7, 
                "min": {}, 
                "max": {}, 
                "month": 12, 
                "second": 20, 
                "microsecond": 860550, 
                "year": 2016, 
                "tzinfo": {}, 
                "resolution": {}, 
                "day": 22, 
                "minute": 45
              }, 
              "disk": [], 
              "snapshot": [], 
              "file": []
            }, 
            "runtime": {
              "powerstate": "poweredOn", 
              "featuremask": [], 
              "onlinestandby": false, 
              "cleanpoweroff": null, 
              "featurerequirement": [], 
              "question": null, 
              "boottime": {
                "hour": 9, 
                "min": {}, 
                "max": {}, 
                "month": 11, 
                "second": 31, 
                "microsecond": 402054, 
                "year": 2016, 
                "tzinfo": {}, 
                "resolution": {}, 
                "day": 30, 
                "minute": 42
              }, 
              "maxmemoryusage": 2048, 
              "offlinefeaturerequirement": [], 
              "minrequiredevcmodekey": "intel-sandybridge", 
              "toolsinstallermounted": false, 
              "suspendinterval": 0, 
              "memoryoverhead": null, 
              "needsecondaryreason": null, 
              "vflashcacheallocation": 0, 
              "host": {
                "alarmactionsenabled": true, 
                "configissue": [], 
                "vm": [], 
                "hardware": {}, 
                "tag": [], 
                "datastore": [], 
                "triggeredalarmstate": [], 
                "network": [], 
                "effectiverole": [], 
                "datastorebrowser": {}, 
                "config": {}, 
                "customvalue": [], 
                "permission": [], 
                "systemresources": {}, 
                "configmanager": {}, 
                "recenttask": [], 
                "availablefield": [], 
                "overallstatus": "green", 
                "name": "esx1.example.com", 
                "configstatus": "green", 
                "value": [], 
                "summary": {}, 
                "capability": {}, 
                "licensableresource": {}, 
                "runtime": {}
              }, 
              "maxcpuusage": 1999, 
              "device": [], 
              "suspendtime": null, 
              "recordreplaystate": "inactive", 
              "consolidationneeded": false, 
              "connectionstate": "connected", 
              "dasvmprotection": {
                "dasprotected": true
              }, 
              "faulttolerancestate": "notConfigured", 
              "nummksconnections": 0
            }, 
            "config": {
              "uuid": "422c78f0-7401-3dbc-2790-9708af08bd03", 
              "alternateguestname": "", 
              "npivonnonrdmdisks": null, 
              "instanceuuid": "502c6c2d-8b58-a01c-4ce0-a18e0a65ac3a", 
              "cpuaffinity": null, 
              "npivdesirednodewwns": null, 
              "memoryhotaddenabled": true, 
              "hardware": {
                "virtualich7mpresent": false, 
                "numcpu": 1, 
                "virtualsmcpresent": false, 
                "memorymb": 2048, 
                "device": [], 
                "numcorespersocket": 1
              }, 
              "vappconfig": null, 
              "tools": {
                "beforegueststandby": true, 
                "beforeguestreboot": null, 
                "beforeguestshutdown": true, 
                "toolsupgradepolicy": "manual", 
                "afterresume": true, 
                "afterpoweron": true, 
                "synctimewithhost": false, 
                "lastinstallinfo": {}, 
                "pendingcustomization": null, 
                "toolsversion": 2147483647
              }, 
              "guestfullname": "CentOS 4/5/6/7 (64-bit)", 
              "changeversion": "2016-11-30T09:42:11.343789Z", 
              "defaultpowerops": {
                "defaultresettype": "soft", 
                "defaultsuspendtype": "hard", 
                "suspendtype": "hard", 
                "standbyaction": "powerOnSuspend", 
                "defaultpowerofftype": "soft", 
                "resettype": "soft", 
                "powerofftype": "soft"
              }, 
              "cpuhotremoveenabled": false, 
              "vpmcenabled": false, 
              "firmware": "bios", 
              "npivworldwidenametype": null, 
              "nestedhvenabled": false, 
              "version": "vmx-11", 
              "locationid": "564da59f-ac2b-54e9-c006-84e06f757410", 
              "maxmksconnections": 40, 
              "template": false, 
              "guestid": "centos64Guest", 
              "bootoptions": {
                "enterbiossetup": false, 
                "bootorder": [], 
                "bootdelay": 0, 
                "bootretryenabled": false, 
                "bootretrydelay": 10000
              }, 
              "cpufeaturemask": [], 
              "hotplugmemorylimit": 3072, 
              "npivnodeworldwidename": [], 
              "cpuallocation": {
                "overheadlimit": null, 
                "reservation": 0, 
                "limit": -1, 
                "shares": {}, 
                "expandablereservation": false
              }, 
              "files": {
                "vmpathname": "[mydatastore] edin_host/edin_host.vmx", 
                "snapshotdirectory": "[mydatastore] edin_host/", 
                "suspenddirectory": "[mydatastore] edint_host/", 
                "logdirectory": "[mydatastore] edin_host/"
              }, 
              "memoryreservationlockedtomax": false, 
              "scheduledhardwareupgradeinfo": {
                "fault": null, 
                "upgradepolicy": "never", 
                "versionkey": null, 
                "scheduledhardwareupgradestatus": "none"
              }, 
              "initialoverhead": null, 
              "hotplugmemoryincrementsize": 128, 
              "guestautolockenabled": false, 
              "latencysensitivity": {
                "sensitivity": null, 
                "level": "normal"
              }, 
              "npivtemporarydisabled": true, 
              "memoryallocation": {
                "overheadlimit": 63, 
                "reservation": 0, 
                "limit": -1, 
                "shares": {}, 
                "expandablereservation": false
              }, 
              "ftinfo": null, 
              "npivportworldwidename": [], 
              "annotation": null, 
              "memoryaffinity": null, 
              "vassertsenabled": false, 
              "datastoreurl": [], 
              "changetrackingenabled": false, 
              "name": "edin_host", 
              "npivdesiredportwwns": null, 
              "vflashcachereservation": 0, 
              "extraconfig": [], 
              "networkshaper": null, 
              "modified": {
                "hour": 0, 
                "min": {}, 
                "max": {}, 
                "month": 1, 
                "second": 0, 
                "microsecond": 0, 
                "year": 1970, 
                "tzinfo": {}, 
                "resolution": {}, 
                "day": 1, 
                "minute": 0
              }, 
              "consolepreferences": null, 
              "swapplacement": "inherit", 
              "flags": {
                "diskuuidenabled": false, 
                "snapshotdisabled": false, 
                "recordreplayenabled": false, 
                "runwithdebuginfo": false, 
                "virtualmmuusage": "automatic", 
                "enablelogging": true, 
                "snapshotpoweroffbehavior": "powerOff", 
                "snapshotlocked": false, 
                "htsharing": "any", 
                "disableacceleration": false, 
                "monitortype": "release", 
                "virtualexecusage": "hvAuto", 
                "usetoe": false
              }, 
              "cpuhotaddenabled": true
            }, 
            "ansible_ssh_host": "192.168.1.1"
    



    Здорово, правда? :) Как я уже сказал, количество метаданных также регулируется max_object_level, так что если данных уж слишком много — опустите до 1.

    Работаем со скриптом.


    Пользоваться можно двумя способами: либо кладем скрипт с настройками в папку наших инвентарей, либо задаем инвентарь вручную:

    ansible all -i /path/to/my/vmware_inventory.py -m setup

    Чем мне нравится модуль setup — он не требует подключения, а просто прогоняется по машинкам.
    Дальше уже можно экспериментировать, причем использовать метаданные виртуалки можно и в обработке условий. Для чистоты эксперимента я буду фильтровать по ресурс пулу.
    Если при запуске Ansible поругается, то необходимо удалить комментарии в начале скрипта.

    Пример номер 1


    - name: example 1
      hosts: mail-scanner*
      gather_facts: False
      tasks:
      - name: say the name of the machine
        debug:
          msg: "Hello from {{ hostvars[inventory_hostname].resourcepool.name }}!"
    

    В этом примере я беру несколько одноименных хостов и вывожу переменную, взятую не из Ansible facts, а именно из метаданных машины.

    Пример номер 2


    ---
    - name: example nr2
      hosts: all
      gather_facts: False
      vars:
        resource_pool: "{{ hostvars[inventory_hostname].resourcepool._moId }}"
      tasks:
      - name: say hello, if in RP
        debug:
          msg: "Hello, fron {{ hostvars[inventory_hostname].name }}"
        when: resource_pool == "resgroup-1"
    

    Здесь приходится применять грязный хак, поскольку квадратные скобки не хотят нормально обрабатываться в блоке when, поэтому сначала я декларирую переменную, а затем сверяюсь. Если машинка в ресурс пуле, Ansible вернет мне ее имя.

    Пример номер 3


    Делать подобные выкрутасы можно и в ролях.

    --
    - name: example nr3
      hosts: centos64Guest
      gather_facts: False
      vars:
        resource_pool: "{{ hostvars[inventory_hostname].resourcepool._moId }}"
      roles:
      - { role: myrole, when: resource_pool == "resgroup-1" }
    

    Дорогой читатель, возможности использования метаданных ограничиваются лишь твоей фантазией!

    Группируем по-своему


    Здорово использовать метаданные для фильтрации в when, но это не решает проблему пробега по всем машинам — нам же хочется группировать машины на уровне скрипта. Для этого мы еще раз поиграем с настройкой groupby_patterns. К примеру, если выставить значение {{ resourcepool.name }} то группироваться будет по имени ресурс пула. Группировать еще можно по имени виртуальной сети ({{ network.name }}) или по таге ({{ tag }})

    Какой способ лучше решать уже тебе, читатель.

    P.S. Кстати, можно делать связку групп-родителей и групп-детей в статическом инвентаре. Подробно это описано в документации Ansible (пусть и на примере AWS).
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое