Search code examples
amazon-web-servicesaws-cloudformationtroposphere

Template validation error: invalid template resource property


I'm validating a CloudFormation template that was generated via a Troposphere script. The resource in question which seems to be causing the error is a Metric Transformation which is defined as follows in the Troposphere script:

t.add_resource(logs.MetricTransformation(
    "planReconciliationFiduciaryStepMetricTransformation",
    MetricNamespace=Ref("metricNamespace"),
    MetricName=Join("", [Ref("springProfile"), "-", "plan-reconciliation-step-known-to-fiduciary"]),
    MetricValue="1"
))

The parameters it depends on are defined beforehand in the script as follows:

t.add_parameter(Parameter(
    "metricNamespace",
    Type="String",
    Default="BATCH-ERRORS",
    Description="Metric namespace for CloudWatch filters"
))

t.add_parameter(Parameter(
    "springProfile",
    Type="String",
    Default=" ",
    Description="SPRING PROFILE"
))

The exact command that I'm running is

aws cloudformation validate-template --template-body 
   file://hor-ubshobackgroundtaskdefinition.template --profile saml

with the resulting output

An error occurred (ValidationError) when calling the ValidateTemplate operation: 
Invalid template resource property 'MetricName'

My properties for the MetricTransformation appear to be well-defined from the AWS documentation. For visibility, this is also what the metric transformation resource in the template that's being validated looks like too:

"planReconciliationFiduciaryStepMetricTransformation": {
            "MetricName": {
                "Fn::Join": [
                    "",
                    [
                        {
                            "Ref": "springProfile"
                        },
                        "-",
                        "plan-reconciliation-step-known-to-fiduciary"
                    ]
                ]
            },
            "MetricNamespace": {
                "Ref": "metricNamespace"
            },
            "MetricValue": "1"
        }

Any ideas?

UPDATE:

As requested, adding the metric filter resource:

"PlanReconciliationFiduciaryStepMetricFilter": {
            "Properties": {
                "FilterPattern": "INFO generatePlanReconciliationStepKnownToFiduciary",
                "LogGroupName": {
                    "Ref": "logGroupName"
                },
                "MetricTransformations": [
                    {
                        "Ref": "planReconciliationFiduciaryStepMetricTransformation"
                    }
                ]
            },
            "Type": "AWS::Logs::MetricFilter"
        }

Solution

  • As it turns out, the MetricTransformation resource needs to be initialized within the MetricFilter itself in order to produce the correct CloudFormation template from the Troposphere script. If you declare the MetricTransformation as a separate resource and try to reference it within the the MetricFilter resource, the ensuing template will be incorrectly formatted.

    The correct format in the Troposphere script will look like the following:

    t.add_resource(logs.MetricFilter(
        "PlanReconciliationFiduciaryStepMetricFilter",
        FilterPattern="INFO generatePlanReconciliationStepKnownToFiduciary",
        LogGroupName=Ref("logGroupName"),
        MetricTransformations=[logs.MetricTransformation(
            "planReconciliationFiduciaryStepMetricTransformation",
            MetricNamespace=Ref("metricNamespace"),
            MetricName=Join("", [Ref("springProfile"), "-", "plan-reconciliation-fiduciary-step"]),
            MetricValue="1")]
    ))