Skip to content

Instantly share code, notes, and snippets.

@PatMyron
Created December 4, 2019 00:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PatMyron/c1940c37d2a6fea0fa950a107d485b81 to your computer and use it in GitHub Desktop.
Save PatMyron/c1940c37d2a6fea0fa950a107d485b81 to your computer and use it in GitHub Desktop.
Template format error: Unrecognized resource types
Parameters:
CreateResource:
Default: false
Type: String
AllowedValues: [true, false]
Conditions:
ShouldCreateResource:
!Equals [true, !Ref CreateResource]
Resources:
Macro:
Type: AWS::CloudFormation::Macro
Properties:
FunctionName: !Ref Function
Name: macro
Function:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.7
Role: !GetAtt Role.Arn
Code:
ZipFile: |
def lambda_handler(event, context):
if event['params']['CreateResource'] == 'false':
return {'fragment': {'Type': 'AWS::CloudFormation::WaitConditionHandle'},
'requestId': event['requestId'],
'status': 'success'}
else:
return {'fragment': event['fragment'],
'requestId': event['requestId'],
'status': 'success'}
Handler: index.lambda_handler
Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: lambda.amazonaws.com
Stack:
Fn::Transform: # these lines must be added in a separate commit after the macro
Name: macro # these lines must be added in a separate commit after the macro
Parameters: # these lines must be added in a separate commit after the macro
CreateResource: !Ref CreateResource # these lines must be added in a separate commit after the macro
Type: AWS::AppStream::Stack
Condition: ShouldCreateResource
@PatMyron
Copy link
Author

aws cloudformation validate-template / aws cloudformation get-template-summary / aws cloudformation create-stack-set throw:
Template format error: Unrecognized resource types: []

aws cloudformation create-stack / aws cloudformation update-stack cannot be called through the console without hitting:
Template format error: Unrecognized resource types: []

aws cloudformation create-change-set --change-set-type IMPORT has similar issues through the console


https://code.amazon.com/packages/AWS21StackBuilderService/blobs/74ba401db270b8329b602a3218f0bb608a2e74f7/--/src/amzn/aws21/sbs/utils/ResourceTypeValidator.java#L22


We should not throw this error where we cannot evaluate conditions


Currently, there is a workaround of adding a transform like Transform: AWS::Serverless-2016-10-31 to your template like this:

Transform: AWS::Serverless-2016-10-31 # https://i.amazon.com/CFN-7763
Resources:
  Stack:
    Type: AWS::AppStream::Stack

This workaround seems to work for the console, validate-template, get-template-summary --template-body, but not get-template-summary --stack-name or create-stack-set

While this might require adding a CAPABILITY_AUTO_EXPAND capability, "there is no charge incurred when using this transform" and it shouldn't affect your template if you don't have any AWS::Serverless resources, and you should already be using this transform if you do have AWS::Serverless resources


Another workaround that works with get-template-summary --stack-name too is a AWS::CloudFormation::Macro that removes that resource type from your template depending on the parameter value:

Parameters:
  CreateResource:
    Default: false
    Type: String
    AllowedValues: [true, false]
Conditions:
  ShouldCreateResource:
    !Equals [true, !Ref CreateResource]
Resources:
  Macro:
    Type: AWS::CloudFormation::Macro
    Properties:
      FunctionName: !Ref Function
      Name: macro
  Function:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.7
      Role: !GetAtt Role.Arn
      Code:
        ZipFile: |
          def lambda_handler(event, context):
            if event['params']['CreateResource'] == 'false':
              return {'fragment': {'Type': 'AWS::CloudFormation::WaitConditionHandle'},
                      'requestId': event['requestId'],
                      'status': 'success'}
            else:
              return {'fragment': event['fragment'],
                      'requestId': event['requestId'],
                      'status': 'success'}
      Handler: index.lambda_handler
  Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service: lambda.amazonaws.com
  Stack:
    Fn::Transform:                          # these lines must be added in a separate commit after the macro
      Name: macro                           # these lines must be added in a separate commit after the macro
      Parameters:                           # these lines must be added in a separate commit after the macro
        CreateResource: !Ref CreateResource # these lines must be added in a separate commit after the macro
    Type: AWS::AppStream::Stack
    Condition: ShouldCreateResource

This might require adding both CAPABILITY_AUTO_EXPAND and CAPABILITY_IAM capabilities

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment