1. 简介
Terraform 是一个基础设施即代码(Infrastructure as Code)工具,可以用于创建、修改和管理基础设施。而 AWS Lambda 是一项无服务器计算服务,允许你在无需预置或管理服务器的情况下运行代码。它会根据工作负载自动扩展应用,响应每个触发事件执行代码。
将 Lambda 的无服务器特性与 Terraform 的基础设施即代码(IaC)方法结合,开发者可以获得以下优势:
✅ 版本化的基础设施配置
✅ 与应用代码一起维护
✅ 复制相同配置的环境
✅ 自动化 CI/CD 流程中的基础设施变更
✅ 跟踪基础设施状态
本教程将讲解如何使用 Terraform 配置 AWS Lambda 函数。所有命令均在 Ubuntu 22.04 上测试通过,AWS CLI 版本为 1.37.11。
2. 前提条件
在开始使用 Terraform 配置 AWS Lambda 之前,需要确保满足以下条件:
- 有效的 AWS 账户,并具有适当的权限
- Terraform 已安装在本地:
$ terraform --version
Terraform v1.9.8
on linux_amd64
- AWS CLI 已安装并配置了管理员权限:
$ aws --version
aws-cli/1.37.11 Python/3.10.12 Linux/5.15.0-82-generic botocore/1.36.11
此外,建议具备基本的 AWS 云平台和 Terraform 使用经验。
3. IAM 角色配置
虽然可以使用 AWS CLI 中已配置的管理员凭据,但遵循最小权限原则并使用专用 IAM 用户是 AWS 的最佳实践。
我们创建一个名为 terraform-user 的专用 IAM 用户,并赋予其管理 AWS Lambda 的有限权限:
$ aws iam create-user --user-name terraform-user
{
"User": {
"Path": "/",
"UserName": "terraform-user",
"UserId": "AIDA4T4OCLX5W42FFGY62",
"Arn": "arn:aws:iam::<ACCOUNT_ID>:user/terraform-user",
"CreateDate": "2025-02-14T15:49:05Z"
}
}
接下来,创建一个名为 aws-lambda-terraform 的目录用于存放示例文件:
$ mkdir ~/aws-lambda-terraform && cd ~/aws-lambda-terraform
在该目录下创建一个名为 terraform-policy.json 的 JSON 文件,用于定义 terraform-user 所需权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:CreateFunction",
"lambda:UpdateFunctionCode",
"lambda:DeleteFunction",
"lambda:AddPermission",
"lambda:RemovePermission",
"lambda:GetFunction",
"lambda:ListVersionsByFunction",
"lambda:GetFunctionCodeSigningConfig",
"lambda:GetPolicy",
"lambda:InvokeFunction",
"events:PutRule",
"events:PutTargets",
"events:DeleteRule",
"events:RemoveTargets",
"events:DescribeRule",
"events:ListRules",
"events:ListTagsForResource",
"events:ListTargetsByRule",
"iam:CreateRole",
"iam:PutRolePolicy",
"iam:AttachRolePolicy",
"iam:DeleteRole",
"iam:DetachRolePolicy",
"iam:GetRole",
"iam:PassRole",
"iam:ListRolePolicies",
"iam:ListAttachedRolePolicies",
"iam:ListInstanceProfilesForRole",
"logs:CreateLogGroup",
"logs:DescribeLogGroups"
],
"Resource": [
"arn:aws:lambda:us-east-1:<ACCOUNT_ID>:function:hello_lambda",
"arn:aws:events:us-east-1:<ACCOUNT_ID>:rule/*",
"arn:aws:iam::<ACCOUNT_ID>:role/lambda_exec_role",
"arn:aws:logs:us-east-1:<ACCOUNT_ID>:log-group:*"
]
}
]
}
使用 AWS CLI 创建策略并绑定到 terraform-user:
$ aws iam create-policy \
--policy-name TerraformLambdaPolicy \
--policy-document file://terraform-policy.json
$ aws iam attach-user-policy \
--user-name terraform-user \
--policy-arn "arn:aws:iam::<ACCOUNT_ID>:policy/TerraformLambdaPolicy"
创建访问密钥并配置默认凭据:
$ aws iam create-access-key --user-name terraform-user
{
"AccessKey": {
"UserName": "terraform-user",
"AccessKeyId": "AKIA4T4OCLX5VF63ZO4K",
"Status": "Active",
"SecretAccessKey": <SECRET_ACCESS_KEY>,
"CreateDate": "2025-02-14T15:58:24Z"
}
}
配置 AWS CLI:
$ aws configure
AWS Access Key ID [****************ZO4K]:
AWS Secret Access Key [****************LRvO]:
Default region name [us-east-1]:
Default output format [json]:
至此,我们已完成 Terraform 操作 AWS Lambda 所需的最小权限配置。
4. 项目结构与初始化
项目结构如下:
aws-lambda-terraform/
├── main.tf # Terraform 主配置
├── outputs.tf # 输出定义
└── lambda/
└── hello_lambda.py # Lambda 函数代码
在 main.tf 中配置 AWS Terraform 提供商:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
该配置将 AWS 作为基础设施提供商,并指定所有资源部署在 us-east-1 区域。
5. Lambda 函数配置
5.1. Lambda 函数代码
Lambda 函数代码保存在 lambda/hello_lambda.py 中:
import json
import os
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Hello from Lambda!',
'environment': os.getenv('ENV', 'default')
})
}
该函数接收 event 和 context 参数,返回一个兼容 API Gateway 的 JSON 响应。
5.2. Lambda IAM 角色配置
为 Lambda 函数创建执行角色:
resource "aws_iam_role" "lambda_exec" {
name = "lambda_exec_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "lambda_basic" {
role = aws_iam_role.lambda_exec.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
⚠️ 没有这个 IAM 配置,Lambda 将无法执行或写入日志。
5.3. 资源定义
使用 archive_file 将 Lambda 函数打包为 ZIP 文件:
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "${path.module}/lambda"
output_path = "${path.module}/lambda/lambda_function.zip"
}
创建 Lambda 函数资源:
resource "aws_lambda_function" "hello_lambda" {
filename = data.archive_file.lambda_zip.output_path
function_name = "hello_lambda"
role = aws_iam_role.lambda_exec.arn
handler = "hello_lambda.lambda_handler"
runtime = "python3.9"
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
environment {
variables = {
ENV = "test"
}
}
}
在 outputs.tf 中输出函数名称和 ARN:
output "lambda_function_name" {
value = aws_lambda_function.hello_lambda.function_name
}
output "lambda_arn" {
value = aws_lambda_function.hello_lambda.arn
}
5.4. 部署与测试
初始化 Terraform 并部署:
$ terraform init
$ terraform plan
$ terraform apply
测试 Lambda 函数:
$ aws lambda invoke \
--function-name hello_lambda \
--region us-east-1 \
output.txt
查看输出:
$ cat output.txt
{"statusCode": 200, "body": "{\"message\": \"Hello from Lambda!\", \"environment\": \"test\"}"}
查看日志:
$ aws lambda invoke \
--function-name hello_lambda \
--region us-east-1 \
--log-type Tail \
output.txt | jq -r .LogResult | base64 --decode
6. Lambda 触发器配置
Lambda 的一大用途是响应特定事件(触发器)执行代码。常见的触发服务包括:
✅ Amazon S3(对象创建/删除)
✅ Amazon DynamoDB(表更新)
✅ Amazon API Gateway(API 调用)
✅ Amazon SNS(消息发布)
✅ Amazon EventBridge(定时事件)
6.1. 使用 EventBridge 配置定时触发器
添加定时规则:
resource "aws_cloudwatch_event_rule" "schedule_lambda" {
name = "scheduled_lambda_trigger"
description = "Triggers Lambda every 5 minutes"
schedule_expression = "rate(5 minutes)"
}
绑定 Lambda 函数作为目标:
resource "aws_cloudwatch_event_target" "lambda_target" {
rule = aws_cloudwatch_event_rule.schedule_lambda.name
target_id = "lambda_target"
arn = aws_lambda_function.hello_lambda.arn
}
授予 EventBridge 调用 Lambda 的权限:
resource "aws_lambda_permission" "allow_cloudwatch" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.hello_lambda.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.schedule_lambda.arn
}
6.2. 测试触发器
应用配置:
$ terraform apply
验证规则状态:
$ aws events describe-rule --name scheduled_lambda_trigger
验证目标是否正确:
$ aws events list-targets-by-rule --rule scheduled_lambda_trigger
查看 AWS 控制台中的 Lambda 调用记录:
7. 总结
本文介绍了如何使用 Terraform 配置 AWS Lambda 函数,包括:
✅ 部署 Python Lambda 函数
✅ 创建 IAM 角色与权限
✅ 配置定时触发器(EventBridge)
✅ 部署、测试与日志查看
通过 Terraform 实现了完整的 Lambda 基础设施管理,为构建可复用、可版本控制的 Serverless 架构打下基础。