vscode-yaml
vscode-yaml copied to clipboard
Cloudformation template: result of !Join fails validation for string
Given the below setup, my cloudformation template is failing validation, as it's (correctly) stating the Name
property below should be a string, but I'm otherwise properly using the !Join
function, which should return a string.
Here's a simplified version of my cloudformation template, to demonstrate failure
mytemplate.cf.yml
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyWebAppUrl:
Type: "AWS::Route53::RecordSet"
Properties:
Type: A
Name: !Join [".", ["StringA", "StringB"]]
HostedZoneId: "FAKE_ZONE_ID"
my settings.json
{
"yaml.customTags": [
"!Join sequence"
],
"yaml.format.enable": true
}
validation failure
{
"severity": 1,
"range": {
"start": {
"line": 22,
"character": 18
},
"end": {
"line": 22,
"character": 47
}
},
"message": "Incorrect type. Expected \"string\"."
}
here's what I suspect is the AST:
[
{
"name": "AWSTemplateFormatVersion",
"kind": 15,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 36
}
}
}
},
{
"name": "Resources",
"kind": 2,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 2,
"character": 0
},
"end": {
"line": 8,
"character": 34
}
}
}
},
{
"name": "MyWebAppUrl",
"kind": 2,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 3,
"character": 2
},
"end": {
"line": 8,
"character": 34
}
}
},
"containerName": "Resources"
},
{
"name": "Type",
"kind": 15,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 4,
"character": 4
},
"end": {
"line": 4,
"character": 35
}
}
},
"containerName": "Resources.MyWebAppUrl"
},
{
"name": "Properties",
"kind": 2,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 5,
"character": 4
},
"end": {
"line": 8,
"character": 34
}
}
},
"containerName": "Resources.MyWebAppUrl"
},
{
"name": "Type",
"kind": 15,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 6,
"character": 6
},
"end": {
"line": 6,
"character": 13
}
}
},
"containerName": "Resources.MyWebAppUrl.Properties"
},
{
"name": "Name",
"kind": 18,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 7,
"character": 6
},
"end": {
"line": 7,
"character": 47
}
}
},
"containerName": "Resources.MyWebAppUrl.Properties"
},
{
"name": "HostedZoneId",
"kind": 15,
"location": {
"uri": "file:///Users/myname/dev/myproject/ops/.cfn/mytemplate.cf.yml",
"range": {
"start": {
"line": 8,
"character": 6
},
"end": {
"line": 8,
"character": 34
}
}
},
"containerName": "Resources.MyWebAppUrl.Properties"
}
]
After digging into the code a bit, it seems that the problem here is that !Join
actually transforms a sequence
into a scalar
, but that concept doesn't appear to be supported by the custom tag parsing mechanism. As such, I'd expect that cloudformation's !Split
function might be problematic for the same reasons (although in the opposite direction).
Perhaps the problem might be solved by adding another optional token to the custom tag to indicate the return type (if it differs from the input type).
Something like !Join sequence -> scalar
could work, and with that approach you could also have !Split -> sequence
, where it would apply the convention of scalar
being the default node type (thus omitted in this example), and sequence
being the actual type of the transformed node.
It is crucial to fix because many other extensions have vscode-yaml as dependency e.g. Kubernetes, Atlassian for VSCode etc. So when you want to use vscode-cfn-lint you have to uninstall them and vscode-yaml.
I have the same problem with cloudformation script and !Join.
If it helps I notice I don't get the issue on a S3 WebsiteBucketPolicy Resource, but I do get the !Join not a string issue on a CloudFront Distribution Properties Origins DomainName.
Resources:
S3Bucket:
WebsiteBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Statement:
- Sid: PublicReadForGetBucketObjects
Effect: Allow
Principal: '*'
Action: s3:GetObject
Resource: !Join [ '', ['arn:aws:s3:::', !Ref S3Bucket, /*] ]
vs
CFDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Comment: Cloudfront Distribution pointing to S3 Bucket
Origins:
- DomainName: !Join [ '', [ !Ref S3Bucket, '.s3.amazonaws.com' ] ] # <-- Error Incorrect type, expected string
I'm experiencing this same issue when working with yaml template. I had to turn off yaml validation in config.json to get rid of it. My config.json settings:
"yaml.customTags": [
"!And scalar",
"!And mapping",
"!And sequence",
"!If scalar",
"!If mapping",
"!If sequence",
"!Not scalar",
"!Not mapping",
"!Not sequence",
"!Equals scalar",
"!Equals mapping",
"!Equals sequence",
"!Or scalar",
"!Or mapping",
"!Or sequence",
"!FindInMap scalar",
"!FindInMap mappping",
"!FindInMap sequence",
"!Base64 scalar",
"!Base64 mapping",
"!Base64 sequence",
"!Cidr scalar",
"!Cidr mapping",
"!Cidr sequence",
"!Ref scalar",
"!Ref mapping",
"!Ref sequence",
"!Sub scalar",
"!Sub mapping",
"!Sub sequence",
"!GetAtt scalar",
"!GetAtt mapping",
"!GetAtt sequence",
"!GetAZs scalar",
"!GetAZs mapping",
"!GetAZs sequence",
"!ImportValue scalar",
"!ImportValue mapping",
"!ImportValue sequence",
"!Select scalar",
"!Select mapping",
"!Select sequence",
"!Split scalar",
"!Split mapping",
"!Split sequence",
"!Join scalar",
"!Join mapping",
"!Join sequence",
"!And",
"!If",
"!Not",
"!Equals",
"!Or",
"!FindInMap",
"!Base64",
"!Join",
"!Cidr",
"!Ref",
"!Sub",
"!GetAtt",
"!GetAZs",
"!ImportValue",
"!Select",
"!Split"
],
"yaml.format.enable": true,
"yaml.validate": false,
@jrnail23 were you ever able to resolve this issue or find a suitable workaround? I am facing the same thing today. Thanks.
no, @pflugs30, I wasn't. We've since moved on to other ways of working with CloudFormation (building up the config using JS, rather than using YAML).
Sad that this got closed b/c this is still an issue.
@samuelms1 this is not closed. I just hasn't been touched in a while.
@samuelms1 this is not closed. I just hasn't been touched in a while.
Any new update?
This is still an issue:
This is as well:
LogGroupName: !Join ["/", ["/aws/pipeline", !Ref "AWS::StackName"]]
Mismo problema: La unica fue deshabilitar la valiacion... busque por horas y nada funciono!
AutorizerApiEntityManagements0001: Type: "AWS::ApiGateway::Authorizer" Properties: IdentitySource: method.request.header.Authorization Name: !ImportValue "Stack-AWS-Cognito-UserPool-UAT-UserPool" RestApiId: !Ref ApiEntityManagements0001 Type: "COGNITO_USER_POOLS" ProviderARNs: - !Join - "" - - !Sub "arn:aws:cognito-idp:us-east-1:${AWS::AccountId}:userpool/" - !ImportValue "Stack-AWS-Cognito-UserPool-UAT-UserPool"