Terraform 共享状态

5

Terraform 0.9.5。

我正在组建一组模块,我们的基础设施团队和自动化团队将使用这些模块以标准方式创建资源,并进而创建堆栈以提供不同的环境。所有工作都进行得很顺利。

像所有使用terraform的团队一样,共享状态成为一个问题。我已经配置了terraform使用S3后端,该后端是版本化和加密的,并通过dynamo db表添加了锁定。完美。所有本地帐户都可以正常工作...好吧,问题是...

我们有多个AWS帐户,1个用于IAM,1个用于计费,1个用于生产,1个用于非生产,1个用于共享服务等等...你知道我要说什么了。我的问题如下。

我以IAM帐户中的用户身份进行身份验证并承担所需的角色。这一直运行得很好,直到我引入了terraform后端配置来利用s3进行共享状态。看起来terraform中的后端配置需要在~/.aws/credentials中设置默认凭据。看起来这些凭据必须是属于创建s3存储桶所在帐户的本地用户。

有没有办法以这样的方式设置后端配置,使其使用在提供程序中配置的凭据和角色?有没有更好的方式来配置共享状态和锁定?欢迎任何建议:)

更新: 已解决。我在创建S3存储桶所在的帐户中创建了一个新用户。创建一个策略,只允许该新用户在特定的s3存储桶和dynamodb表上执行s3:DeleteObject,GetObject,PutObject,ListBucket和dynamodb:*操作。创建了一个自定义凭据文件,并添加了默认配置文件,其中包含分配给该新用户的访问和密钥。使用类似于以下的后端配置。

terraform {
   required_version = ">= 0.9.5"

   backend "s3" {
      bucket                  = "remote_state"
      key                     = "/NAME_OF_STACK/terraform.tfstate"
      region                  = "us-east-1"
      encrypt                 = "true"
      shared_credentials_file = "PATH_TO_CUSTOM_CREDENTAILS_FILE"
      lock_table              = "MY_LOCK_TABLE"
    }
}

它能够正常工作,但是在你的个人资料中需要进行初始配置才能使其正常工作。如果有人知道更好的设置或者可以识别我的后端配置问题,请让我知道。


根据您的描述,很多主要意见都是基于假设的。Terraform从不要求您共享状态文件。 - BMW
看起来按预期工作。我为每个堆栈使用不同的密钥,并且我使用一个dynamodb表。 - DMcKenna
@BMW 这是推荐的做法。在团队中使用 Terraform 时,使用本地文件会使 Terraform 的使用变得复杂,因为每个用户都必须确保在运行 Terraform 之前始终拥有最新的状态数据,并确保没有其他人同时运行 Terraform。https://www.terraform.io/docs/state/remote.html - KCD
1个回答

3
Terraform希望后端配置是静态的,并且不允许包含插值变量,因为需要在进行任何其他工作之前初始化后端。因此,使用不同的AWS帐户多次应用相同的配置可能会有些棘手,但有两种方法可以解决。
最低摩擦的方法是创建一个专门用于跨所有环境存储状态的单个S3存储桶和DynamoDB表,并使用S3权限和/或IAM策略来强制执行细粒度访问控制。
采用这种策略的组织有时会在单独的“管理”AWS帐户中创建S3存储桶,然后将对存储桶中的各个状态对象的访问权限限制为在每个其他帐户中运行Terraform的特定角色。
此解决方案的优点是,在S3 Terraform中正确设置后,可以常规使用Terraform而无需任何不寻常的工作流程:在后端配置单个S3存储桶,并通过环境变量提供适当的凭据以允许它们变化。一旦初始化了后端,请使用workspaces(在Terraform 0.10之前称为“状态环境”)为单个配置的每个目标环境创建单独的状态。
缺点是需要管理更复杂的S3访问配置,而不是仅依赖于整个AWS帐户的粗略访问控制。由于DynamoDB上的访问控制不太灵活,因此与DynamoDB混合使用也更具挑战性。

在Terraform的s3提供程序文档中,有关于此选项更完整的描述,多账户AWS架构


如果复杂的S3配置不可取,可以通过使用部分配置将复杂性转移到Terraform工作流中。在此模式下,仅提供了一部分后端设置,并在运行terraform init时在命令行上提供其他设置。
这允许选项在运行之间变化,但由于需要提供额外的参数,大多数采用这种方法的组织将使用包装脚本根据本地惯例适当地配置Terraform。这可以只是一个简单的shell脚本,它以合适的参数运行terraform init
然后,例如,可以通过在命令行上提供自定义凭据文件来使其变化。在这种情况下,状态环境未被使用,而是在新的后端配置下重新初始化工作目录以在环境之间切换。
这种解决方案的优点是它不会对S3和DynamoDB的使用施加任何特定的限制,只要差异可以表示为CLI选项即可。
缺点是需要使用不同寻常的工作流或包装脚本来配置Terraform。

当使用选项#1时,terraform如何知道我在预生产帐户和生产帐户中运行的差异?我担心状态会被彼此的数据破坏。这是否都由工作区处理? - Josiah
1
每个工作区都有完全独立的状态,只要您确保在运行 terraform planterraform apply 时选择了正确的工作区,它就不会访问任何其他工作区的状态信息。自从我写这篇答案以来,Terraform 网站上现在有一个完整的指南介绍第一种选项:https://www.terraform.io/docs/backends/types/s3.html#multi-account-aws-architecture - Martin Atkins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接