How to get AWS account id as custom variable in serverless framework?

For anyone using Serverless with an "assumed role" where your IAM users are defined in a master AWS account and you're trying to deploy in a child account using a role from that child account: the documented solution - the one in the accepted answer above - does not work.

This setup in described in detail here: https://theithollow.com/2018/04/30/manage-multiple-aws-accounts-with-role-switching/. When using serverless with an --aws-profile that's configured to assume a role defined in another account, sts.getCallerIdentity() returns the account info of your master account from the default profile, and not the account of the assumed role.

To get the account ID of the assumed role (which is where we're deploying to), I did the following:

const { STS } = require('aws-sdk');

module.exports.getAccountId = async (context) => {
  // This loads the AWS credentials Serverless is currently using
  // They contain the role ARN of the assumed role
  const credentials = context.providers.aws.getCredentials();

  // init STS using the same credentials
  const sts = new STS(credentials);
  const identity = await sts.getCallerIdentity().promise();
  return identity.Account;
};

Edit:

Found an even better way, that is simpler than the one presented in Serverless docs and also works fine with assumed roles:

module.exports.getAccountId = async (context) => {
  return context.providers.aws.getAccountId();
};

According to the documentation, to get the Account Id, you can use external js files:

// myCustomFile.js
module.exports.getAccountId = async (context) => {
    return context.providers.aws.getAccountId();
};

.

# serverless.yml
service: new-service
provider: aws
custom:
  accountId: ${file(../myCustomFile.js):getAccountId}