This stumped me for a few hours yesterday while wanting to deploy a cloudformation stack to AWS via PowerShell using New-CFNStack instead of the console, I kept getting the following error:
Test-CFNTemplate : Template format error: unsupported structure.
Not overly helpful, I checked the path was correct, used relative and full file paths and tried with file:// before the file name but the error was still the same.
To check that there wasn’t an error in my cloudformation yaml file, I deployed it successfully via the AWS console and thought I’d try the Test-CFNTemplate command that accepted the -TemplateBody parameter but still failed with the same error message as New-CFNStack
Next I tried:
Test-CFNTemplate -TemplateBody (get-content .\amazon-linux-vm.yaml)
This gave the error:
Test-CFNTemplate : Cannot convert 'System.Object' to the type 'System.String' required by parameter 'TemplateBody'.
What gives here? Get-Content reads the file in and creates a list of objects for each line. If you were to save get content to a variable, then access the first item, you’d get the whole first line of the file returned.
$template = Get-Content -Path .\amazon-linux-vm.yaml $template AWSTemplateFormatVersion: 2010-09-09
Use the -Raw switch
The Raw switch, although not well documented at present, will read in the whole file as one big string object instead of a separate object per line. To demonstrate this:
$template1 = Get-Content -Path .\amazon-linux-vm.yaml $template1 A
See this post about Get-Content and why it’s not your friend on powershell.org
To read the file without line breaks, use the -Raw switch and the cmdlet should now work correctly.
Test-CFNTemplate -TemplateBody (Get-Content .\amazon-linux-vm.yaml -Raw)
The Test-CFNTemplate will now run correctly and you’ll be able to use New-CFNStack to deploy your resources via cloudformation with PowerShell making it easy to change the values of the parameters you pass in.