I have a cloudformation template.
It should create an EC2 instance, change the Adminstrator password and rename the server.
I am passing couple of parameters to the stack template. When I run it, it gives "Template format error: Every Mappings member Type must be a map".
I made sure whatever I am referring in the template, are in the "Mappings" section. Not sure why I am getting this error.
Any suggestions are very helpful.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"LocalAdminPassword" :
{
"Type": "String",
"NoEcho" : "true",
"Description": "Password for the local server administrator account."
}
},
"Mappings": {
"EnvironmentTypeName" :
{
"PlatformName" : {"Dev" : "D", "Test" : "T", "Prod" : "P"}
},
"QRMEnvironmentType" :
{
"Description" : "QRM Dev, test, or Prod Platform",
"Type" : "String",
"AllowedValues" : ["Dev", "Test", "Prod"],
"Default" : "Dev",
"ConstraintDescription" : "must be either Dev, test, or Prod"
},
"QRMAvailabilityZoneIndex" :
{
"Description" : "QRM Platform AZ letter A,B, or C for Dev, Test, or Prod",
"Type" : "String",
"AllowedValues" : ["A", "B", "C"],
"Default" : "A",
"ConstraintDescription" : "Must be a letter of the AZ in the specified Region"
}
},
"Resources": {
"MyInstance": {
"Type": "AWS::EC2::Instance",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"files" : {
"c:\\cfn\\cfn-hup.conf" : {
"content" : { "Fn::Join" : ["", [
"[main]\n",
"stack=", { "Ref" : "AWS::StackId" }, "\n",
"region=", { "Ref" : "AWS::Region" }, "\n"
]]}
},
"c:\\cfn\\hooks.d\\cfn-auto-reloader.conf" : {
"content": { "Fn::Join" : ["", [
"[cfn-auto-reloader-hook]\n",
"triggers=post.update\n",
"path=Resources.MyInstance.Metadata.AWS::CloudFormation::Init\n",
"action=cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" },
" -r MyInstance",
" --region ", { "Ref" : "AWS::Region" }, "\n"
]]}
},
"c:\\scripts\\test.ps1" : {
"content": { "Fn::Join" : ["", [
"Write-Host Hello World!\n"
]]}
}
},
"commands" : {
"1-run-script" :
{
"command" :
{
"Fn::Join" :
[
"",
[
"Powershell.exe ([adsi]\\\"WinNT://$env:computername/Administrator\\\").SetPassword('",{ "Ref": "LocalAdminPassword"},"')"
]
]
}
},
"02-rename-server" :
{
"command" :
{
"Fn::Join" :
[
"",
[
"powershell.exe Rename-Computer -NewName ", {"Fn::Join" : [ "",[ "AW", {"Fn::FindInMap" : [ "EnvironmentTypeName", "PlatformName", {"Ref" : "QRMEnvironmentType"} ]},"W",{"Ref": "QRMAvailabilityZoneIndex"},"QRMHEAD"]] } ," -force -restart"
]
]
},
"WaitAfterCompletion" : "forever"
},
"3-run-script" : {
"command" : { "Fn::Join" : [ "", [
"Powershell.exe Set-ExecutionPolicy Unrestricted -force \n",
"Powershell.exe C:\\scripts\\test.ps1 \n",
"Powershell.exe Start-Sleep -s 60; . C:\\PowershellScripts\\WindowsServiceManager.ps1;StopWindowsService Dnscache" , "\n"
]]}}
},
"services": {
"windows": {
"cfn-hup": {
"enabled": "true",
"ensureRunning": "true",
"files": ["c:\\cfn\\cfn-hup.conf", "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf"]
}
}
}
}
}
},
"Properties": {
"DisableApiTermination": "FALSE",
"ImageId": "ami-3723c04f",
"InstanceType": "t2.micro",
"KeyName": "EC2Instances",
"Monitoring": "false",
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"<script>\n",
"cfn-init.exe -v -s ", { "Ref" : "AWS::StackName" },
" -r MyInstance",
" --region ", { "Ref" : "AWS::Region" }, "\n",
"cfn-signal.exe -e 0 ", { "Fn::Base64" : { "Ref" : "WindowsServerWaitHandle" }}, "\n",
"</script>\n"
]]}},
"Tags": [
{
"Key": "Name",
"Value": "MyEC2Instance"
}
],
}
,
"WindowsServerWaitHandle": {
"Type": "AWS::CloudFormation::WaitConditionHandle"
},
"WindowsServerWaitCondition": {
"Type": "AWS::CloudFormation::WaitCondition",
"DependsOn": "MyInstance",
"Properties": {
"Handle": { "Ref": "WindowsServerWaitHandle" },
"Timeout": "1800"
}
}
}
}
To check your template file for syntax errors, you can use the aws cloudformation validate-template command. The aws cloudformation validate-template command is designed to check only the syntax of your template.
The optional Mappings section matches a key to a corresponding set of named values. For example, if you want to set values based on a region, you can create a mapping that uses the region name as a key and contains the values you want to specify for each specific region.
You can author AWS CloudFormation templates in JSON or YAML formats.
If it isn't, CloudFormation checks if the template is valid YAML. If both checks fail, CloudFormation returns a template validation error. You can validate templates locally by using the --template-body parameter, or remotely with the --template-url parameter.
I had the same problem with yaml template. It looks like only 2-level mappings are supported in the template, so you need to add another level where relevant, eg,
...
"QRMEnvironmentType" :
{
"Description" : {"Value": "QRM Dev, test, or Prod Platform"},
"Type" : {"Value": "String"},
...
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With