Overwrite a nested list element using jsonnet

Solution 1:

See below for an implementation that allows adding env to an existing container by its index in the containers[] array.

Do note that jsonnet is much better suited to work with objects (i.e. dictionaries / maps) rather than arrays, thus it needs contrived handling via std.mapWithIndex(), to be able to modify an entry from its matching index.

local grafana_envs = (import 'deployment_env.json');

// Add extra_env to a container by its idx passed containers array
local override_env(containers, idx, extra_env) = (
  local f(i, x) = (
    if i == idx then x {env+: extra_env} else x
  );
  std.mapWithIndex(f, containers)
);
local grafanaDeployment = (import 'nested.json') + {
    spec+: {
        template+: {
            spec+: {
                containers: override_env(super.containers, 0, grafana_envs.env)
            }
        }
    },
};
grafanaDeployment 

Solution 2:

Alternative implementation, not relying on the array index position, but image value instead (which makes more sense here as the env must be understood by the image implementation)

local grafana_envs = (import 'deployment_env.json');

local TARGET_CONTAINER_IMAGE = 'practodev/test:test';

local grafanaDeployment = (import 'nested.json') + {
  spec+: {
    template+: {
      spec+: {
        containers: [
          // TARGET_CONTAINER_IMAGE identifies which container to modify
          if x.image == TARGET_CONTAINER_IMAGE
          then x { env+: grafana_envs.env }
          else x
          for x in super.containers
        ],
      },
    },
  },
};
grafanaDeployment