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

PyYAML在SSH公钥中插入额外换行的问题排查求助

Fixing PyYAML's Unwanted Line Break in SSH Public Keys for Ansible Vars

I’ve run into this exact issue before when generating Ansible vars files from database-stored SSH keys—PyYAML has a habit of breaking long strings (like SSH public keys) into multiple lines, especially right before the email portion, which messes up Ansible’s ability to parse the key correctly. Let’s break down why this happens and how to fix it.

Why This Happens

PyYAML’s default serialization behavior automatically wraps strings that exceed a default length (around 80 characters) using folded block style (>) or inserting line breaks. For SSH public keys—single-line strings ending with an email address—this often results in a line break right before the @ symbol, splitting the key into two lines that Ansible doesn’t recognize as a valid public key.

Solution 1: Force Plain Scalar Output (Most Reliable)

The best way to ensure your SSH key stays as a single unbroken line is to tell PyYAML to treat it as a plain scalar string, which overrides its automatic wrapping logic. You’ll need to use the PlainScalarString class from PyYAML’s scalarstring module:

import yaml
from yaml.scalarstring import PlainScalarString

# Initialize your base dictionary
yamldict = { "users": [] }

# Example data pulled from MySQL (replace with your actual DB fetch logic)
username = "user"
full_name = "User McUserface"
email = "user@example.com"
ssh_pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 user@example.com"

# Add user data, wrapping the SSH key in PlainScalarString to preserve line structure
yamldict["users"].append({
    "username": username,
    "name": full_name,
    "email": email,
    "ssh_public_key": PlainScalarString(ssh_pubkey)
})

# Dump to YAML with settings that preserve your desired structure
with open("ansible_users.yml", "w") as f:
    yaml.dump(
        yamldict,
        f,
        default_flow_style=False,  # Keeps nested structures as readable block style
        sort_keys=False,  # Preserves the order of your dictionary keys
        allow_unicode=True  # Handles any special characters in names/emails correctly
    )

Solution 2: Increase Line Width (Quick Fix)

If you don’t want to import extra modules, you can tell PyYAML to use a much larger line width, so it won’t wrap the SSH key string. This works for most cases, though it’s less reliable if you have extremely long keys:

import yaml

yamldict = { "users": [] }
# ... (same user data setup as above)

with open("ansible_users.yml", "w") as f:
    yaml.dump(
        yamldict,
        f,
        default_flow_style=False,
        sort_keys=False,
        width=10000  # Set to a value larger than any possible SSH key length
    )

Verify the Output

After running either solution, check your generated YAML file—your SSH public key should appear as a single line, like this:

users:
- username: user
  name: User McUserface
  email: user@example.com
  ssh_public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 user@example.com

No more line breaks in the key, and Ansible will parse it correctly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:37:48