【问题标题】:Terraform Remote State - use variables which are not present during plan/applyTerraform 远程状态 - 使用计划/应用期间不存在的变量
【发布时间】:2021-07-22 11:51:30
【问题描述】:

我有一个关于 terraform 远程状态的问题。也许我使用的远程状态错误或有其他可能的解决方案:

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

我想重用端点和端口值并将它们传递给 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 容器环境的服务和任务?

【问题讨论】:

  • 顺便说一句,也许我的回答很匆忙,应该先回答这个问题,但是为什么要使用terraform_remote_state?因为我假设terraform apply 创建了terraform_remote_state 引用的资源,所以我没有看到使用它的理由。不要忘记您可以在module 中创建输出并通过module.alias.output_name 引用它并将其传递给环境变量。无论如何,如果您能提供最少的可重现示例,那将会很有帮助
  • 太棒了。谢谢你。不知道使用 module. 前缀的可能性。有效。周末愉快
  • PS:更新你的答案,我会接受的

标签: terraform terraform-provider-aws


【解决方案1】:

编辑 21-05-2021

我建议@smsnheck 如果使用module 块,可以通过module.module_name.output_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
}

main.tf

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 脚本创建数据库。如果是这样,您不应该使用data,因为data 是在任何资源创建之前读取的。因此,您正在尝试在创建数据库主机和端口之前获取有关它的信息。

假设您使用aws_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 将知道首先必须创建一个数据库实例,因为 .address.port 是在创建数据库实例之后已知的值(数据库实例现在将成为 docker 容器的依赖项)。

要获取有关创建资源后返回的值的更多信息,请参阅提供程序文档中的Attributes reference。例如,这里是aws_db_instance 的引用:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance#attributes-reference

【讨论】:

    猜你喜欢
    • 2012-06-27
    • 2019-07-29
    • 2019-11-11
    • 2018-04-29
    • 2018-09-18
    • 2016-11-24
    • 2016-12-22
    • 2021-08-30
    相关资源
    最近更新 更多