用于Localstack的Terraform覆盖提供程序



我有一个包含Terraform代码的Git存储库,它正在部署到AWS中。我将Localstack添加到这个存储库中,这样我就可以在计划之前进行更高级的验证测试,并将其应用到我的实际AWS帐户中。为了使用Localstack,我必须创建一个带有自定义端点的新提供商:

provider "aws" {
alias  = "real"
region = "${local.aws_region}"
}
provider "aws" {
alias                       = "fake"
region                      = "${local.aws_region}"
access_key                  = "fake"
secret_key                  = "fake"
skip_credentials_validation = true
skip_metadata_api_check     = true
skip_requesting_account_id  = true
endpoints {
dynamodb = "http://localhost:4566"
lambda   = "http://localhost:4566"
kinesis  = "http://localhost:4566"
}
}

如何在不复制代码的情况下,为Localstack使用一个提供商,为AWS使用一个提供商?

不幸的是,由于这两种情况之间的配置结构有很大的不同,因此不可能在不使结果配置看起来相当复杂的情况下实现动态切换,但是可以使用Terraform语言表达式操作符和dynamic块有条件地设置所有提供程序参数。这样就有了一个带有动态设置的单一提供商配置,而不是两个独立的提供商配置。

首先要决定的是你将如何在这两种可能性之间做出选择。因为你的localstack伪基础结构将不可避免地与"真实的"不同。我希望您希望为它使用单独的状态,因此使用单独的工作空间进行开发/测试可能是一种合理的情况,并且我将编写这个示例,假设无论何时选择工作空间dev, localstack配置都应该是活动的。如果这不是你想要的,那么希望这应该仍然足以适应你的需求。

locals {
use_localstack = (terraform.workspace == "dev")
aws_settings = (
local.use_localstack ?
{
region     = local.aws_region
access_key = "fake"
secret_key = "fake"
skip_credentials_validation = true
skip_metadata_api_check     = true
skip_requesting_account_id  = true
override_endpoint = "http://localhost:4566"
} :
{
region     = local.aws_region
access_key = null
secret_key = null

skip_credentials_validation = null
skip_metadata_api_check     = null
skip_requesting_account_id  = null
override_endpoint = null
}
)
}
provider "aws" {
region     = local.aws_settings.region
access_key = local.aws_settings.access_key
secret_key = local.aws_settings.secret_key
skip_credentials_validation = local.aws_settings.skip_credentials_validation
skip_metadata_api_check     = local.aws_settings.skip_metadata_api_check
skip_requesting_account_id  = local.aws_settings.skip_requesting_account_id
dynamic "endpoints" {
for_each = local.aws_settings.override_endpoint[*]
content {
dynamodb = endpoints.value
lambda   = endpoints.value
kinesis  = endpoints.value
}
}
}

以上依赖于Terraform语言的两个特定行为:

  • 当设置将传递给提供者的参数时,设置null总是与省略该参数相同,因为Terraform内部通过隐式设置它们为null来处理未设置的参数。
  • 使用非列表值的[*]自动将其转换为零元素列表或单元素列表,具体取决于该值是否为null。这允许我们动态地声明endpoints块,只有当override_endpoint属性是非空的,然后把它的值写入所有三个被覆盖的端点参数。

最新更新