#help (2024-03)

Where to get help about getting help!

2024-03-13

Brennan avatar
Brennan

Hi, I’m trying to get templates to work and I believe my situation is such: there’s a TF component that has a setting in settings setting_a: "a" and then the same component it has a variable that references that setting var_a: {{ .settings.setting_a }}. I’m getting an error of invalid stack manifest and yaml: key map: map[… . Any ideas what could be going wrong here? Also it seems like if I put the variable value in double quotes then it is used as a literal string. Thanks!

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

you need to quote the Go templates, use either single or double quotes

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

without the quotes, the yaml is invalid

Brennan avatar
Brennan

It seems to me that both double and single quoting leads to the templated section being single quoted with the literal template as a value (as seen with a describe command).

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

it produces

    atmos_component: vpc
    atmos_manifest: orgs/acme/plat/dev/us-east-2
    atmos_stack: plat-ue2-dev
    terraform_workspace: plat-ue2-dev
Brennan avatar
Brennan

I think I’ve been looking at the first one.

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

i don’t see the final values quoted. What yaml are you using?

Brennan avatar
Brennan

relevant snippet (thanks for responding btw ):

      settings:
        setting_a: "a"
      vars:
        var_a: "{{ .settings.setting_a }}"
Brennan avatar
Brennan

and it’s not that the final values are quote its that the value seems to just be the literal template var_a: '{{ .settings.setting_a }}'

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

hmm, what Atmos version are you using?

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

i’m def not seeing the issue

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)
terraform:
  vars:
    var_a: "{{ .settings.setting_a }}"
    tags:
      var_a: "{{ .settings.setting_a }}"

settings:
  setting_a: "a"
Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)
vars:
  tags:
    var_a: a
  var_a: a
Brennan avatar
Brennan

looks like 1.57.0

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

need to use 1.66.0

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

before that, Go templates were not supported, and that’s why those are literal values

Brennan avatar
Brennan

thanks! works now

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

super

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

also you prob have figured it out, circular deps in templates are not supported (e.g. template a references template b, b references c, c references a). Atmos (at least currently) does only once pass to process the templates

Brennan avatar
Brennan

Good tip, thanks! Had Golang templating existed before and just the utilization by stack manifests is new to 1.66.0? Looks quite helpful

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

Go templates existed before only in imports. Now they are supported in stack manifests in 1.66.0

1
Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

but note that those are completely different methods

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

imports are special because they are used to process the manifests to actually find a component in a stack

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

so you can’t just use templates in imports. You need to specify “context” with already defined values because imports are processed first before processing the component in the stack

Brennan avatar
Brennan

ah okay, interesting.

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)
Stack Imports | atmos

Imports are how we reduce duplication of configurations by creating reusable baselines. The imports should be thought of almost like blueprints. Once

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

import is the special section where you can’t use Go templates without providing the static context

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

that’s b/c of the multi-phase processing. When you execute atmos terraform apply vpc -s plat-ue2-prod, Atmos does the following to find the component in the stack in all those stack manifest files:

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)
  1. Read all top-level stack manifests (defined in atmos.yaml in the stacks.included_path excluding those from the stacks.excluded_paths)
  2. Process Go templates in all the imports (using the static context since no other section (vars, settings, etc.) is know yet for the component
  3. Read all the imported files and merge them into a map (first deep-merging phase)
  4. Deep-merge all Atmos sections (vars, settings etc.) from all scopes (Org, tenant, account, region, base component, component) into a final map of all components in all stacks (second deep-merging phase)
  5. Find the component in the stack (or throw an error if not found)
  6. And finally, process the Go templates in the component in all other sections except import (import is not used here since evrything was already imported and deep-merged)
Brennan avatar
Brennan

Is there a canonical Atmos section to put info in a mixin that might be used for vars in a component? I don’t want to put the info in vars b/c I don’t want it added every time I reference the mixin and may want to process the info a bit while assigning it. Maybe metadata makes sense? Maybe using another mixin is the better approach though.

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)
Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

but settings is a free-form map, you can put anything in there and then get it back in the Go templates or from the command atmos describe component

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)
components:
   terraform:
      vpc:
        settings:
          <anything can go here>
Brennan avatar
Brennan

ah okay, so it’s not like terraform or helm settings only. thanks that helps.

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

you can define anything in settings, make it a separate component, or a separate base abstract component, then import it or inherit from it in other components (https://atmos.tools/core-concepts/components/inheritance)

Component Inheritance | atmos

Component Inheritance is one of the principles of Component-Oriented Programming (COP)

Brennan avatar
Brennan

cool, thanks for all the info

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

let’s use atmos for all Atmos-related questions

    keyboard_arrow_up