我一直在寻找一种 Terraform 方法,以便能够在 Terraform 中同时部署到多个 AWS 账户,但最终却无功而返。AWS 有使用 Stacks 实现此目的的概念,但我不确定是否有办法在 TF 中实现此目的?如果可以,有什么解决方案?
您可以在此处阅读有关 AWS 解决方案的更多信息,https://aws.amazon.com/blogs/mt/supercharge-multi-account-management-with-aws-cloudformation/
答案1
要在多个 AWS 账户中使用相同的 Terraform 配置,需要克服两个问题。首先,您需要为每个账户使用不同的状态文件。其次,确保 AWS 提供商为所需账户使用正确的配置文件/凭证。
每个账户使用不同的状态文件
从高层次来看,terraform 的工作原理很简单,即根据给定的 terraform 配置文件 (*.tf) 创建依赖项资源图;并将它们与状态文件进行比较。状态文件可以是本地的 ( terraform.tfstate
),也可以是远程的后端;常见的 AWS 远程后端是s3。
即使您通过变量指定 AWS 提供商使用单独的帐户(下文将详细介绍),如果两个帐户使用相同的后端,terraform 仍将持续崩溃。之所以会发生这种情况,是因为当它从一个帐户切换到另一个帐户时,资源 AWS ID 将不匹配,并且/或者状态文件中将声明 terraform 当前正在查看的帐户中不存在的资源。
解决这个问题的一个简单方法是使用工作区。工作区允许您使用不同的状态文件,而无需指定不同的后端密钥。使用工作区非常简单。如果您有一个简单的 Terraform 块,例如:
terraform {
backend "s3" {
bucket = "aws_bucket"
key = "terraform.tfstate"
region = "us-east-1"
}
}
您可以使用 创建新的工作区terraform workspace new <workspace-name>
。因此,您可以按照如下顺序为您的两个帐户创建一个工作区:
terraform workspace new account-1
terraform workspace new account-2
您可以使用以下命令切换当前工作区terraform workspace select
:
terraform workspace select account-1
配置 AWS 提供程序以了解工作区
除了使用单独的状态文件之外,您还需要为每个所需的帐户指定不同的 AWS 凭证(即访问密钥)。AWS 凭证使用以下方式声明提供商。 在这种情况下,我们显然使用AWS 提供商。. 你本质上想要使用插值在 AWS 提供商资源块中,因此当您切换工作区时,terraform 将使用正确的凭据。假设您已为每个帐户设置了单独的配置文件,并使用了 aws 凭据文件:
[account-1]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
[account-2]
aws_access_key_id=AKIAI44QH8DHBEXAMPLE
aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
然后您可以简单地将您的 aws 提供程序块编写为:
provider "aws" {
region = "us-east-1"
profile = "${terraform.workspace}"
}
因此,只要您将工作区命名为 AWS 配置文件名称,那么当您切换工作区时,Terraform 将在刷新状态和构建依赖关系图时使用不同的 AWS 凭证配置文件。
替代方法
这并不是实现这一目标的唯一方法。你可以构建模块;然后使用不同的目录调用指定了不同 AWS 提供商和状态文件的模块。每种方法都有优缺点。
工作区方法是使用单个目录执行的操作,并且您将使用与书面内容完全相同的 terraform 配置文件。
模块需要单独的配置文件,这些配置文件至少会调用模块并指定提供程序和后端。如果您要使用多帐户、多区域和多环境,模块将非常有意义。例如,如果您要在每个帐户的两个区域中运行,以及两个不同的环境(暂存和生产)。模块在这里很有意义,因为它使用诸如 count 之类的参数提供了灵活性(也许暂存将运行较少数量的实例等)。
答案2
基本上,诀窍是获取一个共享存储桶内的状态,并在切换帐户时为提供的内容指定不同的凭据。工作区对我来说非常完美
provider "aws" {
version = "~> 2.18"
profile = "second_account"
}
terraform {
backend "s3" {
encrypt = true
bucket = "shared_bucket"
region = "us-east-1"
key = "state"
profile = "first_shared_account"
}
required_version = "~> 0.12.7"
}
请注意,为提供商和后端配置指定了不同的配置文件。您可以拥有许多不同的配置文件,只要每个配置文件都通过自己的工作区隔离即可
aws configure --profile third_account
terraform workspace new third_account
terraform workspace select third_account