Is there a simple way to get the AWS Account ID as a variable in the serverless.yml
? I’m trying to lock down IAM rights very specifically and it would be nice to have a dynamic way of getting the ID rather than requiring it to be hardcoded into the configuration.
@yankeeinlondon are you trying to get the AccountID in CloudFormation. Can you use a Pseudo Parameter ? i.e. AWS::AccountId
- http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html
Yes @johncmckim that looks exactly right. Sorry never sure whether I should be looking for things in cloudfront, serverless, or elsewhere. So if I’m understanding correctly I could put something like this in my serverless.yml
:
custom:
accountId: !Ref AWS::AccountId
I’m running to a meeting but will plug it in this afternoon.
@yankeeinlondon no worries. All part of learning. You won’t be able to use it in that part of the serverless.yml
.
See this example
service: foo
provider: # Not CloudFormation
name: aws
iamRoleStatements: # You can use CloudFormation here
...
functions: # Not CloudFormation
....
resources:
Resources: # This section is CloudFormation
SomeResource:
Type: AWS::IAM::Role
...
# something like this to build an ARN
Resource:
Fn::Sub: 'aws:ec2:${AWS::Region}:${AWS::AccountId}:xxxxx:xxx/*'
If you’re just using the AccountId from IAM you should be able to use it directly rather than through a custom property.
Hope that makes sense. P.S. it’s off the top of my head so there might be syntax issue but should be close
Hmmm. Tried your suggestion and got:
Invalid variable reference syntax for variable AWS::Region.
You can only reference env vars, options, & files. You
can check our docs for more info.
Ah yes sorry. Again, was off the top of my head. That’s an issue with Fn::Sub
right now. The syntax for variables i.e. ${blah}
conflicts with Serverless. It’s a PITA. You would normally be able to use variableSyntax
to work around that but there’s a bug
You might have to do something like this instead:
Fn::Join: ["", [ "aws:ec2:", { "Ref": "AWS::Region" }, ':', { Ref: "AWS::AccountId" }, ":xxx:xxx/*" ]]
Clearly that’s no where near as nice as Fn::Sub
Well lots of thanks for your help. Don’t think I’d have gotten there myself. For now I’ll wildcard the accountId as I have the stage and region available locally in the serverless.yml
and that’s pretty good resolution. I’ve tested and this seems to work:
Resource:
- "arn:aws:lambda:${self:custom.region}:*:function:serverless-event-${self:custom.stage}-*"
Hi … I was wondering if there was any progress on the ability to distinguish AWS variables from serverless variables, or at least to escape the serverless variable replacement functionality … it seems like a pretty useful ability so that I can pass a string literal to AWS for it to use to replace variables. From what I can tell variableSyntax that is referred to above isn’t active right now? No documentation that I can find …
I’ve been down this road myself. Here’s the comment I made to remind me of the problems, and the variableSyntax I’m using to get past this issue:
provider:
name: aws
runtime: nodejs4.3
# by default AWS variables like ${saml:sub} use same format as Serverless variables like ${self:custom.prefix}
# We use variableSyntax here to change serverless vars to look instead like ${{self:custom.prefix}}
variableSyntax: '\${{([\s\S]+?)}}'
With that in place, I can now use Fn::Sub basically as indicated by @johncmckim
Resource:
- Fn::Sub: 'arn:aws:iot:${AWS::Region}:${AWS::AccountId}:topicfilter/public/*'
Don’t forget to then change all your Serverless variables as indicated in the comment above-- ${self:custom.whatever} becomes ${{self:custom.whatever}}
Oh, that’s a really sweet idea @donpedro … I’m definitely going to do that, thanks!
Hey, @donpedro … thanks for the idea, had to adjust your regular expression a little bit to make it work with my recursive variables, thought you might want to know about it:
variableSyntax: '\${{(((?!\${{).)+?)}}'
Now works for things like this:
DefaultCurrency: ${{self:custom.${{opt:region, self:provider.region}}.${{opt:stage, self:provider.stage}}.DefaultCurrency}}
Thanks again! seems like this feature is somewhat undocumented.
@cdichiara I expanded on your regex to
variableSyntax: '\${((self|opt):((?!\${).)+?)}'
The difference is I do not need to wrap my serverless variables in the extra {}
${self:custom.${self.custom.other}}
Thank you for that solution! It doesn’t make much sense to me that Serverless uses the same variable syntax as CloudFormation.
I’ve changed mine accordingly:
variableSyntax: '\$\(([\s\S]+?)\)'
What about this one ?
(?!${AWS::)${([\s\S]+?)}
If you only want to avoid issues with AWS pseudo parameters, it should do the trick without having to deal with changing format of all serverless variables
Ok, easier solution: User the “serverless-pseudo-parameters” plugin.
It fixed my issue instantly by replacing $ character by # in my resource declarations.
This is a much easier solution.
Works for me.
Thanks @donpedro! This works perfectly and now I too have a reminder!