Is there a way to incorporate existing AWS resources that were created outside of cloudformation into an existing cloudformation stack? I'd like to do this without having to add a new resource in the cloudformation stack and migrate the existing resource's data over to that new resource. I see that AWS now has drift detection for cloudformation stacks. I'm wondering if that might be able to be leveraged to incorporate existing resources into a stack.
7 Answers
The ability to import/adopt resources into an existing CloudFormation stack is the #1 ask from CloudFormation customers. We've been thinking about ways to do it for a while, but haven't hit upon the mechanism that both fits customer needs and works at the scale the service operates.
Since we don't expose stack state info anywhere outside the service for you to modify, the only approach you can take until we offer an adoption feature is to either store metadata about the resources in a parameter store, or use a custom resource as a wrapper to retrieve the information about the underlying resource and then surface it to your stack via Fn::GetAtt.
Now you finally can do it with Resource Import feature, references:
https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md
https://twitter.com/shortjared/status/1193985448164691970?s=21
You can do this by passing existing resource information to your stack via Parameters. Here is an example of how to pass these parameters to the stack.
Check out this blog post from Eric Hammond describing how you can incorporate these parameters into the rest of the stack. The use-case described is a bit different in that they are optionally creating new resources if they aren't passed in, but the overall structure applies to the case you've described.
In this case I don't think Drift Detection will help you, since it will show differences between deployed resources and the configuration described in a stack. Resources defined/created outside of the stack won't be checked.
Amazons CDK (currently in the stage of developer preview as of writing) offers a way to do that:
If you need to reference a resource, such as an Amazon S3 bucket or VPC, that's defined outside of your CDK app, you can use the Xxxx.import(...) static methods that are available on AWS constructs. For example, you can use the Bucket.import() method to obtain a BucketRef object, which can be used in most places where a bucket is required. This pattern enables treating resources defined outside of your app as if they are part of your app.
Source: https://docs.aws.amazon.com/CDK/latest/userguide/aws_construct_lib.html
It also allows to import existing CloudFormation templates: https://docs.aws.amazon.com/CDK/latest/userguide/use_cfn_template.html
Importing existing resources to stacks is now supported by CloudFormation :
Announcement from AWS : AWS CloudFormation Launches Resource Import
Instructions Via an example : HERE
Cloudformer might help you to create a new stack from existing resources and then you can add more resources to the stack. But don't know of a way to "merge" an existing stack with existing resources outside the stack.
Im my case I needed to import an ARN value from an existing SAM output in my account, so that I could add the proper invoke policy in my new stack.
I was looking for an equivalent of SAM's Fn::ImportValue
, and found out that the core module has a static Fn.importValue
method you can use as such:
const cdk = require('@aws-cdk/core');
const lambda = require('@aws-cdk/aws-lambda')
class MyStack extends cdk.Stack {
constructor(scope, id, props) {
super(scope, id, props);
// The below line did the trick
const arn = cdk.Fn.importValue(`your-sam-function-export-name`)
const myLambda = lambda.Function.fromFunctionArn(this, 'myLambda', arn)
// ...
}
}
Reference: https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_core.Fn.html