cfn-lint
cfn-lint copied to clipboard
cfn-lint doesn't validate second level key name of a FindInMap that is resolved by a nested FindInMap
cfn-lint version: 0.52.0
cfn-lint doesn't catch the following error:
Mappings:
Mapping:
Key:
BucketNameKeyName: "" # should be BucketName
BucketName: Bucket
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !FindInMap
- Mapping
- Key
- !FindInMap
- Mapping
- Key
- BucketNameKeyName
But the validate-template
API does:
Template error: Unable to get mapping for Mapping::Key::
I was surprised that the template passed cfn-lint but failed validate-template
. Is this something that cfn-lint could validate?
We use this syntax so that we can do something like the following, which is to have a mapping with an extra dimension based on deployment names within an account:
Parameters:
DeploymentName:
Type: String
Mappings:
AccountMap:
"000000000001":
PrimaryDeploymentBucketName: Account1PrimaryBucket
SecondaryDeploymentBucketName: Account1SecondaryBucket
TertiaryDeploymentBucketName: Account1TertiaryBucket
"000000000002":
PrimaryDeploymentBucketName: Account2PrimaryBucket
SecondaryDeploymentBucketName: Account2SecondaryBucket
TertiaryDeploymentBucketName: Account2TertiaryBucket
DeploymentMap:
Primary:
BucketNameAccountMapKey: PrimaryDeploymentBucketName
Secondary:
BucketNameAccountMapKey: SecondaryDeploymentBucketName
Tertiary:
BucketNameAccountMapKey: TertiaryDeploymentBucketName
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !FindInMap
- AccountMap
- !Ref AWS::AccountId
- !FindInMap
- DeploymentMap
- !Ref DeploymentName
- BucketNameAccountMapKey
Just to make sure I have this correct. In this scenario we aren't finding the AWS::AccountId
in the AccountMap
mapping. The one issue we have currently is that cfn-lint is completely offline validation of the template. We don't associate to an account to resolve intrinsic function values. This is done for many reasons... the stack could be used for a StackSet or be put into a code repository and deployed in pipelines to different accounts the user doesn't have configured locally.
I've thought about this a few times and if there is a scalable way to do this testing. If for instance you provide a list of AccountIDs this template could be deployed to so we can validate that the mappings exist for each one. For AWS::Region we could resolve the regions parameters to cfn-lint.
I don't think the issue here is that cfn-lint
can't find AWS::AccountId
in the AccountMap
. The second code example that uses AWS::AccountId
is just an example of how we use this functionality.
The first code example shows the issue. The nested !FindInMap
resolves to ""
:
!FindInMap
- Mapping
- Key
- BucketNameKeyName
The parent !FindInMap
uses the resolved value:
!FindInMap
- Mapping
- Key
- ""
""
isn't a valid key name within the mapping, so this is an error.
However, I do agree with you, it'd be useful if a list of account IDs could be provided similarly to how a list of regions can be provided.