Resolve drift with an import operation - AWS CloudFormation

Resolve drift with an import operation

There may be cases where a resource's configuration has drifted from its intended configuration and you want to accept the new configuration as the intended configuration. In most cases, you would resolve the drift results by updating the resource definition in the stack template with a new configuration and then perform a stack update. However, if the new configuration updates a resource property that requires replacement, then the resource will be recreated during the stack update. If you want to retain the existing resource, you can use the resource import feature to update the resource and resolve the drift results without causing the resource to be replaced.

Resolving drift for a resource through an import operation consists of the following basic steps:

For more information on resource import, see Import AWS resources into a CloudFormation stack with a resource import. For a list of resources that support import, see Resource type support.

In this example, we use the following template, named templateToImport.json.

Example JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Import test", "Resources": { "ServiceTable":{ "Type":"AWS::DynamoDB::Table", "Properties":{ "TableName":"Service", "AttributeDefinitions":[ { "AttributeName":"key", "AttributeType":"S" } ], "KeySchema":[ { "AttributeName":"key", "KeyType":"HASH" } ], "BillingMode": "PROVISIONED", "ProvisionedThroughput":{ "ReadCapacityUnits":5, "WriteCapacityUnits":1 } } }, "GamesTable": { "Type": "AWS::DynamoDB::Table", "Properties": { "TableName": "Games", "AttributeDefinitions": [ { "AttributeName": "key", "AttributeType": "S" } ], "KeySchema": [ { "AttributeName": "key", "KeyType": "HASH" } ], "BillingMode": "PROVISIONED", "ProvisionedThroughput": { "ReadCapacityUnits": 5, "WriteCapacityUnits": 1 } } } } }
Example YAML
AWSTemplateFormatVersion: 2010-09-09 Description: Import test Resources: ServiceTable: Type: 'AWS::DynamoDB::Table' Properties: TableName: Service AttributeDefinitions: - AttributeName: key AttributeType: S KeySchema: - AttributeName: key KeyType: HASH BillingMode: PROVISIONED ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 1 GamesTable: Type: 'AWS::DynamoDB::Table' Properties: TableName: Games AttributeDefinitions: - AttributeName: key AttributeType: S KeySchema: - AttributeName: key KeyType: HASH BillingMode: PROVISIONED ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 1

In this example, let's assume a user changed a resource outside of CloudFormation. After running drift detect, we discovered that GamesTable has been modified BillingMode to PAY_PER_REQUEST. For more information about drift detect, see Detect unmanaged configuration changes to stacks and resources with drift detection.

The drift results display the expected and actual results in the console.

Our stack is now out of date, our resources are live, but we want to preserve the intended resource configuration. We can do this by resolving drift through an import operation, without interrupting services.

Resolve drift with an import operation using the CloudFormation console

Step 1. Update stack with Retain deletion policy

To update stack using a DeletionPolicy attribute with the Retain option
  1. Sign in to the AWS Management Console and open the AWS CloudFormation console at https://console.aws.amazon.com/cloudformation.

  2. On the Stacks page, choose the stack that has drifted.

  3. Choose Update, and then choose Replace current template from the stack details pane.

  4. On the Specify template page, provide your updated template that contains the DeletionPolicy attribute with the Retain option using one of the following methods:

    • Choose Amazon S3 URL, and then specify the URL for your template in the text box.

    • Choose Upload a template file, and then browse for your template.

    Then, choose Next.

  5. Review the Specify stack details page and choose Next.

  6. Review the Configure stack options page and choose Next.

  7. On the Review stack-name page, choose Update stack.

Results: On the Events page of your stack, the status is UPDATE_COMPLETE.

To resolve drift through an import operation, without interrupting services, specify a Retain DeletionPolicy for the resources you want to remove from your stack. In the following example, we've added a DeletionPolicy attribute, set to Retain, to the GamesTable resource.

Example JSON
"GamesTable": { "Type": "AWS::DynamoDB::Table", "DeletionPolicy": "Retain", "Properties": { "TableName": "Games",
Example YAML
GamesTable: Type: 'AWS::DynamoDB::Table' DeletionPolicy: Retain Properties: TableName: Games

Step 2. Remove drifted resources, related parameters, and outputs

To remove drifted resources, related parameters, and outputs
  1. Choose Update, and then choose Replace current template from the stack details pane.

  2. On the Specify template page, provide your updated template with its resources, related parameters, and outputs removed from the stack template using one of the following methods:

    • Choose Amazon S3 URL, and then specify the URL for your template in the text box.

    • Choose Upload a template file, and then browse for your template.

    Then, choose Next.

  3. Review the Specify stack details page and choose Next.

  4. Review the Configure stack options page and choose Next.

  5. On the Review stack-name page, choose Update stack.

Results: The Logical ID GamesTable has a status of DELETE_SKIPPED on the Events page of your stack.

Wait until CloudFormation completes the stack update operation. After the stack update operation completes, remove the resource, related parameters, and outputs from the stack template. Then, import the updated template. After completing these actions, the example template now looks like the following.

Example JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Import test", "Resources": { "ServiceTable":{ "Type":"AWS::DynamoDB::Table", "Properties":{ "TableName":"Service", "AttributeDefinitions":[ { "AttributeName":"key", "AttributeType":"S" } ], "KeySchema":[ { "AttributeName":"key", "KeyType":"HASH" } ], "BillingMode": "PROVISIONED", "ProvisionedThroughput":{ "ReadCapacityUnits":5, "WriteCapacityUnits":1 } } } } }
Example YAML
AWSTemplateFormatVersion: 2010-09-09 Description: Import test Resources: ServiceTable: Type: 'AWS::DynamoDB::Table' Properties: TableName: Service AttributeDefinitions: - AttributeName: key AttributeType: S KeySchema: - AttributeName: key KeyType: HASH BillingMode: PROVISIONED ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 1

Step 3. Update template to match the live state of your resources

To update template to match the live state of resources
  1. To import the updated template, choose Stack actions and then choose Import resources into stack.

    The Import resources into stack option in the console.
  2. Review the Import overview page for a list of things you're required to provide during this operation, and then choose Next.

  3. On the Specify template page, provide your updated template using one of the following methods:

    • Choose Amazon S3 URL, and then specify the URL for your template in the text box.

    • Choose Upload a template file, and then browse for your template.

    Then, choose Next.

  4. On the Identify resources page, identify each target resource. For more information, see Resource identifiers.

    1. Under Identifier property, choose the type of resource identifier. For example, the TableName property identifies the AWS::DynamoDB::Table resource.

    2. Under Identifier value, enter the actual property value. In the example template, the TableName for the GamesTable resource is Games.

    3. Choose Next.

  5. Review the Specify stack details page, and choose Next.

  6. On the Import overview page, review the resources being imported, and then choose Import resources. This will import the AWS::DynamoDB::Table resource type back into your stack.

Results: In this example, we resolved the resource drift through an import operation, without interrupting services. You can check the progress of an import action in the CloudFormation console in the Events tab. Imported resources will have a IMPORT_COMPLETE status followed by a CREATE_COMPLETE status with Resource import complete as the status reason.

Wait until CloudFormation completes the stack update operation. After the stack update operation completes, update your template to match the actual, drifted state of your resources. For example, the BillingMode will be set to PAY_PER_REQUEST and ReadCapacityUnits and WriteCapacityUnits will be set to 0.

Example JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Import test", "Resources": { "ServiceTable":{ "Type":"AWS::DynamoDB::Table", "Properties":{ "TableName":"Service", "AttributeDefinitions":[ { "AttributeName":"key", "AttributeType":"S" } ], "KeySchema":[ { "AttributeName":"key", "KeyType":"HASH" } ], "BillingMode": "PROVISIONED", "ProvisionedThroughput":{ "ReadCapacityUnits":5, "WriteCapacityUnits":1 } } }, "GamesTable": { "Type": "AWS::DynamoDB::Table", "DeletionPolicy": "Retain", "Properties": { "TableName": "Games", "AttributeDefinitions": [ { "AttributeName": "key", "AttributeType": "S" } ], "KeySchema": [ { "AttributeName": "key", "KeyType": "HASH" } ], "BillingMode": "PAY_PER_REQUEST", "ProvisionedThroughput": { "ReadCapacityUnits": 0, "WriteCapacityUnits": 0 } } } } }
Example YAML
AWSTemplateFormatVersion: 2010-09-09 Description: Import test Resources: ServiceTable: Type: 'AWS::DynamoDB::Table' Properties: TableName: Service AttributeDefinitions: - AttributeName: key AttributeType: S KeySchema: - AttributeName: key KeyType: HASH BillingMode: PROVISIONED ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 1 GamesTable: Type: 'AWS::DynamoDB::Table' DeletionPolicy: Retain Properties: TableName: Games AttributeDefinitions: - AttributeName: key AttributeType: S KeySchema: - AttributeName: key KeyType: HASH BillingMode: PAY_PER_REQUEST ProvisionedThroughput: ReadCapacityUnits: 0 WriteCapacityUnits: 0