#amazon-web-services #aws-lambda #boto3 #aws-codepipeline #aws-codestar
#amazon-веб-сервисы #aws-lambda #boto3 #aws-codepipeline #aws-codestar
Вопрос:
У меня есть простой AWS CodePipeline со стандартными этапами конвейера «Исходный код» -> «Сборка» -> «Развертывание», которые работают нормально, и я пытаюсь добавить свой собственный конечный этап конвейера, который представляет собой единую функцию AWS 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. По какой-то причине я не видел вызова вашего кода
put_job_success_result
при первом чтении вашего Q. В любом случае, вам не нужно вызыватьput_third_party_job_success_result
. Попробуйте обойтись без нее и добавьте несколько отладочных отпечатков, чтобы проверить, зависает ли она и где.2. Привет @jweyrich — спасибо за ответ и комментарий. Я пробовал без вызовов «third_party_job», но это по-прежнему не удается. Должно быть, мне чего-то не хватает, но я пока не могу понять этого. Я пробовал различные комбинации «put_third_party_job_success_result», «put_job_success_result» и даже «return». Есть еще идеи? Спасибо.
3. Когда она выполняется бесконечно, она отправляет несколько электронных писем — таким образом, она действует так, как будто лямбда-функция вызывается несколько раз. Это подсказка?
4. Возможно ли
put_job_success_result
вызвать исключение? Переместите ее внутрьtry
блока для проверки.
Ответ №1:
Вы упускаете важную интеграцию между вашим 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();
}
Интеграция была разработана таким образом, потому что может потребоваться интеграция с внешним рабочим заданием, в котором их Lambda запускает этот рабочий процесс (например, процесс утверждения), и этот рабочий затем берет на себя управление и решает, был ли весь шаг успешным или неудачным.