地形-根据条件创建或不创建资源



我需要在指定的环境中创建资源。例如,如果我有一个AWS Lambda还没有准备好进行生产,我需要它只存在于开发环境中。有什么好方法吗?我知道可以将count设置为0,但我不确定如何将此决定级联到其他资源。

例如,我有一个AWS Lambda的资源,并且count设置为0。

resource "aws_lambda_function" "example_lambda" {
count ? local.is_production ? 0 : 1
}

如何将此决定级联到依赖于上述AWS Lambda的其他资源?

假设我有一个S3 Bucket,它将调用Lambda函数。

resource "aws_s3_bucket" "example_bucket" {
bucket = "bucket_name"
}
resource "aws_lambda_permission" "example_bucket_etl" {
statement_id  = "AllowExecutionFromS3Bucket"
action        = "lambda:InvokeFunction"
function_name = aws_lambda_function.example_lambda.arn
principal     = "s3.amazonaws.com"
source_arn    = aws_s3_bucket.example_bucket.arn
}
resource "aws_s3_bucket_notification" "bucket_notification" {
bucket = aws_s3_bucket.example_bucket.id
lambda_function {
lambda_function_arn = aws_lambda_function.example_lambda.arn
events              = ["s3:ObjectCreated:*"]
filter_prefix       = "example_bucket/"
filter_suffix       = ".txt"

lambda_function {
lambda_function_arn = aws_lambda_function.another_lambda_function.arn
events              = ["s3:ObjectCreated:*"]    
filter_prefix       = "another_example_bucket/"
filter_suffix       = ".txt"
}
}

您可以在多个资源上使用相同的计数变量。如果代码中可能的话,一个更好、更清晰的方法是将所有资源添加到一个模块中。https://www.terraform.io/docs/language/meta-arguments/count.html

当在resource块中使用count时,Terraform会将对其他资源的引用视为生成表示该资源的每个实例的对象列表。

由于该值只是一个普通的列表值,您可以取其长度,以便简明地写下本质上是语句"的内容;每个X〃应该有一个Y;,或者在您的具体情况下";对于每个lambda函数应该有一个lambda权限;。

例如:

resource "aws_lambda_function" "example" {
count = local.is_production ? 0 : 1
# ...
}
resource "aws_lambda_permission" "example_bucket_etl" {
count = length(aws_lambda_function.example)
function_name = aws_lambda_function.example[count.index].name
# ...
}

aws_lambda_permission配置中,我们首先将计数设置为aws_lambda_function.example的计数,这告诉Terraform我们希望这些计数始终匹配。这种连接有助于Terraform了解如何解决增加或减少计数的情况,暗示产生的创建/销毁操作需要按照特定顺序进行才能有效。然后,我们使用count.index来引用其他资源的索引,在这种情况下,它只会为零,但这有助于Terraform在验证过程中理解我们的意图。

aws_s3_bucket_notification中的lambda_function嵌套块需要稍微不同的策略,因为在这种情况下,我们不是为每个lambda函数创建单独的资源实例,而是在单个资源实例中生成一些动态配置块。对于这种情况,我们可以使用dynamic块,它作为一种宏,用于基于集合的元素生成多个块:

resource "aws_s3_bucket_notification" "bucket_notification" {
bucket = aws_s3_bucket.example_bucket.id
dynamic "lambda_function" {
for_each = aws_lambda_function.example
content {
# "lambda_function" in this block is the iterator
# symbol, so lambda_function.value refers to the
# current element of aws_lambda_function.example.
lambda_function_arn = lambda_function.value.arn
# ...
}
}
}

同样,这依赖于aws_lambda_function.example是一个对象列表,但方式不同:我们要求Terraform为aws_lambda_function.example的每个元素生成一个lambda_function块,将lambda_function.value设置为与每个块对应的整个aws_lambda_function对象。因此,我们可以访问该对象的.arn属性,以获得我们需要在块内填充lambda_function_arn参数的相应ARN。

同样,在这种情况下,只有零个或一个lambda函数对象,因此只有零个或者一个lambda_function块,但在这两种情况下,这种模式都推广到count的其他值,确保所有这些都将随着配置的发展而保持一致。

相关内容

  • 没有找到相关文章

最新更新