我们're using a similar setup, and it works quite nicely. However, this best-practices repo assumes you'重新使用Atlas,我们已经创建了一个精心设计的Rakefile,基本上(再次通过最佳实践的repo)获取/ terraform / providers / aws的所有子文件夹,并使用命名空间将它们公开为不同的构建 . 所以我们的 rake -T 输出将列出以下任务:
# project/main.tf
module "dev" {
source "./env"
env = "dev"
aws_ssh_keyname = "dev_ssh"
}
module "stage" {
source "./env"
env = "stage"
aws_ssh_keyname = "stage_ssh"
}
# Then in project/env/main.tf
# All the resources would be defined in here
# along with variables for env and aws_ssh_keyname, etc.
5 回答
我建议你看一下hashicorp best-practices repo,它有一个非常好的设置来处理不同的环境(类似于James Woolfenden所建议的) .
我们're using a similar setup, and it works quite nicely. However, this best-practices repo assumes you'重新使用Atlas,我们已经创建了一个精心设计的Rakefile,基本上(再次通过最佳实践的repo)获取/ terraform / providers / aws的所有子文件夹,并使用命名空间将它们公开为不同的构建 . 所以我们的
rake -T
输出将列出以下任务:这种分离可以防止dev可能排除的变化意外地影响(或更糟糕地,破坏)prod中的某些东西,因为它是一个不同的状态文件 . 它还允许在实际应用于prod之前测试dev / staging的变化 .
此外,我最近偶然发现了这个小小的写作,它基本上显示了如果你把所有东西放在一起会发生什么:https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/
请注意,从版本0.10.0开始,Terraform支持Workspaces的概念(0.9.x中的环境) .
工作空间是Terraform状态的命名容器 . 通过多个工作空间,Terraform配置的单个目录可用于管理多个不同的基础架构资源集 .
在这里查看更多信息:https://www.terraform.io/docs/state/workspaces.html
Paul的模块解决方案是正确的想法 . 但是,我强烈建议不要在同一个Terraform文件中定义所有环境(例如QA,登台,制作) . 如果你这样做,那么每当你改变分期时,你都会冒着意外破坏 生产环境 的风险,这部分地阻碍了首先将这些环境隔离开来!请参阅Terraform, VPC, and why you want a tfstate file per env,了解可能出现的问题 .
我总是建议将每个环境的Terraform代码存储在一个单独的文件夹中 . 实际上,您甚至可能希望将每个“组件”(例如数据库,VPC,单个应用程序)的Terraform代码存储在单独的文件夹中 . 同样,原因是隔离:当对单个应用程序进行更改时(您可能每天执行10次),您不希望将整个VPC置于风险之中(您可能永远不会更改) .
因此,我的典型文件布局如下所示:
登台环境的所有Terraform代码都进入
stage
文件夹,prod环境的所有代码都进入prod
文件夹,所有居住在环境之外的代码(例如IAM用户,S3存储桶)都进入global
文件夹 .有关详细信息,请查看How to manage Terraform state . 要深入了解Terraform最佳实践,请查看书籍Terraform: Up & Running .
在扩展terraform使用时,您需要共享状态(开发人员,构建过程和不同项目之间),支持多个环境和区域 . 为此,您需要使用远程状态 . 在执行terraform之前,您需要设置状态 . (我使用powershell)
您的状态现在存储在S3中,按区域,按环境存储,然后您可以在其他tf项目中访问此状态 .
无需制作包装脚本 . 我们所做的是将env分成一个模块然后有一个顶级terraform文件,我们只为每个环境导入该模块 . 只要您的模块设置为足够的变量(通常是env_name和其他一些变量),您就可以了 . 举个例子