Skip to content

Releases: cloudposse/atmos

v1.41.0

14 Jul 17:15
a559e52
Compare
Choose a tag to compare

what

  • Add exampes and tests for validation of components with multiple hierarchical inheritance

why

  • Show that the settings.validation section is inherited all the way down the inheritance chain, even when using multiple abstract bae components, and atmos validate component command executes the validation policies placed at any level of the inheritance hierarchy

    • base-component-1 is an abstract component, and it has the settings.validation section defined using an OPA policy
    • base-component-3 is an abstract component that inherits from the base-component-1 abstract component
    • base-component-4 is an abstract component that inherits from the base-component-3 abstract component (and, by Multilevel Inheritance, from the base-component-1 component
    • derived-component-3 is a real component that inherits from the base-component-4 component (and from base-component-3 and base-component-1 components)
components:
  terraform:
    base-component-1:
      metadata:
        type: abstract
        component: "test/test-component"
      settings:
        validation:
          check-test-component-config-with-opa-policy:
            schema_type: opa
            # 'schema_path' can be an absolute path or a path relative to 'schemas.opa.base_path' defined in `atmos.yaml`
            schema_path: "test-component/validate-test-component.rego"
            description: Check 'test/test-component' configuration using OPA policy
      vars:
        service_1_name: "base-component-1-service-1"
        service_2_name: "base-component-1-service-2"

    base-component-3:
      metadata:
        type: abstract
        component: "test/test-component"
        inherits:
          - base-component-1
      vars:
        service_1_name: "base-component-3-service-1"
        service_2_name: "base-component-3-service-2"

    base-component-4:
      metadata:
        type: abstract
        component: "test/test-component"
        inherits:
          - base-component-3
      vars:
        service_1_name: "base-component-4-service-1"
        service_2_name: "base-component-4-service-2"

    derived-component-3:
      metadata:
        component: "test/test-component"
        inherits:
          - base-component-4
      vars:
        enabled: true
        service_1_name: "bad-name"

When running the command atmos validate component derived-component-3 -s tenant1-ue2-test-1, Atmos finds the validation section from the inheritance chain (in base-component-1) and outputs the following error:

Validating the component 'derived-component-3' using 'opa' file 'test-component/validate-test-component.rego'

'service_1_name' variable length must be greater than 10 chars

The settings.validation section can be defined at any level of the inheritance chain (can be placed on base-component-1, base-component-3, base-component-4 or derived-component-3, and the command atmos validate component derived-component-3 -s tenant1-ue2-test-1 finds it and outputs the same error.

The inheritance chain shown above works and produces the following final variables:

atmos describe component derived-component-3 -s tenant1-ue2-test-1
vars:
  enabled: true
  environment: ue2
  namespace: cp
  region: us-east-2
  service_1_name: bad-name
  service_2_name: base-component-4-service-2
  stage: test-1
  tenant: tenant1

references

  • To test the issue described in #404

v1.40.0

06 Jul 22:31
674acf7
Compare
Choose a tag to compare

what

  • Documentation pages for GitHub Actions for Terraform Plan and Apply

why

  • Documented the two new GitHub actions for Terraform Plan and Apply

v1.39.0

05 Jul 17:04
758c645
Compare
Choose a tag to compare

what

  • Make Atmos understand Terraform configurations and dependencies
  • Update atmos describe component command
  • Update atmos describe affected command
  • Add Atmos custom commands to atmos.yaml
  • Update docs for atmos describe component and atmos describe affected commands

why

  • Atmos now understands Terraform configurations and dependencies! (using a Terraform parser from HashiCorp) This is useful to detect component dependencies when a Terraform component in the components/terraform folder uses local Terraform modules defined in the local filesystem (not from the Terraform registry), and this functionality is used by the atmos describe component and atmos describe affected comamnds described below

  • Update atmos describe component command. The command's output now has these additional sections:

    • atmos_cli_config - information about Atmos CLI configuration from atmos.yaml (useful in Atmos custom commands)

    • component_info - a block describing the Terraform or Helmfile components that the Atmos component manages. The component_info block has the following sections:

      • component_path - the filesystem path to the Terraform or Helmfile component

      • component_type - the type of the component (terraform or helmfile)

      • terraform_config - if the component type is terraform, this sections describes the high-level metadata about the Terraform component from its source code, including variables, outputs and child Terraform modules (using a Terraform parser from HashiCorp). The file names and line numbers where the variables, outputs and child modules are defined are also included. Invalid Terraform configurations are also detected, and in case of any issues, the warnings and errors are shows in the terraform_config.diagnostics section

     atmos describe component test/test-component-override-3 -s tenant1-ue2-dev
    atmos_cli_config:
      base_path: ./examples/complete
      components:
        terraform:
          base_path: components/terraform
          init_run_reconfigure: true
          auto_generate_backend_file: false
        helmfile:
          base_path: components/helmfile
          helm_aws_profile_pattern: '{namespace}-{tenant}-gbl-{stage}-helm'
          cluster_name_pattern: '{namespace}-{tenant}-{environment}-{stage}-eks-cluster'
      stacks:
        base_path: stacks
        included_paths:
          - orgs/**/*
        excluded_paths:
          - '**/_defaults.yaml'
        name_pattern: '{tenant}-{environment}-{stage}'
      workflows:
        base_path: stacks/workflows
    atmos_component: test/test-component-override-3
    atmos_stack: tenant1-ue2-dev
    atmos_stack_file: orgs/cp/tenant1/dev/us-east-2
    component: test/test-component
    component_info:
      component_path: examples/complete/components/terraform/test/test-component
      component_type: terraform
      terraform_config:
        path: examples/complete/components/terraform/test/test-component
        variables:
          enabled:
            name: enabled
            type: bool
            description: Set to false to prevent the module from creating any resources
            default: null
            required: false
            sensitive: false
            pos:
              filename: examples/complete/components/terraform/test/test-component/context.tf
              line: 97
          environment:
            name: environment
            type: string
            description: ID element. Usually used for region e.g. 'uw2', 'us-west-2',
              OR role 'prod', 'staging', 'dev', 'UAT'
            default: null
            required: false
            sensitive: false
            pos:
              filename: examples/complete/components/terraform/test/test-component/context.tf
              line: 115
          name:
            name: name
            type: string
            description: |
              ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
              This is the only ID element not also included as a `tag`.
              The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input.
            default: null
            required: false
            sensitive: false
            pos:
              filename: examples/complete/components/terraform/test/test-component/context.tf
              line: 127
          region:
            name: region
            type: string
            description: Region
            default: null
            required: true
            sensitive: false
            pos:
              filename: examples/complete/components/terraform/test/test-component/variables.tf
              line: 1
        outputs:
          service_1_id:
            name: service_1_id
            description: Service 1 ID
            sensitive: false
            pos:
              filename: examples/complete/components/terraform/test/test-component/outputs.tf
              line: 1
          service_2_id:
            name: service_2_id
            description: Service 2 ID
            sensitive: false
            pos:
              filename: examples/complete/components/terraform/test/test-component/outputs.tf
              line: 6
        requiredcore:
          - '>= 1.0.0'
        modulecalls:
          service_1_label:
            name: service_1_label
            source: cloudposse/label/null
            version: 0.25.0
            pos:
              filename: examples/complete/components/terraform/test/test-component/main.tf
              line: 1
          service_2_label:
            name: service_2_label
            source: cloudposse/label/null
            version: 0.25.0
            pos:
              filename: examples/complete/components/terraform/test/test-component/main.tf
              line: 10
        diagnostics: []

  • Update atmos describe affected command

    The affected attribute in the command's output now can have the additional value component.module, which specify that the Terraform component is affected because it uses a local Terraform module (not from the Terraform registry, but from the local filesystem), and that local module has been changed.

    For example, let's suppose that we have a catalog of reusable Terraform modules in the modules folder (outside the components folder), and we have defined the following label Terraform module in modules/label:

  module "label" {
    source  = "cloudposse/label/null"
    version = "0.25.0"
    context = module.this.context
  }

  output "label" {
    value       = module.label
    description = "Label outputs"
  }

We then use the Terraform module in the components/terraform/top-level-component1 component:

  module "service_2_label" {
    source  = "../../../modules/label"
    context = module.this.context
  }

  output "service_2_id" {
    value       = module.service_2_label.label.id
    description = "Service 2 ID"
  }

The label module is not in the stack config of the top-level-component1 component (not in the YAML stack config files), but Atmos understands Terraform configurations and dependencies (using a Terraform parser from HashiCorp), and can automatically detect any changes to the module.

For example, if you make changes to any files in the folder modules/label, Atmos will detect the module changes, and since the module is a Terraform dependency of the top-level-component1 component, Atmos will mark the component as affected with the affected attribute set to component.module:

  [
    {
      "component": "top-level-component1",
      "component_type": "terraform",
      "component_path": "examples/complete/components/terraform/top-level-component1",
      "stack": "tenant1-ue2-staging",
      "stack_slug": "tenant1-ue2-staging-top-level-component1",
      "spacelift_stack": "tenant1-ue2-staging-top-level-component1",
      "atlantis_project": "tenant1-ue2-staging-top-level-component1",
      "affected": "component.module"
    },
    {
      "component": "top-level-component1",
      "component_type": "terraform",
      "component_path": "examples/complete/components/terraform/top-level-component1",
      "stack": "tenant2-ue2-staging",
      "stack_slug": "tenant2-ue2-staging-top-level-component1",
      "spacelift_stack": "tenant2-ue2-staging-top-level-component1",
      "atlantis_project": "tenant2-ue2-staging-top-level-component1",
      "affected": "component.module"
    }
  ]

  • Add Atmos custom commands to atmos.yaml

    • The custom Atmos commands are examples of how to dynamically extend the Atmos CLI functionality by defining new commands in atmos.yaml without changing the Atmos binary itself

    • The command atmos list stacks is used to list all stacks in the infrastructure

    • The command atmos list components is used to all Atmos components in all stacks or in a single stack

    • The command atmos set-eks-cluster is used to download kubeconfig from an EKS cluster and set EKS cluster

    • The function set-eks-cluster is used to call the atmos set-eks-cluster command and export the KUBECONFIG ENV var into the calling (parent) process (the function itself is sourced from profile.d on a shell startup)

    • The command atmos set-eks-cluster also serves as an example on how to create Atmos custom commands that are context aware, meaning the commands "know" everything about Atmos components and stacks they operate on. This is done by using the component_config section in the custom command configuration:

      # List all stacks in the infrastructure
      atmos list stacks

...

Read more

v1.38.0

22 Jun 20:09
1a5e322
Compare
Choose a tag to compare

what

  • Refactor Atmos components validation with OPA
  • Allow creating a catalog of reusable Rego modules, constants and helper functions to be used in OPA policies
  • Update docs

why

Atmos supports OPA policies for component validation in a single Rego file and in multiple Rego files.

As shown in the example below, you can define some Rego constants, modules and helper functions in a separate
file stacks/schemas/opa/catalog/constants/constants.rego, and then import them into the main policy
file stacks/schemas/opa/vpc/validate-infra-vpc-component.rego.

You also need to specify the module_paths attribute in the component's settings.validation section.
The module_paths attribute is an array of filesystem paths (folders or individual files) to the additional modules for schema validation.

Each path can be an absolute path or a path relative to schemas.opa.base_path defined in atmos.yaml.
If a folder is specified in module_paths, Atmos will recursively process the folder and all its sub-folders and load all Rego files into the OPA engine.

This allows you to separate the common OPA modules, constants and helper functions into a catalog of reusable Rego modules, and to structure your OPA policies to make them DRY.

example

Add the settings.validation section to the component's config:

components:
  terraform:
    infra/vpc:
      settings:
        # Validation
        # Supports JSON Schema and OPA policies
        # All validation steps must succeed to allow the component to be provisioned
        validation:
          validate-infra-vpc-component-with-jsonschema:
            schema_type: jsonschema
            # 'schema_path' can be an absolute path or a path relative to 'schemas.jsonschema.base_path' defined in `atmos.yaml`
            schema_path: "vpc/validate-infra-vpc-component.json"
            description: Validate 'infra/vpc' component variables using JSON Schema
          check-infra-vpc-component-config-with-opa-policy:
            schema_type: opa
            # 'schema_path' can be an absolute path or a path relative to 'schemas.opa.base_path' defined in `atmos.yaml`
            schema_path: "vpc/validate-infra-vpc-component.rego"
            # An array of filesystem paths (folders or individual files) to the additional modules for schema validation
            # Each path can be an absolute path or a path relative to `schemas.opa.base_path` defined in `atmos.yaml`
            # In this example, we have the additional Rego modules in `stacks/schemas/opa/catalog/constants`
            module_paths:
              - "catalog/constants"
            description: Check 'infra/vpc' component configuration using OPA policy
            # Set `disabled` to `true` to skip the validation step
            # `disabled` is set to `false` by default, the step is allowed if `disabled` is not declared
            disabled: false
            # Validation timeout in seconds
            timeout: 10

Add the following Rego package in the file stacks/schemas/opa/catalog/constants/constants.rego:

package atmos.constants

vpc_dev_max_availability_zones_error_message := "In 'dev', only 2 Availability Zones are allowed"

vpc_prod_map_public_ip_on_launch_error_message := "Mapping public IPs on launch is not allowed in 'prod'. Set 'map_public_ip_on_launch' variable to 'false'"

vpc_name_regex := "^[a-zA-Z0-9]{2,20}$"

vpc_name_regex_error_message := "VPC name must be a valid string from 2 to 20 alphanumeric chars"

Add the following OPA policy in the file stacks/schemas/opa/vpc/validate-infra-vpc-component.rego:

# Atmos looks for the 'errors' (array of strings) output from all OPA policies
# If the 'errors' output contains one or more error messages, Atmos considers the policy failed

# 'package atmos' is required in all Atmos OPA policies
package atmos

import future.keywords.in

# Import the constants from the file `stacks/schemas/opa/catalog/constants/constants.rego`
import data.atmos.constants.vpc_dev_max_availability_zones_error_message
import data.atmos.constants.vpc_prod_map_public_ip_on_launch_error_message
import data.atmos.constants.vpc_name_regex
import data.atmos.constants.vpc_name_regex_error_message

# In production, don't allow mapping public IPs on launch
errors[vpc_prod_map_public_ip_on_launch_error_message] {
    input.vars.stage == "prod"
    input.vars.map_public_ip_on_launch == true
}

# In 'dev', only 2 Availability Zones are allowed
errors[vpc_dev_max_availability_zones_error_message] {
    input.vars.stage == "dev"
    count(input.vars.availability_zones) != 2
}

# Check VPC name
errors[vpc_name_regex_error_message] {
    not re_match(vpc_name_regex, input.vars.name)
}

Run the following commands to validate the component in the stacks:

> atmos validate component infra/vpc -s tenant1-ue2-prod

Mapping public IPs on launch is not allowed in 'prod'. Set 'map_public_ip_on_launch' variable to 'false'

exit status 1
> atmos validate component infra/vpc -s tenant1-ue2-dev

In 'dev', only 2 Availability Zones are allowed
VPC name must be a valid string from 2 to 20 alphanumeric chars

exit status 1

v1.37.0

21 Jun 01:40
c476b95
Compare
Choose a tag to compare

what

  • Add spacelift_stack and atlantis_project outputs to atmos describe component command
  • Add --include-spacelift-admin-stacks flag to atmos describe affected command
  • Update Atmos docs

why

  • Having the spacelift_stack and atlantis_project outputs from the atmos describe component command is useful when using the command in GitHub actions related to Spacelift and Atlantis

  • The --include-spacelift-admin-stacks flag for the atmos describe affected command allows including the Spacelift admin stacks of any stack that is affected by config changes. This will optimize Spacelift stack triggering by not triggering all admin stacks on any changes, but instead just triggering the affected admin stacks from a GitHub action

atmos describe affected --include-spacelift-admin-stacks=true
[
  {
    "component": "infrastructure-tenant1",
    "component_type": "terraform",
    "component_path": "examples/complete/components/terraform/spacelift",
    "stack": "tenant1-ue2-prod",
    "stack_slug": "tenant1-ue2-prod-infrastructure-tenant1",
    "spacelift_stack": "tenant1-ue2-prod-infrastructure-tenant1",
    "atlantis_project": "tenant1-ue2-prod-infrastructure-tenant1",
    "affected": "stack.settings.spacelift.admin_stack_context"
  },
  {
    "component": "infrastructure-tenant2",
    "component_type": "terraform",
    "component_path": "examples/complete/components/terraform/spacelift",
    "stack": "tenant2-ue2-prod",
    "stack_slug": "tenant2-ue2-prod-infrastructure-tenant2",
    "spacelift_stack": "tenant2-ue2-prod-infrastructure-tenant2",
    "atlantis_project": "tenant2-ue2-prod-infrastructure-tenant2",
    "affected": "stack.settings.spacelift.admin_stack_context"
  },
  {
    "component": "test/test-component-override-2",
    "component_type": "terraform",
    "component_path": "components/terraform/test/test-component",
    "stack": "tenant1-ue2-dev",
    "stack_slug": "tenant1-ue2-dev-test-test-component-override-2",
    "spacelift_stack": "tenant1-ue2-dev-new-component",
    "atlantis_project": "tenant1-ue2-dev-new-component",
    "affected": "stack.vars"
  },
  {
    "component": "infra/vpc",
    "component_type": "terraform",
    "component_path": "components/terraform/infra/vpc",
    "stack": "tenant2-ue2-staging",
    "stack_slug": "tenant1-ue2-staging-infra-vpc",
    "spacelift_stack": "tenant1-ue2-staging-infra-vpc",
    "atlantis_project": "tenant1-ue2-staging-infra-vpc",
    "affected": "component"
  }
]

The Atmos components for the Spacelift admin stacks will be included in the affected stacks output only if all the following is true:

- The `atmos describe affected` is executed with the `--include-spacelift-admin-stacks=true` flag

- Any of the affected Atmos components has configured the section `settings.spacelift.admin_stack_context` 
  pointing to the Spacelift admin stack that manages the components. For example:
settings:
  spacelift:
    # All Spacelift child stacks for the `tenant1` tenant are managed by the 
    # `tenant1-ue2-prod-infrastructure-tenant1` Spacelift admin stack.
    # The `admin_stack_context` attribute is used to find the affected Spacelift 
    # admin stack for each affected Atmos stack
    # when executing the command 
    # `atmos describe affected --include-spacelift-admin-stacks=true`
    admin_stack_context:
      component: infrastructure-tenant1
      tenant: tenant1
      environment: ue2
      stage: prod
- The Spacelift admin stacks are enabled by `settings.spacelift.workdpace_enabled` set to `true`. For example:
components:
  terraform:
    infrastructure-tenant1:
      metadata:
        component: spacelift
        inherits:
          - spacelift-defaults
      settings:
        spacelift:
          workspace_enabled: true

v1.36.0

17 Jun 23:17
82b6c19
Compare
Choose a tag to compare

what

  • Add timeout parameter to atmos validate component command
  • Add timeout parameter to settings.validation section in the stack config
  • Update docs

why

  • If validation is configured for a component, Atmos executes the configured OPA Rego policies. If a policy is misconfigured (e.g. invalid Rego syntax or import), the validation can take a long time and eventually fail. Use the --timeout parameter to specify the required timeout

  • The timeout (in seconds) can be specified on the command line:

atmos validate component infra/vpc -s tenant1-ue2-dev --timeout 15

Or it can be specified in the YAML config in the settings.validation section

components:
  terraform:
    infra/vpc:
      metadata:
        component: infra/vpc
      settings:
        # Validation
        # Supports JSON Schema and OPA policies
        # All validation steps must succeed to allow the component to be provisioned
        validation:
          check-infra-vpc-component-config-with-opa-policy:
            schema_type: opa
            # 'schema_path' can be an absolute path or a path relative to 'schemas.opa.base_path' defined in `atmos.yaml`
            schema_path: validate-infra-vpc-component.rego
            description: Check 'infra/vpc' component configuration using OPA policy
            # Validation timeout in seconds
            timeout: 10

v1.35.0

09 May 16:19
194300c
Compare
Choose a tag to compare

what

why

  • Add sources of the values from the component's sections (vars, env, settings) to the command output

Sources of Component ENV Variables

The sources.env section of the atmos describe component command output shows the final deep-merged component's environment variables and their inheritance chain.

Each variable descriptor has the following schema:

  • final_value - the final value of the variable after Atmos processes and deep-merges all values from all stack config files

  • name - the variable name

  • stack_dependencies - the variable's inheritance chain (stack config files where the values for the variable were provided). It has the following schema:

    • stack_file - the stack config file where the value for the variable was provided
    • stack_file_section - the section of the stack config file where the value for the variable was provided
    • variable_value - the variable's value
    • dependency_type - how the variable was defined (inline or import). inline means the variable was defined in one of the sections
      in the stack config file. import means the stack config file where the variable is defined was imported into the parent Atmos stack

For example:

atmos describe component test/test-component-override-3 -s tenant1-ue2-dev
sources:
  env:
    TEST_ENV_VAR1:
      final_value: val1-override-3
      name: TEST_ENV_VAR1
      stack_dependencies:
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-3
          stack_file_section: components.terraform.env
          variable_value: val1-override-3
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-2
          stack_file_section: components.terraform.env
          variable_value: val1-override-2
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override
          stack_file_section: components.terraform.env
          variable_value: val1-override
        - dependency_type: import
          stack_file: catalog/terraform/test-component
          stack_file_section: components.terraform.env
          variable_value: val1
    TEST_ENV_VAR2:
      final_value: val2-override-3
      name: TEST_ENV_VAR2
      stack_dependencies:
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-3
          stack_file_section: components.terraform.env
          variable_value: val2-override-3
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-2
          stack_file_section: components.terraform.env
          variable_value: val2-override-2
        - dependency_type: import
          stack_file: catalog/terraform/test-component
          stack_file_section: components.terraform.env
          variable_value: val2

The stack_dependencies inheritance chain shows the ENV variable sources in the reverse order the sources were processed. The first item in the list was processed the last and its variable_value overrode all the previous values of the variable.


For example, the component's TEST_ENV_VAR1 ENV variable has the following inheritance chain:

sources:
  env:
    TEST_ENV_VAR1:
      final_value: val1-override-3
      name: TEST_ENV_VAR1
      stack_dependencies:
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-3
          stack_file_section: components.terraform.env
          variable_value: val1-override-3
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-2
          stack_file_section: components.terraform.env
          variable_value: val1-override-2
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override
          stack_file_section: components.terraform.env
          variable_value: val1-override
        - dependency_type: import
          stack_file: catalog/terraform/test-component
          stack_file_section: components.terraform.env
          variable_value: val1

Which we can interpret as follows (reading from the last to the first item in the stack_dependencies list):

  • In the catalog/terraform/test-component stack config file (the last item in the list), the value for the TEST_ENV_VAR1 ENV variable was set to val1 in the components.terraform.env section

  • Then the value was set to val1-override in the catalog/terraform/test-component-override stack config file. This value overrides the value set in the catalog/terraform/test-component stack config file

  • Then the value was set to val1-override-2 in the catalog/terraform/test-component-override-2 stack config file. This value overrides the values set in the catalog/terraform/test-component and catalog/terraform/test-component-override stack config files

  • Finally, in the catalog/terraform/test-component-override-3 stack config file (which was imported into the parent Atmos stack via import, the value was set to val1-override-3 in the components.terraform.env section of the test/test-component-override-3 Atmos component. This value overrode all the previous values arriving at the final_value: val1-override-3 for the ENV variable


Sources of Component Settings

The sources.settings section of the output shows the final deep-merged component's settings and their inheritance chain.

Each setting descriptor has the following schema:

  • final_value - the final value of the setting after Atmos processes and deep-merges all values from all stack config files

  • name - the setting name

  • stack_dependencies - the setting's inheritance chain (stack config files where the values for the variable were provided). It has the following schema:

    • stack_file - the stack config file where the value for the setting was provided
    • stack_file_section - the section of the stack config file where the value for the setting was provided
    • variable_value - the setting's value
    • dependency_type - how the setting was defined (inline or import). inline means the setting was defined in one of the sections
      in the stack config file. import means the stack config file where the setting is defined was imported into the parent Atmos stack

For example:

atmos describe component test/test-component-override-3 -s tenant1-ue2-dev
sources:
  settings:
    spacelift:
      final_value:
        protect_from_deletion: true
        stack_destructor_enabled: false
        stack_name_pattern: '{tenant}-{environment}-{stage}-new-component'
        workspace_enabled: false
      name: spacelift
      stack_dependencies:
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-3
          stack_file_section: components.terraform.settings
          variable_value:
            workspace_enabled: false
        - dependency_type: import
          stack_file: catalog/terraform/test-component-override-2
          stack_file_section: components.terraform.settings
          variable_value:
            stack_name_pattern: '{tenant}-{environment}-{stage}-new-component'
            workspace_enabled: true
        - dependency_type: import
          stack_file: catalog/terraform/test-component
          stack_file_section: components.terraform.settings
          variable_value:
            workspace_enabled: true
        - dependency_type: import
          stack_file: catalog/terraform/spacelift-and-backend-override-1
          stack_file_section: settings
          variable_value:
            protect_from_deletion: true
            stack_destructor_enabled: false
            workspace_enabled: true

The stack_dependencies inheritance chain shows the sources of the setting in the reverse order the sources were processed. The first item in the list was processed the last and its variable_value overrode all the previous values of the setting.

v1.34.2

27 Apr 14:17
f2a7bf6
Compare
Choose a tag to compare

what

  • Add workspace to the outputs of atmos describe stacks command

why

  • We often need to know the terraform workspace for each component (taking into account that Terraform workspaces can be overridden per component, so they are not always the same as the stack names)

test

tenant1-ue2-dev:
    components:
      terraform:
        
        top-level-component1:
          workspace: tenant1-ue2-dev

        test/test-component-override-3:
          workspace: test-component-override-3-workspace

v1.34.1

26 Apr 03:12
a725464
Compare
Choose a tag to compare

what

  • Add ExecuteDescribeStacks function to pkg package and wrap the same function from the internal package
  • Add tests

why

  • We need to use the ExecuteDescribeStacks in the terraform utils provider, but all code in the internal package is not visible to the calling code. internal package is used to reduce the public API surface. Packages within an internal/directory are therefore said to be internal packages

references

v1.34.0

14 Apr 21:14
d920bee
Compare
Choose a tag to compare

what

  • Update env stack config section
  • Allow using null to unset the ENV var

why

  • If it's set to null, it will not be set as ENV var in the executing process (will be just skipped)
  • Setting it to null will override all other values set in the stack configs for the component
  • This is useful if an ENV var is set globally in top-level stacks for the entire configuration, but needs to be unset for some specific components

test

Set TEST_ENV_VAR4 to some value

components:
  terraform:
    "test/test-component-override-3":
      env:
        TEST_ENV_VAR1: "val1-override-3"
        TEST_ENV_VAR2: "val2-override-3"
        TEST_ENV_VAR3: "val3-override-3"
        TEST_ENV_VAR4: "val4-override-3"
atmos terraform plan test/test-component-override-3 -s tenant1-ue2-dev
Using ENV vars:
TEST_ENV_VAR1=val1-override-3
TEST_ENV_VAR2=val2-override-3
TEST_ENV_VAR3=val3-override-3
TEST_ENV_VAR3=val4-override-3

Set TEST_ENV_VAR4 to null to unset (skip) it

Setting an ENV var to null in stack config has the effect of unsetting it because the exec.Command, which sets these ENV vars in the executing process, is itself executed in a separate process started by the os.StartProcess function.

components:
  terraform:
    "test/test-component-override-3":
      env:
        TEST_ENV_VAR1: "val1-override-3"
        TEST_ENV_VAR2: "val2-override-3"
        TEST_ENV_VAR3: "val3-override-3"
        # Use `null` to unset the ENV var.
        # If it's set to `null`, it will not be set as ENV var in the process (will be just skipped).
        # Setting it to `null` will override all other values set in the stack configs for the component.
        TEST_ENV_VAR4: null
atmos terraform plan test/test-component-override-3 -s tenant1-ue2-dev
Using ENV vars:
TEST_ENV_VAR1=val1-override-3
TEST_ENV_VAR2=val2-override-3
TEST_ENV_VAR3=val3-override-3