在Terraform中,将多个AWS帐户作为环境进行处理的最佳方式是什么



我们希望将每个地形环境都放在一个单独的AWS帐户中,这样就很难意外部署到生产中。这是如何最好地完成的?

我们假设一个帐户专用于生产,另一个专用于预生产,可能还有其他沙箱环境也有唯一的帐户,可能是基于每个管理员。另一个假设是,每个AWS帐户中都有一个S3存储桶,该存储桶是特定于您的环境的。此外,我们希望您的AWS帐户凭据在~/.AWS/credentials中进行管理(或者可能使用IAM角色(。

Terraform后端配置

有两种状态。对于主要状态,我们使用部分配置的概念。我们不能通过模块或其他方式将变量传递到后端配置中,因为它是在确定变量之前读取的。

Terraform配置设置

这意味着我们声明了缺少一些细节的后端,然后将它们作为参数提供给terraform init。一旦初始化,它就会被设置,直到.terraform目录被删除。

terraform {
backend "s3" {
encrypt = true
key     = "name/function/terraform.tfstate"
}
}

工作流注意事项

我们只需要更改初始化方式。我们在terraform init上使用-backend-config参数。这提供了配置中缺少的部分。我通过~/.bash_profile中的bash别名提供了所有缺失的部分,如下所示。

alias terrainit='terraform init 
-backend-config "bucket=s3-state-bucket-name"  
-backend-config "dynamodb_table=table-name" 
-backend-config "region=region-name"'

意外错误配置结果

如果省略了相应的必需-backend-config参数,初始化将提示您输入这些参数。如果提供错误,则可能会由于权限原因导致失败。此外,远程状态必须配置为匹配,否则也会失败。为了部署到生产部门,在确定适当的客户环境时必须出现多个错误。

Terraform远程状态

下一个问题是远程状态也需要更改,并且无法通过从后端配置中提取配置来进行配置;但是,可以通过变量设置远程状态。

模块设置

为了简化帐户切换,我们设置了一个非常简单的模块,该模块接收单个变量aws-account,并返回一组输出,远程状态可以使用这些输出和适当的值。我们还可以包括其他特定于环境/帐户的内容。该模块是一个简单的main.tf,具有映射变量,这些变量具有aws-account键和特定于该帐户的值。然后,我们有一组输出,它们像这样简单地查找映射变量。

variable "aws-region" {
description = "aws region for the environment"
type = "map"
default = {
Production  = "us-west-2"
PP      = "us-east-2"
}
}
output "aws-region" {
description = “The aws region for the account 
value = "${lookup(var.aws-region, var.aws-account, "invalid AWS account specified")}"
}

Terraform配置设置

首先,我们必须将aws帐户传递给模块。这可能接近main.tf的顶部。

module "environment" {
source    = "./aws-account"
aws-account = "${var.aws-account}"
}

然后在variables.tf中添加一个变量声明。

variable "aws-account" {
description = "The environment name used to identify appropriate AWS account resources used to configure remote states. Pre-Production should be identified by the string PP. Production should be identified by the string Production. Other values may be added for other accounts later."
}

现在,我们已经从模块输出了特定于帐户的变量,它们可以在远程状态声明中使用,如下所示。

data "terraform_remote_state" "vpc" {
backend = "s3"
config {
key = "name/vpc/terraform.tfstate"
region = "${module.environment.aws-region}"
bucket = "${module.environment.s3-state-bucket-name}"
}
}

工作流考虑

如果在这样设置后工作流没有任何变化,则每当执行计划/应用等时,都会通过这样的提示提示用户提供aws-account变量的值。提示的内容是对variables.tf中变量的描述。

$ terraform plan
var.aws-account
The environment name used to identify appropriate AWS account
resources used to configure remote states. Pre-Production should be
identified by the string PP. Production should be identified by the
string Production. Other values may be added for other accounts later.
Enter a value:

您可以通过在命令行上提供类似以下的变量来跳过提示

terraform plan -var="aws-account=PP"

意外错误配置结果

如果未指定aws-account变量,则会请求它。如果提供了aws帐户模块不知道的无效值,它将多次返回错误,包括字符串"指定的无效aws帐户",因为这是查找的默认值。如果aws帐户传递正确,但与terraform init中标识的值不匹配,则它将失败,因为正在使用的aws凭据无法访问正在标识的S3存储桶。

我们遇到了类似的问题a,我们解决了(部分(在Jenkins或任何其他CI工具中创建管道的问题。

我们有3个不同的env(dev、staging和prod(。相同的代码,不同的tfvars,不同的aws帐户。

当地形代码合并到master时,可以应用于暂存,只有当暂存为绿色时,才能执行生产。没有人在prod中手动运行terraform,aws凭据存储在CI工具中。

此设置可以解决您所描述的事故,但也可以防止不同的用户应用不同的本地代码。

相关内容

  • 没有找到相关文章

最新更新