Пользовательская лямбда-функция AWS CodePipeline работает вечно и никогда не возвращается - PullRequest
2 голосов
/ 27 марта 2019

У меня есть простая AWS CodePipeline со стандартными этапами конвейера «Source» -> «Build» -> «Deploy», которые работают нормально, и я пытаюсь добавить свой собственный конечный этап конвейера, который представляет собой одну лямбда-функцию AWS.Проблема в том, что моя последняя, ​​настраиваемая лямбда-функция запускается несколько раз и через очень долгое время выдает ошибки со следующим сообщением:

enter image description here

См. Прилагаемыйснимок экрана для всего конвейера:

enter image description here

Когда конвейер достигает этого последнего шага, он очень долго вращается с "Blue (In-Progress)) "перед отображением ошибки, как показано здесь:

enter image description here

Вот мой код функции Lambda:

from __future__ import print_function
import hashlib
import time
import os
import boto3
import json
from botocore.exceptions import ClientError

def lambda_handler(event, context):

    # Test
    AWS_ACCESS_KEY = ASDF1234
    AWS_SECRET_KEY = ASDF1234
    SQS_TESTING_OUTPUT_STATUS_QUEUE_NAME = 'TestingOutputQueue'

    # Get the code pipeline
    code_pipeline = boto3.client('codepipeline')

    # Get the job_id
    for key, value in event.items():
        print(key,value)
    job_id = event['CodePipeline.job']['id']
    DATA = json.dumps(event)

    # Create a connection the SQS Notification service
    sqs_resource_connection = boto3.resource(
        'sqs',
        aws_access_key_id = AWS_ACCESS_KEY,
        aws_secret_access_key = AWS_SECRET_KEY,
        region_name = 'us-west-2'
    )

    # Get the queue handle
    print("Waiting for notification from AWS ...")
    queue = sqs_resource_connection.get_queue_by_name(QueueName = SQS_TESTING_OUTPUT_STATUS_QUEUE_NAME)
    messageContent = ""
    cnt = 1

    # Replace sender@example.com with your "From" address.
    # This address must be verified with Amazon SES.
    SENDER = ME

    # Replace recipient@example.com with a "To" address. If your account
    # is still in the sandbox, this address must be verified.
    RECIPIENTS = [YOU]

    # If necessary, replace us-west-2 with the AWS Region you're using for Amazon SES.
    AWS_REGION = "us-east-1"

    # The subject line for the email.
    SUBJECT = "Test Case Results"

    # The email body for recipients with non-HTML email clients.
    BODY_TEXT = ("Test Case Results Were ...")

    # The HTML body of the email.
    BODY_HTML = """<html>
    <head></head>
    <body>
      <h1>Amazon SES Test (SDK for Python)</h1>
      <p>%s</p>
    </body>
    </html>
                """%(DATA)

    # The character encoding for the email.
    CHARSET = "UTF-8"

    # Create a new SES resource and specify a region.
    client = boto3.client('ses', region_name=AWS_REGION)

    # Try to send the email.
    try:
        # Provide the contents of the email.
        response = client.send_email(
            Destination={
                'ToAddresses': RECIPIENTS,
            },
            Message={
                'Body': {
                    'Html': {
                        'Charset': CHARSET,
                        'Data': BODY_HTML,
                    },
                    'Text': {
                        'Charset': CHARSET,
                        'Data': BODY_TEXT,
                    },
                },
                'Subject': {
                    'Charset': CHARSET,
                    'Data': SUBJECT,
                },
            },
            Source=SENDER,
            # If you are not using a configuration set, comment or delete the
            # following line
            #ConfigurationSetName=CONFIGURATION_SET,
        )
    # Display an error if something goes wrong.
    except ClientError as e:
        code_pipeline.put_third_party_job_failure_result(jobId=job_id, failureDetails={'message': message, 'type': 'JobFailed'})
        code_pipeline.put_job_failure_result(jobId=job_id, failureDetails={'message': message, 'type': 'JobFailed'})      
        print(e.response['Error']['Message'])
    else:
        code_pipeline.put_third_party_job_success_result(jobId=job_id)
        code_pipeline.put_job_success_result(jobId=job_id)
        print("Email sent! Message ID:"),
        print(response['MessageId'])

    print('Function complete.')   
    return "Complete."

Как можноЯ заставляю Лямбду выстрелить один раз и возвращаюсь, чтобы трубопровод мог завершиться правильно.Спасибо!

1 Ответ

4 голосов
/ 27 марта 2019

Вам не хватает важной интеграции между вашим Lambda Function и CodePipeline сервисом.

Вы ДОЛЖНЫ уведомить CodePipeline о результате вашего пользовательского шага, независимо от того, был он успешным или нет - см. Мои примерыниже.

Отчет об успехе:

function reportSuccess(job_id) {
  var codepipeline = new AWS.CodePipeline();
  var params = {
    jobId: job_id,
  };
  return codepipeline.putJobSuccessResult(params).promise();
}

Ошибка отчета:

function reportFailure(job_id, invoke_id, message) {
  var codepipeline = new AWS.CodePipeline();
  var params = {
    failureDetails: {
      message: message,
      type: 'JobFailed',
      externalExecutionId: invoke_id,
    },
    jobId: job_id,
  };
  return codepipeline.putJobFailureResult(params).promise();
}

Интеграция была разработана таким образом, потому что может потребоваться интеграция с внешним рабочим,в котором их лямбда запускает этого работника (например, процесс утверждения), а затем этот работник берет на себя управление и решает, прошел ли весь этап успешно или нет.

...