AWS: CloudFormation – ‘templateBody’ failed to satisfy constraint: Member must have length less than or equal to 51200

By | 09/06/2018
 

Имеется CloudFormation стек.

Сначала создавался Dev-стек, к которому понемногу добавлялись новые ресурсы, всё это тестилось, и в конце-концов заработало.

После этого – пришла пора выкатывать Production-стек, и вдруг…

‘templateBody’ failed to satisfy constraint: Member must have length less than or equal to 51200.

Щито? 🙁

Проверяем лимиты CloudFormation:

Template body size in a request Maximum size of a template body that you can pass in aCreateStackUpdateStack, or ValidateTemplaterequest. 51,200 bytes To use a larger template body, separate your template into multiple templates by using, for example, nested stacks. Or upload the template to an Amazon S3 bucket.

Вариантов решения проблемы два:

  1. разделить ресурсы шаблона на несколько шаблонов, и часть подгружать через AWS::Include – но вложенные шаблоны должны лежать в S3-корзине, что сам по себе уже неудобно, плюс там есть ещё ограничения
  2. использовать препроцессор, который уменьшит размер шаблона, например cfn-include

Устанавливаем npm:

sudo pacman -S npm

Устанавливаем cfn-include:

sudo npm install --global cfn-include

Проверяем:

cfn-include -h
Usage: cfn-include [path] [options]
path     location of template. Either path to a local file, URL or file on an S3 bucket (e.g. s3://bucket-name/example.template)
Options:
-m, --minimize   minimize JSON output  [false]
--metadata       add build metadata to output  [false]
-t, --validate   validate compiled template  [false]
-y, --yaml       output yaml instead of json  [false]
--version        print version and exit

Пробуем уменьшить размер шаблона:

cfn-include -m dme-stack-origin.json > dme-stack-minimized.json

Проверяем:

-rw-r--r-- 1 setevoy setevoy 34K Sep  5 17:25 dme-stack-minimized.json
-rw-r--r-- 1 setevoy setevoy 51K Sep  5 17:24 dme-stack-origin.json

cfn-include убрал всё форматирование, и весь шаблон теперь являет собой одну строку:

cat roles/cloudformation/files/dme-stack-minimized.json
{"AWSTemplateFormatVersion":"2010-09-09","Description":"AWS CloudFormation DME stack","Parameters":{"StackRegion":{"Description":"Region to crate a stack in","Type":"String"},"ENV":{"Description":"Environment type: dme-test for testing, dme-dev or dme-production, taken from Ansible vars","Type":"String","AllowedValues":["dme-test","dme-dev","dme-production"]},
...

Тогда как в оригинальном шаблоне JSON выглядит так:

head -n 17 roles/cloudformation/files/dme-stack-origin.json
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation DME stack",
"Parameters": {
"StackRegion": {
"Description" : "Region to crate a stack in",
"Type" : "String"
},
"ENV": {
"Description": "Environment type: dme-test for testing, dme-dev or dme-production, taken from Ansible vars",
"Type": "String",
"AllowedValues" : [ "dme-test", "dme-dev", "dme-production" ]
},

Пока cfn-include хватает –  можно создавать стек:

Готово.