Pseudo parameters with variables

So, I just used five hours with my serverless.yml file over the most ridiculous thing: iamRoleStatements and Resources, which are an arn address to SNS topics, or SQS.

The problem arose as I got a deprecation warning when using serverless-pseudo-parameters, which claims Serverless Framework natively supports pseudo parameters as of version 2.3.0. So I removed it, thinking I can manage.

However, the documentation does not say that pseudo parameters can be used in conjunction with other variables ie. I cannot seem to be able to write something like this:

iamRoleStatements:
    - Effect: "Allow"
    Action:
        - SNS:Publish
    Resource:
    - 'Fn::Join':
        - ''
        - - 'arn:aws:logs'
            - Ref: 'AWS::Region'
            - ':'
            - Ref: 'AWS::AccountId'
            - ':'
            - 'sns-topic-name-'
            - ${self:provider.stage}

This will result in an error

An error occurred: IamRoleLambdaExecution - The policy failed legacy parsing (Service: AmazonIdentityManagement; Status Code: 400; Error Code: MalformedPolicyDocument; Request ID: 7d50c7e7-87ad-4f3c-bdc2-e569b916e649; Proxy: null).

So, I went back to using the plugin, which has been archived and deprecated.

I do not know if this will reach the original maintainer, but I urge him to restore this plugin. It may be that Serverless Framework now supports these pseudo parameters, but we’re talking about ease of use here.

I’d rather write:

  Resource: "arn:aws:sns:${self:provider.region}:#{AWS::AccountId}:sns-topic-name-${self:provider.stage}"

Than that horrible multiline monster using Fn::Join.

So, is there some hidden documentation page covering this issue, or are we stuck with a deprecated plugin to make this work?

2 Likes

Same here, I don’t understand this documentation, it doesn’t work as described and most importantly you can’t seem to be able to put other variables there too…

Also I don’t understant why in the provided example in the documentation they use once ‘Fn::Join:’ and the other one Ref on it’s own… None of the Cloudformation syntaxes…

Hey folks,

Just wanted to chime in, I too eliminated the same plugin dependency and changed my CloudFormation syntax as follows, producing the exact same CF template as before:

With serverless-pseudo-parameters plugin

  iamRoleStatements:
    - Effect: Allow
      Action:
        - lambda:InvokeFunction
      Resource: 'arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:function-on-error'

Without serverless-pseudo-parameters plugin:

  iamRoleStatements:
    - Effect: Allow
      Action:
        - lambda:InvokeFunction
      Resource: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:function-on-error'

Like I said, the resulting CF template is identical and the changes are minimal, just add CF’s !Sub intrinsic function and replace # with $ and you should get the same template.

Hope it helps!

4 Likes

Just got bitten by this change as well. Removed the package assuming the syntax would match only to have my deployments fail. There is no mention in the docs or deprecation messages that there is a significant syntax difference.

This should be documented, with a guide for updating templates from the deprecated plugin to the new feature.

Cheers to Martin for sharing the CF Sub function!

For anyone using Typescript for their serverless config (serverless.ts instead of serverless.yml) the below should be helpful

{
  Effect: 'Allow',
  Action: ['ssm:GetParameters*'],
  Resource: {
     "Fn::Sub":'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/dev/example*'
   }
}

I think the documentation has beem updated for this

https://www.serverless.com/framework/docs/providers/aws/guide/variables#pseudo-parameters-reference

Thanks @Martin for the sub example. Latest documentation doesn’t show that anywhere, at least that I could find.

I really couldn’t give up the plugin that is tagged as deprecated. I started to remove its usage in my projects but had to rollback. I had to dig in all cloudformation files to check what was wrong, very time consuming

Also there was no need to prefix with !Sub, which is more convenient

Thank you @Martin!
This was really helpful.

We solved our issues on IAM role statements by your example, but one more was causing the same error

IamRoleLambdaExecution - The policy failed legacy parsing

It was scheduled event:

events:
    - sqs:
        arn: "arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:SomeQueue-${self:provider.stage}"

!Sub wasn’t accepted here, so we had to change it to use import value:

  events:
    - sqs:
        arn:
          Fn::ImportValue: SomeQueue-${self:provider.stage}

So after applying changes you suggested and fix events arn above, we were able to get rid of the pseudo parameters plugin and use the latest SLS version.

There several places where cf intrinsic functions are not well supported.
Some frustrating situation I’ve encountered trying to use them:

events:
- stream:
    arn:  

also with authorizers:

events:
- http:
    authorizer:
      arn:

The serverles documentation is mentioning that the pseudo-parameters are now built in variables without relying on CF and !Sub:

${aws:region}
${aws:accountId}

However, I get the following error on deployment:

Serverless Error ----------------------------------------

Invalid variable reference syntax for variable aws:region. You can only reference env vars, options, & files. You can check our docs for more info.

2 Likes

I have this problem as well using:

Invalid variable reference syntax for variable aws:accountId. You can only reference env vars, options, & files. You can check our docs for more info.

I am using this version of serverless:

$ sls --version
Framework Core: 2.54.0 (local)
Plugin: 5.4.3
SDK: 4.2.6
Components: 3.15.0
✨  Done in 1.88s.

I have validated my local serverless package has the code associated with this PR in it:

You are using only one :
You have to change aws:accountId for aws::accountId