0
votes

I have a serverless specification with a nested stack, I want to define Type: AWS :: AppSync :: Resolver using RequestMappingTemplateS3Location and ResponseMappingTemplateS3Location, and the templates are in s3. When I update the template the stack does not update the cloudformation.

 Resource:
    AppSyncResolverTestStack:
      Type: AWS::CloudFormation::Stack
      DependsOn:
        - GraphQlApi
        - GraphQlSchema
      Properties:
        Parameters:
          MappingTemplatesURL:
            Fn::Join:
              - "/"
              - - "s3:/"
                - ${self:provider.deploymentBucket}
                - 'etc'
                - ${opt:stage}
                - 'mapping_templates_extra'
          GraphQlApiId:
            Fn::GetAtt:
              - GraphQlApi
              - ApiId
        TemplateURL:
          Fn::Join:
            - "/"
            - - "https://s3.amazonaws.com"
              - ${self:provider.deploymentBucket}
              - 'etc'
              - ${opt:stage}
              - 'cf-resolvers-2.yml'

Nested

Parameters:
  MappingTemplatesURL:
    Type: String
  GraphQlApiId:
    Type: String
Resources:
  FCSYSAPIGraphQlResolverFinancialRequest:
    Type: AWS::AppSync::Resolver
    Properties:
      ApiId:
        Ref: GraphQlApiId
      TypeName: Mutation
      FieldName: FinanceDocumentsApi
      DataSourceName: "FCFinanceApi"
      RequestMappingTemplateS3Location:
        Fn::Join:
          - "/"
          - - Ref: MappingTemplatesURL
            - "fc-finance"
            - "FinanceDocuments.request.vm"
      ResponseMappingTemplateS3Location:
        Fn::Join:
          - "/"
          - - Ref: MappingTemplatesURL
            - "fc-finance"
            - "FinanceDocuments.response.vm"

I expect that when I update the template in s3 and deploy my project the cloudformation is updated, but it is maintained with the previous code.

1

1 Answers

1
votes

This is the normal behavior of CloudFormation. CloudFormation only updates a resource when its properties change.

Since the properties RequestMappingTemplateS3Location and ResponseMappingTemplateS3Location do not change, CloudFormation doesn't update your AppSync Resolver (even though those S3 locations points to "new" content).

One way to solve your problem is to use the aws cloudformation package command of the AWS CLI. It allows you to define your template with local files:

Type: 'AWS::AppSync::Resolver'
Properties:
  ...
  RequestMappingTemplateS3Location: './path/to/local/template/file'
  ...

Running

aws cloudformation package --template-file mytemplate.yml --s3-bucket mybucket --output-template-file packaged.template

returns a copy of your template (packaged.template), replacing references to local artifacts with the S3 location where the command uploaded the artifacts. The S3 location name (key) depends on the content (uses MD5). Hence, with this strategy, the property RequestMappingTemplateS3Location changes if the content referenced by the S3 location changes.

After that, you can deploy your template with aws cloudformation deploy.

Note: this is the same as using AWS SAM CLI, sam package is an alias of aws cloudformation package

If working with the serverless framework, another solution is to use the serverless-appsync-plugin which allows to specify mapping templates inline or in a file.