Releases: cloudposse/atmos
v1.189.0-rc.0
- No changes
v1.188.0
Update `atmos describe affected` and `atmos describe dependents` commands @aknysh (#1414)
what
- Update
atmos describe affected
andatmos describe dependents
commands - Update docs
- Add tests
why
-
atmos describe affected --include dependents
should respect the flags--process-templates
and--process-functions
in the dependent components-
atmos describe affected --include dependents
will process templates and YAML functions in the affected components and in the dependents -
atmos describe affected --include dependents --process-templates=false --process-functions=false
will not process templates and YAML functions in the affected components and in the dependents for each affected component
-
-
Add
--exclude-locked
flag toatmos describe affected
atmos describe affected --exclude-locked
will not process the locked components (metadata.locked: true
) and will not show them in the results. Refer to https://atmos.tools/core-concepts/stacks/define-components/#locking-components-with-metadatalocked for more details
-
Add
--process-templates
and--process-functions
flags toatmos describe dependents
to explicitly disable templates and YAML functions processing (similar toatmos describe affected
)atmos describe dependents
will process templates and YAML functions in all componentsatmos describe dependents --process-templates=false --process-functions=false
will not process templates and YAML functions in all components
Fix Workflow Error Message @milldr (#1404)
what
- Fix workflow path for workflow error message
why
- If the workflow is in a subdirectory, we need to return the path to the workflow, starting from the workflow base dir
Insert workflow-level stack flag before `--` in workflow args @j4zzcat (#1411)
What
- Updates the workflow utils so that when a workflow-level
stack
is provided, the generated-s <stack>
flag is placed before any--
argument in the command args (instead of always at the end).
The --
marker indicates the end of Atmos CLI arguments; anything after it is passed directly to the underlying tool or script. Appending -s <stack>
after --
caused the stack flag to be ignored in such cases.
Why
Before
atmos workflow deploy -- foo bar
# produces args: ["deploy", "--", "foo", "bar", "-s", "my-stack"]
# "-s my-stack" is ignored since it's after `--`
After
atmos workflow deploy -- foo bar
# produces args: ["deploy", "-s", "my-stack", "--", "foo", "bar"]
# stack flag is correctly passed to Atmos
v1.188.0-test.2
🚀 Feature Preview Release
This is a feature preview based on an open pull request. It is intended for testing artifacts and validating functionality before the feature is merged.
Warning
This release is temporary and may be removed at any time without notice.
v1.188.0-test.1
🚀 Feature Preview Release
This is a feature preview based on an open pull request. It is intended for testing artifacts and validating functionality before the feature is merged.
Warning
This release is temporary and may be removed at any time without notice.
v1.188.0-test.0
🚀 Feature Preview Release
This is a feature preview based on an open pull request. It is intended for testing artifacts and validating functionality before the feature is merged.
Warning
This release is temporary and may be removed at any time without notice.
v1.188.0-rc.0
- No changes
v1.187.0
Update `atmos terraform generate planfile` and `atmos terraform plan-diff` commands. Update `depends_on` for component dependencies @aknysh (#1405)
what
-
Update
atmos terraform generate planfile
andatmos terraform plan-diff
commands. Process templates and Atmos YAML functions before executing the commands. -
Update
depends_on
for component dependencies. Addstack
attribute as one of the context variables independs_on
-
Update docs
-
Add tests
why
-
The
atmos terraform generate planfile
andatmos terraform plan-diff
commands did not process templates and Atmos YAML functions, but they should -
Add
stack
attribute as one of the context variables independs_on
to allow specifying an Atmos stack where the dependent component is provisioned
description
Atmos supports configuring the relationships between components in the same or different stacks. You can define dependencies between components to ensure that components are deployed in the correct order.
You can define component dependencies by using the settings.depends_on
section. The section used to define all the Atmos components (in the same or different stacks) that the current component depends on.
The settings.depends_on
section is a map of objects. The map keys are just the descriptions of dependencies and can be strings or numbers. Provide meaningful descriptions or numbering so that people can understand what the dependencies are about.
If component
is specified, you can provide the other context variables to define an Atmos stack other than the current stack.
For example, you can specify:
stack
if thecomponent
is from a different Atmos stacknamespace
if thecomponent
is from a different Organizationtenant
if thecomponent
is from a different Organizational Unitenvironment
if thecomponent
is from a different regionstage
if thecomponent
is from a different accounttenant
,environment
andstage
if the component is from a different Atmos stack (e.g.tenant1-ue2-dev
)
NOTE:
If stack
is specified, it's processed first and the namespace
, tenant
, environment
and stage
attributes are ignored.
NOTE:
You can use Atmos Stack Manifest Templating in depends_on
.
Atmos processes the templates first, and then detects all the dependencies, allowing you to provide the parameters to
depends_on
dynamically.
In the following example, we specify that the component1
component depends on the following:
- The
component2
component in the same Atmos stack ascomponent1
- The
component3
component from theprod
stage - The
component4
component from thetenant1
tenant,ue2
environment andstaging
stage (tenant1-ue2-staging
Atmos stack) - The
component5
component from thetenant1-ue2-prod
Atmos stack - The
component6
component from the same Atmos stack ascomponent1
- The
component7
component from the same tenant and stage ascomponent1
, butuw2
environment
vars:
tenant: "tenant1"
environment: "ue1"
stage: "dev"
components:
terraform:
component1:
settings:
depends_on:
1:
# If the context (`stack`, `namespace`, `tenant`, `environment`, `stage`) is not
# provided, the `component` is from the same Atmos stack as `component1`
component: "component2"
2:
# `component1` (in any stage) depends on `component3`
# from the `prod` stage (in any `environment` and any `tenant`)
component: "component3"
stage: "prod"
3:
# `component1` depends on `component4`
# from the the `tenant1` tenant, `ue2` environment and `staging` stage
# (`tenant1-ue2-staging` Atmos stack)
component: "component4"
tenant: "tenant1"
environment: "ue2"
stage: "staging"
4:
# `component1` depends on `component5`
# from the `tenant1-ue2-prod` Atmos stack
component: "component5"
stack: "tenant1-ue2-prod"
5:
# `component1` depends on `component6`
# from the same Atmos stack
component: "component6"
stack: "{{ .vars.tenant }}-{{ .vars.environment }}-{{ .vars.stage }}"
6:
# `component1` depends on `component7`
# from the same tenant and stage as `component1`, but `uw2` environment
component: "component7"
stack: "{{ .vars.tenant }}-uw2-{{ .vars.stage }}"
vars:
enabled: true
Specifying stack
The stack
attribute has higher precedence than the other context variables.
If stack
is specified, the namespace
, tenant
, environment
and stage
attributes are ignored.
As you can see in the examples above, we can use Atmos Stack Manifest Templating in the stack
attribute to dynamically specify the stack.
This is useful when configuring
stacks.name_template
in atmos.yaml
to define and refer to stacks. In this case, you can't use the context variables namespace
, tenant
, environment
and stage
in depends_on
.
For example, in atmos.yaml
, we specify stacks.name_template
to define Atmos stacks, and enable templating:
stacks:
base_path: "stacks"
name_template: "{{ .settings.context.tenant }}-{{ .settings.context.environment }}-{{ .settings.context.stage }}"
# `Go` templates in Atmos manifests
templates:
settings:
enabled: true
NOTE:
In this example, stacks are defined by the settings.context
section, not vars
.
In the tenant1-uw2-dev
Atmos stack, we can use the following depends_on
configuration to define the component dependencies:
settings:
context:
tenant: "tenant1"
environment: "uw2"
stage: "dev"
components:
terraform:
vpc:
vars:
enabled: true
tgw/attachment:
settings:
depends_on:
1:
# `tgw/attachment` depends on the `vpc` component
# from the same Atmos stack (same tenant, account and region)
component: vpc
# NOTE: The same stack can be specified by using exactly the same template as in
# `stacks.name_template` in `atmos.yaml`, but it's not required and not recommended.
# If the dependent component is from the same stack, just omit the `stack` attribute completely.
# stack: "{{ .settings.context.tenant }}-{{ .settings.context.environment }}-{{ .settings.context.stage }}"
2:
# `tgw/attachment` depends on the `tgw/hub` components
# from the same tenant and account, but in `us-east-1` region (`ue1` environment)
component: tgw/hub
stack: "{{ .settings.context.tenant }}-ue1-{{ .settings.context.stage }}"
tgw/cross-region-hub-connector:
settings:
depends_on:
1:
# `tgw/cross-region-hub-connector` depends on `tgw/hub` components
# in the same tenant and account, but in `us-east-1` region (`ue1` environment)
component: tgw/hub
stack: "{{ .settings.context.tenant }}-ue1-{{ .settings.context.stage }}"
Execute the following Atmos commands to see the component dependencies:
> atmos describe dependents vpc -s tenant1-uw2-dev --pager off
[
{
"component": "tgw/attachment",
"component_type": "terraform",
"stack": "tenant1-uw2-dev",
"stack_slug": "tenant1-uw2-dev-tgw-attachment"
}
]
> atmos describe dependents tgw/hub -s tenant1-ue1-dev --pager off
[
{
"component": "tgw/attachment",
"component_type": "terraform",
"stack": "tenant1-uw2-dev",
"stack_slug": "tenant1-uw2-dev-tgw-attachment"
},
{
"component": "tgw/cross-region-hub-connector",
"component_type": "terraform",
"stack": "tenant1-uw2-dev",
"stack_slug": "tenant1-uw2-dev-tgw-cross-region-hub-connector"
}
]
Add `!store.get` YAML function for arbitrary key retrieval @jamengual (#1352)
what
- Add the
!store.get
YAML function, enabling retrieval of arbitrary keys from any supported store (Azure Key Vault, AWS SSM, Redis, Google Secret Manager, Artifactory)
why
- Unlike the existing
!store
function,!store.get
does not require keys to follow the Atmos stack/component/key naming pattern. Users can retrieve any key by specifying its exact name or path.
usage examples
# Retrieve a key from Redis by its exact name
my_config: !store.get redis global-config
# Retrieve a secret from Azure Key Vault by its name
my_secret: !store.get azure-keyvault my-arbitrary-secret
# Retrieve a parameter from AWS SSM by its full path
ssm_value: !store.get aws-ssm-parameter-store /custom/path/to/parameter
Notable Differences from !store
!store.get
does not construct keys using stack/component/key; it expects the full key or path.- Useful for retrieving values stored outside of Atmos or not following the standard naming convention.
v1.187.0-rc.0
- No changes
v1.186.0
Add native Packer support (Atmos loves Packer) @aknysh (#1394)
what
-
Add native HashiCorp Packer support to Atmos
-
Add Packer docs and
atmos packer
CLI commands docs -
Add tests
why
- Use the power of Atmos components, stacks, imports, inheritance, templating and YAML functions to configure and provision Packer components to build machine images for multiple cloud platforms from Packer templates
description
Atmos natively supports HashiCorp Packer and lets you create identical machine images for multiple platforms from a single source template using the power of Atmos components, stacks, imports, inheritance, templating and YAML functions. It's compatible with every version of Packer and designed to work with multiple different versions of it concurrently.
Configure Packer in atmos.yaml
base_path: "./"
components:
packer:
# Can also be set using 'ATMOS_COMPONENTS_PACKER_COMMAND' ENV var, or '--packer-command' command-line argument
command: packer
# Can also be set using 'ATMOS_COMPONENTS_PACKER_BASE_PATH' ENV var, or '--packer-dir' command-line argument
base_path: "components/packer"
stacks:
base_path: "stacks"
included_paths:
- "deploy/**/*"
excluded_paths:
- "**/_defaults.yaml"
name_template: "{{ .vars.stage }}"
Add Packer template (Packer component)
packer {
required_plugins {
# https://developer.hashicorp.com/packer/integrations/hashicorp/amazon
amazon = {
source = "github.com/hashicorp/amazon"
version = "~> 1"
}
}
}
variable "region" {
type = string
description = "AWS Region"
}
variable "stage" {
type = string
default = null
}
variable "ami_org_arns" {
type = list(string)
description = "List of Amazon Resource Names (ARN) of AWS Organizations that have access to launch the resulting AMI(s). By default no organizations have permission to launch the AMI"
default = []
}
variable "ami_ou_arns" {
type = list(string)
description = "List of Amazon Resource Names (ARN) of AWS Organizations organizational units (OU) that have access to launch the resulting AMI(s). By default no organizational units have permission to launch the AMI."
default = []
}
variable "ami_users" {
type = list(string)
description = "List of account IDs that have access to launch the resulting AMI(s). By default no additional users other than the user creating the AMI has permissions to launch it."
default = []
}
# https://developer.hashicorp.com/packer/integrations/hashicorp/amazon#authentication
variable "assume_role_arn" {
type = string
description = "Amazon Resource Name (ARN) of the IAM Role to assume. Refer to https://developer.hashicorp.com/packer/integrations/hashicorp/amazon#authentication"
}
variable "provisioner_shell_commands" {
type = list(string)
description = "List of commands to execute on the machine that Packer builds"
default = []
}
source "amazon-ebs" "al2023" {
ami_name = var.ami_name
source_ami = var.source_ami
instance_type = var.instance_type
region = var.region
ssh_username = var.ssh_username
ami_org_arns = var.ami_org_arns
ami_ou_arns = var.ami_ou_arns
ami_users = var.ami_users
kms_key_id = var.kms_key_arn
encrypt_boot = var.encrypt_boot
force_deregister = var.force_deregister
force_delete_snapshot = var.force_delete_snapshot
associate_public_ip_address = var.associate_public_ip_address
ami_block_device_mappings {
device_name = "/dev/xvda"
volume_size = var.volume_size
volume_type = var.volume_type
delete_on_termination = true
}
assume_role {
role_arn = var.assume_role_arn
session_name = var.assume_role_session_name
duration_seconds = var.assume_role_duration_seconds
}
aws_polling {
delay_seconds = 5
max_attempts = 100
}
tags = var.ami_tags
}
build {
sources = ["source.amazon-ebs.al2023"]
provisioner "shell" {
inline = var.provisioner_shell_commands
}
# https://developer.hashicorp.com/packer/tutorials/docker-get-started/docker-get-started-post-processors
# https://developer.hashicorp.com/packer/docs/post-processors
# https://developer.hashicorp.com/packer/docs/post-processors/manifest
post-processor "manifest" {
output = var.manifest_file_name
strip_path = var.manifest_strip_path
}
}
Configure defaults for the Packer component in the catalog
components:
packer:
aws/bastion:
settings:
packer:
template: "main.pkr.hcl"
source_ami: "ami-0013ceeff668b979b"
source_ami_name: "al2023-ami-2023.7.20250527.1-kernel-6.12-arm64"
source_ami_description: "Amazon Linux 2023 AMI 2023.7.20250527.1 arm64 HVM kernel-6.12"
source_ami_owner_account_id: "137112412989"
region: "us-east-2"
org_id: "o-xxxxxxxxx"
org_management_account_id: "xxxxxxxxxxxx"
metadata:
component: aws/bastion
vars:
# https://masterminds.github.io/sprig/date.html
ami_name: "bastion-al2023-{{ now | unixEpoch }}"
source_ami: "{{ .settings.packer.source_ami }}"
region: "{{ .settings.packer.region }}"
ami_org_arns:
- "arn:aws:organizations::{{ .settings.packer.org_management_account_id }}:organization/{{ .settings.packer.org_id }}"
ami_ou_arns: []
ami_users: []
kms_key_arn: null
encrypt_boot: false
ssh_username: "ec2-user"
associate_public_ip_address: true
volume_type: "gp3"
skip_create_ami: false
manifest_file_name: "manifest.json"
manifest_strip_path: false
assume_role_session_name: "atmos-packer"
assume_role_duration_seconds: 1800
force_deregister: false
force_delete_snapshot: false
# SSM Agent is pre-installed on AL2023 AMIs but should be enabled explicitly as done above.
# `dnf clean all` removes cached metadata and packages to reduce AMI size.
# `cloud-init clean` ensures the image will boot as a new instance on the next launch.
provisioner_shell_commands:
# Enable and start the SSM agent (already installed by default on AL2023)
- "sudo systemctl enable --now amazon-ssm-agent"
# Install packages, clean metadata and cloud-init
- "sudo -E bash -c 'dnf install -y jq && dnf clean all && cloud-init clean'"
# Install other packages
ami_tags:
SourceAMI: "{{ .settings.packer.source_ami }}"
SourceAMIName: "{{ .settings.packer.source_ami_name }}"
SourceAMIDescription: "{{ .settings.packer.source_ami_description }}"
SourceAMIOwnerAccountId: "{{ .settings.packer.source_ami_owner_account_id }}"
ScanStatus: pending
Define Atmos nonprod
and prod
stacks
vars:
stage: nonprod
import:
- catalog/aws/bastion/defaults
components:
packer:
aws/bastion:
vars:
# Define the variables specific to the `nonprod` account
instance_type: "t4g.small"
volume_size: 8
assume_role_arn: "arn:aws:iam::NONPROD_ACCOUNT_ID:role/ROLE_NAME"
ami_tags:
Stage: nonprod
vars:
stage: prod
import:
- catalog/aws/bastion/defaults
components:
packer:
aws/bastion:
vars:
# Define the variables specific to the `prod` account
instance_type: "t4g.medium"
volume_size: 16
assume_role_arn: "arn:aws:iam::PROD_ACCOUNT_ID:role/ROLE_NAME"
ami_tags:
Stage: prod
Execute Atmos Packer commands
> atmos packer version
Packer v1.14.1
# https://developer.hashicorp.com/packer/docs/commands/validate
> atmos packer validate aws/bastion -s nonprod
The configuration is valid.
# https://developer.hashicorp.com/packer/docs/commands/inspect
> atmos packer inspect aws/bastion -s nonprod
Packer Inspect: HCL2 mode
> input-variables:
var.ami_name: "bastion-al2023-1754457104"
var.ami_org_arns: "[\n \"arn:aws:organizations::xxxxxxxxxxxx:organization/o-xxxxxxxxx\",\n]"
var.ami_ou_arns: "[]"
var.ami_tags: "{\n \"ScanStatus\" = \"pending\"\n \"SourceAMI\" = \"ami-0013ceeff668b979b\"\n \"SourceAMIDescription\" = \"Amazon Linux 2023 AMI 2023.7.20250527.1 arm64 HVM kernel-6.12\"\n \"SourceAMIName\" = \"al2023-ami-2023.7.20250527.1-kernel-6.12-arm64\"\n \"SourceAMIOwnerAccountId\" = \"137112412989\"\n \"Stage\" = \"nonprod\"\n}"
var.ami_users: "[]"
> local-variables:
> builds:
> <0>:
sources:
amazon-ebs.al2023
provisioners:
shell
post-processors:
0:
manifest
# https://developer.hashicorp.com/packer/docs/commands/init
> atmos packer init aws/bastion -s nonprod
Installed plugin github.com/hashicorp/amazon v1.3.9 in "~/.config/packer/plugins/github.com/hashicorp/amazon/packer-plugin-amazon_v1.3.9_x5.0_darwin_arm64"
# https://developer.hashicorp.com/packer/docs/commands/build
> atmos packer build aws/bastion -s nonprod
amazon-ebs.al2023:
==> amazon-ebs.al2023: Prevalidating any provided VPC information
==> amazon-ebs.al2023: Prevalidating AMI Name: bastion-al2023-1754025080
==> amazon-ebs.al2023: Found Image ID: ami-0013ceeff668b979b
==> amazon-ebs.al2023: Setting public IP add...
v1.185.1-test.3
🚀 Feature Preview Release
This is a feature preview based on an open pull request. It is intended for testing artifacts and validating functionality before the feature is merged.
Warning
This release is temporary and may be removed at any time without notice.