首页 文章

Terraform s3后端未被模块使用

提问于
浏览
0

我已经开始使用Terraform并完全买入它 - 太棒了!我已经根据AWS VPC,子网,NACL,SG,路由表等创建了我的整个Dev环境,我已经决定最好把它变成可重用的模块 .

所以现在我把它变成了模块,变量等 . 现在我的开发模板只需要变量并将它们用作模块的输入 . 我最终得到了这个:

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

2 回答

  • 1

    好的,所以我认为我误解的是使用模块改变状态文件中路径的方式 . 我意识到我在阅读关于州迁移的Terraform文档时处于正确的位置 .

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

    没有评论部分让我感谢那家伙!无论如何,在看到它有多容易之后,我只是将 terraform state list 命令输出到主文件的文本文件中 . 使用PowerShell快速迭代这些并编写我正在移动它们的模块的命令 . 当我尝试用这个脚本执行行时,我得到了"Terraform has crashed!!!!"错误,所以只需将它们剪切并粘贴到我的shell中 . 适当的nooby,但只有50左右的资源,所以不是那么耗费时间 . 我很高兴我在开发阶段这样做,而不是决定在 生产环境 中回顾性地做这件事 .

    所以我排序了 . 感谢您通过JBirdVegas提供的输入 .

  • 0

    我们遇到了这个问题,并决定每个环境都需要一个代码表示,我们可以在需要时同时查看其他代码,即将开发配置与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.tfqa/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基本相同(在顶部修改几个变量)然而最重要的区别是 qa/main.tf 的最顶层这些变量:

    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"
    }
    

    使用这个我们的后端 devqa 在不同的aws帐户中的不同存储桶中有不同的状态文件 . Idk您的要求是什么,但这已经满足了我与之合作的大多数项目,实际上我们正在扩展我的组织在我的组织中的使用 .

相关问题