运行 terraform apply 时如何从多个提供程序中进行选择?

问题描述

我有一些在 AWS 中创建资源的 terraform 代码

对于生产,我们有一个针对真实 AWS 运行的 CICD 管道。对于本地开发,我使用 localstack。所以有两个像这样的提供者:

# AWS config
provider "aws" {
  region = ...
}

# Localstack config
provider "aws" {
  region = ...

  access_key = "mock_access_key"
  secret_key = "mock_secret_key"

  skip_credentials_validation = true

  endpoints {
    s3 = "http://localhost:4566"
    ...
  }
}

我当前的解决方案是注释掉未使用的提供程序。这并不理想,因为我们需要记住在本地开发时取消对 localstack 配置的注释,在推送代码时取消对真正的 aws 配置的注释,忘记这可能是一个大问题。

我还尝试为 localstack 配置 alias = localstack 和几个变量创建别名:

variable provider_id {
  type = map
  default = {
    localdev = "aws.localstack"
    prod = "aws"
  }
}

variable aws_account {
  type = string
  default = ""
}

然后资源可以这样查找提供者:

provider = lookup(var.provider_id,var.aws_account)

那么想法是我们可以在运行 aws_account=... 时传递变量 terraform apply,以便资源选择正确的提供者。但是,这不起作用并返回此错误(我认为是因为它应该查找 aws 而不是 "aws"):

╷
│ Error: Invalid provider configuration reference
│
│   on s3.tf line 2,in resource "aws_s3_bucket" "bucket":
│    2:   provider = lookup(var.provider_id,var.aws_account)
│
│ The provider argument requires a provider type name,optionally followed by a period and then a configuration alias.
╵

即使它确实有效,它也不是理想的,因为我们必须记住将提供者查找添加到每个资源块。


我想知道与这样的多个提供商合作的最佳方式是什么?理想情况下是一个简单的解决方案,例如在运行 terraform apply 时传递变量或参数。我不介意它是否需要重构 terraform(我上周才学会了这个工具)。

解决方法

典型的处理方式是通过terraform workspaces

特别是,组织通常希望在为不同开发阶段(例如,分阶段与生产)或不同内部团队服务的同一基础架构的多个部署之间创建强隔离。

所以您可以尝试拥有两个工作区,一个用于本地堆栈,第二个用于真正的 aws。

,

您可以通过 Alias 工作流程实现这一点 - 但需要更改代码以在资源部分包含别名。请参考此文档:

https://www.terraform.io/docs/language/modules/develop/providers.html

尽管正如您提到的,一个配置用于 prod/root 帐户,另一个用于本地开发,在这种情况下推荐和测试的方法是创建两个工作区 - 分离工作区将为您带来很多优势,例如:

1- code is separate so no chances of messing with it accidentally
2- debugging will be much easier
3- you are free to experiment with your code without fear