Nurzhan Nogerbek
Nurzhan Nogerbek

Reputation: 5236

Where exactly is the error in the CloudFormation template?

I am faced with the fact that my CloudFormation template is greater than 51200 bytes. So I decided to split this main template into several templates. When I try to build the stack, I get an error that the resource properties in the nested template are not correct.

QUESTION:

Is it possible that the nested template doesn't see the parameter values that were declared in the main template?

Error:

Invalid template resource property 'CreateWidgetRole'

template.yaml (snippet):

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Parameters:
  EnvironmentName:
    Type: String
  SettingsServiceStackName:
    Type: String
  S3Bucket:
    Type: String
Conditions:
  IsProductionEnvironment:
    'Fn::Equals':
      - Ref: EnvironmentName
      - Prod
Resources:
  SettingsServiceResources:
    'Fn::Transform':
      Name: 'AWS::Include'
      Parameters:
        Location:
          'Fn::Sub': >-
            s3://${S3Bucket}/included_templates/settings_service_resources_template.yaml

settings_service_resources_template.yaml:

CreateWidgetRole:
  Type: 'AWS::IAM::Role'
  Properties:
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Principal:
            Service: appsync.amazonaws.com
          Action: 'sts:AssumeRole'
    Policies:
      - PolicyName: CreateWidgetFunctionAccess
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action: 'lambda:InvokeFunction'
              Resource:
                'Fn::ImportValue':
                  'Fn::Sub': >-
                    ${EnvironmentName}${SettingsServiceStackName}:${EnvironmentName}CreateWidgetARN
CreateWidgetDataSource:
  Type: 'AWS::AppSync::DataSource'
  Properties:
    ApiId:
      'Fn::GetAtt': GraphQLApi.ApiId
    Name:
      'Fn::Sub': '${EnvironmentName}CreateWidget'
    Type: AWS_LAMBDA
    LambdaConfig:
      LambdaFunctionArn:
        'Fn::ImportValue':
          'Fn::Sub': >-
            ${EnvironmentName}${SettingsServiceStackName}:${EnvironmentName}CreateWidgetARN
    ServiceRoleArn:
      'Fn::GetAtt': CreateWidgetRole.Arn
CreateWidgetResolver:
  Type: 'AWS::AppSync::Resolver'
  Properties:
    ApiId:
      'Fn::GetAtt': GraphQLApi.ApiId
    FieldName: createWidget
    TypeName: Mutation
    DataSourceName:
      'Fn::GetAtt': CreateWidgetDataSource.Name

Upvotes: 0

Views: 645

Answers (2)

berenbums
berenbums

Reputation: 1354

The issue is the SettingsServiceResources line in the template.yaml. All your resources in the nested template have Logical IDs (like CreateWidgetRole), so there is no need to put another one in front of the Transform block. The following worked for me:

Resources:
  'Fn::Transform':
    Name: 'AWS::Include'
    Parameters:
      Location:
        'Fn::Sub': >-
          s3://${S3Bucket}/included_templates/settings_service_resources_template.yaml

You can also check the syntax in the docs.

Upvotes: 1

jarmod
jarmod

Reputation: 78553

The quickest and simplest solution to the 51,200 bytes local CloudFormation template size limit is to upload the template to S3 and create/update your stack from that. That will allow you to indicate an S3 URL instead of sending the actual template body (limited to 51,200 bytes), and the template in S3 can be up to 1MB in size.

You also have the option to split your template into multiple, nested templates though that is typically more work as you have to arrange inputs and outputs accordingly.

Upvotes: 1

Related Questions