#atmos (2024-11)
2024-11-01
with the atmos github actions I can plan/apply no problem but now I want to destroy and I do not have a count = module.this.enabled ? 1 : 0
, how do you guys destroy? I will like to be able to find the delete yaml from the stack and destroy that one if possible
Interesting. So we are working on supporting an enabled flag for components.
what
why
references
• DEV-2150
The scope is not currently to destroy. However, it might be worth considering that.
In the current implementation, enabled would make the component “invisible”
an alternative to commenting it out.
I can see a component as having 3 states
• enabled
• disabled
• destroyed
I think if the components are commented out or deleted from the stack file, describe affected
should know what to do with it or output a destroyed
flag or something like that for another job to use that matrix to destroy it
Ok, that makes sense.
So enabled = true/false affects the visibility, but removal from the configuration is visible via atmos describe affected
@Andriy Knysh (Cloud Posse) what happens today in describe affected if the component is removed? is that surfaced?
I renamed a component from pepetest
to pepetest1
, describe affected saw the new pepetest1
component got deployed, but the old one is still there in the cloud environment
the key is do we have the information in describe affected
JSON output
The right behavior might not be implemented, but maybe we have the data there to act on
if a component is removed, Atmos does not see it (it will not consider it affected) - this is the current implementation. This is b/c Atmos compares the current branch with a remote branch/tag/sha - if the current branch does not have the component, then it’s “not affected”.
Setting enabled: false
is not “removal”, so describe affected
sees that
but with that, you need a two-step approach, one to say enable: false and then another PR to remove the yaml from the stack file
yes
i would say we didn’t consider a complete component removal with describe affected - we need to revisit this
2024-11-02
Improve terraform
and helmfile
help. Enable Go
templating in the command
field. Clean Terraform workspace before executing terraform init
@aknysh (#759)
what
• Improve terraform
and helmfile
help
• Enable Go
templating in the command
field of stack config
• Clean Terraform workspace before executing terraform init
why
• Improve the help messages. When a user executes atmos terraform --help
or atmos helmfile --help
(or help for a subcommand), print a message describing the command and how to execute the terraform
and helmfile
help command
atmos terraform –help
• Enable Go templating in the command
stack config in addition to the already supported sections.
You can now use Go
templates in the following Atmos sections to refer to values in the same or other sections:
• vars
• settings
• env
• providers
• overrides
• backend
• backend_type
• component
• metadata.component
• command
Enabling Go
templates in the command
section allows specifying different Terraform/OpenTofu/Helmfile versions per component/stack, and get the value from different Atmos sections or from external data sources
• Clean Terraform workspace before executing terraform init
. When using multiple backends for the same component (e.g. separate backends per tenant or account), and if an Atmos command was executed that selected a Terraform workspace, Terraform will prompt the user to select one of the following workspaces:
- default
-
The prompt forces the user to always make a selection (which is error-prone), and also makes it complicated when running on CI/CD. The PR adds the logic that deletes the `.terraform/environment` file from the component directory before executing `terraform init`. The `.terraform/environment` file contains the name of the currently selected workspace, helping Terraform identify the active workspace context for managing your infrastructure. We delete the file before executing `terraform init` to prevent the Terraform prompt asking to select the default or the previously used workspace.
@jose.amengual another one for you
Improve terraform
and helmfile
help. Enable Go
templating in the command
field. Clean Terraform workspace before executing terraform init
@aknysh (#759)
what
• Improve terraform
and helmfile
help
• Enable Go
templating in the command
field of stack config
• Clean Terraform workspace before executing terraform init
why
• Improve the help messages. When a user executes atmos terraform --help
or atmos helmfile --help
(or help for a subcommand), print a message describing the command and how to execute the terraform
and helmfile
help command
atmos terraform –help
• Enable Go templating in the command
stack config in addition to the already supported sections.
You can now use Go
templates in the following Atmos sections to refer to values in the same or other sections:
• vars
• settings
• env
• providers
• overrides
• backend
• backend_type
• component
• metadata.component
• command
Enabling Go
templates in the command
section allows specifying different Terraform/OpenTofu/Helmfile versions per component/stack, and get the value from different Atmos sections or from external data sources
• Clean Terraform workspace before executing terraform init
. When using multiple backends for the same component (e.g. separate backends per tenant or account), and if an Atmos command was executed that selected a Terraform workspace, Terraform will prompt the user to select one of the following workspaces:
- default
-
The prompt forces the user to always make a selection (which is error-prone), and also makes it complicated when running on CI/CD. The PR adds the logic that deletes the `.terraform/environment` file from the component directory before executing `terraform init`. The `.terraform/environment` file contains the name of the currently selected workspace, helping Terraform identify the active workspace context for managing your infrastructure. We delete the file before executing `terraform init` to prevent the Terraform prompt asking to select the default or the previously used workspace.
this feels like Xmas
2024-11-03
hey folks, for some reason atmos generate wrong terraform workspace name, i have a component named nats
and stack named dev
and instead of dev-nats
the workspace is simply dev
what could cause that ?
Something is wrong with your name_pattern or name_template
i didn’t change those.
Share your atmos config, if you can
Use the atmos.yaml
to configure where Atmos will discover stack configurations.
base_path: .
components:
terraform:
command: tofu
base_path: components/terraform
apply_auto_approve: false
deploy_run_init: true
init_run_reconfigure: true
auto_generate_backend_file: true
stacks:
base_path: stacks
included_paths:
- "deploy/**/*"
excluded_paths:
- "**/_defaults.yaml"
name_pattern: "{stage}"
workflows:
base_path: stacks/workflows
templates:
settings:
enabled: true
sprig:
enabled: true
logs:
file: /dev/stderr
level: Info
Ok, I think I initially misunderstood.
Are you setting workspace key prefix anywhere?
nope
@Andriy Knysh (Cloud Posse) any ideas
is the workspaces are port of the terraform state right?
i’ve tried to clean all tf files and deleted this workspace, but still got back named as dev
so maybe the default workspace holds some information?
Yes, in atmos we use one workspace for each instance of a component deployed.
Have you updated to the latest atmos? We just fixed a problem related to workspaces and changing backends
yes, i’m using the very latest
Workspace "dev" doesn't exist.
You can create this workspace with the "new" subcommand
or include the "-or-create" flag with the "select" subcommand.
Created and switched to workspace "dev"!
but i bet it’s atmos what is switching to the workspace so the name dev
comes from atmos not from the state
Yes, atmos dynamically computes the workspace name and switches to it
i see.
vars:
stage: dev
import:
- deploy/_defaults
- catalog/do/project
- catalog/do/doks
- catalog/nats
components:
terraform:
project:
vars:
name: "platform-{{ .stack }}"
environment: Development
cluster:
vars:
name: doks-cluster-1
project: '{{ (atmos.Component "project" .stack).outputs.id }}'
nats:
vars:
kube_host: '{{ (atmos.Component "cluster" .stack).outputs.kube_host }}'
kube_token: '{{ (atmos.Component "cluster" .stack).outputs.kube_token }}'
kube_cert: '{{ (atmos.Component "cluster" .stack).outputs.kube_cert }}'
this is my dev stack file
and interestingly for the project and the cluster the names are generated correctly
❯ tofu -chdir=components/terraform/nats workspace list
default
* dev
dev-cluster
dev-project
i have a component named nats
and stack named dev
and instead of dev-nats
the workspace is simply dev
this is the correct behavior for Atmos components that don’t inherit from other components
in this case, the TF workspace is simply the stack name
only if you have a derived component (inherited from a base component), then TF workspace will be <stack>+<component>
hmm. what you mean by “inherit” the do cluster and project name is correct and didn’t inherit from anything. or i miss something here.
components:
terraform:
nats:
metadata:
component: nats
vars:
...
vs
components:
terraform:
cluster:
metadata:
component: do/doks
regarding inheritance, please see https://atmos.tools/core-concepts/stacks/inheritance/
Inheritance provides a template-free way to customize Stack configurations. When combined with imports, it provides the ability to combine multiple configurations through ordered deep-merging of configurations. Inheritance is how you manage configuration variations, without resorting to templating.
ok i read that before. but i didn’t us that in any catalog so far.
in the two examples above, both nats
and cluster
Atmos components do not inherit from any other Atmos components, so the TF workspaces for both of them will be dev
so what you have is 100% correct, the workspaces for these two components are just dev
- the stack name
❯ tofu -chdir=components/terraform/do/doks workspace list
default
dev
* dev-cluster
dev-project
maybe those were generated wrongly because i made a lot changes back and forth since.
yes, looks like it
anyhow i’ fine with a single dev workspace named after the stack. as long as the states are correctly separated.
i’m not fully familiar with tf workspaces, but that means if all these components are in the same workspace they are sharing the state or not ?
each component has workspace_key_prefix
- it’s usually generated by Atmos, but you can override it per component
workspace_key_prefix
is, if you look at the backend s3 bucket, the top-level folder
so each component will have it’s own top-level folder in the bucket, and each stack, in a separate TF worksapce, will have its own subfolder in the folder
so yes, each component state is separated from any other component state (diff folders in the state bucket)
note that it’s still in the same backend (same S3 bucket). If you want to separate backends (e.g. per tenant/OU, per account, etc.), you need to create and configure multiple backends
sure. but i don’t see workspace_key_prefix
generated anywhere.
{
"terraform": {
"backend": {
"gcs": {
"bucket": "mw-tf-state",
"encryption_key": "...",
"prefix": "platform/infra"
}
}
}
}
it’s gcs, not s3 actually.
_defaults.yaml
:
terraform:
backend_type: gcs
backend:
gcs:
bucket: mw-tf-state
prefix: platform/infra
encryption_key: '{{ env "GCS_ENCRYPTION_KEY" }}'
GCP has prefix
which is the same
Configure Terraform Backends.
If the prefix is not specified for a component, Atmos will use the component name (my-component in the example above) to auto-generate the prefix. In the component name, all occurrences of / (slash) will be replaced with - (dash).
you don’t need to hardcode it here
backend:
gcs:
bucket: mw-tf-state
prefix: platform/infra
in this case, all components will use the same prefix
hmm ok, let me check that
please review the doc, if you don’t specify prefix
, Atmos will auto-generate it
thank you!
so if i understand it correctly, without setting the prefix atmos will generate it and because of that my component states will end up in separate folders in the gcs bucket, so even they share a workspace states are separated.
good to know that.:)
only problem is that i prefer to store them in some folder instead of the root of the bucket but i can leave with that
note that you can specify the prefix per component, in which case Atmos will just use it
i can review your config, let me know
it’s fine. this bucket is solely for tf states so it’s ok even in the root. i prefer to leave it to atmos to generate.
on a different topic while we chat.. any chance to add support for command like this in atmos.yaml
:
components:
terraform:
command: xy command -- tofu
so support command with double dash
it would be perfect that way i could load secrets as env vars. and i won’t need custom commands.
i don’t remember if command: xy command -- tofu
is supported now (need to look at the code). Did you test it?
yes. i just tested unfortunately it’s not working.
atmos terraform plan cluster --stack dev
template: all-atmos-sections:100:35: executing "all-atmos-sections" at <atmos.Component>: error calling Component: exec: "op run --no-masking --env-file=.env -- tofu": executable file not found in $PATH
I have done that with asdf and it works
ok, we’ll create a task for this, thank you
did you try to quote it?
thanks a lot!!
@Erik Osterman (Cloud Posse) do you have an example maybe with asdf?
i’ve just tried with quote but not working.
trying with a small shell script:
command: ./optofu.sh
but still not working
i’ve created a PR: https://github.com/cloudposse/atmos/pull/762
what
Add support for shell commands.
why
To support complex commands, for example:
components: terraform: command: op run –no-masking –env-file=.env – tofu
thanks, i’ll review it today. Did you test it?
roughly. is there any go test(s) i can run?
strange but for some reason it’s not working with my atmos config. it’s working fine with atmos.yaml in the repository. i will dig into it.
problem is that when the template executed it uses tfexec
ah, yes, tfexec doesn’t understand those commands, it needs terraform
2024-11-04
possible to organize a few smaller components into one catalog?
Of course… this is what we frequently do
you can create a catalog stack file for a solution.
E.g. here’s how we do “EKS” and all related components
ok. is there any related example in the repo?
Here you can see we created a default cluster config, that imports a bunch of other componetns
Those could be inline, but we chose to import them
thanks!
2024-11-05
whats the best way to share vars between some components but not all of them?
if i place in the stack yaml vars section, i got warnings from the components which are not using them.
Warning: Value for undeclared variable
yes, please don’t use globals
there are a few ways to share vars b/w components
e.g. create a base abstract component (with the default values) and inherit it in the other components
see this doc for ref https://atmos.tools/design-patterns/abstract-component
Abstract Component Atmos Design Pattern
And multiple inheritance
Inheritance provides a template-free way to customize Stack configurations. When combined with imports, it provides the ability to combine multiple configurations through ordered deep-merging of configurations. Inheritance is how you manage configuration variations, without resorting to templating.
thx!