#atmos (2025-01)
2025-01-02
Is there any documentation for writing Atmos integrations or is this not a recommended practice? https://atmos.tools/terms/integration/
An Integration is a mechanism of working with other tools and APIs.
I think we would like to have more, haven’t standardized the interface
An Integration is a mechanism of working with other tools and APIs.
Could you elaborate on what you might want to integrate?
I’m considering integrating different tooling that would benefit from Atmos’ YAML deep merging. Right now, I’d like to add a new component type to atmos.yaml
. For example:
components:
ansible:
base_path: "components/ansible"
I’d like to use the atmos describe stacks
and components functionality to create my own version of tfvars.json
using a custom wrapper script that is harnessed by a custom Atmos command. I ran into a schema failure because it couldn’t validate the structure, so I added new Ansible component definitions to stacks/schemas/atmos/atmos-manifest/1.0/atmos-manifest.json
, created a catalog default for the component, and everything validates but it can’t find the Ansible components. So I’m just looking into if there are any better ways to handle this edge case
Ah yes, I have been thinking about this some and how we could add support for custom component types. That’s interesting if atmos is not loading those other custom components. I don’t think we have tested that, and also the implication on schemas. I think to support multiple custom types, we would want to extend support for multiple json schemas that get deep merged
I think we would want to register custom types in atmos.yaml, and provide some common conventions like base_path, command, and so forth. This is also where we could define the schema validation to use for the component type.
Is there some best practices users have figured out or recommended by the authors regarding using the atmos.Component
template function across different (AWS) accounts? It seems a bit tricky with role assumption. For example if a user or a automation runner assumes role A in account A but has an atmos.Component
template function that references to state in stack B then if it seems that the B stack’s state bucket would need to allow cross account access from A role? Is there another way? It seems like you could end up with a lot of access config following this strategy.
It doesn’t work well, unless you have a role that can access all backends
So we are implementing a better long term solution
what
• Add the concepts of hooks that can run before/after other atmos commands • Add a hook type that can write output values to stores (AWS SSM Param Store, Artifactory)
why
In order to share data between components and to decouple the Terraform permissions context from the shared values permissions context.
Using this, you can store outputs outside of the terraform state, and read from the store
This simplifies the permissions model
ETA for this is end of next week
@Erik Osterman (Cloud Posse) neat, thanks for the info!
2025-01-03
:rocket: Enhancements
Support default values for arguments in Atmos custom commands @Listener430 (#905)
what
• Support default values for arguments in Atmos custom commands in atmos.yaml
why
• Allow specifying default values and don’t not require the users to provide the values when invoking the custom commands
before
a custom cli-command is defined
after
Implement Custom Markdown Styling for Workflow Commands @Cerebrovinny (#853)
Implement Custom Markdown Styling for Workflow Commands
What
• Added custom markdown styling support for workflow command outputs
• Implemented a configurable markdown styling system through atmos.yaml
• Added fallback to built-in default styles when no custom styles are defined
• Added new workflow error templates in markdown format
• Improved code readability and maintainability in markdown rendering logic
Why
• Enhances user experience • Allows users to define their own color schemes and styling preferences • Improves error message readability with consistent formatting and styling • Makes the CLI more accessible by supporting both default and custom color schemes • Follows modern CLI design patterns with rich text formatting
Technical Details
• Added markdown
settings section in atmos.yaml
for custom styling configuration
• Implemented style inheritance system (custom styles override built-in defaults)
• Added support for styling:
• Document text and background colors
• Headings (H1-H6) with custom colors and formatting
• Code blocks with syntax highlighting
• Links with custom colors and underlining
• Blockquotes and emphasis styles
• Enhanced error handling with structured markdown templates
• Added proper fallback mechanisms for style configuration
References
• Implements styling using glamour for terminal markdown rendering • Follows ANSI terminal styling standards • https://github.com/charmbracelet/bubbletea • https://github.com/charmbracelet • https://github.com/charmbracelet/glow • https://github.com/charmbracelet/glamour/blob/master/styles/gallery/README.md
Testing
The implementation has been tested with:
• Custom styling configurations in atmos.yaml
Screenshot 2024-12-29 at 23 34 33
• Default styling fallback when no custom styles are defined
Screenshot 2024-12-30 at 23 37 04
2025-01-05
Hello! I am new to atmos and I am trying to implement it for our new infrastructure (I hope I am asking at the good place, sorry if it is not the case). I am currently blocked on trying to get working atmos with the http backend (interface with gitlab). Unfortunately the http backend doesn’t support workspace (terraform doc) and therefore atmos is crashing when trying to select the workspace. In your documentation (link) the http backend is supported. Is there a way to get it working? Maybe I can use environment variables to force a workspace like here? Am I on the good path or am I missing something? Thanks in advance for your help!
Workspaces allow the use of multiple states with a single configuration directory.
Configure Terraform Backends.
Describe the Bug
In our deployment pipeline, we create the TF workspace via HTTP API as need to configuration not possible from [backend.tf](http://backend.tf)
, e.g. working-directory
, global-remote-state
, etc.
Once the workspace is created/checked, it sets the TF_WORKSPACE
variable.
In setting Atmos for the first time, found what I think is incorrect behaviour.
Terraform has been successfully initialized!
Command info:
Terraform binary: terraform
Terraform command: plan
Arguments and flags: []
Component: ecr/redacted-app
Terraform component: ecr
Stack: redacted-dev
Working dir: components/terraform/ecr
Executing command:
/usr/bin/terraform workspace select long_complex_workspace_name_redacted
The selected workspace is currently overridden using the TF_WORKSPACE
environment variable.
To select a new workspace, either update this environment variable or unset
it and then run this command again.
Executing command:
/usr/bin/terraform workspace new long_complex_workspace_name_redacted
Workspace "new long_complex_workspace_name_redacted" already exists
exit status 1
Expected Behavior
If the workspace is overridden by TF_WORKSPACE
, then atmos
should accept that it is managed elsewhere and don’t try create it again.
Steps to Reproduce
Run atmos
with TF_WORKSPACE
environment variable set.
Screenshots
No response
Environment
• OS: Windows 11 • Atmos: 1.83.1 • Terraform: 1.8.2
Additional Context
I think we could change the error handling in ~L394
atmos/internal/exec/terraform.go
Lines 382 to 409 in8060adb
err = ExecuteShellCommand( | |
---|---|
cliConfig, | |
info.Command, | |
[]string{“workspace”, “select”, info.TerraformWorkspace}, | |
componentPath, | |
info.ComponentEnvList, | |
info.DryRun, | |
workspaceSelectRedirectStdErr, | |
) | |
if err != nil { | |
var osErr *osexec.ExitError | |
ok := errors.As(err, &osErr) | |
if !ok | | osErr.ExitCode() != 1 { |
// err is not a non-zero exit code or err is not exit code 1, which we are expecting | |
return err | |
} | |
err = ExecuteShellCommand( | |
cliConfig, | |
info.Command, | |
[]string{“workspace”, “new”, info.TerraformWorkspace}, | |
componentPath, | |
info.ComponentEnvList, | |
info.DryRun, | |
info.RedirectStdErr, | |
) | |
if err != nil { | |
return err | |
} |
So this came up recently in separate thread for a different purpose
Workspaces allow the use of multiple states with a single configuration directory.
Configure Terraform Backends.
Describe the Bug
In our deployment pipeline, we create the TF workspace via HTTP API as need to configuration not possible from [backend.tf](http://backend.tf)
, e.g. working-directory
, global-remote-state
, etc.
Once the workspace is created/checked, it sets the TF_WORKSPACE
variable.
In setting Atmos for the first time, found what I think is incorrect behaviour.
Terraform has been successfully initialized!
Command info:
Terraform binary: terraform
Terraform command: plan
Arguments and flags: []
Component: ecr/redacted-app
Terraform component: ecr
Stack: redacted-dev
Working dir: components/terraform/ecr
Executing command:
/usr/bin/terraform workspace select long_complex_workspace_name_redacted
The selected workspace is currently overridden using the TF_WORKSPACE
environment variable.
To select a new workspace, either update this environment variable or unset
it and then run this command again.
Executing command:
/usr/bin/terraform workspace new long_complex_workspace_name_redacted
Workspace "new long_complex_workspace_name_redacted" already exists
exit status 1
Expected Behavior
If the workspace is overridden by TF_WORKSPACE
, then atmos
should accept that it is managed elsewhere and don’t try create it again.
Steps to Reproduce
Run atmos
with TF_WORKSPACE
environment variable set.
Screenshots
No response
Environment
• OS: Windows 11 • Atmos: 1.83.1 • Terraform: 1.8.2
Additional Context
I think we could change the error handling in ~L394
atmos/internal/exec/terraform.go
Lines 382 to 409 in8060adb
err = ExecuteShellCommand( | |
---|---|
cliConfig, | |
info.Command, | |
[]string{“workspace”, “select”, info.TerraformWorkspace}, | |
componentPath, | |
info.ComponentEnvList, | |
info.DryRun, | |
workspaceSelectRedirectStdErr, | |
) | |
if err != nil { | |
var osErr *osexec.ExitError | |
ok := errors.As(err, &osErr) | |
if !ok | | osErr.ExitCode() != 1 { |
// err is not a non-zero exit code or err is not exit code 1, which we are expecting | |
return err | |
} | |
err = ExecuteShellCommand( | |
cliConfig, | |
info.Command, | |
[]string{“workspace”, “new”, info.TerraformWorkspace}, | |
componentPath, | |
info.ComponentEnvList, | |
info.DryRun, | |
info.RedirectStdErr, | |
) | |
if err != nil { | |
return err | |
} |
Opentofu is considering deprecating workspaces
https://github.com/opentofu/opentofu/issues/2160
Is it possible to use atmos without workspaces and instead use unique keys per stack instead of unique workspaces per stack ?
We need to add a feature flag to toggle usage of workspaces. Relatively easy fix for us to make.
It would be great!
Should I open an issue on github to track the issue?
Sure, let’s do that, so we can notify you when it’s done
I think we can get to it in the next 2 weeks or so.
Sounds good to me, I will create the issue tomorrow then
Enhancements
Support for a circuit breaker to avoid recursive calls to Atmos custom commands (infinite loop) @Listener430 (#906)
what
• Support for a circuit breaker to avoid recursive calls to Atmos custom commands
why
• Avoid infinite loops
test
Add-on to atmos.yaml
The circuit breaker in use