Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API Gateway with SAM isn't updated correctly

We use Cloud Formation for define a bunch of Lambda functions:

AWSTemplateFormatVersion: '2010-09-09'
Transform:
- 'AWS::Serverless-2016-10-31'

Resources:
  MyLambda:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: com.handler::MyLambda
      Runtime: java8
      CodeUri: .
      Description: Some desc
      MemorySize: 512
      Timeout: 15
      Role: !Ref LambdaRole
      FunctionName: MyLambda
      Events:
        MyLambdaEvt:
          Type: Api
          Properties:
            RestApiId: !Ref MyApiDef
            Path: /lambda/my
            Method: get

  MyApiDef:
    Type: AWS::Serverless::Api
    Properties:
      DefinitionUri: s3://a-bucket/api-gateway.yml
      StageName: prod

Outputs:
  ApiUrl:
    Description: URL of your API endpoint
    Value: !Join
      - ''
      - - https://
        - !Ref MyApiDef
        - '.execute-api.'
        - !Ref 'AWS::Region'
        - '.amazonaws.com/prod'

A CodePipeline generate a changeset and execute it.

In this way all the Lambda function are correctly updated but the API Gateway endpoint are not update correctly and we need to import and deploy the YML in s3://a-bucket/api-gateway.yml manually.

like image 669
BAD_SEED Avatar asked Dec 19 '17 16:12

BAD_SEED


1 Answers

Why the API doesn't update (an educated guess)

In order for a change to be added to a a change set, CloudFormation has to detect a change. If the only thing that changes (for MyApiDef) between deployments is the contents of the .yaml file out on S3, CloudFormation isn't going to detect a change that it needs to add to the change set.

If this API definition lived in the CF template, rather than a file on S3, CF would (obviously) detect every change and update the API for you.

Since the definition lives in S3, and the file name hasn't changed, no change is detected, so nothing gets updated.

Possible work arounds

You have to convince CloudFormation that something has changed with your API definition. These two things worked for me:

  • Updating the MyApiDef key itself each run works. (MyApiDefv2, MyApiDefv3, etc)
  • Updating the DefinitionUri works. (i.e. version the filename in S3).

Neither of these is great, but appending a version to the filename in S3 seems more reasonable than the other option.

There are probably other ways to convince CloudFormation a change has taken place. Notably, I could not get Variables to work for this purpose.

like image 134
Mike Patrick Avatar answered Oct 28 '22 01:10

Mike Patrick