【问题标题】:Is it possible to link a terraform workspace to an AWS account是否可以将 terraform 工作区链接到 AWS 账户
【发布时间】:2019-01-18 02:35:24
【问题描述】:

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

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

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

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

我确实找到了这个https://github.com/hashicorp/terraform/issues/13700,但它指的是已弃用的env 命令,this comment 看起来特别有希望

更新

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

【问题讨论】:

    标签: terraform terraform-provider-aws


    【解决方案1】:

    以下是您如何使用 Terraform 模块来构建指向不同 AWS 账户的实时和开发环境,但环境都具有/使用相同的 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
    

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


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

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

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

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

    希望这会有所帮助!

    【讨论】:

    • 您也许应该稍微扩展一下这个答案,以讨论为什么它不使用工作空间以及何时应该使用工作空间(如果有的话)考虑到这个问题是专门关于 Terraform 的工作空间的,但这几乎就是我的做法东西。
    • 谢谢@ydaetskcoR。我添加了一个部分。
    • @kjh 在这个模型中,terraform init 在每个子目录中分别执行(例如dev/live/),因为我认为后端状态需要每个目录同步(这涉及到不同的后端,例如每个帐户中的唯一 s3 存储桶)
    • @DavidGoate - 是的!顺便说一句,不必是唯一的 S3 存储桶;可能只是同一存储桶中的差异键(“文件夹”)。
    【解决方案2】:

    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_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 的 您要链接到工作区的 AWS 帐户

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

    这将每次加载正确的凭据

    terraform workspace select <WORKSPACE>
    

    被使用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-02
      • 1970-01-01
      • 2017-04-20
      • 2016-01-31
      • 2020-01-25
      • 1970-01-01
      • 2014-04-11
      相关资源
      最近更新 更多