aws / aws/aws-cdk

CfnInclude: Support lazy mappings, allow more user control

Open
#23,143 7 comments 1 reaction 0 assignees View on GitHub
@aws-cdk/cloudformation-include @aws-cdk/core effort/medium feature-request p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the feature

I have a template I am importing via CfnInclude with many mappings. I get a lot of the following errors:

```
[Info at /JobExecutor-626488381203-us-east-1/Import/ImportIMP0/$Mappings/PrefixListId] Consider making this CfnMapping a lazy mapping by providing `lazy: true`: either no findInMap was called or every findInMap could be immediately resolved without using Fn::FindInMap
```

I'd like an option in CfnInclude that would allow me to create lazy mappings.

But more than that, I'd like to have a way to resolve ANY token created by CfnInclude myself, via an interface.

### Use Case

I'm always frustrated when...

1. I'm importing a template using CfnInclude and there is an ImportValue that I'd like to replace. As is, I need to create my own Bootstrap stack that exports the value so I can use this template in another account. Pre-processing the template to remove the ImportValue is not really an option.
2. I'm importing a template using CfnInclude and there is a custom token, like "{{IMAGE}}" to specify an ECR image link, and Id like to resolve that without having to pre-process the template. Currently, pre-processing requires reading the template in, replacing the custom tokens with my own IResolvable, then writing it out to a TEMP file. I have to do this because CfnInclude requires a file name, not template JSON).
3. I'd like to resolve mappings with a call to a function in my Stack class instead of using the mapping in the template.
4. I'd like to resolve Fn::If statements based on context.

### Proposed Solution

An interface based on the Fn statics that can be passed to CfnInclude that allows me to resolve tokens myself (e.g. by returning my own IResolvable or just a value).

Might be something like this:
```
// In the below, context parameter would be the path to the Fn in the template
// Context may not be necessary, but it would be nice.
interface FnResolver {
importValue(sharedValueToImport: string, context: string[]): string
// You could just pass any unknown token to ref, and then the customToken functions below would not be necessary.
ref(logicalName: string, context: string[]): string
findInMap(mapName: string, topLevelKey: string, secondLevelKey: string): string

get customTokens() : string[] // I can return a list of custom tokens here
resolveCustomToken(customToken: string, context: string[])
}
```

### Other Information

My current solutions are:

1. Alter the template before I import it. But that makes my import tool non-generic.
2. Add a bootstrap stack to export values needed by the template I wish to import.

### Acknowledgements

- [ ] I may be able to implement this feature request
- [ ] This feature might incur a breaking change

### CDK version used

2.41.0

### Environment details (OS name and version, etc.)

AL2

Contributor guide

Open the contributing guide

Research direction

Start with the CfnInclude implementation and the Fn statics referenced in the proposal, then trace how imported mappings, ImportValue, Ref, custom tokens, and Fn::If are currently handled. Define an interface that supports caller-controlled token resolution and lazy mappings. Done means the listed use cases are supported without preprocessing templates or bootstrap exports.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
cloud, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.