How do I create an environment variable inside my config map, so I can set the env variable to be equal to a kubectl command

Hello folks I am super new to the entire kubernetes world and I am trying to do some really stupid things (since google clearly tells me that I am), But I wanted to confirm if this is indeed something that is impossible or I am just not approaching this problem correctly.

I have this config map, and here are my questions:

  • I would like to create a new env variable called CURRENT_CONTEXT ?
  • Which would hold the value of this executed command
kubectl config current-context
  • Then I want to use this CURRENT_CONTEXT, inside my config map.

How can I achieve this ? Truly appreciate anything to help me get better

{{- if .Values.collectMetrics }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-metric-publisher-config
  labels:
    {{- include "infrastructure.labels" . | nindent 4 }}
data:
  input.conf: |-
    input {
      kafka {
        bootstrap_servers => {{ template  "infrastructure.kafka.bootstrapServers" . }}
        topics => ["acs.to.metric"]
        client_id => "metric"
        enable_auto_commit => false
        codec => protobuf
        {
          class_name => "some.thing"
          class_file => '/some/location/metric_pb.rb'
          protobuf_root_directory => '/proto'
          protobuf_version => 3
        }
      }
    }
  bot_state_input.conf: |-
    input {
      kafka {
        bootstrap_servers => {{ template  "infrastructure.kafka.bootstrapServers" . }}
        topics => ["acs.to.state.bot"]
        client_id => "bot_state"
        enable_auto_commit => false
        key_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
        value_deserializer_class => "org.apache.kafka.common.serialization.ByteArrayDeserializer"
        codec => protobuf
        {
          class_name => "some.thing"
          class_file => '/some/thing/rcs/bot_state_pb.rb'
          protobuf_root_directory => '/proto'
          protobuf_version => 3
        }
      }
    }
  bot_cold_state_input.conf: |-
    input {
      kafka {
        bootstrap_servers => {{ template  "infrastructure.kafka.bootstrapServers" . }}
        topics => ["acs.to.state.bot.cold"]
        client_id => "cold_state"
        enable_auto_commit => false
        codec => protobuf
        {
          class_name => “some.thing”
          class_file => ‘/some/location/bot_cold_state_pb.rb'
          protobuf_root_directory => '/proto'
          protobuf_version => 3
        }
      }
    }
  convert_timestamp.conf: |-
    filter {
      ruby {
        code => "
          event.set('[@timestamp_nanoseconds]', (Time.at((event.get('[timestamp][epoch_second]').to_i )).to_datetime).strftime('%Y-%m-%dT%H:%M:%S.') + (event.get('[timestamp][nano]').to_s) +'Z' );
        "
      }
    }
  12_append_convert_types.conf: |-
    filter {
      mutate {
        convert => {
          "power_supply_status" => "string"
        }
      }
    }
  {{- if .Values.elasticsearch.enabled }}
  90_output_elastic.conf: |-
    output {
      elasticsearch {
        index => metrics_write
        hosts => "${ELASTICSEARCH_HOSTS}"
      }
    }
  {{- end }}
  {{- if .Values.shipMetricsToADX }}
  91_output_adx.conf: |-
    output {
      kafka {
        codec => json
        security_protocol => "SASL_SSL"
        sasl_mechanism => "PLAIN"
        topic_id => "{{ .Values.eventHub.entityPath }}"
        metadata_max_age_ms => 180000
        max_request_size => 1000000
        retries => 3
        request_timeout_ms => 30000
        linger_ms => 1000
      }
    }
  {{- end }}
  {{- if not ( or .Values.elasticsearch.enabled .Values.shipMetricsToADX) }}
    output {
      stdout {}
    }
  {{- end }}
  {{- end }}

A ConfigMap is data. It doesn’t have an environment because it is not “running”. It does not know anything about how it is going to be consumed.

Environment variables are defined on and consumed by workloads (Pods, Deployments, etc.)

The CURRENT_CONTEXT is a name, which is used as a lookup into a locally accessible file (kubeconfig) which has information like the hostname, username, creentials, etc. Even if you could pass that into your config, you ALSO need to make the actual config file available.

If your goal is to embed the context name into the config, you need to pre-process the config either up front (stored into the ConfigMap) or ehwn the workload starts.

e.g.

  • pod starts
  • pod reads configmap “template”
  • pod processes the template and expands variable definitions
  • pod writes a “final” config file

Thank you for the response, appreciate the quickness as well. I looked up some of the docs on pre-processing the config map. May I ask if you have any code suggestions on how your example can be done ? so I can try to mimic the solution. Any readables or docs or git urls just so I can see and try the same.

Hard without any real details of your use-case. It might be as simple as:

entrypoint.sh:

cat input.conf.tmpl | sed -e "s/{{VARIABLE_NAME}}/${VARIABLE_NAME}/g" > real.conf
exec "$@"