You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Lambda Python代码中引用Terraform生成的SNS ARN?

如何在Python Lambda代码中引用Terraform动态生成的SNS Topic ARN?

问题背景

我的Lambda Python代码需要调用SNS Topic,但该Topic的ARN是由Terraform动态创建生成的,无法在代码中硬写固定值,需要找到动态引用的方法。


方案1:通过Lambda环境变量传递(推荐)

这是AWS基础设施与代码解耦的最佳实践,无需修改代码逻辑,仅通过配置传递参数。

步骤1:在Terraform中为Lambda配置环境变量

修改你的Lambda资源定义,添加environment块,将SNS Topic的ARN注入为环境变量:

resource "aws_lambda_function" "vote_processor" {
  # 保留原有配置(如filename、function_name、role、runtime等)
  environment {
    variables = {
      # 将动态生成的SNS ARN传入Lambda环境变量
      SNS_TOPIC_ARN = aws_sns_topic.vote_sns.arn
    }
  }
}

步骤2:为Lambda添加SNS发布权限

确保Lambda的执行IAM角色拥有向该SNS Topic发布消息的权限,补充Terraform配置:

data "aws_iam_policy_document" "lambda_sns_publish" {
  statement {
    actions   = ["sns:Publish"]
    resources = [aws_sns_topic.vote_sns.arn]
  }
}

resource "aws_iam_role_policy" "lambda_sns_access" {
  name = "lambda-sns-publish-permission"
  role = aws_iam_role.lambda_exec_role.id
  policy = data.aws_iam_policy_document.lambda_sns_publish.json
}

步骤3:修改Python代码读取环境变量

在Lambda代码中通过os.environ获取环境变量中的ARN:

import os
import boto3

def lambda_handler(event, context):
    try:            
        # 业务逻辑代码
        publish_vote(vote, voter)
    except Exception as e:
        # 异常处理逻辑
        print(f"Error: {str(e)}")
    
    return {'statusCode': 200, 'body': '{"status": "success"}'}

def publish_vote(vote, voter):
    sns = boto3.client('sns', region_name='us-east-1')
    # 从环境变量中读取动态生成的SNS ARN
    sns_topic_arn = os.environ.get('SNS_TOPIC_ARN')

    sns.publish(
        TopicArn=sns_topic_arn,
        Message='',
        MessageAttributes={
            "vote": {
                "DataType": "String",
                "StringValue": vote,
            },
            "voter": {
                "DataType": "String",
                "StringValue": voter,
            }          
        }
    )

方案2:通过Terraform模板动态生成Lambda代码(不推荐)

这种方式会将基础设施配置直接嵌入业务代码,耦合度高,仅适合特殊场景。

步骤1:将Python代码改为模板文件

创建带占位符的代码模板(如lambda_template.tpl):

import boto3

def lambda_handler(event, context):
    try:            
        # 业务逻辑代码
        publish_vote(vote, voter)
    except Exception as e:
        # 异常处理逻辑
        print(f"Error: {str(e)}")
    
    return {'statusCode': 200, 'body': '{"status": "success"}'}

def publish_vote(vote, voter):
    sns = boto3.client('sns', region_name='us-east-1')

    sns.publish(
        TopicArn='${sns_topic_arn}',
        Message='',
        MessageAttributes={
            "vote": {
                "DataType": "String",
                "StringValue": vote,
            },
            "voter": {
                "DataType": "String",
                "StringValue": voter,
            }          
        }
    )

步骤2:用Terraform渲染模板并打包Lambda

在Terraform中使用templatefile函数替换占位符,生成最终代码并打包:

resource "aws_lambda_function" "vote_processor" {
  filename      = "lambda_function.zip"
  function_name = "vote-processor"
  role          = aws_iam_role.lambda_exec_role.arn
  handler       = "lambda_function.lambda_handler"
  runtime       = "python3.11"

  # 渲染模板并计算代码哈希值
  source_code_hash = filebase64sha256(templatefile("${path.module}/lambda_template.tpl", {
    sns_topic_arn = aws_sns_topic.vote_sns.arn
  }))
}

方案对比

  • 方案1:解耦配置与代码,无需重新打包即可修改ARN,符合DevOps最佳实践,优先推荐。
  • 方案2:代码与基础设施绑定,维护成本高,仅在特殊场景下使用。

内容的提问来源于stack exchange,提问作者ERJAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:05:26