Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support CloudFormation intrinsic functions in SAM resources #22

Closed
sanathkr opened this issue Nov 23, 2016 · 37 comments
Closed

Support CloudFormation intrinsic functions in SAM resources #22

sanathkr opened this issue Nov 23, 2016 · 37 comments

Comments

@sanathkr
Copy link
Contributor

We quite often use !Ref, !Sub, !Join in properties that are supposed to hold strings such as CodeUri, DefinitionUri, StageName (#19) etc. This is a perfectly valid CloudFormation, but the transformation logic that parses SAM does not resolve intrinsic functions before parsing the property as a string. So the transformation logic would fail and depending on the property it could either return a validation error or internal failure. Properties that are directly passed down to CloudFormation are unaffected by this problem.

This is a feature request to add support for resolving a subset of CloudFormation intrinsics in the transformation logic. We care about only the subset of properties that the transform manipulates, like CodeUri.

Following intrinsics will be supported:

  • !Sub
  • !Join

on following properties:

  • CodeUri on AWS::Serverless::Function
  • Role on AWS::Serverless::Function
  • DefinitionUri on AWS::Serverless::Api
  • StageName on AWS::Serverless::Api
@deathbob
Copy link

Trying to use !GetAtt for SecurityGroupIds in a VpcConfig section of a Lambda, get Type of property 'VpcConfig' is invalid.

Works fine when I manually look up the values and plug in the strings, so figure it must be this same issue.

Timeframe on a fix? Any workarounds possible?

Loving the new SAM stuff but this is a deal-breaker.

@sanathkr
Copy link
Contributor Author

I am sorry you are running into the bug. Unfortunately there are no workarounds besides switching to regular AWS::Lambda::Function resource.

We are actively working on fixing it. Will let you know once its done

@stuartstevenson
Copy link

I've been having this issue with Fn::ImportValue for the ::Api Variables property to be able to pass in the function arn.

Is this bug fix to support all of the intrinsic functions?

@sanathkr
Copy link
Contributor Author

@stuartstevenson #20 was a bug that was fixed. You should be able to use any Fn:: function with Variables property. However you cannot pass the ARN directly to your Swagger. It doesn't work. You should pass function name and construct the ARN there. See this example: https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/api_swagger_cors/swagger.yaml#L23

@joekiller
Copy link

Fn::Import wasn't working for.me earlier today. Can you all confirm that it is fixed? I can create an example if necessary.

@sanathkr
Copy link
Contributor Author

Can you give me an example with the error you received?

@joekiller
Copy link

I'll create one tomorrow and post here.

@stuartstevenson
Copy link

stuartstevenson commented Dec 16, 2016

@sanathkr Thank you for your response. Is there a reason why ARNs in particular cannot be passed as I had made the assumption that the stage variable was just a string i was setting? I would not have assumed that the contents of the string would be validated.

@joekiller
Copy link

I was using multiple short form functions in a row which is not supported. So trying

Resource: !ImportValue !Sub '${KMSKey}-blah'

Is improper while

Resource: !ImportValue 
                      'Fn::Sub': '${KMSKey}-blah'

Works. http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-base64.html Notes the problem I had.

@brettstack
Copy link
Contributor

I'm still getting this error when trying to use !ImportValue for AWS::Serverless::Function

Resources:
  LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: bundle.handler
      MemorySize: 128
      Runtime: nodejs4.3
      Timeout: 3
      Events:
        List:
          Type: Api
          Properties:
            RestApiId: !ImportValue API-ApiId
            Path: /users
            Method: GET

@weargoggles
Copy link

weargoggles commented Jan 19, 2017

I'm experiencing a variation of this trying to use !Ref as a value in a Function's Environment. Is my only option to switch to AWS::Lambda::Function for now?

Edit: I had a typo in my CodeUri attribute and that caused "internal error in transform" which led me here. Sorry.

@sanathkr
Copy link
Contributor Author

!Ref in environment variables is supposed to work out-of-box. Can you post an example?

@weargoggles
Copy link

It did work. I was mistaken.

@jolexa
Copy link

jolexa commented Feb 9, 2017

Our org would also like to see !Ref supported in a the CodeUri field of a AWS::Serverless::Function in addition to the proposed items in the original comment.

Something like this, is what we are thinking (idolized design):

      CodeUri:
        Fn::Join:
          - '-'
          - - s3://some-known-convention
            - Ref: AWS::AccountId
            - '/github-sha/deployment.zip'

@sanathkr
Copy link
Contributor Author

sanathkr commented Feb 9, 2017

Thanks for the comment. Yes, we will support this usecase as well...

@sanathkr sanathkr mentioned this issue Feb 9, 2017
@dinvlad
Copy link

dinvlad commented Feb 16, 2017

Interestingly, many of the intrinsics work through CodePipeline action for CloudFormation. Is that case handled differently?

@sanathkr
Copy link
Contributor Author

We have just pushed support for Intrinsic functions - https://github.com/awslabs/serverless-application-model/blob/master/HOWTO.md#using-intrinsic-functions

It should work everywhere except for the caveats mentioned in the above doc. If you find any scenario where it doesn't work, please create a new bug.

!Sub "Thanks everyone for the awesome feedback. ${your_username} are awesome!"

@judahb
Copy link

judahb commented Sep 25, 2017

Just curious, when is this available? Is it currently available in AWS::Serverless-2016-10-31?

@joekiller
Copy link

joekiller commented Sep 25, 2017 via email

@baechul
Copy link

baechul commented Dec 23, 2017

I am trying to do something like this to enable both local and CI run but doesn't work:
CodeUri:
!If
- CreateDevEnvironment
- ../../../target/helloworld-1.0-SNAPSHOT.jar
-
Bucket: !Ref BucketName
Key: !Ref CodeKey
Is If intrinsic function supported? Or how I can switch between 2 different objects (string and S3 location object) for CodeUrl in the same template?

@MaiKaY
Copy link

MaiKaY commented Dec 23, 2017

Dont know if If intrinsic functions are supported but an alternative would be to pass BucketName and Key as a parameter into your CF template.

@baechul
Copy link

baechul commented Dec 24, 2017

@MaiKaY Thanks. But in may case, I use a S3 location with BucketName and Key for CI. For local with "sam local", my CodeUri value should be "./../../target/helloworld-1.0-SNAPSHOT.jar", which is a string type.

@aaronp-hd
Copy link

This is exactly what I'm trying to do as well but I haven't yet been able to find a way around this -- surely this must be a reasonably common use case? I too would like to switch CodeUri conditionally depending on if I'm running locally or not. If running locally CodeUri should be a String, but if not I need a S3 location with bucket name and key.

Are there any plans to support the If intrinsic function, or are there any other ways to achieve this?

@bluepeter
Copy link

@eelixa did you try using the full name for the intrinsic function, versus the shorthand notation? For SAM my understanding is you must use the former.

@aaronp-hd
Copy link

@bluepeter Ah right, I didn't realise that was the case. I have the If part working now. Thanks a lot for your help!

@MaiKaY
Copy link

MaiKaY commented Feb 5, 2018

@eelixa would be cool if you can paste your working code here. To avoid similar issues in the future :-)

@aaronp-hd
Copy link

I ended up with something like this:

Conditions:
  RunLocally:
    Fn::Equals:
      - Ref: pEnvironment
      - "local"

And then:

  MyFunction:
    Type: "AWS::Serverless::Function"
    Properties:
      CodeUri:
        Fn::If:
          - RunLocally
          - "../../../build/distributions/myfunction.zip"
          -
            Bucket: pMyFunctionS3BucketName
            Key: pMyFunctionS3BucketKey

@bluepeter
Copy link

You cannot use the shorthand notation in SAM. Please use, e.g., Fn::Join and Ref instead. See the discussion above in this very issue.

@joshuahiggins
Copy link

Sorry, removed my prior comment on accident. For anyone confused by @bluepeter's reply to seemingly no-one, I posted about the an API event in an AWS:Serverless:Function with a path of !Join [ !Ref ApiBaseUrl, /something ] failing to transform on CloudFormation, but running fine in aws-sam-local and validating locally.

Anyway, I do not see anyone mentioning that shorthand isn't supported except you. The documentation doesn't mention it either, and the pending documentation update (#290) indicates that Events in AWS:Serverless:Function should support all intrinsic functions. Our team is using the same !Join & !Ref shorthand combo as above to set Policies and some other values in our serverless functions without issue, so that's why I'm surprised to hit a wall with Path.

@sanathkr
Copy link
Contributor Author

sanathkr commented Feb 8, 2018

With Path property of Events structure, SAM needs to insert the value of this property into Swagger as a key of a dictionary like this:

{
  "paths": {
     "<Value of Path property>": {...}
  }
}

Since SAM runs "before" any intrinsic functions are processed, it has no way of getting the path string that you expect to be obtained by resolving the intrinsics. SAM works around this problem in most cases by carefully passing the value (containing intrinsics) directly to the next stage of processing that deploys the stack. In case of Path, we need cannot insert an intrinsic function as a key of a dictionary. Therefore SAM gives up and fails. Policies, on the other hand, are never entirely resolved in SAM. They are passed through directly to the next layer if SAM finds an intrinsic function there.

@joshuahiggins
Copy link

Good to know. Thanks for the detailed info.

@anandchristal
Copy link

in usage plan defintion AWS::ApiGateway::UsagePlan...not able to refer stage name from AWS::Serverless::Api...getting into race situation the usageplan ran ahead of api/stage creation...event i marked dependson:api resource for usageplan resource...but still it is not working

@brunofitas
Copy link

Hi guys.
I still have problems with Fn::ImportValue and SAM Local.
The following deploys but I'm unable to invoke it locally.

Environment:
  Variables:
    TOPIC_ARN:
       Fn::ImportValue:
         !Sub "${AlarmNotificationTopicStackName}-TopicName"

Any ideas?
Thanks

@weargoggles
Copy link

weargoggles commented Apr 24, 2018 via email

@weargoggles
Copy link

weargoggles commented Apr 24, 2018 via email

@OGoodness
Copy link

what's the most recent issue related to this? So that my team can track this issue.

@hoffa
Copy link
Contributor

hoffa commented Oct 11, 2022

@OGoodness I've created the #2533 meta-issue to track intrinsic function-related problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests