Serverless-application-model: CodeUri intrinsic function doesn't work for S3 bucket

Created on 26 Jul 2018  路  9Comments  路  Source: aws/serverless-application-model

I defined CodeUri param with !Sub function in YAML:

Parameters:
  Version:
     Type: String
     Default: latest
     Description: Lambda version.
MyFunc:
      Type: AWS::Serverless::Function
      Properties:
        FunctionName: MyFuncName
        CodeUri: !Sub "s3://my_backet/my_app/${Version}/code.zip"
        Handler: func.handler
        Role: !Sub "arn:aws:iam::${AWS::AccountId}:role/RoleName"
        Runtime: python3.6
        Timeout: 300
        MemorySize: 256

And only Specifying CodeUri using inartistic functions caused exception:

Resource with id [MyFunc] is invalid. 'CodeUri' requires Bucket and Key properties to be specified`

According to https://aws.amazon.com/about-aws/whats-new/2017/02/aws-serverless-application-model-aws-sam-supports-inline-swagger-and-aws-cloudformation-intrinsic-functions/ (Posted On: Feb 17, 2017):

Use intrinsic functions to specify URIs - CodeUri and DefinitionUri now accept Amazon S3 objects with a Bucket, Key and Version. This means you can now use intrinsic functions to dynamically specify your code or Swagger file鈥檚 location.
  1. Define "CodeUri" with intrinsic function: CodeUri: !Sub "s3://my_backet/my_app/${Version}/code.zip"
  2. run 'sam deploy --template-file template.yaml --stack-name stack_name'

Observed result:
Exception:
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [MyFunc] is invalid. 'CodeUri' requires Bucket and Key properties to be specified
Expected result:
CodeUri could by defined as S3 bucket using inartistic functions like !Sub

typbug

Most helpful comment

Unfortunately, the SAM translator does not support intrinsic functions in the CodeUri field of AWS::Serverless::Function if you are using the S3 URI format of that property. Looking at the code, if it sees the CodeUri is an object (which it will be if you're using intrinsic functions), it assumes you are using the form of CodeUri that accepts an S3 Location Object, which is why you're getting that error.

https://github.com/awslabs/serverless-application-model/blob/master/samtranslator/model/sam_resources.py#L336-L343

You should be able to workaround this limitation by using the S3 location format of CodeUri and using your intrinsic functions inside that object. Try this instead:

Parameters:
  Version:
     Type: String
     Default: latest
     Description: Lambda version.
MyFunc:
      Type: AWS::Serverless::Function
      Properties:
        FunctionName: MyFuncName
        CodeUri:
          Bucket: my_backet
          Key: !Sub "my_app/${Version}/code.zip"
        Handler: func.handler
        Role: !Sub "arn:aws:iam::${AWS::AccountId}:role/RoleName"
        Runtime: python3.6
        Timeout: 300
        MemorySize: 256

If you use this form of CodeUri, the SAM translator just validates that you've provided Bucket and Key parameters and will then pass those values onto the Code property of the AWS::Lambda::Function resource in the transformed CloudFormation template.

All 9 comments

Unfortunately, the SAM translator does not support intrinsic functions in the CodeUri field of AWS::Serverless::Function if you are using the S3 URI format of that property. Looking at the code, if it sees the CodeUri is an object (which it will be if you're using intrinsic functions), it assumes you are using the form of CodeUri that accepts an S3 Location Object, which is why you're getting that error.

https://github.com/awslabs/serverless-application-model/blob/master/samtranslator/model/sam_resources.py#L336-L343

You should be able to workaround this limitation by using the S3 location format of CodeUri and using your intrinsic functions inside that object. Try this instead:

Parameters:
  Version:
     Type: String
     Default: latest
     Description: Lambda version.
MyFunc:
      Type: AWS::Serverless::Function
      Properties:
        FunctionName: MyFuncName
        CodeUri:
          Bucket: my_backet
          Key: !Sub "my_app/${Version}/code.zip"
        Handler: func.handler
        Role: !Sub "arn:aws:iam::${AWS::AccountId}:role/RoleName"
        Runtime: python3.6
        Timeout: 300
        MemorySize: 256

If you use this form of CodeUri, the SAM translator just validates that you've provided Bucket and Key parameters and will then pass those values onto the Code property of the AWS::Lambda::Function resource in the transformed CloudFormation template.

Hit this issue when using a !Ref to a Parameter. In our case, we're pointing at a local file so the workaround doesn't help.

@rjlohan Could you provide an example of what you were trying to do? Were you trying to ref a parameter in the CodeUri field or in a different location?

Hi there,

I have a similar issue with intrinsic functions with s3 codeUri I think (although specifically with !Ref rather than !Sub).

What we started with was this:

CodeUri: !Ref PathToFunction

however this was causing errors, presumably due to the issues with intrinsic functions here, so we switched to something like this which works:

CodeUri: ../path/to/my/lambda/function

However we quite like the parameterisation... So following the above workaround we end up with this:

CodeUri:
    Bucket: some-s3-bucket
    Key: !Ref PathToFunction

However locally that path appears to get set incorrectly, so I tried hardcoding it again:

CodeUri:
    Bucket: some-s3-bucket
    Key: ../path/to/my/lambda/function

But unfortunately still no luck. Presumably because locally I don't have an s3 bucket to reference... which I suspect may be the same issue as @rjlohan is having @keetonian .

Just found https://github.com/awslabs/serverless-application-model/issues/271 which looks like a similar issue to this one (and better matches my comment/question).

@craigkj You can't specify a local path like this. The only case where you're allowed to specify a local path is when you run sam package which packages and uploads your assets to S3 for you and modifies the template to the correct location it was uploaded to.

SAM CLI, version 0.18.0 this issue still exists Lambda function 'xxx' has specified S3 location for CodeUri which is unsupported. Using default value of '.' instead

      CodeUri:
        Bucket: some_bucket_name
        Key: "some_JAR_file_in_bucket"

SAM CLI, version 1.0.0, still has error "Lambda function 'HelloWorldFunction' has specified S3 location for CodeUri which is unsupported. Using default value of '.' instead"
CodeUri:
Bucket: lambda
Key: test.zip

I just build for Example Hello World of SAM. Has any solution for it? :(((

Worry not my little chicklets, I've submitted a feature request for this bug. It will be passed to the internal AWS engineering team. However, I'm not sure how long it will take for them to engineer the solution.

Was this page helpful?
0 / 5 - 0 ratings