Skip to content

feat: Add flag for import existing resources#8114

Open
electrofelix wants to merge 11 commits intoaws:developfrom
electrofelix:support-import-existing-resources
Open

feat: Add flag for import existing resources#8114
electrofelix wants to merge 11 commits intoaws:developfrom
electrofelix:support-import-existing-resources

Conversation

@electrofelix
Copy link
Copy Markdown

Pass through option for importing existing resources which allows using
Retain for DeletionPolicy on resources to avoid removal on data
resources if stack needs to be deleted and recreated.

Fixes: #1699

@electrofelix electrofelix requested a review from a team as a code owner June 18, 2025 10:29
@github-actions github-actions bot added area/deploy sam deploy command area/sync sam sync command labels Jun 18, 2025
Pass through option for importing existing resources which allows using
Retain for DeletionPolicy on resources to avoid removal on data
resources if stack needs to be deleted and recreated.

Fixes: aws#1699
@electrofelix electrofelix force-pushed the support-import-existing-resources branch from 161e41b to dcc51f7 Compare June 18, 2025 10:30
@github-actions github-actions bot added pr/external stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at. labels Jun 18, 2025
@electrofelix
Copy link
Copy Markdown
Author

Main use case I have for this is that sometimes the stack gets into a funk and needs to be deleted and recreated, however if there are data resources in the same application stack specifying DeletionPolicy: Retain prevents re-deploying via sam.

The workarounds are to move data resources out to separate stacks, which can work for event buses and DBs, but is a pain when working with queues. End up needing to pass a multitude of resource identifiers in via parameters.

Using this approach, I can mark queues, event buses (+ archives), and any DBs to be retained and be able to teardown and redeploy without dropping messages/events/data, and at the same time avoid needing a complex orchastrated deployment spanning multiple repositories or needing complex CI jobs to handle what stacks to delete vs deploy.

Note: when testing I noticed CloudFormation doesn't handle automatically re-importing AWS::Logs::LogGroup resources particular well.

I have a fairly rough script that does the same as this code the AWS CLI, which encountered the same issue suggesting there may be a bug in Cloudformation. Appears it fails to remove some information from resources associated with the original stack meaning they still appear to be part of a stack and it refuses to import. Solving this in Cloudformation would automatically fix it for this feature as well.

It would be nicer for it to be available built in rather than needing to run the script sometimes:

TEMP_TEMPLATE=$(mktemp -t template.yaml) || exit 1

stack_name=$(toml get --toml-path ${configName} ${sectionName}.global.parameters.stack_name)
capabilities=$(toml get --toml-path ${configName} ${sectionName}.global.parameters.capabilities)
parameter_overrides=$(toml get --toml-path ${configName} ${sectionName}.global.parameters.parameter_overrides | sed -e 's/^\[//g; s/\]$//g')
params=""
for param in ${parameter_overrides}
do
    param=${param%,}
    param=${param%\'}
    param=${param#\'}
    key=${param%%=*}
    value=${param#*=}
    params="${params}${params:+ }ParameterKey=${key},ParameterValue=${value}"
done

# make sure all aws commands use the requested profile
export AWS_PROFILE=$profile

echo "Packaging stack and then using cloudformation to import existing using config file: '$configName' ..."
command="sam package --config-file $configName --output-template-file ${TEMP_TEMPLATE}"
echo "Executing $command"
$command


command="aws cloudformation describe-stacks --stack-name "${stack_name}""
echo "Checking if stack exists"
echo "Executing $command"
if ! $command >/dev/null 2>&1; then
    change_set_type=CREATE
    stack_complete_command=stack-create-complete
else
    change_set_type=UPDATE
    stack_complete_command=stack-update-complete
fi

change_set_name="change-set-$(date +%s)"
command="aws cloudformation create-change-set --stack-name ${stack_name} --change-set-type ${change_set_type} \
 --change-set-name ${change_set_name} --template-body "file://${TEMP_TEMPLATE}" --capabilities ${capabilities} \
 --parameters ${params} --import-existing-resources"
echo "Executing $command"
$command

sleep 2
echo "Waiting for changeset to be complete"
command="aws cloudformation wait change-set-create-complete --stack-name ${stack_name} --change-set-name ${change_set_name}"
echo "Executing $command"
$command
if [[ $? -ne 0 ]]; then
    failure_reason=$(aws cloudformation describe-change-set --stack-name ${stack_name} --change-set-name ${change_set_name} --query "StatusReason" --output text)
    if [[ "${failure_reason}" == *"The submitted information didn't contain changes."* ]] || [[ "${failure_reason}" == *"No updates are to be performed."* ]]; then
        echo "No changes detected, exiting"
        exit 0
    else
        echo "Changeset failed to create: ${failure_reason}"
        exit 1
    fi
fi
exit 0

@vicheey
Copy link
Copy Markdown
Contributor

vicheey commented Jun 20, 2025

Thank you for your contribution, @electrofelix. The current code implementation is clear and concise. We just need to verify both forward and backward deployment scenarios that this update would not leave a stack in an unrecoverable state if deployment fail. Would you be able to enhance this further by adding integration tests to cover your specific deployment use case as well?

@electrofelix
Copy link
Copy Markdown
Author

@vicheey sure, I presume it's just follow the existing integration tests such as https://github.com/aws/aws-sam-cli/blob/develop/tests/integration/deploy/test_deploy_command.py#L1542-L1593 going with the following steps:

  • deploy template with some resources marked retain (eventbus + archive, sqs, & dynamodb)
  • delete stack
  • re-deploy same template and assert expected resources have import in deploy_process_execute.stdout.strip()

Presumably some work around tear will be needed for this scenario? Extend add_left_over_resources_from_stack to cover the additional resource types added?

Is this better as a separate test file to cover the import functionality under the deploy tests?

Might be a few weeks before I will get back to updating

@vicheey
Copy link
Copy Markdown
Contributor

vicheey commented Aug 18, 2025

Do you mind help with the make pr failure?

@electrofelix
Copy link
Copy Markdown
Author

Do you mind help with the make pr failure?

Not at all, just delayed getting back to it

@c-ameron
Copy link
Copy Markdown

Thanks so much for this @electrofelix !

@vicheey is this up for consideration? This would help me a lot move from terraform to SAM for some resources.

Thanks!

@vicheey
Copy link
Copy Markdown
Contributor

vicheey commented Mar 27, 2026

Hi @electrofelix,

I've pushed a small follow-up commit on top of your work:

  • Fixed a minor typo in the --import-existing-resources help text (missing word "resources")
  • Added an integration test that creates a pre-existing SSM parameter, deploys with --import-existing-resources, and verifies the changeset shows the Import action
  • Added the import_existing_resources parameter to the integration test base helper
    CI is running now. Will follow up once results are in.

@c-ameron,
We're working on getting this merged. I'll need another team member to review and hopefully get this out soon.
Stay tuned!

vicheey and others added 3 commits March 27, 2026 13:04
…gration test

  - Switch from SNS (SCP-blocked) to CloudWatch LogGroup
  - Use static name in template (required for CFN auto-import)
  - Generate template at test time for unique names per run
  - Remove unused aws-sns-topic-import.yaml template

  Auto-import requires a settable primaryIdentifier (not read-only).
  AWS::Logs::LogGroup (LogGroupName) meets this requirement, unlike
  AWS::SQS::Queue (QueueUrl) or AWS::SNS::Topic \Ref: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/import-resources-automatically.html
@vicheey
Copy link
Copy Markdown
Contributor

vicheey commented Mar 27, 2026

"default",
False,
True,
False,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a test for reading this param from the samconfig?

Copy link
Copy Markdown
Contributor

@reedham-aws reedham-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the idea of the PR is solid, I think there's a hidden issue with how this will interact with CloudFormation. In the past, the reason we've had difficulty implementing this is because the CloudFormation import feature does not support AWS::Serverless resources. This might have changed, but I think it's because the import step is happening before the transform is server-side. The reason the integration tests are passing is because it's not using a AWS::Serverless resource.

We do this resource import in the AWS Toolkit, but when we do it there we actually deploy the stack as raw CloudFormation before translating it back to SAM. I don't think that would work well in this case considering we're already coming with a user-defined template.

That being said, I think there needs to be changes to warn that this won't work or to not allow it all for serverless resources.

Comment on lines +12 to +21
TEMPLATE = """\
AWSTemplateFormatVersion: '2010-09-09'
Description: Template for testing --import-existing-resources flag.
Resources:
TestLogGroup:
DeletionPolicy: Retain
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: {log_group_name}
"""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in other places in the code, we don't have the template inline, but rather in tests/integration/testdata

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/deploy sam deploy command area/sync sam sync command pr/external stage/needs-triage Automatically applied to new issues and PRs, indicating they haven't been looked at.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

import existing resources into new stack

5 participants