Skip to main content

Importing Resources

You might have some existing resources in your AWS account that you'd like to use in your SST app. There are two ways to use them in your SST app.

  1. Reference resources — Easy to do but you cannot modify the resource
  2. Migrate resources — Harder to do but gives you full control

In this doc we'll look at both these approaches.


Reference resources

The easiest way to use an existing resource in your AWS app is to just reference it. To reference a resource, you can use the fromXXX() methods that most CDK Constructs support . Here are a couple of examples of it in action.


Using an existing VPC for Lambda Functions

import * as ec2 from "@aws-cdk/aws-ec2";

const vpc = ec2.Vpc.fromLookup(stack, "ExistingVPC", { isDefault: true });

new Api(stack, "Api", {
defaultFunctionProps: { vpc },
routes: {
"GET /": "src/lambda.main",
},
});

Adding routes to an existing HTTP API

import { HttpApi } from 'aws-cdk-lib/aws-apigatewayv2';

new Api(stack, "Api", {
cdk: {
httpApi: HttpApi.fromHttpApiAttributes(stack, "ExistingApi", {
httpApiId,
}),
},
routes: {
"GET /new": "src/lambda.main",
},
});

Adding subscribers to an existing SNS Topic

import * as sns from "aws-cdk-lib/aws-sns";

new Topic(stack, "Topic", {
subscribers: {
subscriber1: "src/subscriber1.main",
subscriber2: "src/subscriber2.main",
},
cdk: {
topic: sns.Topic.fromTopicArn(stack, "ExistingTopic", topicArn),
},
});

Limitations

In general, most SST constructs support using existing AWS resources. You can find examples in the doc for the construct. However, the following AWS limitations should be noted:

  • Cognito does not support configuring triggers to existing Cognito User Pools.

In addition, when you reference a resource, you cannot modify the resource or configure it. You are using it as-is. To have full control over an existing resource, you should look at migrating it over to SST.


Migrate resources

To use SST to manage an existing resource, you need to migrate it over. It is a manual process but it gives you full control over the resource.

  1. Orphan the resource from the original stack using a DeletionPolicy: Retain. This keeps the resource when the stack is deleted.
  2. Mirror the resource in your SST stacks code and compile the CloudFormation template by running sst build.
  3. Pass the compiled CloudFormation template into the CloudFormation import resources process for the stack (CloudFormation console > Stack > Stack actions > Import resources into stack). You'll need to remove any meta information from the CloudFormation template, leaving only the resources you are importing. Otherwise, the import will fail because other resources are being updated.
  4. Provide a unique identifier or physical ID during the import process. For example, when importing an S3 bucket, use the bucket name as the identifier.
  5. If you have done everything correctly, it'll import the resources into the stack using the logical ID generated by SST. Running a sst diff should report no changes, indicating that the resource is now part of the SST stack.
  6. Finally, run a stack drift check (Stack actions > Detect drift) to ensure all configurations are synchronized.

From now on the resource can be modified in your SST app.


Orphan resources

Sometimes while deploying you might run into errors that look like this.

"Resource of type 'AWS::DynamoDB::Table' with identifier 'some-stack-name-table-name' already exists."

These usually happens because of a combination of the default removal policy and an accidental change of the stack name. Recall that stacks are not removed when you take them out of your stacks code and certain stateful resources are not removed by default.

This creates a case of orphaned resources. For CloudFormation to use these resources as a part of the stack it needs the following to be true:

  1. The stack name of the deployment needs to be the same as the currently orphaned resource.
  2. The logical ID in the CloudFormation template for the resource is the same.
  3. The name of the resource also has to be the same.

Say you have a bucket.

stack/MyStack.ts
new Bucket(stack, "bucket");

The logical ID of this resource is generated based on the name of the stage it's being deployed to, the stack name, and the name provided here.

You can force CDK to use a specific ID, instead of letting SST generate it by passing it in as a part of the cdk prop.

stack/MyStack.ts
new Bucket(stack, "adminFiles", {
cdk: { id: "bucket" },
});

You can check the logical ID of a resource by running sst build and looking at the .sst/dist directory for the generated CloudFormation templates.