Terraform版本= 0.12
resource "aws_instance" "bespin-ec2-web" {
ami = "ami-0bea7fd38fabe821a"
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.bespin-sg.id]
subnet_id = aws_subnet.bespin-subnet-private-a.id
associate_public_ip_address = true
tags = {
Name = "bespin-ec2-web-a"
}
user_data = <<EOF
#!/bin/bash
USERS="bespin"
GROUP="bespin"
for i in $USERS; do
adduser ${i} -g ${GROUP};
echo ${i}:${i}1! | chpasswd;
cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config_old
sed -i 's/PasswordAuthentication no/#PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd
EOF
}为什么我在运行地形计划时会出错?
错误:无效引用
在instance.tf第15行中,在资源"aws_instance“”bespin-EC2-web“中: 15: adduser ${i} -g ${GROUP};
对资源类型的引用之后必须至少有一个属性访问,指定资源名称。
错误:无效引用
在instance.tf第15行中,在资源"aws_instance“”bespin-EC2-web“中: 15: adduser ${i} -g ${GROUP};
对资源类型的引用之后必须至少有一个属性访问,指定资源名称。
发布于 2020-02-13 19:13:17
这里错误的直接原因是${ ... }是Terraform的字符串模板插值语法,所以Terraform将${GROUP}理解为试图插值表达式GROUP,而GROUP不是有效的Terraform表达式。正如错误消息所暗示的,Terraform将GROUP理解为一种资源类型,就好像这是像aws_instance.foo这样的引用的第一部分。
修复此问题的最小更改是通过在前面添加一个附加的${ ... }序列来转义$序列,以便文字${GROUP}可以传递到user_data值:
user_data = <<-EOF
#!/bin/bash
USERS="bespin"
GROUP="bespin"
for i in $USERS; do
adduser ${i} -g $${GROUP};
echo $${i}:$${i}1! | chpasswd;
cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config_old
sed -i 's/PasswordAuthentication no/#PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd
EOF注意,转义只适用于${ ... },而不是像$USERS这样的序列: Terraform并不将单个美元符号解释为一个特殊字符,所以这将始终是字面意义上的。
这个特定的user_data表达式是完全静态的,不包含任何预期的Terraform模板语法,因此可以通过将user_data值移动到一个单独的文件中并使用函数逐字获取该文件的内容(根本没有模板解释)来避免转义:
user_data = file("${path.module}/user_data.sh")有时,user_data确实需要包含来自Terraform配置中其他位置的数据,并与shell语法混合。可以像上面描述的那样使用转义来做到这一点,但是随着所需字符串变得更加复杂,将包含插值的部分从文字部分中分离出来是很有用的,以便充分利用这两个世界,并避免脚本主体中的转义:
user_data = <<-EOT
EXAMPLE_VARIABLE='${var.example}'
${file("${path.module}/user_data.sh")}
EOT发布于 2020-02-13 06:49:49
应该通过模板呈现传递user_data,或者也可以使用base64encode函数传递文件。
data "template_file" "user-data" {
template = file("${path.module}/user-data.sh")
}
resource "aws_instance" "bespin-ec2-web" {
...
...
user_data = "${data.template_file.user_data.rendered}"
...
}https://stackoverflow.com/questions/60200964
复制相似问题