Terraform:如何将变量传递给 user_data 初始化脚本

Les*_*Les 5 amazon-ec2 amazon-web-services amazon-rds terraform

我已经被这个问题困扰了一段时间,但无法解决。

我正在启动一个运行 bash 脚本并安装一些东西的 EC2 实例。同时,我还启动了一个 RDS 实例,但我需要能够将值从 RDS 端点传递到 EC2 实例来配置连接。

我正在尝试使用模板文件来做到这一点,就像这样

resource "aws_rds_cluster_instance" "cluster_instances" {
  count               = 1
  identifier          = "rds-prod-ddbb-${count.index}"
  cluster_identifier  = aws_rds_cluster.default.id
  instance_class      = "db.r5.large"
  engine              = "aurora"
  engine_version      = "5.6.mysql_aurora.1.22.5"
  publicly_accessible = "true"
}

resource "aws_rds_cluster" "default" {
  cluster_identifier      = "aws-rds-ddbb-cluster"
  availability_zones      = ["us-west-2b"]
  db_subnet_group_name    = "default-vpc-003d3ab296c"
  skip_final_snapshot     = "true"
  backup_retention_period = 30
  vpc_security_group_ids  = [aws_security_group.ddbb.id]
}

data "template_file" "RDSs" {
  template = file("init.sh")
  vars = {
    rds = aws_rds_cluster.default.endpoint
  }
  depends_on = [
    aws_rds_cluster.default,
    aws_rds_cluster_instance.cluster_instances,
  ]
}

resource "aws_instance" "web_01" {
  ami                    = "ami-0477c9562acb09"
  instance_type          = "t2.micro"
  subnet_id              = "subnet-0d0558d99ec3cd3"
  key_name               = "web-01"
  user_data_base64       = base64encode(data.template_file.RDSs.rendered)
  vpc_security_group_ids = [aws_security_group.ddbb.id]
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_type = "gp2"
    volume_size = 20
  }
  tags = {
    Name = "Web01"
  }
  depends_on = [
    aws_rds_cluster.default,
    aws_rds_cluster_instance.cluster_instances,
  ]
}
Run Code Online (Sandbox Code Playgroud)

然后我的init.sh就是这样的:

#!/bin/bash
echo "rds = $rds" > /var/tmp/rds
Run Code Online (Sandbox Code Playgroud)

但我什么也没得到/var/tmp/rds,所以看起来变量$rds是空的。

对你的帮助表示感谢。

Ps:我的输出配置如下:

outputs.tf

output "rds_endpoint" {
  value = aws_rds_cluster.default.endpoint
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,当应用完成时,它会向我显示 rds 端点的值。

Per*_*rry 8

Terraform 0.12开始,有一种更优雅的方式将变量传递给user_data

而不是使用terraform 中的data "template_file"新函数更喜欢使用templatefile


locals {
  WEB_SERVER_UNAME   = "your_username"
  WEB_SERVER_PASS    = "your_password"
}

resource "aws_instance" "web_01" {
  ....
  user_data_base64 = base64encode("${templatefile("${path.module}/user_data_script.sh", {
    WEB_SERVER_UNAME   = local.WEB_SERVER_UNAME
    WEB_SERVER_PASS    = local.WEB_SERVER_PASS
  })}")
  ....
}
Run Code Online (Sandbox Code Playgroud)

通过使用,$rds您引用了 shell 脚本或环境变量中的变量,这就是它不显示任何内容的原因。

要使用模板变量,您需要按以下方式进行插值${variable}

有关更多详细信息,请参阅此内容:- https://www.terraform.io/language/expressions/strings#string-templates


β.ε*_*.βε 6

免责声明:虽然这个答案确实解决了原始问题的语法,但还有更好的方法来处理底层用例。为此,请参阅@Perry的回答

\n
\n

该变量不是 shell 变量,而是模板变量 \xe2\x80\x94,因此 terraform 将解析该文件,无论其类型如何,并替换所述文件中的 terraform 变量。

\n

知道这一点,$rds不是 terraform 变量插值,${rds}

\n

所以,你的 bash 脚本应该是:

\n
#!/bin/bash\necho "rds = ${rds}" > /var/tmp/rds\n
Run Code Online (Sandbox Code Playgroud)\n