You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Puppet模板嵌套迭代报错,如何正确生成sudo_authorized_keys文件?

问题:Puppet模板嵌套迭代生成sudo_authorized_keys失败

背景与目标

我本周开始学习Puppet,想要把用户密钥写入/etc/ssh/sudo_authorized_keys文件。

数据存储(sudo_users.yaml)

core::sudo_users_keys:
  kate:
    keys:
      key1:
        type: "ssh-ed25519"
        key: "AAAAC3N..."
  john:
    keys:
      key1:
        type: "ssh-ed25519"
        key: "AAAAC..."
  marvin:
    keys:
      key1:
        type: "ssh-ed25519"
        key: "AAAAC3Nza..."

已编写的Puppet类(sudokeys.pp)

class core::sudokeys {
    file { "/etc/ssh/sudo_authorized_keys":
      ensure  => file,
      mode    => "0440",
      content => template("core/sudo_authorized_keys.erb"),
    }
}

当前模板代码(sudo_authorized_keys.erb)

<%- scope['core::sudo_users_keys'].each | user | -%>
    {
        <%- if user[1] -%>
        <%- $user[1]['keys'].each do | key | -%>
        <%= $key[1]['type'] $key[1]['key'] -%> 
        <%- end end -%>
      }
    <%- end -%>

参考可用代码(sshkeys类)

之前用相同数据结构配置用户ssh密钥时,这段代码可以正常工作,但无法直接用于生成sudo_authorized_keys文件,所以选择模板方式:

class core::sshkeys {
  lookup("core::sudo_users_keys").each | $user | {
    if $user[1] {
      $user[1]["keys"].each | $key | {
        ssh_authorized_key { "${user[0]}-${key[0]}":
          ensure => present,
          user   => $user[0],
          type   => $key[1]["type"],
          key    => $key[1]["key"],
        }
      }
    }
  }
}

遇到的错误

部署模板时出现语法错误:

Internal Server Error: org.jruby.exceptions.SyntaxError: (SyntaxError) /etc/puppetlabs/code/environments/test/modules/core/templates/sudo_authorized_keys.erb:2: syntax error, unexpected tSTRING_BEG
_erbout<< "    {\n".freeze
           ^

解决方案

你的模板存在多处语法问题,修正后的模板代码如下:

<%- scope.lookupvar('core::sudo_users_keys').each_pair |$username, $user_data| -%>
<%-   if $user_data['keys'] -%>
<%-     $user_data['keys'].each_pair |$key_name, $key_data| -%>
<%=       "${key_data['type']} ${key_data['key']}" -%>
<%-     end -%>
<%-   end -%>
<%- end -%>

关键修改点:

  1. 遍历方式优化:使用each_pair直接获取键值对(用户名和对应数据),替代原有的each+索引取值,代码更直观易读。
  2. 变量引用修正:Puppet ERB模板中变量无需加$前缀,同时用scope.lookupvar()规范获取类变量。
  3. 格式与语法修复:原模板中密钥类型和内容缺少空格分隔,且多余$前缀导致语法错误,修正后输出符合sudo_authorized_keys要求的每行一个密钥的格式(类型+空格+密钥内容)。
  4. 冗余符号移除:原模板中的{}属于多余内容,直接输出密钥行即可,匹配文件格式要求。

可选扩展

如果需要在密钥后添加注释(比如关联用户名),可以修改输出行:

<%=   "${key_data['type']} ${key_data['key']} ${username}" -%>

内容的提问来源于stack exchange,提问作者Brzozova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:05:25