TL;DR: A kubernetes OperatorGroup expects the node spec/targetNamespace to be an array!
Utilizing the terraform kubernetes_manifest resource I ran into an error specifying the operator namespace.
resource “kubernetes_manifest” “grafana-operator” {
manifest = {
“spec” = {
targetNamespaces = “grafana”
}
}
The error and the stacktrace were more confusing than helpful, initially.
Error: “Failed to morph manifest to OAPI type”
AttributeName(“spec”): [AttributeName(“spec”)] failed to morph object element into object element: AttributeName(“spec”): [AttributeName(“spec”)] unsupported morph of tuple value into type: tftypes.Object[“selector”:tftypes.Object[“matchExpressions”:tftypes.List[tftypes.Object[“key”:tftypes.String, “operator”:tftypes.String, “values”:tftypes.List[tftypes.String]]], “matchLabels”:tftypes.Map[tftypes.String]], “serviceAccountName”:tftypes.String, “staticProvidedAPIs”:tftypes.Bool, “targetNamespaces”:tftypes.List[tftypes.String]]
I created this from a working YAML and use similar structures elsewhere so I wasn’t sure why this particular one was throwing an error. Finally, after fruitless searching I loaded up the OperatorGroup schema and saw:
targetNamespaces array
It seems like a fair mistake to make and overlook since passing a single namespace as a string is accepted in most areas, but terraform can be less flexible. In hindsight, the error message was quite helpful. Note the last line:
“targetNamespaces”:tftypes.List[tftypes.String]]
Any problem is an opportunity for learning and my takeaways from this are:
- Read and try to understand the whole error message, even if you think it’s not useful.
- Recognize the differences between the different technologies and how they deal with certain scenarios. In this case, how do terraform and k8s handle type casting and conversion?
- Technology is constantly evolving and documentation and error logging can lag which makes them great opportunities for contributions.
Until the next time, RTFM!