Ansible 创建 ConfigMap 报 cannot unmarshal object:JSON 内容仍要是字符串
Ansible 创建 ConfigMap 报 cannot unmarshal object,先核 data 文件值的最终类型,以 JSON 序列化保留字符串,并区分 2.19 模板引擎变化。
通过 kubernetes.core.k8s 创建 ConfigMap,JSON 内容能通过语法检查,API 却报 cannot unmarshal object into Go struct field ConfigMap.data of type string。先查看实际提交的数据类型:data.appsettings.json 如果已经是字典对象,Kubernetes 就不会把它自动当成文件内容保存。
这条处理路径适用于 Ansible 将带模板变量的 JSON 内容交给 ConfigMap 的场景。ansible-core 2.14 与 kubernetes.core 3.0.0 的组合可能在模板处理后得到对象;2.19 起模板引擎改变了类型处理规则,因此按最终类型判断,不要认定所有版本都会发生相同的隐式转换。
JSON 文档合法,不代表 ConfigMap 字段类型合法
ConfigMap 的 data 是键与字符串值的映射。键可以叫 appsettings.json,但这个名称不会改变值的类型要求。下面是错误结构示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: example-app-config
data:
appsettings.json:
Enabled: true
Server: example-service
整个对象可以序列化成合法 JSON,appsettings.json 的值仍是对象。Kubernetes 在解析 ConfigMap 时要求这里是 UTF-8 字符串,于是拒绝请求。
正确的文件内容形式可以使用 YAML 多行字符串:
apiVersion: v1
kind: ConfigMap
metadata:
name: example-app-config
data:
appsettings.json: |-
{
"Enabled": true,
"Server": "example-service"
}
这只是静态结构示例。在 Ansible 中还要检查模板处理后的结果;源文件用了 |-,不能单独证明提交阶段仍然是字符串。错误日志或模块参数中,若该键下面显示嵌套字段,而不是一个字符串,先修正序列化边界。
把业务配置保留为对象,只在 data 的边界转成 JSON
需要动态填入变量时,可以在变量中管理业务配置,再明确把它序列化为 JSON 字符串。下面是任务结构示例,依赖已安装的 kubernetes.core 集合和现有的集群认证配置:
- name: Create application ConfigMap
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: ConfigMap
metadata:
name: example-app-config
namespace: team-app
data:
appsettings.json: "{{ app_settings | ansible.builtin.to_nice_json(indent=2) }}"
vars:
app_settings:
Enabled: true
Server: "{{ app_service_name }}"
app_settings 是配置对象,to_nice_json 在写入 data 的位置返回 JSON 字符串。不要再对结果使用 from_json,否则又会恢复成对象。也不要对已经编码好的 JSON 字符串重复序列化,导致文件内容多一层引号和转义。
这里的 true 是应用 JSON 内部的布尔值,可以保留;需要字符串的是 ConfigMap 外层的文件内容。把每个内部布尔值都加引号,不会修复“整个文件值是对象”的问题,反而可能改变应用期望的类型。
如果使用 template、lookup 或其他渲染链路,核对该链路在实际 Ansible 版本中的最终类型。2.19 起原生类型保留和模板信任规则有变化,旧的自动字符串转换经验不能代替核对。无需为此更改整个集群的安全设置或关闭证书校验。
发布前检查数据完整性,创建后检查应用读法
在受控环境中检查生成对象和相关值的类型,并确认业务 JSON 可以解析、关键字段完整、模板变量已按预期替换。不要用插入反斜杠、删除首行或破坏 JSON 的方式让 API 暂时接受请求。
ConfigMap 不提供凭据保护。诊断输出可能带整个配置,避免把数据库密码、API Token 或认证字段打印到公共日志;敏感内容按现有 Secret 或凭据管理流程处理,不能因排查方便放入示例 ConfigMap。
更新已有对象前保存清单和部署版本,确认名称、命名空间、immutable 设置及配置管理归属,避免最小示例覆盖原有其他键。ConfigMap 更新被接受后,应用是否取得新值还与文件挂载、环境变量、subPath 和应用重读机制有关。需要替换 Pod 时按原部署流程安排影响,不能把创建成功当成业务已经切换。
验收包括三个结果:API 不再报该字符串类型错误,保存的文件内容是预期 JSON,应用实际读取后行为正确。若需要回退,恢复保存的 ConfigMap 和对应应用版本;恢复清单不会自动刷新已经启动的进程环境,也不会撤销应用已经处理的数据。


