I'm getting this:
2018-04-22 00:46:35,869 - cfnlint - DEBUG - Get resources from template...
Traceback (most recent call last):
File "/usr/local/bin/cfn-lint", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python3.6/dist-packages/cfnlint/__main__.py", line 157, in main
matches.extend(runner.run())
File "/usr/local/lib/python3.6/dist-packages/cfnlint/__init__.py", line 560, in run
self.filename, self.cfn, self.ignore_checks))
File "/usr/local/lib/python3.6/dist-packages/cfnlint/__init__.py", line 107, in run
matches.extend(rule.matchall(filename, cfn))
File "/usr/local/lib/python3.6/dist-packages/cfnlint/__init__.py", line 55, in matchall
results = self.match(cfn) # pylint: disable=E1102
File "/usr/local/lib/python3.6/dist-packages/cfnlint/rules/resources/properties/Properties.py", line 195, in match
resourcetype, resourcename, path, True))
File "/usr/local/lib/python3.6/dist-packages/cfnlint/rules/resources/properties/Properties.py", line 131, in propertycheck
parenttype, resourcename, arrproppath, False))
File "/usr/local/lib/python3.6/dist-packages/cfnlint/rules/resources/properties/Properties.py", line 172, in propertycheck
resourcename, proppath, False))
File "/usr/local/lib/python3.6/dist-packages/cfnlint/rules/resources/properties/Properties.py", line 111, in propertycheck
if prop not in resourcespec:
TypeError: unhashable type: 'dict_node'
The template deploys just fine.
Thanks @trondhindenes . Looking into it. I may need a few more details if I hit a wall.
My current theory is we are running into a list/array when we weren't expecting one. Could be a list of lists. The result is that when we do the for loop we are doing it on an array instead of a dict. If I switch it to items to be specific we will still get an error. Not sure how we are getting an array there thinking through some additional scenarios.
Let me know if you want me to post the template!
@trondhindenes that would be fantastic.
No problem, here's the unmodified one:
Parameters:
VpcId:
Type: String
RdsSubnets:
Type: "List<AWS::EC2::Subnet::Id>"
DbIdentifier:
Type: String
MasterUserName:
Type: String
MasterPassword:
Type: String
BackupRestoreIamRole:
Type: String
DoUseMultiAz:
Description: Use multi-AZ
Default: "false"
Type: String
AllowedValues: ["true", "false"]
Environment:
Type: String
EnvironmentId:
Type: String
StorageSize:
Type: Number
DBInstanceClass:
Type: String
SourceAllowedCidr:
Type: String
Conditions:
BoolDoUseMultiAz:
!Equals [true, !Ref DoUseMultiAz]
Resources:
DBEC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription:
Ref: DbIdentifier
VpcId:
Ref: VpcId
SecurityGroupIngress:
-
CidrIp:
Ref: SourceAllowedCidr
Description: Allow traffic from current aws network
IpProtocol: tcp
FromPort: 1433
ToPort: 1433
-
CidrIp: "10.40.0.0/16"
Description: Allow traffic from in-clients1 and in-clients2
IpProtocol: tcp
FromPort: 1433
ToPort: 1433
-
CidrIp: "10.60.24.0/24"
Description: Allow traffic from in-clients3
IpProtocol: tcp
FromPort: 1433
ToPort: 1433
-
CidrIp: "10.140.103.0/24"
Description: Allow traffic from in-vpn
IpProtocol: tcp
FromPort: 1433
ToPort: 1433
-
CidrIp: "10.65.109.0/24"
Description: Allow traffic from tc-vpn
IpProtocol: tcp
FromPort: 1433
ToPort: 1433
-
CidrIp: "10.245.8.0/21"
Description: Allow traffic from aws-euw1-prod1
IpProtocol: tcp
FromPort: 1433
ToPort: 1433
RdsSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupDescription:
Ref: DbIdentifier
DBSubnetGroupName:
Ref: DbIdentifier
SubnetIds:
Ref: RdsSubnets
OptionGroup:
Type: "AWS::RDS::OptionGroup"
Properties:
EngineName: sqlserver-se
MajorEngineVersion: '14.00'
OptionGroupDescription:
Ref: DbIdentifier
OptionConfigurations:
- OptionName: SQLSERVER_BACKUP_RESTORE
OptionSettings:
- Name: IAM_ROLE_ARN
Value:
Ref: BackupRestoreIamRole
DBInstance:
Type: AWS::RDS::DBInstance
DependsOn: OptionGroup
Properties:
DBInstanceIdentifier:
Ref: DbIdentifier
DBSubnetGroupName:
Ref: DbIdentifier
OptionGroupName:
Ref: OptionGroup
Engine: sqlserver-se
EngineVersion: '14.00.3015.40.v1'
MultiAZ: !If [BoolDoUseMultiAz, true, false]
StorageEncrypted: true
StorageType: gp2
MasterUsername:
Ref: MasterUserName
DBInstanceClass:
Ref: DBInstanceClass
AllocatedStorage:
Ref: StorageSize
MasterUserPassword:
Ref: MasterPassword
LicenseModel: license-included
VPCSecurityGroups:
- !GetAtt DBEC2SecurityGroup.GroupId
PreferredBackupWindow: 02:00-03:00
PreferredMaintenanceWindow: Tue:03:00-Tue:05:00
AutoMinorVersionUpgrade: false
Tags:
- Key: environment
Value:
Ref: Environment
- Key: environmentid
Value:
Ref: EnvironmentId
ok this helps a lot. It looks like to me the spec file doesn't match the documentation. Let me see what I can do on my side.
Documentation: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-optiongroup-optionconfigurations.html
Spec File:
"OptionSettings": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-optiongroup-optionconfigurations.html#cfn-rds-optiongroup-optionconfigurations-optionsettings",
"Required": false,
"Type": "OptionSetting",
"UpdateType": "Mutable"
},
I think this should be
"OptionSettings": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-optiongroup-optionconfigurations.html#cfn-rds-optiongroup-optionconfigurations-optionsettings",
"Required": false,
"Type": "List",
"ItemType": "OptionSetting",
"UpdateType": "Mutable"
},
At the very least I'm working on a change now to more gracefully catch this issue going forward.
awesome!
Release 0.0.8 should capture this error and not fail. I'm torn on closing this issue until the CloudFormation Spec is updated to fix it because part of this issue still does exist.
I'd prefer keeping the issue open untill the "core" issue is solved.
Minor off-track: Do the Spec file actually do something under the hood? Or is it an automated (documentation) feature?
Got this issue with version 0.0.10 now:
RDSOptionGroup:
Type: "AWS::RDS::OptionGroup"
Properties:
EngineName: "oracle-se2"
MajorEngineVersion: "12.1"
OptionGroupDescription: "SSL and Timezone options"
OptionConfigurations:
- OptionName: "SSL"
VpcSecurityGroupMemberships:
- !Ref "PrivateSecurityGroup"
- OptionName: "Timezone"
OptionSettings:
- Name: "TIME_ZONE"
Value: "Europe/Amsterdam"
Error:
E3002 Expecting an object at Resources/RDSOptionGroup/Properties/OptionConfigurations/1/OptionSettings
@cmmeyer looks like the spec is off on this one too.
OptionSettings
The settings for this option.
Required: No
Type: List of Amazon RDS OptionGroup OptionSetting
Looks like it doesn't match.
"OptionSettings": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-optiongroup-optionconfigurations.html#cfn-rds-optiongroup-optionconfigurations-optionsettings",
"Required": false,
"Type": "OptionSetting",
"UpdateType": "Mutable"
},
Wait, I'm confused -- it's not required, the spec shows it as not required, but the linter is throwing an error because it's missing? The spec says it's not required, so how is it wrong? Could it be a processing issues in the rule engine? I may need someone to talk me through this...
The issue is that the documentation says it lists, looks like the API probably asks for a list but the CloudFormation Spec doesn't specify it is a list.
Got it. I'll file another internal ticket.
As a workaround I changed this setting in spec override file we already pass along, like
{
"PropertyTypes": {
"AWS::RDS::OptionGroup.OptionConfiguration": {
"Properties": {
"OptionSettings": {
"ItemType": "OptionSetting",
"Type": "List"
}
}
}
}
}
This indeed solved the issue... So I can confirm that this indeed is the issue... So for now we've got a workaround.
This is resolved in the 2.8.0 resource specification:
"OptionSettings": {
"Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-optiongroup-optionconfigurations.html#cfn-rds-optiongroup-optionconfigurations-optionsettings",
"DuplicatesAllowed": false,
"ItemType": "OptionSetting",
"Required": false,
"Type": "List",
"UpdateType": "Mutable"
},
You can either update to cfn-lint 0.7.3 or update to the latest specification manually in your current version using cfn-lint --update-spec
I got unhashable type: 'dict_node' error when I add !IF condition in my template.
PersonServiceApi:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ${StageName}-PersonAPI
StageName: !Ref StageName
Auth:
DefaultAuthorizer:
!If
- IsMaster
- !Sub 'None'
- !Ref CustomAuthorizer
Authorizers:
CustomAuthorizer:
FunctionPayloadType: REQUEST
FunctionArn: !GetAtt ApiGatewayAuthorizerLambda.Arn
FunctionInvokeRole: !Ref ApiGatewayLambdaExecutionRole
Identity:
Headers:
- cookie
ReauthorizeEvery: 0
DefinitionBody:
openapi: 3.0.0
info:
sorry for bad indentation
This looks to be something related to sam translator that was added to prevent re-deploys of APIs.
It seems to happen when you reference an existing AWS::Serverless::Api in a lambda Event using Ref
I've made a PR on the SAM repo #1396 for a fix.
I got unhashable type: 'dict_node' error when I add !IF condition in my template.
PersonServiceApi:
Type: AWS::Serverless::Api
Properties:
Name: !Sub ${StageName}-PersonAPI
StageName: !Ref StageName
Auth:
DefaultAuthorizer:
!If - IsMaster - !Sub 'None' - !Ref CustomAuthorizer
Authorizers:
CustomAuthorizer:
FunctionPayloadType: REQUEST
FunctionArn: !GetAtt ApiGatewayAuthorizerLambda.Arn
FunctionInvokeRole: !Ref ApiGatewayLambdaExecutionRole
Identity:
Headers:
- cookie
ReauthorizeEvery: 0
DefinitionBody:
openapi: 3.0.0
info:
I have the same error if i add a condition. How did you resolve?
Conditions:
UseSSLCert: !Not [!Equals [!Ref 'SSLCertificateId', '']]