terraform - 用于 Localstack 的 Terraform 覆盖提供程序
问题描述
我有一个正在部署到 AWS 中的带有 Terraform 代码的 Git 存储库。我将 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 伪基础设施将不可避免地与“真实”基础设施不同,我希望您希望为它使用单独的状态,因此这可能是使用单独的工作区进行开发/测试的合理情况,我'将编写此示例,假设只要选择了工作空间,localstack 配置就应该处于活动状态dev
。如果那不是您想要的,那么希望这仍然足以适应您的需求。
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
推荐阅读
- android - 有没有办法知道动态壁纸的 SettingsActivity 是如何启动的?
- sequential - 如何顺序运行lerna?
- python - `plt.imshow` 只生成 suplot 的最后一张图片
- python - Pandas 中这种 df.drop() 行为的可能原因是什么?
- node.js - 如何将midi文件转换为mp3文件?
- html - 如何将 CSS 放在背景图片上
- json - 通用字体字距映射
- c++ - 使用线程时的未知类型名称
- python - Spyder 网络抓取工具不会转到新网址
- javascript - 在页面上多次使用自动完成时从自动完成中获取数据