Skip to content

RFC 52: Support for importing existing resources into a CDK stack#392

Merged
rix0rrr merged 3 commits intoaws:masterfrom
tomas-mazak:0052-resource-importing-support
Feb 16, 2022
Merged

RFC 52: Support for importing existing resources into a CDK stack#392
rix0rrr merged 3 commits intoaws:masterfrom
tomas-mazak:0052-resource-importing-support

Conversation

@tomas-mazak
Copy link
Copy Markdown
Contributor

This is a request for comments about "Support importing resources". See #52 for
additional details.

Rendered version

APIs are signed off by @rix0rrr .


By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache-2.0 license

@rix0rrr rix0rrr mentioned this pull request Dec 20, 2021
7 tasks
@tomas-mazak tomas-mazak force-pushed the 0052-resource-importing-support branch from 3afafaa to 3aee196 Compare December 20, 2021 13:18
Copy link
Copy Markdown
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

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

I love this! Thanks for your thoroughness here!

being created). Furthermore, CDK can't automatically determine what
resources to import and what to create. For this to behave correctly, the
solution will prompt user for each resource - whether it should be imported
or not. If not, the resource is removed from the template before creating
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.

Just thinking: the other way around might be easier.

Why don't we download the current template from the Stack, and then add the resources we're trying to import? Seems safer than dropping resources from the target template.

So the workflow looks a bit like:

  • Take the new template, identify candidate resources to import by looking at cdk diff
  • Obtain the import map by a combination of heuristics and user input. Include the resource definitions of the resources in the import map

Then:

  • Download the old template
  • Add the resources from the previous step to the template
  • (Potentially: check the integrity of the template)
  • Do an IMPORT update with the import map

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 wonder what we're going to do about dependencies on non-imported resources here... but I also don't have a good intuition for where and how those are going to crop up. I guess the best path forward is roll this feature out and seeing where it's going to creak 😅

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I am happy to revert the logic here, although it should produce exactly the same template, as:

  • we already download the current template and perform the diff
  • for any modification (besides CDKMetadata that we copy over) we fail so non-addition difference will never get to the import action
  • for any newly defined resource, we decide whether it is going to be imported (we keep it) or not (we remove it) ... which would be the same other way around: if it's going to be imported we add it, otherwise we skip it

But now thinking about it, the above applies only to the Resources section of the template. I will double-check what if Parameters or Outputs change - this can add some more complexity. Imagine a resource properties of a resource-to-be-imported reference a parameter that did not exist in the previous template.

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.

Exactly. It just feels to me that taking a known-good template and doing a very concrete set of operations to it that we thought about beforehand is going to be safer than taking an unknown, new template, and hoping we remember to take out all the unintended modifications.

On the other hand, some Parameters and Mappings might be necessary to support the new resource?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

rephrased to reflect this

the resource, causing the stack to be drifted. This can be left to the user
to handle (manually checking the config prior to the import or running drift
detection after the import), but for convenience, this solution uses
CloudControl API to look up the physical resource and validate its configuration
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.

This is worth calling out in the above section as well.

I assume this happens before doing the actual import?

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 wonder if running a drift detection afterwards might be good enough for a start?

The CCAPI will require us to do a JSON diff, and I'm not sure it's complete enough. Have you experimented with this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have experimented with this and it works quite nicely. The greatest benefit is that CCAPI uses the same resource type nomenclature as CloudFormation so we can simply pass the type to the API call. There are two issues I am still looking at though:

Firstly, I need to understand how the "import identifiers" of a resource relate to "primary" and "secondary" indentifiers that CCAPI uses. While for CFN import, explicit identifier key has to be provided (e.g. BucketName for S3 Bucket, or VpcId for VPC), with CCAPI call you always provide Identifier key that has a value based on the type - it can be either primary or secondary identifier. My plan is to get all resource schemas from CFN resource catalog, extract primary/secondary identifiers info, then run get-template-summary for a template containing all resource types and do some analysis on that. It will be somewhat time consuming though, not sure when I can get to that.

Secondly, CCAPI returns all resource properties, but some of them are not mandatory in CFN templates and if not specified, will be set to default values. So in order to do the comparison correctly, I would need to know the default values of all optional properties of all resources, didn't find a way to do that yet (in best-effort approach, we could only compare properties explicitly set in CFN).

I agree with your suggestion: If it is OK to get this merged without this extra validation, let's do it and either run drift detection automatically or display a post import message to tell user to run it. And leave the CCAPI extra validation for the next iteration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For now, I have updated the RFC to omit the CCAPI validations and I have added a "Possible future expansions" section with some thoughts on how to leverage CCAPI to provide a better user experience in future - perhaps beyond simple validations.

in the main `aws-cdk` repository that is being iteratively expanded with the
proposed features. Once the approach is agreed and the agreed solution is
implemented, the PR will be moved from "Draft" to "Open" status and CDK team
member code review will be requested. Once all approved, the PR will be ready
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.

Does that mean everything is going to be implemented in 1 big PR?

Is there a logical order in which we can deliver things incrementally?

What's the aftercare/future extensions story?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure about the lifecycle of the code post-merge, I guess that is for you and your team to decide - I can't guarantee I will be able to support this afterwards, although I will certainly watch the space for some time as I will be interested how is my so-far-biggest contribution doing :)

It might make sense to split the feature into multiple stages (and in fact, I believe the first stage might be pretty much ready now), I would take your guidance on how to split it.

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'm thinking we slice the elephant here. We'll say something like:

  • First we implement interactive import with current credentials
  • Then noninteractive import
  • Then support using the lookup role
  • Then support CCAPI validations

I see you put some in the extensions piece, that's a good place too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

modified as suggested


First, identify what properties must be looked up/asked for for each resource to
be imported. This information can be obtained by executing CloudFormation API
action `GetTemplateSummary` with the new template. The action returns the
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.

Does this require additional permissions for the cdk-deploy role in the bootstrap stack? Or are we going to use the cdk-lookup role for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's a very good point. Not sure but I will have a look

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

So here I am actually using an existing SdkProvider that is initialized in the main file of CDK CLI (same as the cdk deploy command is using). If I understand the code right, it will only ever use the AWS CLI credentials - it doesn't seem to be assuming any role from the bootstrap stack or so:

https://github.com/aws/aws-cdk/blob/master/packages/aws-cdk/bin/cdk.ts#L212-L219

So I don't think the bootstrap stack needs to be updated, am I correct?

Copy link
Copy Markdown
Contributor

@rix0rrr rix0rrr Jan 4, 2022

Choose a reason for hiding this comment

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

It probably will eventually, but for now I suppose the trivial solution will do.

Can you add a note in the RFC (execution plan probably) that we're going to initially support "current" credentials, and later on support using bootstrapped roles?

(For the part where we determine the identifiers to be used, so also when --create-resource-mapping is used. For the part where we do the actual import, we should always be using the CDK deploy role if available)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

1. make the original IaC orchestrator "abandon" the resource - remove it
from its orchestration without physically removing the resource
2. "import" the resource in a CDK stack
- **App refactoring:** The team already uses CDK but a major refactor is needed
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.

This is good to identify as a use case. I like that you thought about it.

But in practice, we're going to have (in AWS) 20+ copies of every app deployed... so if you really want to refactor something across 20 copies, we're going to need more automation to take care of this.

In any case -- not for this RFC, we will deal with that when we get to it! Perhaps people will be clever and build something on top of the structured input file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added in the "possible future expansions" section

might still be needed.

It might be considered to release such convenience features iteratively
per resource type, beginning with the most frequently used types.
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 mass refactoring support (across multiple stacks) would be a great extension we could write down here.

It's going to require some additional tooling I think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

rix0rrr
rix0rrr previously requested changes Jan 4, 2022
Copy link
Copy Markdown
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

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

This thing is as good as done! I like it. Some small changes and then we can ship it. Thanks!

@mergify mergify bot dismissed rix0rrr’s stale review February 14, 2022 10:13

Pull request has been modified.

Copy link
Copy Markdown
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

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

I like it! Going to merge this.

Copy link
Copy Markdown
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

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

But then I mis-clicked

@rix0rrr rix0rrr merged commit fca5210 into aws:master Feb 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants