是否可以 link 将 Terraform 工作空间添加到 AWS 帐户

Is it possible to link a terraform workspace to an AWS account

如果一个人有两个 AWS 账户,一个用于开发,一个用于实时(例如)我知道可以使用 Terraform 工作区来管理每个环境的状态。

但是,如果我将工作区从 "dev" 切换到 "live",有没有办法告诉 Terraform 它现在应该将状态应用到真实账户而不是测试账户?

我想到的一个容易出错的方法是每次切换工作区时交换我的 secret.auto.tfvars 文件,因为我假设 运行 不同的访问密钥(属于"live" 帐户)AWS 提供商随后将向该帐户申请。但是,交换工作区并提供错误的凭据非常容易,这将 运行 针对错误环境进行更改。

我正在寻找一种几乎 link 在 AWS 中使用帐户 ID 的工作区的方法。

我确实发现这个 https://github.com/hashicorp/terraform/issues/13700 but it refers to the deprecated env command, this comment 看起来特别有前途

更新

我在 GitHub 我离开 this comment 的地方找到了一些信息作为对早先建议考虑模块而不是工作区的评论的回复,实际上表明工作区不太适合这个任务。如果有人可以提供有关如何使用模块来解决同时维护 "same" 基础架构的多个版本的问题的信息,我很想知道这如何改进工作区概念。

Terraform 工作区保存状态信息。它们根据 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 在环境中的使用方式连接到用户帐户。为了 link 任何给定的工作区到 AWS 帐户,他们必须以某种方式存储用户凭证,可以理解,他们不会。因此,我不希望看到工作区直接支持它。

但是,要几乎 link一个工作区到一个帐户你只需要自动切换AWS_ACCESS_KEY_ID和 AWS_SECRET_ACCESS_KEY 每次切换工作区时。您可以通过围绕 terraform 编写一个包装器来做到这一点,其中:

  1. 将所有命令传递给真正的 terraform,除非它找到 workspace select 在命令行中。

  2. 在命令行中找到 workspace select 后,它会解析出 工作区名称。

  3. 导出 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 您要link到工作空间

  4. 的AWS账户
  5. 通过将工作区命令传递给真正的terraform

  6. 完成

每次都会加载正确的凭据

terraform workspace select <WORKSPACE>

已使用

以下是如何使用 Terraform 模块构建指向不同 AWS 账户的实时和开发环境,但两个环境 have/use 相同的 Terraform 代码。

这是您构建目录的(许多)方法之一;您甚至可以将模块放入它们自己的 Git 存储库中,但我会尽量避免混淆太多。在此示例中,您有一个简单的应用程序,其中包含 1 个 EC2 实例和 1 个 RDS 数据库。您可以在 modules/*/ 子目录中编写所需的任何 Terraform 代码,确保参数化跨环境的任何不同属性。

然后在您的 dev/live/ 目录中,main.tf 应该相同,而 provider.tfterraform.tfvars 反映特定于环境的信息。 main.tf 将调用模块并传入特定于环境的参数。

modules/
|-- ec2_instance/
|-- rds_db/
dev/
|-- main.tf             # --> uses the 2 modules
|-- provider.tf         # --> has info about dev AWS account
|-- terraform.tfvars    # --> has dev-specific values
live/
|-- main.tf             # --> uses the 2 modules
|-- provider.tf         # --> has info about live/prod AWS account
|-- terraform.tfvars    # --> has prod-specific values

当你需要 plan/apply 任一个 env 时,你可以进入适当的目录并 运行 你的 TF 命令在那里。


至于为什么这优于使用 Terraform Workspaces,TF docs 解释得很好:

In particular, organizations commonly want to create a strong separation between multiple deployments of the same infrastructure serving different development stages (e.g. staging vs. production) or different internal teams. In this case, the backend used for each deployment often belongs to that deployment, with different credentials and access controls. Named workspaces are not a suitable isolation mechanism for this scenario.

Instead, use one or more re-usable modules to represent the common elements, and then represent each instance as a separate configuration that instantiates those common elements in the context of a different backend. In that case, the root module of each configuration will consist only of a backend configuration and a small number of module blocks whose arguments describe any small differences between the deployments.

BTW> 当 Terraform 认为 'env' 有点太混乱时,他们只是将 env 子命令更改为 workspace

希望对您有所帮助!