如何从AWS CodeDeploy向Lambda传递targetASG参数?
我之前也碰到过一模一样的问题——CodeDeploy的触发器确实没有提供直接输入自定义参数的入口,所以你的Lambda才会抛出KeyError: 'targetASG',因为CodeDeploy发送给Lambda的事件 payload 里根本没有这个字段。下面是几个我亲测有效的解决方案,你可以根据自己的场景选择:
方法一:从CodeDeploy事件关联的部署组自动获取ASG名称
如果你的CodeDeploy部署组已经关联了目标Auto Scaling组,那完全不用手动传参数,直接在Lambda里通过CodeDeploy API拉取部署组对应的ASG信息就行:
- 确保你的Lambda角色拥有
codedeploy:GetDeploymentGroup和autoscaling:DescribeAutoScalingGroups的权限 - 修改Lambda代码,从CodeDeploy事件中提取部署组信息,再查询关联的ASG:
import boto3 codedeploy_client = boto3.client('codedeploy') asg_client = boto3.client('autoscaling') def lambda_handler(event, context): # 从CodeDeploy事件payload中提取应用和部署组名称 app_name = event['detail']['applicationName'] deployment_group_name = event['detail']['deploymentGroupName'] # 查询部署组详细配置,获取关联的Auto Scaling组 deployment_group = codedeploy_client.get_deployment_group( applicationName=app_name, deploymentGroupName=deployment_group_name ) # 取第一个关联的ASG(若部署组仅关联一个ASG) target_asg = deployment_group['deploymentGroupInfo']['autoScalingGroups'][0]['name'] # 执行原有逻辑 asg_details = asg_client.describe_auto_scaling_groups(AutoScalingGroupNames=[target_asg]) # ... 你的其他代码
这个方法无需额外配置,只要部署组和ASG关联正确就可以工作,非常适合一对一的场景。
方法二:通过SNS中间层传递自定义参数
如果你的场景需要更灵活的参数传递(比如同一个Lambda要处理多个ASG),可以加个SNS主题当中间层,这样就能在消息里添加自定义参数:
- 创建一个SNS主题,比如
CodeDeploy-Success-Notifications - 修改CodeDeploy的触发器,将「部署成功」的事件通知发送到这个SNS主题
- 将你的Lambda函数订阅到该SNS主题
- 传递参数的两种方式:
- 静态映射:在Lambda里维护部署组到ASG的映射字典,从SNS消息中拿到部署组名称后匹配:
import boto3 import json asg_client = boto3.client('autoscaling') # 维护部署组与ASG的对应关系 deployment_group_to_asg = { "my-web-deployment-group": "web-server-asg", "my-api-deployment-group": "api-server-asg" } def lambda_handler(event, context): # 解析SNS消息中的CodeDeploy事件内容 sns_message = json.loads(event['Records'][0]['Sns']['Message']) deployment_group = sns_message['detail']['deploymentGroupName'] target_asg = deployment_group_to_asg[deployment_group] # 执行原有逻辑 asg_details = asg_client.describe_auto_scaling_groups(AutoScalingGroupNames=[target_asg]) # ... 其他代码 - 动态添加参数:如果需要在部署过程中动态传递参数,可以在CodeDeploy的部署钩子脚本里调用SNS的
publishAPI,手动发送带自定义参数的消息,Lambda就能直接从SNS消息的属性中拿到targetASG。
- 静态映射:在Lambda里维护部署组到ASG的映射字典,从SNS消息中拿到部署组名称后匹配:
方法三:给Lambda设置环境变量
如果这个Lambda专门为某一个ASG服务,最简单的办法就是把targetASG设为Lambda的环境变量:
- 打开Lambda控制台,进入你的函数,切换到「配置」标签页
- 选择「环境变量」,点击「编辑」,添加键为
targetASG、值为你的ASG名称的变量 - 修改Lambda代码,从环境变量中读取参数:
import boto3 import os asg_client = boto3.client('autoscaling') def lambda_handler(event, context): # 从环境变量获取ASG名称 target_asg = os.environ['targetASG'] asg_details = asg_client.describe_auto_scaling_groups(AutoScalingGroupNames=[target_asg]) # ... 其他代码
这个方法最省事,适合单一用途的Lambda函数。
最后补充一下:你遇到的KeyError,是因为CodeDeploy触发Lambda时发送的事件结构是固定的,大致如下:
{
"version": "0",
"detail-type": "CodeDeploy Deployment State-change Notification",
"source": "aws.codedeploy",
"detail": {
"applicationName": "你的应用名",
"deploymentGroupName": "你的部署组名",
"state": "SUCCEEDED"
// 其他固定字段
}
}
里面根本没有targetASG这个键,所以直接取值肯定会报错。
内容的提问来源于stack exchange,提问作者Frodo

