如何在不知道当前版本的情况下使用 codedeploy 部署 lambda 函数

问题描述 投票:0回答:1

我正在为我的 lambda 函数设置构建+发布管道。我的构建工作正常,并在运行时发布新的 lambda 版本。我有 2 个别名:

  • 分期
  • 生产

当 codepipeline 运行时,我希望将新版本发布到

staging
别名。这是我的
appspec.yml
,硬编码效果很好:

version: 0.0
resources:
  - myLambdaFunction:
      type: "AWS::Lambda::Function"
      properties:
        name: myLambdaFunction
        alias: staging
        targetversion: "3"
        # current version is required or it will error
        currentversion: "2"

currentversion
应该是
staging
别名指向的版本,但问题是我在部署时不知道这一点,而 AWS 肯定知道 - 事实上,如果我得到,它会抛出错误并终止部署那错了。启动部署时,我理想情况下希望使用 aws cli 获取它当前指向的版本,但 AWS 似乎阻止
hooks
在代码部署中运行 lambda 函数。

我的问题是 - 有没有办法让我在部署脚本中获取给定别名的当前版本(

appspec.yml
)。

我可以在构建过程中替换为

targetversion
,但是由于发布管道不需要在构建后立即运行,因此它可能的当前版本可能会在运行之前发生变化,所以我需要在部署时实际设置它。

amazon-web-services aws-code-deploy
1个回答
0
投票

您说得对,通过 CodeDeploy 进行 Lambda 部署很棘手。 我过去也遇到过同样的问题。 这是一个应该有所帮助的解决方法:

  1. 使用 Lambda 函数作为 CloudFormation 中的自定义资源来获取当前版本。
  2. 在您的 AppSpec 文件中引用此内容。

实现方法如下:

  1. 创建 Lambda 函数来获取当前版本:
import boto3
import cfnresponse

def handler(event, context):
    if event['RequestType'] == 'Delete':
        cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
        return

    lambda_client = boto3.client('lambda')
    function_name = event['ResourceProperties']['FunctionName']
    alias_name = event['ResourceProperties']['AliasName']

    try:
        response = lambda_client.get_alias(
            FunctionName=function_name,
            Name=alias_name
        )
        current_version = response['FunctionVersion']
        cfnresponse.send(event, context, cfnresponse.SUCCESS, 
                         {'CurrentVersion': current_version})
    except Exception as e:
        cfnresponse.send(event, context, cfnresponse.FAILED, 
                         {'Error': str(e)})
  1. 在您的 CloudFormation 模板中,添加:
Resources:
  GetCurrentVersionFunction:
    Type: AWS::Lambda::Function
    Properties:
      # ... (code from step 1)

  GetCurrentVersion:
    Type: Custom::GetCurrentVersion
    Properties:
      ServiceToken: !GetAtt GetCurrentVersionFunction.Arn
      FunctionName: myLambdaFunction
      AliasName: staging

Outputs:
  CurrentVersion:
    Value: !GetAtt GetCurrentVersion.CurrentVersion
  1. 修改您的 AppSpec 以使用此输出:
version: 0.0
Resources:
  - myLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: myLambdaFunction
        Alias: staging
        CurrentVersion: '#{CurrentVersion}'
        TargetVersion: '#{NewVersion}'
  1. 在您的 CodePipeline 中,添加一个步骤以在部署之前更新 CloudFormation 堆栈,并将新版本作为参数传递。

  2. 在 CodeDeploy 中使用变量替换将

    #{CurrentVersion}
    #{NewVersion}
    替换为实际值。

这种方法允许您在部署时动态获取当前版本,解决构建和部署之间潜在更改的问题。

请记住向您的自定义 Lambda 函数和 CodeDeploy 授予必要的 IAM 权限。

© www.soinside.com 2019 - 2024. All rights reserved.