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

Автор: | 06/09/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:

[simterm]

$ sudo pacman -S npm

[/simterm]

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

[simterm]

$ sudo npm install --global cfn-include

[/simterm]

Проверяем:

[simterm]

$ 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

[/simterm]

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

[simterm]

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

[/simterm]

Проверяем:

[simterm]

-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

[/simterm]

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

[simterm]

$ 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"]},
...

[/simterm]

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

[simterm]

$ 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" ]
    },

[/simterm]

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

Готово.