Search code examples
kubernetesjsonnet

Referencing a loop object


i am currently checking out tanka + jsonnet. But evertime i think i understand it... sth. new irritates me. Can somebody help me understand how to do a loop-reference? (Or general better solution?)

Trying to create multiple deployments with a corresponding configmapVolumeMount and i am not sure how to reference to the according configmap object here? (using a configVolumeMount it works since it refers to the name, not the object).

deployment: [
  deploy.new(
    name='demo-' + instance.name,
    ],
  )
  + deploy.configMapVolumeMount('config-' + instance.name, '/config.yml', k.core.v1.volumeMount.withSubPath('config.yml'))
  for instance in $._config.demo.instances
],

configMap: [
  configMap.new('config-' + instance.name, {
   'config.yml': (importstr 'files/config.yml') % {
      name: instance.name,
      ....
    },
  }),
  for instance in $._config.demo.instances
]

regards


Solution

  • Great to read that you're making progress with tanka, it's an awesome tool (once you learned how to ride it heh).

    Find below a possible answer, see inline comments in the code, in particular how we ab-use tanka layout flexibility, to "populate" deploys: [...] array with jsonnet objects containing each paired deploy+configMap.

    config.jsonnet

    {
      demo: {
        instances: ['foo', 'bar'],
        image: 'nginx',  // just as example
      },
    }
    

    main.jsonnet

    local config = import 'config.jsonnet';
    local k = import 'github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet';
    
    {
      local deployment = k.apps.v1.deployment,
      local configMap = k.core.v1.configMap,
      _config:: import 'config.jsonnet',
    
      // my_deploy(name) will return name-d deploy+configMap object
      my_deploy(name):: {
        local this = self,
        deployment:
          deployment.new(
            name='deploy-%s' % name,
            replicas=1,
            containers=[
              k.core.v1.container.new('demo-%s' % name, $._config.demo.image),
            ],
          )
          + deployment.configMapVolumeMount(
            this.configMap,
            '/config.yml',
            k.core.v1.volumeMount.withSubPath('config.yml')
          ),
        configMap:
          configMap.new('config-%s' % name)
          + configMap.withData({
            // NB: replacing `importstr 'files/config.yml';` by
            //     a simple YAML multi-line string, just for the sake of having
            //     a simple yet complete/usable example.
            'config.yml': |||
              name: %(name)s
              other: value
            ||| % { name: name },  //
          }),
      },
    
      // Tanka is pretty flexible with the "layout" of the Kubernetes objects
      // in the Environment (can be arrays, objects, etc), below using an array
      // for simplicity (built via a loop/comprehension)
      deploys: [$.my_deploy(name) for name in $._config.demo.instances],
    }
    

    output

    $ tk init
    [...]
    
    ## NOTE: using https://kind.sigs.k8s.io/ local Kubernetes cluster
    $ tk env set --server-from-context kind-kind environments/default
    [... save main.jsonnet, config.jsonnet to ./environments/default/]
    
    $ tk apply --dry-run=server environments/default
    [...]
    configmap/config-bar created (server dry run)
    configmap/config-foo created (server dry run)
    deployment.apps/deploy-bar created (server dry run)
    deployment.apps/deploy-foo created (server dry run)