Cloudformation sub function for cloudwatch dashboard body

736 Views Asked by At

I'm running into issues using the !Sub intrinsic cloudformation function with AWS::Region pseudoparameter within the body of my cloudwatch dashboard (to ensure my stack is region agnostic). The cloudformation I am using is given below

  OrderDashboard:
    Type: AWS::CloudWatch::Dashboard
    Properties:
      DashboardBody:  !Sub  '{  "widgets": [    {      "type": "metric",      "x": 6,      "y": 0,      "width": 6,      "height": 6,      "properties": {        "metrics": [          [ "address", "validateAddressApiLatency" ]        ],        "view": "timeSeries",        "stacked": false,        "region": "${AWS::Region}",        "title": "ValidateAddressApiSuccessLatencyP99",        "period": 300,        "stat": "p99"      }    },    {      "type": "metric",      "x": 12,      "y": 0,      "width": 8,      "height": 6,      "properties": {        "metrics": [          [ "address", "validateAddressApiErrorLatency" ]        ],        "view": "timeSeries",        "stacked": false,        "region": "${AWS::Region}",        "title": "ValidateAddressApiErrorLatencyP99",        "period": 300,        "stat": "p99"      }    },    {      "type": "text",      "x": 0,      "y": 0,      "width": 6,      "height": 6,      "properties": {        "markdown": "# Heading \nThis dashboard exists to show that our success latency metric and error latency metric are published successfully using a single annotation and aspectj.\n\nThe first row shows the 99th percentile latencies, and the bottom column shows the count of the number of calls"      }    },    {      "type": "metric",      "x": 6,      "y": 6,      "width": 6,      "height": 6,      "properties": {        "metrics": [          [ { "expression": "SELECT COUNT(validateAddressApiLatency) FROM SCHEMA(address)", "label": "NumberOfSuccessfulCalls", "id": "q1", "region": "${AWS::Region}" } ]        ],        "view": "timeSeries",        "stacked": false,        "region": "${AWS::Region}",        "stat": "Average",        "period": 300,        "title": "NumberOfSuccessfulValidateCalls"      }    },    {      "type": "metric",      "x": 12,      "y": 6,      "width": 6,      "height": 6,      "properties": {        "metrics": [          [ { "expression": "SELECT COUNT(validateAddressApiErrorLatency) FROM SCHEMA(address)", "label": "NumberOfErroredCalls", "id": "q1", "region": "${AWS::Region}" } ]        ],        "view": "timeSeries",        "stacked": false,        "region": "${AWS::Region}",        "stat": "Average",        "period": 300,        "title": "NumberOfErrorValidateCalls"     }    }  ]}'
      DashboardName: order-dashboard

When I deploy the dashboard, the region is not substituted enter image description here

The interesting thing is I use sub with the region parameter other places in the template, it works.

Outputs:
  OrderApiUrl:
    Description: "The endpoint you can use to place orders.  Make sure to append the order id to the end"
    Value: !Sub "https://${OrderApi}.execute-api.${AWS::Region}.amazonaws.com/v1/orders/"

Any idea on what I can do to get the value substituted? Thanks

2

There are 2 best solutions below

2
On

The code that you provided works perfectly fine. Thus the issue that you have must be related to other factors than your CloudFormation code in the question.

Maybe you are using some other code, not the one in the question.

0
On

I agree with @ErikAsplund, something like:

  OrderDashboard:
    Type: AWS::CloudWatch::Dashboard
    Properties:
      DashboardName: order-dashboard
      DashboardBody: !Sub |
        {
          "widgets": [
            {
              "properties": {
                "metrics": [
                  "AWS/Lambda",
                  "Duration",
                  "FunctionName",
                  "${MyReference}"
                ]
              }
            }
        }