6

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

但是,如果我将工作区从“dev”切换到“live”,有没有办法告诉 terraform 它现在应该将状态应用于实时帐户而不是测试帐户?

我想到的一种容易出错的方法是交换我的secret.auto.tfvars每次切换工作区时交换我的文件,因为我假设当使用不同的访问密钥(属于“实时”账户的那个)运行时,AWS 提供商将申请那个帐户。但是,交换工作区并存在错误的凭据会非常容易,这将针对错误的环境运行更改。

我正在寻找一种几乎将工作区与 AWS 中的帐户 ID 链接的方法。

我确实找到了这个https://github.com/hashicorp/terraform/issues/13700但它指的是不推荐使用的env命令,这个评论看起来特别有希望

更新

我在 GitHub 上找到了一些信息,我在其中留下了这条评论作为对先前评论的回复,该评论建议考虑模块而不是工作区,实际上表明工作区不太适合这项任务。如果有人可以提供有关如何使用模块来解决同时维护“相同”基础设施的多个版本的问题的信息,我很想看看这如何改进工作空间的概念。

4

2 回答 2

6

以下是您如何使用 Terraform 模块来构建指向不同 AWS 账户的实时与开发环境,但这些环境都具有/使用相同的 Terraform 代码。

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

然后在你的dev/live/目录中,main.tf应该是相同的,同时provider.tf反映terraform.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

当您需要计划/应用任一环境时,您可以放入适当的目录并在那里运行您的 TF 命令。


至于为什么这比使用 Terraform Workspaces 更受欢迎,TF 文档解释得很好:

特别是,组织通常希望在服务于不同开发阶段(例如分期与生产)或不同内部团队的同一基础架构的多个部署之间建立强有力的分离。在这种情况下,用于每个部署的后端通常属于该部署,具有不同的凭据和访问控制。命名工作空间不适合这种情况下的隔离机制。

相反,使用一个或多个可重用模块来表示公共元素,然后将每个实例表示为一个单独的配置,该配置在不同后端的上下文中实例化这些公共元素。在这种情况下,每个配置的根模块将仅包含一个后端配置和少量模块块,其参数描述了部署之间的任何微小差异。

顺便说一句> Terraform 只是将env子命令更改为workspace当他们认为“env”有点太混乱时。

希望这可以帮助!

于 2018-08-14T21:38:15.750 回答
1

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

但是,为了几乎将工作区链接到帐户,您只需要在每次切换工作区时自动切换 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY。您可以通过编写一个包装器来做到这terraform一点:

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

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

  3. 导出要链接到工作区的 AWS 账户的 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY

  4. 通过将工作区命令传递给真实的来完成terraform

这将每次加载正确的凭据

terraform workspace select <WORKSPACE>

被使用

于 2018-08-14T18:01:08.507 回答