Skip to main content

Atmos component migration in YAML config

Rename a Terraform Stack Without Moving State​

An Atmos stack name is a configuration identifier. For Terraform/OpenTofu, it can also contribute to the generated workspace and backend path. Renaming it without preserving those values can make the next plan target a different state.

This example changes the Atmos stack name from dev-old to dev while retaining the same Terraform state. It assumes vpc already uses the non-default Terraform workspace dev-old and the S3 backend values shown below. Substitute the values from your own resolved component; do not adopt these example values for existing infrastructure.

Record and Pin the Existing Identity​

Inspect the current component before changing its name:

atmos describe component vpc -s dev-old --query '{"backend": .backend, "workspace": .workspace}'

For this example, the existing backend is bucket example-tfstate, region us-east-1, workspace_key_prefix: vpc, and key: terraform.tfstate; the resolved workspace is dev-old. For a non-default S3 workspace, that identifies s3://example-tfstate/vpc/dev-old/terraform.tfstate.

Use a setting for the Atmos stack name so changing it does not also change a Terraform resource input:

atmos.yaml (relevant setting)
stacks:
name_template: "{{ .settings.deployment_name }}"

Before renaming, explicitly retain the existing backend and workspace in the stack:

stacks/deploy/dev.yaml
settings:
deployment_name: dev-old

components:
terraform:
vpc:
metadata:
terraform_workspace: dev-old
backend_type: s3
backend:
s3:
bucket: example-tfstate
region: us-east-1
workspace_key_prefix: vpc
key: terraform.tfstate
# Keep the existing component inputs, auth, imports, and other settings.

If inherited metadata sets terraform_workspace_template or terraform_workspace_pattern, update or remove that higher-priority override first: it takes precedence over terraform_workspace. Preserve any additional backend options such as role assumption or encryption. Check the resolved identity again and review a plan before renaming; pinning should not itself change infrastructure.

Change the Atmos Name and Compare​

Change only settings.deployment_name to dev. Keep metadata.terraform_workspace: dev-old and the backend settings unchanged. Update cross-stack references that use the old Atmos name.

atmos describe component vpc -s dev --query '{"backend": .backend, "workspace": .workspace}'
atmos terraform plan vpc -s dev

Both descriptions must resolve to the same backend and workspace: dev-old. The plan must show no unintended infrastructure changes. Repeat this check for every component in the renamed stack. Also inspect names or tags templated from .atmos_stack: preserving state does not prevent a resource replacement caused by a changed Terraform input.

If you want to change the workspace or state path too, treat that as a separate state migration with a backup and the backend-specific procedure. init -reconfigure does not copy state; see backend troubleshooting and Terraform backend initialization.

Other Component Types​

The workspace and backend guidance above is specific to Terraform/OpenTofu. For other tools, preserve their deployed identity when reorganizing Atmos configuration. For example, a native CloudFormation component uses stack_name, and Helmfile identifies releases through its own configuration. Review changes to any deployment names derived from Atmos stack or component names with the tool's plan or diff.

Migrate component from using deprecated key component to use metadata.inherits​

  1. Identify the component to move, we'll use vpc for this example.

    Here is an example of the older method of using the component key

    # stacks/catalog/vpc.yaml
    components:
    terraform:
    vpc:
    # This cannot be enabled here in the older method due to the global
    # AZ fragment importation
    settings:
    spacelift:
    workspace_enabled: false
    vars:
    enabled: true
    # ...etc...

    # stacks/gbl-ue2.yaml
    components:
    terraform:
    vpc:
    # This is the AZ fragment importation that's imported across all stacks
    # even stacks without a vpc.
    availability_zones:
    - us-east-1a
    - us-east-1b
    - us-east-1c

    # stacks/plat-ue2-dev.yaml
    import:
    - gbl-ue2
    - catalog/vpc

    components:
    terraform:
    vpc:
    component: vpc
    # This is where spacelift has to be enabled
    settings:
    spacelift:
    workspace_enabled: true
    vars:
    name: vpc
    # ...etc...

    vpc1:
    component: vpc
    # This is where spacelift has to be enabled
    settings:
    spacelift:
    workspace_enabled: true
    vars:
    name: vpc1
    # ...etc...
  2. Verify terraform plan for vpc component is a no change. If not, configure it and apply it until it shows no change.

    ⨠ atmos terraform plan vpc --stack plat-ue2-dev
  3. Pull down the latest vpc component and repeat the previous step (optional)

    ⨠ wget https://raw.githubusercontent.com/cloudposse/atmos/main/examples/quick-start-advanced/components/terraform/vpc/component.yaml -O components/terraform/vpc/component.yaml
    ⨠ sed -i 's,infra/vpc-flow-logs-bucket,vpc,g' components/terraform/vpc/component.yaml
    ⨠ atmos vendor pull -c vpc
  4. Verify the current workspace name

    ⨠ atmos describe component vpc --stack plat-ue2-dev | grep ^workspace
    workspace: plat-ue2-dev
  5. Count the current root stacks where the vpc component is defined

    ⨠ atmos describe stacks --components=vpc --sections=components | grep -oP '^[a-z0-9-]+' | wc -l
    17
  6. In the vpc.yaml stack catalog, rename vpc to be vpc/defaults

    Add the metadata block

    components:
    terraform:
    vpc/defaults:
    metadata:
    type: abstract
    # spacelift can now be enabled in the catalog
    settings:
    spacelift:
    workspace_enabled: true
    vars:
    enabled: true
    # ...etc...
  7. Create a vpc component that inherits from vpc/defaults

    vpc:
    metadata:
    component: vpc
    inherits:
    - vpc/defaults
    vars:
    name: vpc
  8. Verify the workspace is the same

    ⨠ atmos describe component vpc --stack plat-ue2-dev | grep ^workspace
    workspace: plat-ue2-dev

    NOTE: Since the vpc component name shares the same name as its base component, the workspace will remain the same.

    NOTE: If the workspace has the component suffixed to it e.g. plat-ue2-dev-vpc1 then the tfstate will have to be migrated. See component renaming and subsequent tfstate rename below before continuing.

  9. Add availability_zones to vpc/defaults and only add the letters and omit the region.

  10. Move any vpc component global overrides for availability_zones to vpc/defaults.

    The vpc configuration may have a fragment in a global region file

    vpc:
    availability_zones:
    - us-east-1a
    - us-east-1b
    - us-east-1c

    It can now be set as this in the vpc.yaml catalog

    availability_zones:
    - a
    - b
    - c
  11. Count the root stacks again and verify the number is lower than previous

    ⨠ atmos describe stacks --components=vpc --sections=components | grep -oP '^[a-z0-9-]+' | wc -l
    9
  12. Rerun the plan and verify no changes again

    ⨠ atmos terraform plan vpc --stack plat-ue2-dev

Renaming components​

If renaming a component is desired, for example, from vpc to vpc1, the workspace will change.

Follow these steps to ensure your state is properly managed.

  1. Identify all the stacks affected by the component rename

  2. Select a root stack and the component. We will use plat-ue2-dev root stack and vpc component for this example.

  3. Verify terraform plan for vpc component is a no change. If not, configure and apply it.

  4. Verify the old and new workspaces.

    Before renaming

    ⨠ atmos describe component vpc --stack plat-ue2-dev | grep ^workspace
    workspace: plat-ue2-dev

    After renaming

    ⨠ atmos describe component vpc1 --stack plat-ue2-dev | grep ^workspace
    workspace: plat-ue2-dev-vpc1
  5. Follow one of the guides below for migrating the state or overriding the workspace

  6. After you have completed the previous step, you will also need to rename any component keys in remote-state.tf files since the original reference to the component has been removed from the tfstate

Migrating state manually​

This approach is recommended because this will allow the catalog to be imported without additional overrides.

  1. Navigate to the component and list the workspaces

    ⨠ cd components/terraform/vpc
    ⨠ terraform init
    ⨠ terraform workspace list
    default
    * plat-gbl-sandbox
    plat-ue2-dev
  2. Select the original component's workspace

    ⨠ terraform workspace select plat-ue2-dev
  3. Dump the terraform state into a new file

    ⨠ terraform state pull > plat-ue2-dev.tfstate
  4. Select or create the new workspace if it does not exist

    ⨠ terraform workspace select plat-ue2-dev-vpc1
    ⨠ terraform workspace new plat-ue2-dev-vpc1
    Created and switched to workspace "plat-ue2-dev-vpc1"!
  5. Push up the original workspace's state to the new workspace's state

    ⨠ terraform state push plat-ue2-dev.tfstate
    Releasing state lock. This may take a few moments...
  6. Verify terraform plan for the new component is a no change.

    ⨠ atmos terraform plan vpc1 --stack plat-ue2-dev

Overriding the workspace name​

The fastest approach would be to override the workspace name but is not recommended since this will need to be done for every root stack where the catalog is imported.

  1. In the root stack affected, instantiate the component and override the terraform_workspace to match the original.

    # root stack: plat-ue2-dev
    import:
    - catalog/vpc

    components:
    terraform:
    vpc1:
    metadata:
    terraform_workspace: plat-ue2-dev
    component: vpc
    inherits:
    - vpc/defaults
    vars:
    name: vpc
  2. Verify the workspace is correct

    ⨠ atmos describe component vpc1 --stack plat-ue2-dev | grep ^workspace
    workspace: plat-ue2-dev
  3. Repeat the above steps for all the root stacks where the component is imported