AWS CodePipeline 自定义 Lambda 函数永远运行 Returns

AWS CodePipeline Custom Lambda Function Runs Forever and Never Returns

我有一个简单的 AWS CodePipeline,标准 "Source" -> "Build" -> "Deploy" 管道阶段工作正常,我正在尝试添加我自己的自定义最终管道阶段这是单个 AWS Lambda 函数。问题是我的最后一个自定义 Lambda 函数运行了很长时间后,出现以下消息的错误:

整个流水线请看附件截图:

当管道到达最后一步时,它会在 "Blue ( In-Progress )" 状态下旋转很长时间,然后显示错误,如下所示:

这是我的 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."

如何让 Lambda 触发一次并 return 以便管道能够正常完成。谢谢!

您缺少 Lambda FunctionCodePipeline 服务之间的重要集成。

您必须通知 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();
}

以这种方式设计集成是因为人们可能希望与外部工作人员集成,其中他们的 Lambda 启动该工作人员(例如,批准流程),然后该工作人员控制并决定是否完成整个步骤成功或失败。