首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在terrafom中创建实例时使用user_data时出错

在terrafom中创建实例时使用user_data时出错
EN

Stack Overflow用户
提问于 2020-02-13 05:24:15
回答 2查看 2K关注 0票数 1

Terraform版本= 0.12

代码语言:javascript
复制
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};

对资源类型的引用之后必须至少有一个属性访问,指定资源名称。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-13 19:13:17

这里错误的直接原因是${ ... }Terraform的字符串模板插值语法,所以Terraform将${GROUP}理解为试图插值表达式GROUP,而GROUP不是有效的Terraform表达式。正如错误消息所暗示的,Terraform将GROUP理解为一种资源类型,就好像这是像aws_instance.foo这样的引用的第一部分。

修复此问题的最小更改是通过在前面添加一个附加的${ ... }序列来转义$序列,以便文字${GROUP}可以传递到user_data值:

代码语言:javascript
复制
  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值移动到一个单独的文件中并使用函数逐字获取该文件的内容(根本没有模板解释)来避免转义:

代码语言:javascript
复制
  user_data = file("${path.module}/user_data.sh")

有时,user_data确实需要包含来自Terraform配置中其他位置的数据,并与shell语法混合。可以像上面描述的那样使用转义来做到这一点,但是随着所需字符串变得更加复杂,将包含插值的部分从文字部分中分离出来是很有用的,以便充分利用这两个世界,并避免脚本主体中的转义:

代码语言:javascript
复制
  user_data = <<-EOT
    EXAMPLE_VARIABLE='${var.example}'
    ${file("${path.module}/user_data.sh")}
  EOT
票数 4
EN

Stack Overflow用户

发布于 2020-02-13 06:49:49

应该通过模板呈现传递user_data,或者也可以使用base64encode函数传递文件。

代码语言:javascript
复制
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}"

  ...
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60200964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档