Using data from a file as a string value in serverless.yml

Is it possible to import the contents of an external file as a value in serverless.yml. My usecase is for creating an AWS CloudWatch Dashboard, the DashboardBody element takes a string of JSON configuration. I could just write this into the yaml file, but it would be way nicer if I could do the following:

resources:
  DashboardIntegrationMonitor:
    Type: AWS::CloudWatch::Dashboard
    Properties:
      DashboardName: "${self:provider.stage}Importer"
      DashboardBody: "${file(./dashboard.json)}"

But serverless will read the json file and insert it as the content of DashboardBody:

"DashboardIntegrationMonitor": {
  "Type": "AWS::CloudWatch::Dashboard",
  "Properties": {
    "DashboardName": "stagingImporter",
    "DashboardBody": {
      "widgets": [
          ...
      ]

instead of

"DashboardIntegrationMonitor": {
  "Type": "AWS::CloudWatch::Dashboard",
  "Properties": {
    "DashboardName": "stagingImporter",
    "DashboardBody": "{\"widgets\": [...]}"

Is this possible?

1 Like

I solved this over on stackoverflow:

You can reference an external .js file, and then stringify the .json file there:

serverless.yml:

...
resources:
  Resources:
    MyDashboard:
      Type: AWS::CloudWatch::Dashboard
      Properties:
      DashboardName: My-Dashboard
      DashboardBody: ${file(my-dashboard-body.js):myDashboardBody}

${file(my-dashboard-body.js):myDashboardBody} is a serverless variable reference. It means that we want to use the value from the myDashboardBody module of the my-dashboard-body.js file.

my-dashboard-body.js:

module.exports.myDashboardBody = (serverless) => {
 const fsPromises = require('fs').promises
 return fsPromises.readFile('my-dashboard-body.json', 'utf-8')
};

my-dashboard-body.json:

{
  "widgets": [
    ...
  ]
}
3 Likes

That is perfect, thanks!

When I use this, the \n in the CloudWatch query is resolved as \\n and CloudWatch dashboard has a hard time parsing it