我正在Terraform v0.12模块中动态创建以下资源:
variables.tf:
variable "stages" {
type = list(string)
default = ["v1", "v2"]
}
variable "rest_api_id" {
description = "The ID of the associated REST API"
}
variable "api_root_resource_id" {
description = "The API resource ID"
}
variable "region" {
description = "The AWS region"
}
variable "method" {
description = "The HTTP method"
default = "GET"
variable "lambda" {
description = "The lambda name to invoke"
}
variable "account_id" {
description = "The AWS account ID"
}
main.tf
resource "aws_lambda_permission" "lambda_permision" {
count = length(var.stages)
statement_id = "${var.lambda}${element(var.stages, count.index)}Invoke"
action = "lambda:InvokeFunction"
function_name = "${var.lambda}:${element(var.stages, count.index)}"
principal = "apigateway.amazonaws.com"
source_arn = "arn:aws:execute-api:${var.region}:${var.account_id}:${var.rest_api_id}/*/${var.method}${aws_api_gateway_resource.api_resource.path}"
}
输入不变。但是每一次申请我都会收到以下通知:
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# module.signurl_get.aws_lambda_permission.lambda_permision[0] must be replaced
-/+ resource "aws_lambda_permission" "lambda_permision" {
action = "lambda:InvokeFunction"
~ function_name = "peng_lambda_test_version_eu_dev" -> "peng_lambda_test_version_eu_dev:v1" # forces replacement
~ id = "peng_lambda_test_version_eu_devv1Invoke" -> (known after apply)
principal = "apigateway.amazonaws.com"
- qualifier = "v1" -> null # forces replacement
source_arn = "arn:aws:execute-api:eu-west-1:887428995966:t4m0c9z1uk/*/GET/signurl"
statement_id = "peng_lambda_test_version_eu_devv1Invoke"
}
# module.signurl_get.aws_lambda_permission.lambda_permision[1] must be replaced
-/+ resource "aws_lambda_permission" "lambda_permision" {
action = "lambda:InvokeFunction"
~ function_name = "peng_lambda_test_version_eu_dev" -> "peng_lambda_test_version_eu_dev:v2" # forces replacement
~ id = "peng_lambda_test_version_eu_devv2Invoke" -> (known after apply)
principal = "apigateway.amazonaws.com"
- qualifier = "v2" -> null # forces replacement
source_arn = "arn:aws:execute-api:eu-west-1:887428995966:t4m0c9z1uk/*/GET/signurl"
statement_id = "peng_lambda_test_version_eu_devv2Invoke"
}
答案 0 :(得分:4)
使用aws_lambda_permission
资源时,您的函数名称应为unqualified Lambda function name。如果您需要指定别名来版本化Lambda,则应使用qualifier
parameter代替。
现在,Terraform正在尝试将函数名称设置为包括限定符,并将限定符设置为nil。 AWS API很乐意接受此操作并执行您想要的操作,但是随后当Terraform刷新并更新其状态时,它会看到该函数名称已去除了限定符并且已设置了qualifier参数,因此它尝试将其强制返回到代码告诉它应该的方式。不幸的是,此操作也不支持对Lambda权限资源进行适当的升级,因此它还需要删除现有的Lambda权限并重新创建。
从函数名称中删除限定符并将其添加到适当的qualifier
参数中可以解决此问题:
resource "aws_lambda_permission" "lambda_permision" {
count = length(var.stages)
statement_id = "${var.lambda}${var.stages[count.index]}Invoke"
action = "lambda:InvokeFunction"
function_name = "${var.lambda}"
qualifier = ${var.stages[count.index]}"
principal = "apigateway.amazonaws.com"
source_arn = "arn:aws:execute-api:${var.region}:${var.account_id}:${var.rest_api_id}/*/${var.method}${aws_api_gateway_resource.api_resource.path}"
}
在上面的示例中,我还用带有方括号符号的直线列表索引替换了element
函数。如果您需要多次循环遍历列表而不对索引取模,element
很有用,否则方括号表示法会更易读且具有相同的行为。
如前所述,当您使用Terraform 0.12时,也可以在不连接字符串和变量时使用新的语法:
resource "aws_lambda_permission" "lambda_permision" {
count = length(var.stages)
statement_id = "${var.lambda}${var.stages[count.index]}Invoke"
action = "lambda:InvokeFunction"
function_name = var.lambda
qualifier = var.stages[count.index]
principal = "apigateway.amazonaws.com"
source_arn = "arn:aws:execute-api:${var.region}:${var.account_id}:${var.rest_api_id}/*/${var.method}${aws_api_gateway_resource.api_resource.path}"
}