首页 文章

Terraform(Hashicorp)的不同环境

提问于
浏览
26

我一直在使用Terraform来构建我的AWS栈并且一直很喜欢它 . 如果要在商业环境中使用,则需要针对不同环境(例如QA,STAGING,PROD)重用配置 .

我怎么能做到这一点?我是否需要创建一个包装器脚本来调用terraform的cli,同时按照下面的环境传入不同的状态文件?我想知道Terraform是否提供了更原生的解决方案 .

terraform apply -state=qa.tfstate

5 回答

  • 3

    我建议你看一下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 输出将列出以下任务:

    us_east_1_prod:init
    us_east_1_prod:plan
    us_east_1_prod:apply
    
    us_east_1_staging:init
    us_east_1_staging:plan
    us_east_1_staging:apply
    

    这种分离可以防止dev可能排除的变化意外地影响(或更糟糕地,破坏)prod中的某些东西,因为它是一个不同的状态文件 . 它还允许在实际应用于prod之前测试dev / staging的变化 .

    此外,我最近偶然发现了这个小小的写作,它基本上显示了如果你把所有东西放在一起会发生什么:https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/

  • 11

    请注意,从版本0.10.0开始,Terraform支持Workspaces的概念(0.9.x中的环境) .

    工作空间是Terraform状态的命名容器 . 通过多个工作空间,Terraform配置的单个目录可用于管理多个不同的基础架构资源集 .

    在这里查看更多信息:https://www.terraform.io/docs/state/workspaces.html

  • 6

    Paul的模块解决方案是正确的想法 . 但是,我强烈建议不要在同一个Terraform文件中定义所有环境(例如QA,登台,制作) . 如果你这样做,那么每当你改变分期时,你都会冒着意外破坏 生产环境 的风险,这部分地阻碍了首先将这些环境隔离开来!请参阅Terraform, VPC, and why you want a tfstate file per env,了解可能出现的问题 .

    我总是建议将每个环境的Terraform代码存储在一个单独的文件夹中 . 实际上,您甚至可能希望将每个“组件”(例如数据库,VPC,单个应用程序)的Terraform代码存储在单独的文件夹中 . 同样,原因是隔离:当对单个应用程序进行更改时(您可能每天执行10次),您不希望将整个VPC置于风险之中(您可能永远不会更改) .

    因此,我的典型文件布局如下所示:

    stage
      └ vpc
         └ main.tf
         └ vars.tf
         └ outputs.tf
      └ app
      └ db
    prod
      └ vpc
      └ app
      └ db
    global
      └ s3
      └ iam
    

    登台环境的所有Terraform代码都进入 stage 文件夹,prod环境的所有代码都进入 prod 文件夹,所有居住在环境之外的代码(例如IAM用户,S3存储桶)都进入 global 文件夹 .

    有关详细信息,请查看How to manage Terraform state . 要深入了解Terraform最佳实践,请查看书籍Terraform: Up & Running .

  • 12

    在扩展terraform使用时,您需要共享状态(开发人员,构建过程和不同项目之间),支持多个环境和区域 . 为此,您需要使用远程状态 . 在执行terraform之前,您需要设置状态 . (我使用powershell)

    $environment="devtestexample"
    $region     ="eu-west-1"
    $remote_state_bucket = "${environment}-terraform-state"
    $bucket_key = "yoursharedobject.$region.tfstate"
    
    aws s3 ls "s3://$remote_state_bucket"|out-null
    if ($lastexitcode)
    {
       aws s3 mb "s3://$remote_state_bucket"
    }
    
    terraform remote config -backend S3 -backend-config="bucket=$remote_state_bucket"  -backend-config="key=$bucket_key" -backend-config="region=$region"
    #(see here: https://www.terraform.io/docs/commands/remote-config.html)
    
    terraform apply -var='environment=$environment' -var='region=$region'
    

    您的状态现在存储在S3中,按区域,按环境存储,然后您可以在其他tf项目中访问此状态 .

  • 15

    无需制作包装脚本 . 我们所做的是将env分成一个模块然后有一个顶级terraform文件,我们只为每个环境导入该模块 . 只要您的模块设置为足够的变量(通常是env_name和其他一些变量),您就可以了 . 举个例子

    # 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.
    

相关问题