Preventing false drift detection results for resource types - Extension Development for CloudFormation

Preventing false drift detection results for resource types

When AWS CloudFormation performs drift detection on a resource, it looks up the value for each resource property as specified in the stack template, and compares that value with the current resource property value returned by the resource read handler. A resource is then considered to have drifted if one or more of its properties have been deleted, or had their value changed. In some cases, however, the resource may not be able to return the exact same value in the read handler as was specified in the stack template, even though the value is essentially the same and shouldn't be considered as drifted.

To prevent these cases from being incorrectly reported as drifted resources, you can specify a property transform in your resource schema. The property transform provides a way for CloudFormation to accurately compare the resource property value specified in the template with the value returned from the read handler. During drift detection, if CloudFormation finds a property where the template value differs from the value returned by the read handler, it determines if a property transform has been defined for that property in the resource schema. If it has, CloudFormation applies that property transform to the value specified in the template, and then compares it to the read handler value again. If these two values match, the property isn't considered to have drifted, and is marked as IN_SYNC.

For more information about drift detection, see Detecting unmanaged configuration changes to stacks and resources in the CloudFormation User Guide.

Defining a property transform for drift detection operations

Use the propertyTransform element to define a property transform for a given resource property.

"propertyTransform": { "property_path": "transform" }

Where:

  • property_path is the path to the resource property in the resource schema.

  • transform is the transform to perform on the resource property value specified in the stack template.

    Property transforms are written in JSONata, an open-source, lightweight query and transformation language for JSON data.

For example, consider the AWS::Route53::HostedZone resource. For the Name property, users can specify a domain name with or without a trailing . in their templates. However, assume the Route 53 service always returns the domain name with a trailing .. This means that if a user specified a domain name without the trailing . in their template, created the stack, and then performed drift detection on the stack, CloudFormation would erroneously report the AWS::Route53::HostedZone resource as drifted. To prevent this from happening, the resource developer would add a propertyTransform element to the resource schema to enable CloudFormation to determine if both property values were actually the same:

"propertyTransform": { "/properties/Name": "$join([Name, \".\"])" }

Specifying multiple transforms for a property

You can specify multiple transforms for CloudFormation to attempt by using the $OR operator. If you specify multiple transforms, CloudFormation tries them all, in the order they're specified, until it finds one that results in the property values matching, or it has tried them all.

For example, for the following property transform, CloudFormation would attempt two transforms to determine whether the property value has actually drifted:

  • Append . to the template property value, and determine if the updated value now matches the property value returned by the resource read handler. If it does, CloudFormation reports the property as IN_SYNC. If not, CloudFormation performs the next transform.

  • Append the string test to the template property value, and determine if the updated value now matches the property value returned by the resource read handler. If it does, CloudFormation reports the property as IN_SYNC. If not, CloudFormation reports the property, and the resource, as MODIFIED.

"propertyTransform": { "/properties/Name": "$join([Name, \".\"]) $OR $join([Name, \"test\"])" }