Я хочу запустить шаблон CloudFormation с CodePipeline. Этот шаблон ожидает входной параметр, который должен содержать текущую дату / время. К сожалению, CloudFormation не может генерировать текущий DateTime самостоятельно из коробки.
Мой подход состоял в том, чтобы сначала запустить простую лямбда-функцию, чтобы создать текущую метку времени и сохранить ее как OutputArtifacts
. Впоследствии задача CloudFormation импортирует этот артефакт как InputArtifacts
, получает значение из атрибута DateTime и передает его в CloudFormation с помощью инструкции ParameterOverrides
.
К сожалению, CodePipeline продолжает говорить, что параметр DateTimeInput
недопустим (очевидно, что поиск GetArtifactAtt не удался).
Я предполагаю, что лямбда-вывод (python: print) не сохраняется как артефакт правильно?
Знаете ли вы, как правильно передавать лямбда-вывод, или у вас есть идея, как этого добиться лучше?
Все компоненты конвейера определены в CloudFormation как YAML. Вот соответствующие части:
Лямбда-функция:
Resources:
...
GetDateTimeFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.lambda_handler
Runtime: python2.7
Timeout: '10'
Role: !GetAtt GetDateTimeFunctionExecutionRole.Arn
Code:
ZipFile: |
import datetime
import boto3
import json
code_pipeline = boto3.client('codepipeline')
def lambda_handler(event, context):
now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
responseData = {'DateTime':now}
print json.dumps(responseData)
response = code_pipeline.put_job_success_result(jobId=event['CodePipeline.job']['id'])
return response
Вот конвейерные задачи:
Resources:
...
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
ArtifactStore:
Location: !Ref ArtifactStoreBucket
Type: S3
DisableInboundStageTransitions: []
Name: !Ref PipelineName
RoleArn: !GetAtt PipelineRole.Arn
Stages:
- Name: Deploy
Actions:
- Name: GetDateTime
RunOrder: 1
ActionTypeId:
Category: Invoke
Owner: AWS
Provider: Lambda
Version: '1'
Configuration:
FunctionName: !Ref GetDateTimeFunction
OutputArtifacts:
- Name: GetDateTimeOutput
- Name: CreateStack
RunOrder: 2
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CloudFormation
Version: '1'
InputArtifacts:
- Name: TemplateSource
- Name: GetDateTimeOutput
Configuration:
ActionMode: REPLACE_ON_FAILURE
Capabilities: CAPABILITY_IAM
RoleArn: !GetAtt CloudFormationRole.Arn
StackName: !Ref CFNStackname
TemplatePath: !Sub TemplateSource::${CFNScriptfile}
TemplateConfiguration: !Sub TemplateSource::${CFNConfigfile}
ParameterOverrides: |
{
"DateTimeInput" : { "Fn::GetArtifactAtt" : [ "GetDateTimeOutput", "DateTime" ] }
}
Обновление : Я был наивным и думал, что будет простой способ.
Теперь я знаю, что это более сложная и ручная задача - просто доставить простой выходной артефакт с помощью лямбды.
Внутри кода Python нужно оценить переданный event
словарь (CodePipeline.job
) для поиска:
- предопределенные выходные Артефакты (S3 Bucket / Key) и
- временные учетные данные сеанса S3, предоставляемые CodePipeline.
Затем клиент S3 должен быть инициализирован этими учетными данными. S3 put_object
необходимо запустить позже.
https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html
https://forums.aws.amazon.com/thread.jspa?threadID=232174
Итак, мой вопрос снова: у вас, ребята, есть идея, как добиться этого лучшим или более простым способом?
Я просто хочу указать текущую дату и время в качестве входного параметра для CloudFormation и не хочу нарушать автоматизацию.