Рубрики
Uncategorized

AWS: Lambda — Скопируйте теги EC2 на его EBS, часть 1 — Python и Boto3

AWS: Lambda — Скопируйте теги EC2 на его EBS, часть 1 — Python и Boto3 У нас есть AWS Elastic … Tagged с помощью AWS, без серверов, DevOps, Tupormial.

AWS: Lambda — Скопируйте теги EC2 на его EBS, часть 1 — Python и Boto3

У нас есть сервисный кластер AWS Elastic Kubernetes, в котором есть несколько групп рабочих, которые были созданы в качестве AWS Autoscaling Groups с помощью EKSCTL, см. AWS Elastic Kubernetes Service: автоматизация создания кластера, часть 2 — Ansible, eksctl Больше подробностей.

Конфигурация группы рабочей группы для eksctl сохраняет набор тегов, которые используются нашей командой для инвентаря AWS:

--------
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: "{{ eks_cluster_name }}"
  region: "{{ region }}"
  version: "{{ k8s_version }}"

nodeGroups:

### Common ###

  - name: "{{ k8s_common_nodegroup_name }}-{{ item }}-v2021-09"
    instanceType: "{{ k8s_common_nodegroup_instance_type }}"
    privateNetworking: true
    labels:
      role: common-workers
    ...
    tags:
      Tier: "Devops"
      Domain: "eks.devops.{{ region }}.{{ env | lower }}.bttrm.local"
      ServiceType: "EC2"
      Env: {{ env }}
      Function: "Kubernetes WorkerNode"
      NetworkType: "Private"
      DataClass: "Public"
      AssetOwner: "{{ asset_owner }}"
      AssetCustodian: "{{ asset_custodian }}"
      OperatingSystem: "Amazon Linux"
      JiraTicket: "{{ jira_ticket }}"
      ConfidentialityRequirement: "Med"
      IntegrityRequirement: "Med"
      AvailabilityRequirement: "Med"
...

И эти теги применяются к группам автомасшюрадки:

А затем применяются к экземплярам EC2, созданным из этой автомасляной группы.

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

Кроме того, помимо Kubernetes Workernodes, в нашей учетной записи AWS, у нас есть общие экземпляры EC2, и некоторые из экземпляров могут иметь только одно, корневое устройство, в то время как другие могут иметь дополнительные диски для данных для резервного копирования.

Кроме того, нам нужно не только копировать теги из его EC2, но я также хочу добавить выделенный тег, описывая функцию диска — Корневой объем , Объем данных Или Kubernetes PVC Том Анкет

Как мы можем это сделать? Что ж, как и почти все в AWS, которые не покрываются консолью AWS — с помощью службы AWS Lambda: давайте создадим функцию, которая будет вызвана при запуске нового EC2 и скопирует эти теги EC2 во все объемы EBS, прилагается к этому экземпляру.

Итак, что нам нужно выйти в логике этой функции AWS Lambda:

  1. Когда создается новый EC2 — запустите функцию лямбды
  2. Функция примет идентификатор EC2 и найдет все связанные объемы EBS
  3. скопирует теги AWS из этого EC2 на все его EBS
  4. добавит новый тег с именем Роль :
  5. Если EBS был создан из PVC Kubernetes и установлен на EC2, запущенную из группы AWS AWS AWS Workernode Kubernetes, то мы установим тег Роль: "pvcvolume"
  6. Если EBS был создан во время общего создания EC2, будет проверять его точку монтирования и решит, какое значение использовать — Роль: "rootvolume" , или Роль: "Datavolume «

Пойдем.

Содержимое

Скрипт Python: копировать теги AWS

Сначала давайте напишем сценарий Python, протестируйте его и перейдем к AWS Lambda, во второй части этого поста.

Когда мы адаптируемся для функции Lambda, мы быстро обновим ее, чтобы сделать ее доступным для использования выделенного идентификатора EC2.

BOTO3: Получение списка экземпляров EC2 и их объемов EBS

Самое первое, что нужно проверить подлинность в учетной записи AWS, получить все экземпляры EC2 в определенной области, а затем получить список объемов EBS, прикрепленных к каждому EC2.

Затем, имея эту информацию, мы можем играть с их тегами.

Сценарий:

#!/usr/bin/env python

import os   
import boto3

ec2 = boto3.resource('ec2',
        region_name=os.getenv("AWS_DEFAULT_REGION"),
        aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
        aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY")
    )

def lambda_handler(event, context):

    base = ec2.instances.all()

    for instance in base:

        print("\n[DEBUG] EC2\n\t\tID: " + str(instance))
        print("\tEBS")

        for vol in instance.volumes.all():

            vol_id = str(vol)
            print("\t\tID: " + vol_id)

if __name__ == " __main__":
    lambda_handler(0, 0)

Здесь, в EC2 Переменная мы создаем объект Boto3.resource с EC2 введите и будут аутентифицировать в учетной записи AWS с помощью $ Aws_access_key_id и $ Aws_secret_access_key переменные. Позже, в нашей Lambda, аутентификация и разрешение будут выполнены с роли IAWS IAM.

В конце сценария мы называем Lambda_handler () Функция, если сценарий был выполнен в качестве специальной программы, см. Python: что такое if имя == » Главный «? Для деталей.

В Lambda_handler () Мы называем ec2.insance.all () Метод для получения всех экземпляров в регионе, а затем в цикле для каждого EC2, вызывая exants.volumes.all () Мы получаем список объемов EBS, прикрепленных к этому EC2.

На данный момент аргументы в отношении Lambda_handler () передаются как » 0, 0 «, а затем, в Lambda, мы поместим объекты события и контекста.

Установите переменные аутентификации AWS:

$ export AWS_ACCESS_KEY_ID=AKI***D4Q
$ export AWS_SECRET_ACCESS_KEY=QUC***BTI
$ export AWS_DEFAULT_REGION=eu-west-3

Запустите скрипт:

$ ./ec2_tags.py
[DEBUG] EC2
ID: ec2.Instance(id='i-0df2fe9ec4b5e1855')
EBS
ID: ec2.Volume(id='vol-0d11fd27f3702a0fc')
[DEBUG] EC2
ID: ec2.Instance(id='i-023529a843d02f680')
EBS
ID: ec2.Volume(id='vol-0f3548ae321cd040c')
[DEBUG] EC2
ID: ec2.Instance(id='i-02ab1438a79a3e475')
EBS
ID: ec2.Volume(id='vol-09b6f60396e56c363')
ID: ec2.Volume(id='vol-0d75c44a594e312a1')
…

Хорошо, это работает! У нас есть все ES2 в ЕС-Вест-3 Регион AWS, и для каждого EC2 получил список своих EBS.

Что дальше? Следующим является определение того, как объем устанавливается в EC2, и зная его точку монтирования, мы сможем узнать, является ли этот диск корневым объемом или какой -то дополнительный объем для данных.

Это можно сделать, получив вложения () Атрибут, который сохраняет значение для Устройство ключ.

Установите новую переменную в скрипте с именем device_id :

...
        for vol in instance.volumes.all():

            vol_id = str(vol)
            device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"

            print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id + "\n")
...

Запустите сценарий снова:

$ ./ec2_tags.py
[DEBUG] EC2
ID: ec2.Instance(id='i-0df2fe9ec4b5e1855')
EBS
ID: ec2.Volume(id='vol-0d11fd27f3702a0fc')
Dev: ec2.vol.Device('/dev/xvda')
[DEBUG] EC2
ID: ec2.Instance(id='i-023529a843d02f680')
EBS
ID: ec2.Volume(id='vol-0f3548ae321cd040c')
Dev: ec2.vol.Device('/dev/xvda')
[DEBUG] EC2
ID: ec2.Instance(id='i-02ab1438a79a3e475')
EBS
ID: ec2.Volume(id='vol-09b6f60396e56c363')
Dev: ec2.vol.Device('/dev/xvda')
ID: ec2.Volume(id='vol-0d75c44a594e312a1')
Dev: ec2.vol.Device('/dev/xvdbm')
…

И здесь у нас есть ES2 с id I-02AB1438A79A3E475 , и этот EC2 имеет две монтированные объемы EBS — VOL-09B6F60396E56C363 как /dev/xvda и Vol-0D75C44A594E312A1 как /dev/xvdbm Анкет

/dev/xvda Очевидно, это корневой объем, и /dev/xvdbm — Некоторые дополнительные данные.

Boto3: добавление тегов AWS в EBS

Теперь давайте создадим тег роли, который будет держать его от следующих значений:

  1. Если у EBS есть тег с kubernetes.io/created-for/pvc/name Ключ, затем установит Роль: "pvcvolume"
  2. Если это не объем ПВХ, то необходимо проверить его точку крепления, и если устройство == » /dev/xvda «, затем установить Роль: "rootvolume"
  3. И, наконец, если переменная устройства имеет какое -либо другое значение, то просто отметьте EBS с помощью Роль: "DataDisk"

Для этого давайте добавим еще одну функцию, которая будет использоваться для установки тегов, и еще одну небольшую функцию, называемую is_pvc () , это проверит, есть ли у EBS kubernetes.io/created-for/pvc/name Ярлык:

...
def is_pvc(vol):

    try:
        for tag in vol.tags:
            if tag['Key'] == 'kubernetes.io/created-for/pvc/name':
                return True
                break
    except TypeError:
            return False

def set_role_tag(vol):

    device = vol.attachments[0]['Device']
    tags_list = []
    values = {}

    if is_pvc(vol):
        values['Key'] = "Role"
        values['Value'] = "PvcDisk"
        tags_list.append(values)
    elif device == "/dev/xvda":
        values['Key'] = "Role"
        values['Value'] = "RootDisk"
        tags_list.append(values)
    else:
        values['Key'] = "Role"
        values['Value'] = "DataDisk"
        tags_list.append(values)

    return tags_list
...

Здесь, в set_role_tag () Функция, которую мы сначала передаем значение Vol в качестве аргумента в отношении is_pvc () функция, которая проверяет теги для ‘kubernetes.io/created-for/pvc/name’ ключ. Попробуйте/кроме Здесь используется, чтобы знать, есть ли у EBS вообще теги.

Если ‘kubernetes.io/created-for/pvc/name’ тег был найден, тогда is_pvc () вернется Верно , если не найдено, то Ложный Анкет

Затем в if/elif/else Условия, которые мы проверяем, если EBS является громкостью ПВХ, и если это так, то это будет помечено как Роль: "pvcvolume" , если нет — проверит его точку крепления, и если она установлена как » /dev/xvda «, затем установите Роль: "rootvolume" , если to — будет использовать Роль: "DataDisk" Анкет

Добавьте set_role_tag () Призыв к Lambda_handler () как аргумент в отношении vol.create_tags () Функция:

...
def lambda_handler(event, context):

    base = ec2.instances.all()

    for instance in base:

        print("\n[DEBUG] EC2\n\t\tID: " + str(instance))
        print("\tEBS")

        for vol in instance.volumes.all():

            vol_id = str(vol)
            device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"
            print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id)

            role_tag = vol.create_tags(Tags=set_role_tag(vol))
            print("\t\tTags set:\n\t\t\t" + str(role_tag))
...

Запустите сценарий снова:

$ ./ec2_tags.py
[DEBUG] EC2
ID: ec2.Instance(id='i-0df2fe9ec4b5e1855')
EBS
ID: ec2.Volume(id='vol-0d11fd27f3702a0fc')
Dev: ec2.vol.Device('/dev/xvda')
Tags set:
[ec2.Tag(resource_id='vol-0d11fd27f3702a0fc', key='Role', value='RootDisk')]
…
[DEBUG] EC2
ID: ec2.Instance(id='i-02ab1438a79a3e475')
EBS
ID: ec2.Volume(id='vol-09b6f60396e56c363')
Dev: ec2.vol.Device('/dev/xvda')
Tags set:
[ec2.Tag(resource_id='vol-09b6f60396e56c363', key='Role', value='RootDisk')]
ID: ec2.Volume(id='vol-0d75c44a594e312a1')
Dev: ec2.vol.Device('/dev/xvdbm')
Tags set:
[ec2.Tag(resource_id='vol-0d75c44a594e312a1', key='Role', value='PvcDisk')]

Давайте проверим объемы I-02AB1438A79A3E47 Экземпляр EC2.

Его корневой объем VOL-09B6F60396E56C363 :

И Kubernetes PVC — Vol-0D75C44A594E312A1 :

Хорошо, мы добавили создание ролевых тегов, и теперь нужно добавить возможность копировать теги AWS из EC2 в его EBS.

BOTO3: Скопируйте теги AWS из EC2 до EBS

Копия тегов также может быть перемещена на выделенную функцию, давайте назваем это copy_ec2_tags () , и он примет аргумент, где мы передадим идентификатор EC2:

...
def copy_ec2_tags(instance):

    tags_list = []
    values = {} 

    for instance_tag in instance.tags:

        if instance_tag['Key'] == 'Env':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'Tier':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'DataClass':
            tags_list.append(instance_tag)

    return tags_list
...

В функции, в цикле, мы проверяем все теги экземпляра, и, если найдем какой -либо из трех тегов, указанных в нашей функции, они будут добавлены в список TAGS_LIST [] , это позже будет передано в vol.create_tags () Анкет

Добавить copy_ec2_tags () исполнение в Lambda_handler () :

...
def lambda_handler(event, context):

    base = ec2.instances.all()

    for instance in base:

        print("\n[DEBUG] EC2\n\t\tID: " + str(instance))
        print("\tEBS")

        for vol in instance.volumes.all():

            vol_id = str(vol)
            device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"
            print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id)

            role_tag = vol.create_tags(Tags=set_role_tag(vol))
            ec2_tags = vol.create_tags(Tags=copy_ec2_tags(instance))
            print("\t\tTags set:\n\t\t\t" + str(role_tag) + "\n\t\t\t" + str(ec2_tags))
...

Бежать:

$ ./ec2_tags.py
[DEBUG] EC2
ID: ec2.Instance(id='i-0df2fe9ec4b5e1855')
EBS
ID: ec2.Volume(id='vol-0d11fd27f3702a0fc')
Dev: ec2.vol.Device('/dev/xvda')
Tags set:
[ec2.Tag(resource_id='vol-0d11fd27f3702a0fc', key='Role', value='RootDisk')]
[ec2.Tag(resource_id='vol-0d11fd27f3702a0fc', key='DataClass', value='Public'), ec2.Tag(resource_id='vol-0d11fd27f3702a0fc', key='Env', value='Dev'), ec2.Tag(resource_id='vol-0d11fd27f3702a0fc', key='Tier', value='Devops')]
…
[DEBUG] EC2
ID: ec2.Instance(id='i-02ab1438a79a3e475')
EBS
ID: ec2.Volume(id='vol-09b6f60396e56c363')
Dev: ec2.vol.Device('/dev/xvda')
Tags set:
[ec2.Tag(resource_id='vol-09b6f60396e56c363', key='Role', value='RootDisk')]
[ec2.Tag(resource_id='vol-09b6f60396e56c363', key='Env', value='Dev'), ec2.Tag(resource_id='vol-09b6f60396e56c363', key='DataClass', value='Public'), ec2.Tag(resource_id='vol-09b6f60396e56c363', key='Tier', value='Devops')]
ID: ec2.Volume(id='vol-0d75c44a594e312a1')
Dev: ec2.vol.Device('/dev/xvdbm')
Tags set:
[ec2.Tag(resource_id='vol-0d75c44a594e312a1', key='Role', value='PvcDisk')]
[ec2.Tag(resource_id='vol-0d75c44a594e312a1', key='Env', value='Dev'), ec2.Tag(resource_id='vol-0d75c44a594e312a1', key='DataClass', value='Public'), ec2.Tag(resource_id='vol-0d75c44a594e312a1', key='Tier', value='Devops')]
...

И проверить:

Весь скрипт теперь выглядит следующим::

#!/usr/bin/env python

import os
import boto3

ec2 = boto3.resource('ec2',
        region_name=os.getenv("AWS_DEFAULT_REGION"),
        aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
        aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY")
    )

def lambda_handler(event, context):

    base = ec2.instances.all()

    for instance in base:

        print("[DEBUG] EC2\n\t\tID: " + str(instance))
        print("\tEBS")

        for vol in instance.volumes.all():

            vol_id = str(vol)
            device_id = "ec2.vol.Device('" + str(vol.attachments[0]['Device']) + "')"
            print("\t\tID: " + vol_id + "\n\t\tDev: " + device_id)

            role_tag = vol.create_tags(Tags=set_role_tag(vol))
            ec2_tags = vol.create_tags(Tags=copy_ec2_tags(instance))
            print("\t\tTags set:\n\t\t\t" + str(role_tag) + "\n\t\t\t" + str(ec2_tags) + "\n")

def is_pvc(vol): 

    try:
        for tag in vol.tags:
            if tag['Key'] == 'kubernetes.io/created-for/pvc/name':
                return True
                break
    except TypeError:
            return False

def set_role_tag(vol):

    device = vol.attachments[0]['Device']
    tags_list = []
    values = {}

    if is_pvc(vol):
        values['Key'] = "Role"
        values['Value'] = "PvcDisk"
        tags_list.append(values)
    elif device == "/dev/xvda":
        values['Key'] = "Role"
        values['Value'] = "RootDisk"
        tags_list.append(values)
    else:   
        values['Key'] = "Role"
        values['Value'] = "DataDisk"
        tags_list.append(values)

    return tags_list

def copy_ec2_tags(instance):

    tags_list = []
    values = {} 

    for instance_tag in instance.tags:

        if instance_tag['Key'] == 'Env':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'Tier':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'DataClass':
            tags_list.append(instance_tag)
        elif instance_tag['Key'] == 'JiraTicket':
            tags_list.append(instance_tag)

    return tags_list

if __name__ == " __main__":
    lambda_handler(0, 0)

И мы закончили здесь, и теперь можем продолжить функцию AWS Lambda. Смотрите следующую часть в AWS: Lambda — Скопируйте теги EC2 на его EBS, часть 2 — создайте функцию лямбды почта.

Первоначально опубликовано в RTFM: Linux, DevOps и системное администрирование Анкет

Оригинал: «https://dev.to/setevoy/aws-lambda-copy-ec2-tags-to-its-ebs-part-1-python-and-boto3-1m92»