【问题标题】:Terraform only runs the first part of multi-part user dataTerraform 仅运行多部分用户数据的第一部分
【发布时间】:2021-09-11 18:56:45
【问题描述】:

我正在研究使用 Terraform 设置 VM 基础架构并使用 cloud-init 启动 VM。我正在尝试使用多部分方法,第一部分使用 cloud-config 内容类型,第二部分使用 shellscript

但是,在terraform apply 上,只有第一部分被执行,而第二部分没有运行(通过检查生成的 VM 是否已应用更改)。

相关配置部分如下。

data "template_cloudinit_config" "config" {
  gzip = true
  base64_encode = true
  part {
      filename = "init-cloud-config"
      content_type = "text/cloud-config"
      content = file("../modules/services/${var.service_name}/init.yaml")
  }
  part {
      filename = "init-shellscript"
      content_type = "text/x-shellscript"
      content = templatefile("../modules/services/${var.service_name}/init.sh",
        { hostname = "${var.prefix}-${var.service_name}" }
      )
  }
}

cloud-init init.yaml 内容如下

groups:
  - dataops

users:
  - default
  - name: dataops
    gecos: Data Operations
    shell: /bin/bash
    primary_group: dataops
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: users, admin
    lock_passwd: false

package_update: true

packages:
  - wget

shellscript init.sh 的内容只有一行

hostnamectl set-hostname testconfig

来自 cloud-init.log 的错误如下

2021-06-29 16:09:51,315 - util.py[DEBUG]: Running command ['/var/lib/cloud/instance/scripts/init-shellscript'] with allowed return codes [0] (shell=False, capture=False)
2021-06-29 16:09:51,317 - util.py[WARNING]: Failed running /var/lib/cloud/instance/scripts/init-shellscript [-]
2021-06-29 16:09:51,317 - util.py[DEBUG]: Failed running /var/lib/cloud/instance/scripts/init-shellscript [-]
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/cloudinit/util.py", line 2048, in subp
    env=env, shell=shell)
  File "/usr/lib64/python3.6/subprocess.py", line 729, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.6/subprocess.py", line 1364, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 8] Exec format error: b'/var/lib/cloud/instance/scripts/init-shellscript'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/cloudinit/util.py", line 896, in runparts
    subp(prefix + [exe_path], capture=False)
  File "/usr/lib/python3.6/site-packages/cloudinit/util.py", line 2056, in subp
    stderr="-" if decode else b"-")
cloudinit.util.ProcessExecutionError: Exec format error. Missing #! in script?
Command: ['/var/lib/cloud/instance/scripts/init-shellscript']
Exit code: -
Reason: [Errno 8] Exec format error: b'/var/lib/cloud/instance/scripts/init-shellscript'
Stdout: -
Stderr: -
2021-06-29 16:09:51,329 - cc_scripts_user.py[WARNING]: Failed to run module scripts-user (scripts in /var/lib/cloud/instance/scripts)
2021-06-29 16:09:51,330 - handlers.py[DEBUG]: finish: modules-final/config-scripts-user: FAIL: running config-scripts-user with frequency once-per-instance
2021-06-29 16:09:51,330 - util.py[WARNING]: Running module scripts-user (<module 'cloudinit.config.cc_scripts_user' from '/usr/lib/python3.6/site-packages/cloudinit/config/cc_scripts_user.py'>) failed    
2021-06-29 16:09:51,330 - util.py[DEBUG]: Running module scripts-user (<module 'cloudinit.config.cc_scripts_user' from '/usr/lib/python3.6/site-packages/cloudinit/config/cc_scripts_user.py'>) failed      
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/cloudinit/stages.py", line 852, in _run_modules
    freq=freq)
  File "/usr/lib/python3.6/site-packages/cloudinit/cloud.py", line 54, in run
    return self._runners.run(name, functor, args, freq, clear_on_fail)
  File "/usr/lib/python3.6/site-packages/cloudinit/helpers.py", line 187, in run
    results = functor(*args)
  File "/usr/lib/python3.6/site-packages/cloudinit/config/cc_scripts_user.py", line 45, in handle
    util.runparts(runparts_path)
  File "/usr/lib/python3.6/site-packages/cloudinit/util.py", line 903, in runparts
    % (len(failed), len(attempted)))
RuntimeError: Runparts: 1 failures in 1 attempted commands
2021-06-29 16:09:51,356 - stages.py[DEBUG]: Running module ssh-authkey-fingerprints (<module 'cloudinit.config.cc_ssh_authkey_fingerprints' from '/usr/lib/python3.6/site-packages/cloudinit/config/cc_ssh_authkey_fingerprints.py'>) with frequency once-per-instance

【问题讨论】:

  • 用户数据在哪里运行?例如 AWS/GCP/其他地方?是否所有用户数据部分最终都在机器上? /var/log/cloud-init.log/var/log/cloud-init-output.log 显示什么?你能分享你的用户数据部分吗?
  • 作为参考,template_file 数据源已被弃用,取而代之的是 templatefile 函数,您已经在使用它,这有点令人困惑。您可以按照content = templatefile("../modules/services/${var.service_name}/init.sh", { hostname = "${var.prefix}-${var.service_name}" } 使用它。对于第一个,它看起来根本不像模板,所以你可以使用content = file("../modules/services/${var.service_name}/init.yaml")
  • 感谢简化方法。按建议编辑

标签: terraform cloud-init


【解决方案1】:

该错误中的相关行是这样的:

cloudinit.util.ProcessExecutionError: Exec format error. Missing #! in script?

为了让 cloud-init 运行用户数据 shell 脚本,它需要知道解释器将是什么,因此必须以 shebang - #! 开头 - 以及解释器的路径,因此您的脚本应该如下所示:

#!/bin/sh
hostnamectl set-hostname testconfig

或者在您的情况下,它是一个模板,期望将 hostname 作为变量传递,所以它应该是:

#!/bin/sh
hostnamectl set-hostname ${hostname}

【讨论】:

    猜你喜欢
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 2011-06-21
    • 1970-01-01
    • 2019-10-12
    • 2015-01-15
    • 1970-01-01
    相关资源
    最近更新 更多