用于 Localstack 的 Terraform Override Provider
Terraform Override Provider for use with Localstack
我有一个 Git 存储库,其中包含正在部署到 AWS 中的 Terraform 代码。我正在将 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 伪基础设施将不可避免地与“真实”基础设施不同,我希望您会希望为其使用单独的状态,因此这可能是使用单独的 workspace 的合理情况 development/testing,并且我将编写此示例,假设只要选择工作区 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
来处理未设置的参数。
- 仅当
override_endpoint
属性为非空时才使用 [*]
with a non-list value automatically converts it into a zero-element list or a one-element list, depending on whether the value is null
. That allows us to dynamically declare the endpoints
block,然后将其值写入所有三个覆盖的端点参数。
我有一个 Git 存储库,其中包含正在部署到 AWS 中的 Terraform 代码。我正在将 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 伪基础设施将不可避免地与“真实”基础设施不同,我希望您会希望为其使用单独的状态,因此这可能是使用单独的 workspace 的合理情况 development/testing,并且我将编写此示例,假设只要选择工作区 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
来处理未设置的参数。 - 仅当
override_endpoint
属性为非空时才使用[*]
with a non-list value automatically converts it into a zero-element list or a one-element list, depending on whether the value isnull
. That allows us to dynamically declare theendpoints
block,然后将其值写入所有三个覆盖的端点参数。