Amazon web services AWS CodePipeline自定义Lambda函数永远运行,永远不会返回

Amazon web services AWS CodePipeline自定义Lambda函数永远运行,永远不会返回,amazon-web-services,aws-lambda,boto3,aws-codepipeline,aws-codestar,Amazon Web Services,Aws Lambda,Boto3,Aws Codepipeline,Aws Codestar,我有一个简单的AWS代码管道,带有标准的“Source”->“Build”->“Deploy”管道阶段,运行良好,我正在尝试添加我自己的定制最终管道阶段,即单个AWS Lambda函数。问题是我的最后一个自定义Lambda函数多次运行,经过很长时间后,出现以下错误消息: 请参见随附的整个管道的屏幕截图: 当管道到达这最后一步时,它会在显示错误之前以“蓝色(进行中)”状态旋转很长时间,如下所示: 这是我的Lambda函数代码: from __future__ import print_fun

我有一个简单的AWS代码管道,带有标准的“Source”->“Build”->“Deploy”管道阶段,运行良好,我正在尝试添加我自己的定制最终管道阶段,即单个AWS Lambda函数。问题是我的最后一个自定义Lambda函数多次运行,经过很长时间后,出现以下错误消息:

请参见随附的整个管道的屏幕截图:

当管道到达这最后一步时,它会在显示错误之前以“蓝色(进行中)”状态旋转很长时间,如下所示:

这是我的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."
from\uuuuu future\uuuuu导入打印功能
导入hashlib
导入时间
导入操作系统
进口boto3
导入json
从botocore.exceptions导入ClientError
def lambda_处理程序(事件、上下文):
#试验
AWS\u访问\u密钥=ASDF1234
AWS_SECRET_KEY=ASDF1234
SQS\测试\输出\状态\队列\名称='TestingOutputQueue'
#获取代码管道
code_pipeline=boto3.client('code管道')
#拿到工作证
对于键,event.items()中的值:
打印(键、值)
job_id=event['codepippeline.job']['id']
DATA=json.dumps(事件)
#在SQS通知服务中创建连接
sqs_资源_连接=bot3.resource(
“sqs”,
aws\u访问密钥\u id=aws\u访问密钥,
aws_secret_access_key=aws_secret_key,
地区名称='us-west-2'
)
#获取队列句柄
打印(“等待AWS通知…”)
queue=sqs\u资源\u连接。通过名称获取队列(QueueName=sqs\u测试\u输出\u状态\u队列\u名称)
messageContent=“”
cnt=1
#替换sender@example.com用你的“发件人”地址。
#必须通过Amazon SES验证此地址。
发送者=我
#替换recipient@example.com带有“收件人”地址。如果你的帐户
#仍在沙箱中,必须验证此地址。
收件人=[您]
#如有必要,将us-west-2替换为您用于Amazon SES的AWS区域。
AWS_REGION=“美国东部-1”
#电子邮件的主题行。
SUBJECT=“测试用例结果”
#具有非HTML电子邮件客户端的收件人的电子邮件正文。
正文文本=(“测试用例结果为…”)
#电子邮件的HTML正文。
BODY_HTML=“”
AmazonSES测试(Python的SDK)
%

“”“%(数据) #电子邮件的字符编码。 CHARSET=“UTF-8” #创建新的SES资源并指定区域。 客户机=boto3.客户机('ses',地区名称=AWS\U地区) #尝试发送电子邮件。 尝试: #提供电子邮件的内容。 响应=client.send_电子邮件( 目的地={ “ToAddress”:收件人, }, 信息={ “身体”:{ “Html”:{ “字符集”:字符集, “数据”:正文和HTML, }, “文本”:{ “字符集”:字符集, “数据”:正文文本, }, }, “主题”:{ “字符集”:字符集, “数据”:主题, }, }, 来源=发送方, #如果未使用配置集,请注释或删除 #下线 #ConfigurationSetName=配置集合, ) #如果出现错误,则显示错误。 除ClientError作为e外: 代码\u管道。放置\u第三方\u作业\u失败\u结果(jobId=job\u id,failureDetails={'message':消息,'type':'JobFailed'}) 代码\u管道。放置\u作业\u失败\u结果(jobId=job\u id,failureDetails={'message':消息,'type':'JobFailed'}) 打印(例如响应['Error']['Message']) 其他: 编码管道。放置第三方作业成功结果(作业id=作业id) 编码管道。放置作业成功结果(作业id=作业id) 打印(“已发送电子邮件!邮件ID:”), 打印(响应['MessageId']) 打印('功能完成') 返回“完成”

如何让Lambda一次点火并返回,以便管道能够正常完成。谢谢

您缺少
Lambda函数
codepippeline
服务之间的重要集成

您必须将自定义步骤的结果通知
codepippeline
,无论它是否成功-请参阅下面的示例

报告成功:

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在其中启动该工作人员(例如,批准流程),然后,该工作人员控制并决定整个步骤是成功还是失败。

由于某种原因,我在第一次阅读你的问题时没有看到你的代码调用
put\u job\u success\u result
。无论如何,你不需要调用
put\u third party\u job\u success\u result
。尝试不使用它,并添加一些调试打印以检查它是否挂起以及挂起的位置。Hi@jweyrich-感谢您的回答和评论。我试过不打“第三方工作”电话,但还是失败了。我肯定错过了什么,但我还没弄明白。我尝试过各种组合,包括“投入第三方工作成功结果”、“投入工作成功结果”,甚至还有“回报”。还有其他想法吗?谢谢。当它无限期运行时,它会发送多封电子邮件-因此它的行为就像lambda函数被调用了好几次一样。这是线索吗?
put\u job\u success\u result
是否可能引发异常?将其移动到
试着
块中进行验证。