Terraform 地形远程状态-使用计划/应用期间不存在的变量

Terraform 地形远程状态-使用计划/应用期间不存在的变量,terraform,terraform-provider-aws,Terraform,Terraform Provider Aws,我有一个关于地形偏远州的问题。可能我使用远程状态错误,或者有另一种可能的解决方案: 在我的脚本中,我创建了一个db实例。创建的端点、端口等应保存在远程状态。DB脚本在一个模块中外包 我希望重用端点和端口值,并将它们传递给docker容器环境: environment = [ { name: "SPRING_DATASOURCE_URL", value: "jdbc:postgresql://${data.terraform_remot

我有一个关于地形偏远州的问题。可能我使用远程状态错误,或者有另一种可能的解决方案:

在我的脚本中,我创建了一个db实例。创建的端点、端口等应保存在远程状态。DB脚本在一个模块中外包

我希望重用端点和端口值,并将它们传递给docker容器环境:

environment = [
    {
      name: "SPRING_DATASOURCE_URL",
      value: "jdbc:postgresql://${data.terraform_remote_state.foo.outputs.db_endpoint}:${data.terraform_remote_state.foo.outputs.db_port}"
    }
这些脚本也外包到一个单独的模块中

在第一次运行时,terraform声明这些值不存在。因此,我必须对环境值进行注释,运行
terraform apply
,在创建完所有内容后,我必须重新运行terraform apply-现在使用环境值


是否有其他可能(更好的解决方案)将创建的db值传递给包含docker容器环境的服务和任务?

编辑21-05-2021

我建议@smsnheck,如果使用
模块
块,可以通过
模块.module\u name.output\u name
引用输出变量。例如:

module/main.tf

resource "aws_db_instance" "example" {
  // Arguments taken from example
  allocated_storage    = 10
  engine               = "mysql"
  engine_version       = "5.7"
  instance_class       = "db.t3.micro"
  name                 = "mydb"
  username             = "foo"
  password             = "foobarbaz"
  parameter_group_name = "default.mysql5.7"
  skip_final_snapshot  = true
}

output "db_host" {
  value = aws_db_instance.example.address
}

output "db_port" {
  value = aws_db_instance.example.port
}
module "db" {
  source = "./module"
}

// ...

resource "some_docker_provider" "example" {
// ...
  environment = [
    {
      name: "SPRING_DATASOURCE_URL",
      value: "jdbc:postgresql://${module.db.db_host}:${module.db.db_port}"
    }
  ]
// ...
}
main.tf

resource "aws_db_instance" "example" {
  // Arguments taken from example
  allocated_storage    = 10
  engine               = "mysql"
  engine_version       = "5.7"
  instance_class       = "db.t3.micro"
  name                 = "mydb"
  username             = "foo"
  password             = "foobarbaz"
  parameter_group_name = "default.mysql5.7"
  skip_final_snapshot  = true
}

output "db_host" {
  value = aws_db_instance.example.address
}

output "db_port" {
  value = aws_db_instance.example.port
}
module "db" {
  source = "./module"
}

// ...

resource "some_docker_provider" "example" {
// ...
  environment = [
    {
      name: "SPRING_DATASOURCE_URL",
      value: "jdbc:postgresql://${module.db.db_host}:${module.db.db_port}"
    }
  ]
// ...
}
旧答案


我假定您是从terraform脚本创建数据库的。如果是这样,您不应该使用
数据
,因为
数据
是在创建任何资源之前读取的。所以,您正在尝试在创建db主机和端口之前获取有关它的信息

假设您正在使用aws_DB_instance创建DB instance,您应该像下面这样引用端口和主机:

resource "aws_db_instance" "example" {
  // Arguments taken from example
  allocated_storage    = 10
  engine               = "mysql"
  engine_version       = "5.7"
  instance_class       = "db.t3.micro"
  name                 = "mydb"
  username             = "foo"
  password             = "foobarbaz"
  parameter_group_name = "default.mysql5.7"
  skip_final_snapshot  = true
}

// ...

// Locals are not required, you may use aws_db_instance.example. values directly
locals {
  db_host = aws_db_instance.example.address
  db_port = aws_db_instance.example.port
}

// ...

resource "some_docker_provider" "example" {
// ...
  environment = [
    {
      name: "SPRING_DATASOURCE_URL",
      value: "jdbc:postgresql://${local.db_host}:${local.db_port}"
    }
  ]
// ...
}
通过这种方式,Terraform将知道首先必须创建一个DB实例,因为
.address
.port
是在创建一个DB实例后已知的值(DB实例现在将成为docker容器的依赖项)


要获取有关创建资源后返回的值的更多信息,请参阅提供程序文档中的
属性参考
。例如,这里是aws\u db\u实例的参考资料。:

顺便说一句,也许我的答案太仓促了,应该先回答这个问题,但是为什么要使用
terraform\u remote\u state
?因为我假定
terraform apply
创建了由
terraform\u remote\u state
引用的资源,所以我看不到使用它的理由。不要忘记,您可以在
模块中创建输出,并通过
模块.alias.output\u name
引用它,然后将其传递给环境变量。无论如何,如果你能提供最小的可复制的例子,那将是很有帮助的。非常感谢。不知道是否可以使用
模块。
前缀。成功了。祝你周末愉快更新你的答案,我会接受的