Import existing resources into an AWS CloudFormation-stack
Anders Bjørnestad
AWS Authorized Instructor
Working with infrastructure as code is the recommended way to provision resources in AWS. The native AWS-way of doing it is via CloudFormation or CDK (Cloud Development Kit), and you should of course do this from day one. But there are cases where you have started using an S3-bucket or DynamoDB-table which you provisioned via the console, or some day down the line you need to refactor your code and split your stack into multiple stacks.
It is not very often I have cases where I need to import resources. It is usually in a production environment, and where the resource can not easily be deleted and recreated (for example a resource that contains a lot of data like an S3-bucket).
Before you start
There are some things you should have in mind and consider before you look into importing existing resources:
- Not all resources can be imported into CloudFormation. For example you can not import EC2-instances, RDS-instances and SNS-topics which is a pain some times, as these are resources which are hard to remove and recreate from scratch without a lot of pain. The current list is available in the documentation here https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import-supported-resources.html
- If you have resources that do not contain data, consider removing them and just add them to the stack as new resources (for example a Lambda function), this could save you a lot of manual work.
- Double-check that your resource-type(s) can be imported and test it in a sandbox-account. This is very important when refactoring so you do not remove a resource from a stack which you can not import later.
- Do not design your infrastructure with the assumption that you can move resources between stacks. There are a lot of resources that can not be imported, and there are also risks and a lot of work involved in doing this.
- You can not import resources and do other updates to your stack at the same time so make sure your stack is up to date with no changes pending.
- You can not import resources that are in another stack, so it need to be detached from it’s existing stack if needed.
Existing resource
If your existing resource belong to an existing stack you must first remove it from that stack. To remove a resource from a stack without deleting it you must add a deletion policy to the resource in your cloud formation template like this:
Resources:
myS3Bucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
BucketName: myExistingbucket-123-abc
Make sure this is in place and update your stack with it before removing the resource from the stack.
Import you resource into the new CloudFormation stack
Add the existing resource to your new CloudFormation-template in the same way you would add a new resource.
Resources:
myExistingS3Bucket:
Type: AWS::S3::Bucket
BucketName: myExistingbucket-123-abc
Go to the CloudFormation-console, select your new stack, go to Stack actions and Import resources into stack and follow the wizard where you will have the option to add resource parameters.
After completing the wizard, your resource(s) should be available in the stack.
Importing in a CDK-stack
Importing a resources into a CDK-stack is done more or less as described above.
If you have a resource in an existing CDK-stack you need to set the removal-policy and clean up your code. Remember to check that the policy is being applied to the stack before removing any code (use cdk diff to check when code has been removed).
myResource.apply_removal_policy(RemovalPolicy.RETAIN)
Update your existing CDK-stack with the no-version-reportingparameter. This removes the cdk-metadata-resource from your stack temporarily (CDK Metadata-resource makes it impossible to import your new resource(s)).
cdk --no-version-reporting deploy
Add your new resource to the CDK-app and run a synth (and a cdk diff if you like)
cdk --no-version-reporting synth
In the cdk.out-folder you will find an updated CloudFormation-template with the new resource(s) (file is named stackname.template.json). Use this template to import the resource(s) manually in CloudFormation as described above.
When you have imported you can run deploys as earlier.
cdk deploy
See this for information about CDK Metadata and version reporting: https://docs.aws.amazon.com/cdk/v2/guide/cli.html#version_reporting
Conclusion
Importing resources into an existing CloudFormation-stack is a manual process which can be nice to have when needed. A big drawback are all the resource-types that are not supported. My experience is that a lot of cases contain unsupported resource-types so I have to find other work-around, and I do hope more resource-types will be supported later.