Amazon web services Terraform在每个应用程序上为Lambda重新创建API权限,从而导致停机(Lambda模块、无服务器框架、VPC)
我有一个Lambda创建通过。它指向一个版本化的Lambda,因为我使用了保留并发。它还驻留在专有网络中 配置如下所示:Amazon web services Terraform在每个应用程序上为Lambda重新创建API权限,从而导致停机(Lambda模块、无服务器框架、VPC),amazon-web-services,aws-lambda,terraform,serverless-framework,terraform-provider-aws,Amazon Web Services,Aws Lambda,Terraform,Serverless Framework,Terraform Provider Aws,我有一个Lambda创建通过。它指向一个版本化的Lambda,因为我使用了保留并发。它还驻留在专有网络中 配置如下所示: module "my-lambda" { source = "terraform-aws-modules/lambda/aws" version = "~> v1.45.0" function_name = "${local.lambda_name}" d
module "my-lambda" {
source = "terraform-aws-modules/lambda/aws"
version = "~> v1.45.0"
function_name = "${local.lambda_name}"
description = local.lambda_name
handler = "handler.handler"
runtime = "python3.8"
hash_extra = local.lambda_name
attach_tracing_policy = true
tracing_mode = "Active"
publish = true
vpc_security_group_ids = [
// required VPC security groups
]
vpc_subnet_ids = var.private_subnet_ids
source_path = [
// ... abriged
]
build_in_docker = true
provisioned_concurrent_executions = var.provisioned_concurrency_lambdas
create_current_version_allowed_triggers = true
create_unqualified_alias_allowed_triggers = false
allowed_triggers = {
APIGateway = {
service = "apigateway"
source_arn = "${module.my_api_gateway.this_apigatewayv2_api_execution_arn}/*"
}
}
attach_policies = true
policies = [
// policies needed for a VPC lambda
]
}
我发现,在terraform plan中,即使我不做任何更改并反复发布terraform plan
,这种替换仍在发生,这导致重新创建API网关权限,并基本上减少了停机时间:
# module.my_entire_api.module.my-lambda.aws_lambda_permission.current_version_triggers["APIGateway"] must be replaced
-/+ resource "aws_lambda_permission" "current_version_triggers" {
~ id = "APIGateway" -> (known after apply)
~ qualifier = "1" -> (known after apply) # forces replacement
# (5 unchanged attributes hidden)
}
# module.my_entire_api.module.my-lambda.aws_lambda_provisioned_concurrency_config.current_version[0] must be replaced
-/+ resource "aws_lambda_provisioned_concurrency_config" "current_version" {
~ id = "env-my-lambda:1" -> (known after apply)
~ qualifier = "1" -> (known after apply) # forces replacement
# (2 unchanged attributes hidden)
}
还有一些其他lambda不在VPC中运行。目前,我没有看到这种效果在这些,而我不完全肯定,它从来没有发生过
可以肯定的是,我并不关心并发配置,因为重新创建它不会导致停机。但是我想配置模块,使aws_lambda_权限不会被重新创建。我怎么可能做到这一点呢?terraform提供商aws中的一个问题:
从文件中 通常,Lambda函数资源会在源代码更改时更新。如果指定了
publish=true
,则还将创建新的Lambda函数版本
因此,每次部署时,都会部署一个新版本,该版本在相应的资源中引用以更新策略。因此,它每次都会触发更新
根据您为部署和发布派生上下文的位置,通常部署意味着使用新代码重新部署lambda,而发布则增加lambda版本(而不是重新部署代码)
我所面临的问题归结为几件事
- 在设置并发性时,必须“发布”lambda,以便它们具有适当的版本限定符(类似于“1”而不是
),因此,允许网关调用lambda的lambda权限绑定到特定的lambda版本。当您创建另一个版本时,这些权限将被销毁,并为新的Lambda版本重新创建<代码>在销毁之前创建生命周期标志可能会有所帮助。我还没有看到在没有变化的情况下为非专有网络lambda重新创建这些;更改Lambda后,在Lambda中删除和重新创建API网关的重新保存的并发性和权限只需几分钟$LATEST
- 此外,即使Lambda没有改变,VPC Lambda也会经历并发性和权限的再创造,Terraform bug
Resource=
指令将允许此角色调用所有lambda。您可能希望将这些权限限制为lambda的子集,以提高安全性并减少人为错误
设置此角色后,我使用一个常用模块配置API网关:
但我不更新lambda本身,只运行apply几个times@AskarIbragimov在每次部署中,它都会创建一个新版本。不,它不会:)@AskarIbragimov至少docs这么说。@AskarIbragimov
aws_lambda_函数
根据。您共享的部署日志中也显示了同样的内容。
publish = true
variable "publish" {
description = "Whether to publish creation/change as new Lambda Function Version."
type = bool
default = false
}
resource "aws_lambda_permission" "current_version_triggers" {
for_each = var.create && var.create_function && !var.create_layer && var.create_current_version_allowed_triggers ? var.allowed_triggers : {}
function_name = aws_lambda_function.this[0].function_name
qualifier = aws_lambda_function.this[0].version
resource "aws_iam_role" "api_gateway_credentials_call_lambda" {
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "lambda.amazonaws.com"
},
Action = "sts:AssumeRole"
},
{
Effect = "Allow",
Principal = {
Service = "apigateway.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
inline_policy {
name = "permission-apigw-lambda-invokefunction"
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
Effect = "Allow",
Action = "lambda:InvokeFunction",
Resource = "arn:aws:lambda:*:${data.aws_caller_identity.current.account_id}:function:*"
}
]
})
}
}
module "api_gateway" {
source = "terraform-aws-modules/apigateway-v2/aws"
version = "~> 0.14.0"
# various parameters ...
# Routes and integrations
integrations = {
"GET /myLambda" = {
integration_type = "AWS_PROXY"
integration_http_method = "POST"
payload_format_version = "2.0"
lambda_arn = my_lambda_qualified_arn
# This line enables the permissions:
credentials_arn = aws_iam_role.api_gateway_credentials_call_lambda.arn
}