title: Cloudformation Template error: every Ref object must have a single String value
body: <p>I am recieving this error when validating my cfn.</p>
  
  <pre><code>'Template error: every Ref object must have a single String value.`
  </code></pre>
  
  <p>Is anyone able to tell me where I am going wrong with my cfn template.</p>
  
  <p>I am unable to tell which Ref it is referring to as I have checked them and can see all are defined as parameters.</p>
  
  <pre><code>    CloudFormation {
  
    #Script Parameters
    Parameter ("region") {
      Type String
      Default region
    }
  
    Parameter ("environment") {
      Type String
      Default environment.capitalize
    }
  
    Parameter ("vpcId") {
      Type String
      Default vpcId
    }
  
    Parameter ("vpcCidr") {
        Type String
        Default vpcCidr
    }
  
    Parameter ("keyName") {
        Type String
        Default keyName
    }
  
    Parameter ("pubSub1") {
        Type String
        Default pubSub1
    }
  
    Parameter ("pubSub2") {
        Type String
        Default pubSub2
    }
  
    Parameter ("priRtb1") {
        Type String
        Default priRtb1
    }
  
    Parameter ("priRtb2") {
        Type String
        Default priRtb2
    }
  
    Parameter ("natType") {
        Type String
        Default natType
    }
  
    Parameter ("nuPings") {
        Type String
        Default nuPings
    }
  
    Parameter ("pingTimeout") {
        Type String
        Default pingTimeout
    }
  
    Parameter ("pingWait") {
        Type String
        Default pingWait
    }
  
    Parameter ("instStopWait") {
        Type String
        Default instStopWait
    }
  
    Parameter ("instStartWait") {
        Type String
        Default instStartWait
    }
  
    Mapping("AWSNATAMI", {
    "us-east-1" =&gt; {
      "AMI" =&gt; "ami-54cf5c3d"
    },
    "us-west-2" =&gt; {
      "AMI" =&gt; "ami-8e27adbe"
    },
    "us-west-1" =&gt; {
      "AMI" =&gt; "ami-b63210f3"
    },
    "eu-west-1" =&gt; {
      "AMI" =&gt; "ami-3c5f5748"
    },
    "ap-southeast-1" =&gt; {
      "AMI" =&gt; "ami-ba7538e8"
    },
    "ap-southeast-2" =&gt; {
      "AMI" =&gt; "ami-b6df4e8c"
    },
    "ap-northeast-1" =&gt; {
      "AMI" =&gt; "ami-5d7dfa5c"
    },
    "sa-east-1" =&gt; {
      "AMI" =&gt; "ami-89c81394"
    }
  })
  
    Resource("NATRole") do
      Type("AWS::IAM::Role")
      Property("PolicyName", "NAT_Takeover")
      Property("Path", "/")
      Property("AssumeRolePolicyDocument", {
                "Effect" =&gt; "Allow",
                "Principal"=&gt; { 
                    "Service" =&gt; [ "ec2.amazonaws.com" ]
                  },
                 "Action" =&gt; [ "sts:AssumeRole" ]
      })
      Property("Policies", [
        {
        "PolicyDocument" =&gt; {
        "Statement" =&gt; [
          {
            "Action"   =&gt; [
                            "ec2:DescribeInstances",
                            "ec2:DescribeRouteTables",
                            "ec2:CreateRoute",
                            "ec2:ReplaceRoute",
                            "ec2:StartInstances",
                            "ec2:StopInstances"
                           ],
            "Effect"   =&gt; "Allow",
            "Resource" =&gt; "*"
          }
        ]
       }
      }
    ])
    end
  
    Resource("NATRoleProfile") do
      Type("AWS::IAM::Role")
      Property("Path", "/")
      Property("Roles", {
        "Ref" =&gt; [ "NATRole" ]
      })
    end
  
    Resource("NAT1EIP") do
      Type("AWS::EC2::EIP")
      Property("Domain", "vpc")
      Property("InstanceId", {
        "Ref" =&gt; [ "NAT1Instance" ]
      })
    end
  
    Resource("NAT2EIP") do
      Type("AWS::EC2::EIP")
      Property("Domain", "vpc")
      Property("InstanceId", {
        "Ref" =&gt; [ "NAT2Instance" ]
      })
    end
  
    Resource("NAT1Instance") do
      Type("AWS::EC2::Instance")
      Metadata("Comment1", "Create NAT #1")
      Property("InstanceType", {
        "Ref" =&gt; [ "natType" ]
      })
      Property("KeyName", {
        "Ref" =&gt; [ "keyName" ]
      })
      Property("IamInstanceProfile", {
        "Ref" =&gt; [ "NATRoleProfile" ]
      })
      Property("SubnetId", {
        "Ref" =&gt; [ "pubSub1" ]
      })
      Property("SourceDestCheck", "false")
      Property("ImageID", FnFindInMap("AWSNATAMI", Ref("region"), "AMI"))
      Property("SecurityGroupIds", {
        "Ref" =&gt; [ "NATSecurityGroup" ]
      })
      Property("Tags", {
        "Key" =&gt; [ "Name" ],
        "Value" =&gt; [ "NAT #1" ],
      })
      Property("UserData", FnBase64(FnJoin("", [
        "#!/bin/bash\n",
        "yum update -y aws*\n",
        ". /etc/profile.d/aws-apitools-common.sh\n",
        "# Configure iptables\n",
        "/sbin/iptables -t nat -A POSTROUTING -o eth0 -s 0.0.0.0/0 -j MASQUERADE\n",
        "/sbin/iptables-save &gt; /etc/sysconfig/iptables\n",
        "# Configure ip forwarding and redirects\n",
        "echo 1 &gt;  /proc/sys/net/ipv4/ip_forward &amp;&amp; echo 0 &gt;  /proc/sys/net/ipv4/conf/eth0/send_redirects\n",
        "mkdir -p /etc/sysctl.d/\n",
        "cat &lt;&lt;EOF &gt; /etc/sysctl.d/nat.conf\n",
        "net.ipv4.ip_forward = 1\n",
        "net.ipv4.conf.eth0.send_redirects = 0\n",
        "EOF\n",
        "# Download nat_monitor.sh and configure\n",
        "cd /root\n",
        "wget http://media.amazonwebservices.com/articles/nat_monitor_files/nat_monitor.sh\n",
        "# Wait for NAT #2 to boot up and update PrivateRouteTable2\n",
        "sleep 180\n",
        "NAT_ID=\n",
        "# CloudFormation should have updated the PrivateRouteTable2 by now (due to yum update), however loop to make sure\n",
        "while [ \"$NAT_ID\" == \"\" ]; do\n",
        "  sleep 60\n",
        "  NAT_ID=`/opt/aws/bin/ec2-describe-route-tables ", Ref( "priRtb2"),
        " -U https://ec2.", Ref("region"), ".amazonaws.com | grep 0.0.0.0/0 | awk '{print $2;}'`\n",
        "  #echo `date` \"-- NAT_ID=$NAT_ID\" &gt;&gt; /tmp/test.log\n",
        "done\n",
        "# Update NAT_ID, NAT_RT_ID, and My_RT_ID\n",
        "sed \"s/NAT_ID=/NAT_ID=$NAT_ID/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
        "sed \"s/NAT_RT_ID=/NAT_RT_ID=",
        Ref("priRtb2" ),
        "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
        "sed \"s/My_RT_ID=/My_RT_ID=",
        Ref("priRtb1"),
        "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
        "sed \"s/EC2_URL=/EC2_URL=https:\\/\\/ec2.",
        Ref("region"),
        ".amazonaws.com",
        "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
        "sed \"s/Num_Pings=3/Num_Pings=",
        Ref("nuPings"),
        "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
        "sed \"s/Ping_Timeout=1/Ping_Timeout=",
        Ref("pingTimeout"),
        "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
        "sed \"s/Wait_Between_Pings=2/Wait_Between_Pings=",
        Ref("pingWait"),
        "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
        "sed \"s/Wait_for_Instance_Stop=60/Wait_for_Instance_Stop=",
        Ref("instStopWait"),
        "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
        "sed \"s/Wait_for_Instance_Start=300/Wait_for_Instance_Start=",
        Ref("instStartWait"),
        "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
        "mv /root/nat_monitor.tmp /root/nat_monitor.sh\n",
        "chmod a+x /root/nat_monitor.sh\n",
        "echo '@reboot /root/nat_monitor.sh &gt; /tmp/nat_monitor.log' | crontab\n",
        "/root/nat_monitor.sh &gt; /tmp/nat_monitor.log &amp;\n"
        ])))
      end
  
    Resource("NAT2Instance") do
      Type("AWS::EC2::Instance")
      Metadata("Comment1", "Create NAT #2")
      Property("InstanceType", {
        "Ref" =&gt; [ "natType" ]
      })
      Property("KeyName", {
        "Ref" =&gt; [ "keyName" ]
      })
      Property("IamInstanceProfile", {
        "Ref" =&gt; [ "NATRoleProfile" ]
      })
      Property("SubnetId", {
        "Ref" =&gt; [ "pubSub2" ]
      })
      Property("SourceDestCheck", "false")
      Property("ImageID", FnFindInMap("AWSNATAMI", Ref("region"), "AMI"))
      Property("SecurityGroupIds", {
        "Ref" =&gt; [ "NATSecurityGroup" ]
      })
      Property("Tags", {
        "Key" =&gt; [ "Name" ],
        "Value" =&gt; [ "NAT #2" ],
      })
      Property("UserData", FnBase64(FnJoin("", [
                  "#!/bin/bash -v\n",
            "yum update -y aws*\n",
            "# Configure iptables\n",
            "/sbin/iptables -t nat -A POSTROUTING -o eth0 -s 0.0.0.0/0 -j MASQUERADE\n",
            "/sbin/iptables-save &gt; /etc/sysconfig/iptables\n",
            "# Configure ip forwarding and redirects\n",
            "echo 1 &gt;  /proc/sys/net/ipv4/ip_forward &amp;&amp; echo 0 &gt;  /proc/sys/net/ipv4/conf/eth0/send_redirects\n",
            "mkdir -p /etc/sysctl.d/\n",
            "cat &lt;&lt;EOF &gt; /etc/sysctl.d/nat.conf\n",
            "net.ipv4.ip_forward = 1\n",
            "net.ipv4.conf.eth0.send_redirects = 0\n",
            "EOF\n",
            "# Download nat_monitor.sh and configure\n",
            "cd /root\n",
            "wget http://media.amazonwebservices.com/articles/nat_monitor_files/nat_monitor.sh\n",
            "# Update NAT_ID, NAT_RT_ID, and My_RT_ID\n",
            "sed \"s/NAT_ID=/NAT_ID=",
            Ref("NAT1Instance"),
            "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
            "sed \"s/NAT_RT_ID=/NAT_RT_ID=",
            Ref("priRtb1"),
            "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
            "sed \"s/My_RT_ID=/My_RT_ID=",
            Ref("priRtb2"),
            "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
            "sed \"s/EC2_URL=/EC2_URL=https:\\/\\/ec2.",
            Ref("region"), ".amazonaws.com",
            "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
            "sed \"s/Num_Pings=3/Num_Pings=",
            Ref("nuPings"),
            "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
            "sed \"s/Ping_Timeout=1/Ping_Timeout=",
            Ref("pingTimeout"),
            "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
            "sed \"s/Wait_Between_Pings=2/Wait_Between_Pings=",
            Ref("pingWait"),
            "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
            "sed \"s/Wait_for_Instance_Stop=60/Wait_for_Instance_Stop=",
            Ref("instStopWait"),
            "/g\" /root/nat_monitor.tmp &gt; /root/nat_monitor.sh\n",
            "sed \"s/Wait_for_Instance_Start=300/Wait_for_Instance_Start=",
            Ref("instStartWait"),
            "/g\" /root/nat_monitor.sh &gt; /root/nat_monitor.tmp\n",
            "mv /root/nat_monitor.tmp /root/nat_monitor.sh\n",
            "chmod a+x /root/nat_monitor.sh\n",
            "echo '@reboot /root/nat_monitor.sh &gt; /tmp/nat_monitor.log' | crontab\n",
            "/root/nat_monitor.sh &gt;&gt; /tmp/nat_monitor.log &amp;\n"
        ])))
      end
  
    Resource("NATSecurityGroup") do
      Type("AWS::EC2::SecurityGroup")
      Property("GroupDescription", "Rules for allowing access to HA Nodes")
      Property("VpcId", {
        "Ref" =&gt; [ "vpcId" ]
      })
      Property("SecurityGroupIngress", [
        {
          "CidrIp"     =&gt; "0.0.0.0/0",
          "FromPort"   =&gt; "22",
          "IpProtocol" =&gt; "tcp",
          "ToPort"     =&gt; "22"
        },
        {
          "CidrIp"     =&gt; "0.0.0.0/0",
          "FromPort"   =&gt; "0",
          "IpProtocol" =&gt; "-1",
          "ToPort"     =&gt; "65535"
        }
      ])
      Property("SecurityGroupEgress", [
        {
          "CidrIp"     =&gt; "0.0.0.0/0",
          "FromPort"   =&gt; "0",
          "IpProtocol" =&gt; "-1",
          "ToPort"     =&gt; "65535"
        }
      ])
    end
  
    Resource("NATAllowICMP") do
      Type("AWS::EC2::SecurityGroupIngress")
      Property("GroupId", {
        "Ref" =&gt; [ "NATSecurityGroup" ]
      })
      Property("IpProtocol", "icmp")
      Property("FromPort", "-1")
      Property("ToPort", "-1")
      Property("SourceSecurityGroupId", {
        "Ref" =&gt; [ "NATSecurityGroup" ]
      })
    end
  
  }'
  </code></pre>
  
  <p>I am using a parameter file when generating json from my cfndsl</p>
  
  <pre><code>---
  region: "us-east-1"
  environment: "test"
  vpcId: "vpc-xxxxxxxx"
  vpcCidr: "10.0.0.0/16"
  keyName: "xxxxxx"
  pubSub1: "subnet-xxxxxxx"
  pubSub2: "subnet-xxxxxxx"
  priRtb1: "rtb-xxxxxxx"
  priRtb2: "rtb-xxxxxxx"
  natType: "t2.micro"
  nuPings: "3"
  pingTimeout: "1"
  pingWait: "2"
  instStopWait: "60"
  instStartWait: "300"
  </code></pre>