serverless-application-model
serverless-application-model copied to clipboard
AutoPublishAlias does not accept a !Ref
Description:
Using a !Ref
in AutoPublishAlias
throws an error when running sam validate
.
This is a duplicate of awslabs/cfn-python-lint#582 but it looks like it's a SAM error and not a cfn-lint error, so I'm opening a ticket here.
It is not a duplicate of #220 as using!Ref
in AutoPublishAlias
should be allowed. Even the error message say so.
Steps to reproduce the issue:
- Use this template:
---
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
Stage:
Description: Environment stage (deployment phase)
Type: String
AllowedValues:
- beta
- prod
Resources:
SkillFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: '.'
Handler: main.handler
Runtime: python3.7
Timeout: 30
MemorySize: 128
AutoPublishAlias: !Ref Stage
- Run
sam validate
on that template
Observed result: The command results in an error 💥
Error: [InvalidResourceException('SkillFunction', "'AutoPublishAlias' must be a string or a Ref to a template parameter")] ('SkillFunction', "'AutoPublishAlias' must be a string or a Ref to a template parameter")
Expected result: The command finishes successfully without any error message.
That is a valid SAM template and deploys via CloudFormation. It appears that SAM is trying to resolve the parameter passed into AutoPublishAlias and can't, thus throwing an error.
Allowing parameter overrides in sam validate
would fix this issue, as this expects a valid parameter to be available. Since no default is set and no parameter is passed in to the validate command, SAM cannot resolve this parameter.
Talked with @jfuss who brought up that template validation should depend on whether or not a template is valid, not on the existence of a parameter. Customers should not have to pass in parameters for validation.
The issue here is that SAM actually needs to resolve the value of certain parameters in order to generate the logical ids of other CloudFormation resources during the transform. AutoPublishAlias
is one example where this is true, which is why SAM is failing here. Since these parameters are required when actually deploying the template, it works fine when deploying direct to CloudFormation. However, it fails on validate, because CFN lint (and SAM CLI) are manually calling the SAM transform function without any parameter values in order to do validation.
The fix for this is either for the SAM translator library to offer a validate()
function that accounts for issues like this under the covers, or for CFN lint to call transform with dummy parameter values.
Hi folks, just curious, is a fix for this on the roadmap?
I pinged https://github.com/aws-cloudformation/cfn-python-lint/issues/582 again. Was hoping the issue could be fixed on the cfn-lint side.
Still seeing this issue, it has not been resolved yet.
Just ran this issue again. Results:
sam validate
failed with Error: [InvalidResourceException('SkillFunction', "'AutoPublishAlias' must be a string or a Ref to a template parameter")] ('SkillFunction', "'AutoPublishAlias' must be a string or a Ref to a template parameter")
cfn-lint
succeeded
Seeing this not only on validate but also on deploy. template.yaml:
Parameters:
Stage:
Type: String
Description: Which stage the code is in
Default: test
AllowedValues:
- test
- prod
Resources:
HelloWorldSQSFunction:
Type: AWS::Serverless::Function
Properties:
AutoPublishAlias: !Ref: Stage
When I deploy I get the following error:
Failed to create changeset for the stack: sams-app, ex: 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 [HelloWorldSQSFunction] is invalid. 'AutoPublishAlias' must be a string or a Ref to a template parameter
Just in case, check the issue is not the colon not needed after !Ref
. I had the same scenario and it worked with no issues when deploying.
Parameters:
Environment:
Type: String
Description: Environment to deploy resources to
AllowedValues:
- staging
- production
Resources:
PutFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub 'put-${Environment}'
CodeUri: ./src/put-book/
Handler: index.handler
AutoPublishAlias: !Ref Environment
@jbernalvallejo That was definitely the issue w/ !Ref, thanks! The remaining issue would be around !FindInMap:
Parameters:
Stage:
Type: String
Description: Which stage the code is in
Default: test
AllowedValues:
- preprod
- prod
Mappings:
Alias:
preprod:
alias: test
prod:
alias: live
Resources:
HelloWorldSQSFunction:
Type: AWS::Serverless::Function
Properties:
AutoPublishAlias: !FindInMap [Alias, !Ref Stage, alias]
Error: Failed to create changeset for the stack: sams-app, ex: 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 [HelloWorldSQSFunction] is invalid. 'AutoPublishAlias' must be a string or a Ref to a template parameter
I concede this is likely intended behavior due to the error message, but it would still be nice to have.
SAM currently supports only Ref
for AutopublishAlias
and doesn't support other intrinsic functions. Thanks for the feature request! We have passed this along to our product team for possible prioritization for FindInMap
support. Please +1 on the feature to help with prioritization.
@ShreyaGangishetty if "SAM currently supports only Ref for AutopublishAlias" is true, do you think we can close this issue?
If not this ticket, where should support for Intrinsic functions (Fn::Join) be requested for AutoPublishAlias?
SAM currently supports only
Ref
forAutopublishAlias
and doesn't support other intrinsic functions.
That's not entirely accurate. Or more accurately, it does not support a !Ref
to a pseudo parameter (NoValue, Region, AccountID, ...). I want to enable AutopublishAlias
globally, and disable it for one function:
Globals:
Function:
AutoPublishAlias: live
Resources:
HelloFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: "Hello"
CodeUri: ./src/hello/
Handler: index.handler
AutoPublishAlias: !Ref AWS::NoValue
Is my use case common? No. I'm just transitioning to aliases, but there's one function that I need it disabled on. The suitable workaround is copy/paste.
I do believe that "AWS::NoValue"
should universally apply to any property and certainly to the properties that could be set in the Globals
section.
Closing in favor of https://github.com/aws/serverless-application-model/issues/2533.