Andys1814
Andys1814

Reputation: 125

Retrieving contents of j2 template file on stdout

I'm attempting to use Ansible to better manage my Kubernetes configmaps in a multienvironment project (dev, stage, and prod). I've generalized each of the config maps as j2 templates, and I'll override the variables depending on how they might change in different environments (so that they aren't duplicated three times for basically the same file).

My playbook currently looks something like this:

---
- hosts: localhost
  vars_files:
    - "vars/{{ env }}.yml"
  tasks:
    - name: Generate YAML from j2 template
      template:
        src: templates/foo.j2
        dest: output/foo.yml

And this has been working great for testing so far. However, I'm at the point where I want to incorporate this into my already existing Jenkins CI/CD, but I'm having trouble understanding how it might work with what I am doing currently.

After generating what is basically a Kuberenets ConfigMap from the j2, I'll somehow do this within Jenkins:

kubectl apply -f <yaml>

However, the playbook is creating a YAML file every time I run it, and I am wondering if there is an alternative that would allow me to pipe the contents of the YAML file or somehow retrieve it from stdout.

Basically, I want to evaluate the template and retrieve it without necessarily creating a file.

If I do this, I could do something like the following:

echo result | kubectl apply -f -

where result of course is the contents of the YAML file that results after the templating, and the short dash after the f flag specifies Kubernetes to use the process' stdout.

Sorry for so much explaining, I can clarify anything if needed.

Upvotes: 3

Views: 4275

Answers (2)

thisguy123
thisguy123

Reputation: 945

You've got a couple options here. I usually try to stay away from shelling out to command wherever possible. Check out the k8s module in ansible. Note that as long as state is present ansible will patch your object.

- name: Apply your previously generated configmap if you so choose.
  k8s:
    state: present
    definition: "{{ lookup('file', '/output/foo.yml') }}"

Or even better, you could just directly create the configmap

 - name: Create the configmap for {{ env }}
   k8s:
    state: present
    definition:
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: ConfigMap
        namespace: "{{ foo_namespace }}"
        labels:
          app: bar
          environment: "{{ bizzbang }}"

Upvotes: 1

mdaniel
mdaniel

Reputation: 33223

I would like to retrieve the result of the template, and pipe it into that command, such as "echo result | kubectl apply -f -"

In which case, you'd use the stdin: parameter of the command: module:

- name: generate kubernetes yaml
  command: echo "run your command that generates yaml here"
  register: k8s_yaml

- name: feed the yaml to kubectl apply
  command: kubectl apply -f -
  stdin: '{{ k8s_yaml.stdout }}'

It isn't super clear what the relationship is in your question between the top part, dealing with the template:, and the bottom part about apply -f -, but if you mean "how can I render a template to a variable, instead of a file?" the the answer is the template lookup plugin:

- name: render the yaml
  set_fact:
    k8s_yaml: '{{ lookup("template", "templates/foo.j2") }}'

- name: now feed it to apply
  command: kubectl apply -f -
  stdin: '{{ k8s_yaml }}'

Upvotes: 4

Related Questions