Не удается синхронизировать c s3 с папкой ec2 из aws lambda - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь автоматизировать обработку данных, используя AWS. Я настроил AWS лямбда-функцию в python, которая:

  1. Получает срабатывание события S3 PUT
  2. S sh в экземпляре EC2 с использованием слоя paramiko
  3. Скопируйте новые объекты из корзины в некоторую папку в экземпляре, разархивируйте файл внутри экземпляра и запустите сценарий python, который очищает файлы csv.

Проблема в том, что aws cli-вызов syn c s3 bucket с папкой ec2 не работает, но когда я вручную s sh ввел в экземпляр ec2 и запустил команду, это работает .My aws -cli настроен на мои access_keys, а у ec2 есть роль s3, которая позволяет ему полный доступ.

    import boto3
    import time
    import paramiko

    def lambda_handler(event, context):
    #create a low level client representing s3
        s3 = boto3.client('s3')
        ec2 = boto3.resource('ec2', region_name='eu-west-a')
        instance_id = 'i-058456c79fjcde676'
        instance = ec2.Instance(instance_id)
    ------------------------------------------------------'''
    #start instance
        instance.start()
    #allow some time for the instance to start
        time.sleep(30)

    # Print few details of the instance
       print("Instance id - ", instance.id)
       print("Instance public IP - ", instance.public_ip_address)
       print("Instance private IP - ", instance.private_ip_address)
       print("Public dns name - ", instance.public_dns_name)
       print("----------------------------------------------------")
       print('Downloading pem file')
       s3.download_file('some_bucket', 'some_pem_file.pem', '/tmp/some_pem_file.pem')

    # Allowing few seconds for the download to complete
       print('waiting for instance to start')
       time.sleep(30)
       print('sshing to instsnce')
       ssh = paramiko.SSHClient()
       ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
       privkey = paramiko.RSAKey.from_private_key_file('/tmp/some_pem_file.pem')
    # username is most likely 'ec2-user' or 'root' or 'ubuntu'
    # depending upon yor ec2 AMI
    #s3_path = "s3://some_bucket/" + object_name
       ssh.connect(
       instance.public_dns_name, username='ubuntu', pkey=privkey)
       print('inside machine...running commands')
       stdin, stdout, stderr = ssh.exec_command('aws s3 sync s3://some_bucket/ ~/ec2_folder;\
       bash ~/ec2_folder/unzip.sh; python3 ~/ec2_folder/process.py;')
       stdin.flush()
       data = stdout.read().splitlines()
       for line in data:
        print(line)
        print('done, closing ssh session')
       ssh.close()

    # Stop the instance
      instance.stop()

    return('Triggered')

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Этот ответ основан на дополнительной информации о том, что вы sh до выключаете экземпляр EC2 между выполнениями .

Я бы порекомендовал:

  • Amazon S3 Event запускает лямбда-функцию
  • Лямбда-функция запускает экземпляр , передавая информацию об имени файла через поле Данные пользователя (может использоваться для передавать данные, а не только скрипты). Затем функция Lambda может немедленно выйти (что более экономично, чем ожидание завершения задания)
  • Поместите сценарий обработки в каталог /var/lib/cloud/scripts/per-boot/, что приведет к его запуску каждый раз экземпляр запускается ( каждый раз, а не только в первый раз)
  • Сценарий может извлекать пользовательские данные , переданные из функции Lambda, путем извлечения curl http://169.254.169.254/latest/user-data/, чтобы он знал имя файла из S3
  • Затем сценарий обрабатывает файл
  • Затем сценарий запускает sudo shutdown now -h до Остановка экземпляра

Если есть вероятность, что другой файл может прийти , когда экземпляр уже обрабатывает файл , тогда я бы немного изменил процесс:

  • Вместо того, чтобы передавать имя файла через пользовательские данные, поместите его в очередь Amazon SQS
  • Когда экземпляр запущен, он должен получить сведения из Очередь SQS
  • После файла Обрабатывается, он должен снова проверить очередь , чтобы увидеть, было ли отправлено еще одно сообщение
    • Если да, обработать файл и повторить
    • Если нет, выключить себя

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

0 голосов
/ 13 февраля 2020

Использование инструмента S SH несколько необычно.

Вот еще несколько «дружественных к облаку» вариантов, которые вы могли бы рассмотреть.

Команда запуска системного менеджера

Команда запуска AWS Systems Manager позволяет выполнять сценарий на экземпляре Amazon EC2 (и фактически на любом компьютере, на котором работает агент System Manager). ). Он может даже запускать команду на многих (сотнях!) Экземплярах / компьютерах одновременно, отслеживая успешность каждого выполнения.

Это означает, что вместо подключения к экземпляру через S SH, лямбда-функция может вызывать команду «Выполнить» через вызов API, а системный менеджер будет запускать код на экземпляре.

Потяните, не извлекайте sh

Вместо того, чтобы «выталкивать» работу в экземпляр, экземпляр может «вытягивать работу»:

  • Сконфигурируйте событие Amazon S3 для pu sh сообщения в очередь Amazon SQS
  • Код экземпляра может регулярно опрашивать очередь SQS
  • Когда он находит сообщение в очереди, он запускает сценарий, который загружает файл (ведро и ключ передаются в сообщении) и затем запускает сценарий обработки

Запуск по HTTP

Экземпляр может запустить веб-сервер, прослушивая сообщение.

  • Настройте событие Amazon S3 на pu * 10 49 * сообщение в топик Amazon SNS c
  • Добавление URL-адреса экземпляра в виде подписки HTTP к топике SNS c
  • Когда сообщение отправляется в SNS, оно пересылает его на URL-адрес экземпляра
  • Код на веб-сервере, затем запускает ваш скрипт
...