Recreate on Update#

When Idem can’t update an existing resource, use recreate_on_update to delete the resource and recreate it.

A name_prefix argument prevents duplicate resource names when the recreated resource must exist before deleting the old one. The name prefix, with a timestamp suffix, becomes the name of the new resource, making it unique from the old name.

An SLS state might include name, name_prefix, or both, with the following results.

SLS attributes that are set:

Resource name will be:

name

name_prefix

X

name

X

name_prefix with timestamp

X

X

name

Dependent resources - When a resource that must be recreated has dependent resources, you only include name_prefix and no name. That way, Idem creates the unique name as described above and avoids name duplication conflicts while following these steps in order:

  1. Idem creates the new resource with the unique name.

  2. Idem updates dependent resources.

  3. Idem deletes the old resource.

No dependent resources - When a resource that must be recreated doesn’t have dependent resources, you can use name or name_prefix. There is no name duplication to avoid because the old resource is deleted first.

In the following examples, State_A isn’t supported for updates. The only way to update values in State_A is to create a new resource and delete the one that has the old values.

Greenfield Example 1#

In the following greenfield example, State_B is dependent on State_A output. State_B parameter_2 requires the State_A resource_id.

Because this is a greenfield deployment, and State_A will be new, the recreate_on_update shown in State_A is never activated. There is no State_A name argument, so the name_prefix is used.

State_A:
  cloud.instance.present:
    - name_prefix: my-resource-A
    - parameter_1: value-1
    - parameter_2: value-2
    - ignore_changes:
      - parameter_2
    - recreate_on_update:
        create_before_destroy: true

State_B:
  cloud.instance.present:
    - name: Instance-B
    - parameter_1: value-1
    - parameter_2: "${cloud:State_A:resource_id}"

The console output for the example is:

ID: State_A
Function: cloud.instance.present
Result: True
Comment: ("Created cloud.instance 'my-resource-A-1'",)
Changes:
new:
----------
    name:
        my-resource-A-1
    name_prefix:
        my-resource-A
    resource_id:
        my-resource-A-1
    parameter_1:
        value-1
    parameter_2:
        value-2

------
ID: State_B
Function: cloud.instance.present
Result: True
Comment: ("Created cloud.instance 'Instance-B'",)
Changes:
new:
----------
    name:
        Instance-B
    parameter_1:
        value-1
    parameter_2:
        my-resource-A-1

Brownfield Example 1#

In the following brownfield example, State_A needs to update its parameter_1 value. Because this is a brownfield example, and State_A isn’t supported for updates, it must be recreated with the new value.

Note that create_before_destroy is set to true so that Idem can create the new State_A resource, supply its resource_id to State_B, and delete the old State_A resource afterward. If create_before_destroy were not true, State_A might fail to delete because it is used by State_B.

In addition, name_prefix lets Idem generate a unique name for the new State_A. Idem can then update State_B, then delete the old State_A afterward, all without conflicts in the State_A name.

State_A:
  cloud.instance.present:
    - name_prefix: my-resource-A
    - resource_id: my-resource-A-1
    - parameter_1: value-1-updated
    - parameter_2: value-2
    - ignore_changes:
      - parameter_2
    - recreate_on_update:
        create_before_destroy: true

State_B:
  cloud.instance.present:
    - name: Instance-B
    - parameter_1: value-1
    - parameter_2: "${cloud:State_A:resource_id}"

The console output for the example is:

ID: State_A
Function: cloud.instance.present
Result: True
Comment: ("Created cloud.instance 'my-resource-A-2'",)
Changes:
new:
----------
    name:
        my-resource-A-2
    name_prefix:
        my-resource-A
    resource_id:
        my-resource-A-2
    parameter_1:
        value-1-updated
    parameter_2:
        value-2

------
ID: State_B
Function: cloud.instance.present
Result: True
Comment: ("Updated cloud.instance 'Instance-B'",)
Changes:
old:
-----
    parameter_2:
        my-resource-A-1
new:
----------
    parameter_2:
        my-resource-A-2

------
ID: State_A_delete_old
Function: cloud.instance.present
Result: True
Comment: ("Deleted cloud.instance 'State_A_delete_old'",)
Changes:
old:
----------
    name:
        State_A_delete_old
    name_prefix:
        my-resource-A
    resource_id:
        my-resource-A-1
    parameter_1:
        value-1
    parameter_2:
        value-2

Brownfield Example 2#

In the following brownfield example, State_A needs to update its parameter_1 value. State_A isn’t supported for updates, so it must be recreated with the new value.

In this case, State_A doesn’t have any dependent resources, so create_before_destroy can be false. Idem can safely delete the old State_A resource before creating the new one.

State_A:
  cloud.instance.present:
    - name_prefix: my-resource-A
    - resource_id: my-resource-A-1
    - parameter_1: value-1-updated
    - parameter_2: value-2
    - ignore_changes:
      - parameter_2
    - recreate_on_update:
        create_before_destroy: false

The console output for the example is:

ID: State_A_delete_old
Function: cloud.instance.present
Result: True
Comment: ("Deleted cloud.instance 'State_A_delete_old'",)
Changes:
old:
----------
    name:
        State_A_delete_old
    name_prefix:
        my-resource-A
    resource_id:
        my-resource-A-1
    parameter_1:
        value-1
    parameter_2:
        value-2

-----------

ID: State_A_create_new
Function: cloud.instance.present
Result: True
Comment: ("Created cloud.instance 'my-resource-A-2'",)
Changes:
new:
----------
    name:
        my-resource-A-2
    name_prefix:
        my-resource-A
    resource_id:
        my-resource-A-2
    parameter_1:
        value-1-updated
    parameter_2:
        value-2

Greenfield Example 2#

In the following greenfield example, State_A will be newly created, including its tags. Remember, State_A is still unsupported for updates.

Because ignore_changes contains tags, if tag keys or values have drifted from their newly created states, a subsequent Idem run to bring the resource back into tag compliance won’t recreate the resource, even though recreate_on_update is present.

Note that, in addition, the subsequent run won’t bring the tag keys or values back into compliance.

State_A:
   cloud.instance.present:
     - name_prefix: my-resource
     - tags: {tag-key: tag-value}
     - ignore_changes:
       - tags
     - recreate_on_update:
         create_before_destroy: false