【问题标题】:Terraform s3 backend not used by module模块未使用 Terraform s3 后端
【发布时间】:2017-12-02 04:44:14
【问题描述】:

我已经开始使用 Terraform 并且完全接受它 - 太棒了!在 AWS VPC、子网、NACL、SG、路由表等方面创建了我的整个开发环境后,我决定最好把它变成可重用的模块。

所以现在我已经把它变成了带有变量等的模块。现在我的开发模板只接受变量并将它们用作模块的输入。我最终得到了这个:

terraform {
  backend "s3" {
    bucket = "redacted"
    key    = "dev/vpc/terraform.tfstate"
    region = "eu-west-1"
    encrypt = true
    dynamodb_table = "terraform_statelock_redacted"
  }
}

provider "aws"{
  access_key = ""
  secret_key = ""
  region     = "eu-west-1"
}

module "base_vpc" {
  source = "git@github.com:closed/terraform-modules.git//vpc"


  vpc_cidr = "${var.vpc_cidr}"
  vpc_region = "${var.vpc_region}"
  Environment = "${var.Environment}"
  Public-subnet-1a = "${var.Public-subnet-1a}"
  Public-subnet-1b = "${var.Public-subnet-1b}"
  Private-subnet-1a = "${var.Private-subnet-1a}"
  Private-subnet-1b = "${var.Private-subnet-1b}"
  Private-db-subnet-1a = "${var.Private-db-subnet-1a}"
  Private-db-subnet-1b = "${var.Private-db-subnet-1b}"
  Onsite-computers = "${var.Onsite-computers}"
  browse_access = "${var.browse_access}"
}

现在我在 s3 后端管理所有状态,如您在上面的配置中所见。我还有其他正在运行的服务/实例的状态文件。我的问题是,现在我已经把它变成了一个模块并像上面一样引用它,它想吹走我的状态!我的印象是它会导入模块并在尊重其他配置的同时运行它。实际的模块代码是从原始模板复制而来的,所以那里没有任何变化。

它试图吹走一切并重新开始是有原因的吗?在使用模块的情况下,如何管理每个环境的单独状态?我没有其他错误。我现在有开发人员在一些服务器上工作,所以我现在瘫痪了哈!

我想我误解了一些东西,非常感谢任何帮助:) 谢谢。 编辑 - 使用 Terraform 0.9.8

【问题讨论】:

    标签: terraform


    【解决方案1】:

    我们遇到了这个问题,并决定每个环境都需要一个代码表示,如果需要,我们可以与其他环境同时查看,即将开发配置与 qa 进行比较。

    所以现在我们有一个用于 dev 的文件夹和一个用于 qa 的文件夹,我们从那里启动 terraform。每个基本上都是为每个组件调用模块的变量列表。

    这是我的可视化表示树

    $ tree terraform/
    terraform/
    ├── api_gateway
    │   ├── main.tf
    │   ├── output.tf
    │   └── variables.tf
    ├── database
    │   ├── main.tf
    │   ├── output.tf
    │   └── variables.tf
    ├── dev
    │   └── main.tf
    ├── ec2
    │   ├── main.tf
    │   ├── output.tf
    │   └── variables.tf
    ├── kms
    │   ├── main.tf
    │   ├── output.tf
    │   └── variables.tf
    ├── network
    │   ├── main.tf
    │   ├── output.tf
    │   └── variables.tf
    ├── qa
    │   └── main.tf
    └── sns
        ├── output.tf
        ├── main.tf
        └── variables.tf
    

    dev/main.tf 和 qa/main.tf 导入其他文件夹提供的模块,为每个模块提供特定于环境的配置。

    编辑:这是我的 dev/main.tf 的净化版本

    provider "aws" {
      region = "us-east-1"
      profile = "blah-dev"
      shared_credentials_file = "${pathexpand("~/.aws/credentials")}"
    }
    
    terraform {
      backend "s3" {
        bucket = "sweet-dev-bucket"
        key = "sweet/dev.terraform.tfstate"
        region = "us-east-1"
        profile = "blah-dev"
      }
    }
    
    variable "aws_account" {
      default = "000000000000"
    }
    variable "env" {
      default = "dev"
    }
    variable "aws_region" {
      default = "us-east-1"
    }
    variable "tag_product" {
      default = "sweet"
    }
    variable "tag_business_region" {
      default = "east"
    }
    variable "tag_business_unit" {
      default = "my-department"
    }
    variable "tag_client" {
      default = "some-client"
    }
    
    module build_env {
      source = "../datasources"
    }
    
    module "kms" {
      source = "../kms"
      tag_client = "${var.tag_client}"
      tag_business_region = "${var.tag_business_region}"
      tag_business_unit = "${var.tag_business_unit}"
      tag_product = "${var.tag_product}"
    }
    
    module "network" {
      source = "../network"
      vpc_id = "vpc-000a0000"
      subnet_external_1B = "subnet-000a0000"
      subnet_external_1D = "subnet-000a0001"
      subnet_db_1A = "subnet-000a0002"
      subnet_db_1B = "subnet-000a0003"
    }
    
    module "database" {
      source = "../database"
      env = "dev"
      vpc_id = "${module.network.vpc_id}"
      subnet_external_1B = "${module.network.subnet_external_1B}"
      subnet_external_1D = "${module.network.subnet_external_1D}"
      subnet_db_1A = "${module.network.subnet_db_1A}"
      subnet_db_1B = "${module.network.subnet_db_1B}"
      database_instance_size = "db.t2.small"
      database_name = "my-${var.tag_product}-db"
      database_user_name = "${var.tag_product}"
      database_passwd = "${module.kms.passwd_plaintext}"
      database_identifier = "${var.tag_product}-rds-database"
      database_max_connections = "150"
    }
    
    module sns {
      source = "../sns"
      aws_account = "${var.aws_account}"
    }
    
    module "api_gateway" {
      source = "../api_gateway"
      env = "${var.env}"
      vpc_id = "${module.network.vpc_id}"
      domain_name = "${var.tag_product}-dev.example.com"
      dev_certificate_arn = "arn:aws:acm:${var.aws_region}:${var.aws_account}:certificate/abcd0000-a000-a000-a000-1234567890ab"
      aws_account = "${var.aws_account}"
      aws_region = "${var.aws_region}"
      tag_client = "${var.tag_client}"
      tag_business_unit = "${var.tag_business_unit}"
      tag_product = "${var.tag_product}"
      tag_business_region = "${var.tag_business_region}"
      autoscaling_events_sns_topic_arn = "${module.sns.sns_topic_arn}"
      db_subnet_id_1 = "${module.network.subnet_db_1A}"
      db_subnet_id_2 = "${module.network.subnet_db_1B}"
      ec2_role = "${var.tag_product}-assume-iam-role"
      kms_key_arn = "${module.kms.kms_arn}"
      passwd_cypher_text = "${module.kms.passwd_cyphertext}"
    }
    
    module "ec2" {
      source = "../ec2"
      s3_bucket = "${var.tag_product}_dev_bucket"
      aws_region = "${var.aws_region}"
      env = "${var.env}"
      ec2_key_name = "my-${var.tag_product}-key"
      ec2_instance_type = "t2.micro"
      aws_account = "${var.aws_account}"
      vpc_id = "${module.network.vpc_id}"
      binary_path = "${module.build_env.binary_path}"
      binary_hash = "${module.build_env.binary_hash}"
      git_hash_short = "${module.build_env.git_hash_short}"
      private_key = "${format("%s/keys/%s-%s.pem", path.root, var.tag_product, var.env)}"
      cloudfront_domain = "${module.api_gateway.cloudfront_domain}"
      api_gateway_domain = "${module.api_gateway.api_gateway_cname}"
      tag_client = "${var.tag_client}"
      tag_business_region = "${var.tag_business_region}"
      tag_product = "${var.tag_product}"
      tag_business_unit = "${var.tag_business_unit}"
      auto_scale_desired_capacity = "1"
      auto_scale_max = "2"
      auto_scale_min = "1"
      autoscaling_events_sns_topic = "${module.sns.sns_topic_arn}"
      subnet_external_b = "${module.network.subnet_external_b}"
      subnet_external_a = "${module.network.subnet_external_a}"
      kms_key_arn = "${module.kms.kms_arn}"
      passwd_cypher_text = "${module.kms.passwd_cyphertext}"
    }
    

    然后我的 QA 基本相同(在顶部修改几个 var)但最重要的区别是 qa/main.tf 的最顶部主要是这些 var:

    provider "aws" {
      region = "us-east-1"
      profile = "blah-qa"
      shared_credentials_file = "${pathexpand("~/.aws/credentials")}"
    }
    
    terraform {
      backend "s3" {
        bucket = "sweet-qa-bucket"
        key = "sweet/qa.terraform.tfstate"
        region = "us-east-1"
        profile = "blah-qa"
      }
    }
    
    variable "aws_account" {
      default = "000000000001"
    }
    variable "env" {
      default = "qa"
    }
    

    使用这个我们的dev 和qa 的后端在不同的aws 帐户的不同存储桶中具有不同的状态文件。我知道您的要求是什么,但这已经满足了我参与过的大多数项目,事实上,我们正在整个组织中扩展我们对该模型的使用。

    【讨论】:

    • 您好,感谢您的回复。所以我试图遵循一个非常相似的模型,其中 /dev、/test 和 /prod 文件夹基本上只是调用一堆模块。我坚持的一点是我在这些文件夹中保存了 s3 后端配置,似乎使用模块意味着它们将现有状态视为不再需要,即将它们标记为销毁,然后重新配置所有内容。您是否有机会分享您的 dev.tf 的编辑版本,以展示您如何管理后端?
    • @TomNorth 更新了我的dev/main.tf,主要区别在于显示qa/main.tf 的变化。这样可以很好地分离您的状态文件,并在您创建 qa 时避免拆除 dev
    【解决方案2】:

    好的,所以我认为我误解的一点是使用模块更改状态文件中的路径的方式。在阅读有关状态迁移的 Terraform 文档时,我意识到我的思路是正确的。

    我发现这个很棒的博客文章可以帮助我理解它: https://ryaneschinger.com/blog/terraform-state-move/

    没有评论区让我感谢那个人!无论如何,在看到它有多简单之后,我只是将terraform state list 命令输出到主文件的文本文件中。使用 PowerShell 快速迭代这些并为我将它们移动到的模块编写命令。当我尝试使用此脚本执行这些行时,我得到“Terraform 已崩溃!!!!”错误,所以只需将它们一一剪切并粘贴到我的外壳中。正确的nooby,但只有50个左右的资源,所以不是那么耗时。很高兴我在开发阶段这样做,而不是决定在产品中回顾性地这样做。

    所以我被排序了。感谢您通过 JBirdVegas 提供的意见。

    【讨论】:

      猜你喜欢
      • 2020-06-25
      • 2021-06-12
      • 2018-11-21
      • 2019-08-22
      • 2021-02-09
      • 2021-09-26
      • 2019-05-03
      • 1970-01-01
      • 2021-06-26
      相关资源
      最近更新 更多