Есть ли способ определить ярлыки для часто используемых значений, полученных из параметров шаблона CloudFormation?
Например - у меня есть скрипт, который создает стек проекта Multi-AZ с именем ELB project
и двумя экземплярами позади ELB, которые называются project-1
и project-2
. Я только передаю ELBHostName
параметр в шаблон и позже использую его для построения:
"Fn::Join": [
".", [
{ "Fn::Join": [ "", [ { "Ref": "ELBHostName" }, "-1" ] ] },
{ "Ref": "EnvironmentVersioned" },
{ "Ref": "HostedZone" }
]
]
Эта или очень похожая конструкция повторяется много раз по всему шаблону - для создания имени хоста EC2, записей Route53 и т. Д.
Вместо того, чтобы повторять это снова и снова, я хотел бы присвоить вывод этой Fn::Join
переменной некоторой переменной и ссылаться только на это, точно так же, как я могу с "Ref":
утверждением.
В идеале что-то вроде:
Var::HostNameFull = "Fn::Join": [ ... ]
...
{ "Name": { "Ref": "Var::HostNameFull" } }
или что-то такое же простое.
Это возможно с Amazon CloudFormation?
Ответы:
Я искал ту же функциональность. Мне пришло в голову использовать вложенный стек, как предложил SpoonMeiser, но потом я понял, что на самом деле мне нужны пользовательские функции. К счастью, CloudFormation позволяет использовать AWS :: CloudFormation :: CustomResource, который, немного поработав, позволяет сделать именно это. Это похоже на излишество только для переменных (я бы сказал, что это должно было произойти в CloudFormation в первую очередь), но оно выполняет свою работу и, кроме того, учитывает всю гибкость (выбирайте python / node /Джава). Следует отметить, что лямбда-функции стоят денег, но мы говорим здесь ни копейки, если вы не создаете / удаляете свои стеки несколько раз в час.
Первым шагом является создание лямбда-функции на этой странице, которая делает только входные значения и копирует их в выходные данные. Мы могли бы заставить лямбда-функцию делать всякие сумасшедшие вещи, но как только мы получим функцию идентификации, все остальное будет легко. В качестве альтернативы мы можем создать лямбда-функцию в самом стеке. Поскольку я использую много стеков в 1 учетной записи, у меня будет целая куча оставшихся лямбда-функций и ролей (и все стеки должны быть созданы с помощью
--capabilities=CAPABILITY_IAM
, так как для этого также нужна роль.Создать лямбда-функцию
index.handler
Затем скопируйте и вставьте приведенный ниже код в поле кода. Верхняя часть функции - это код из модуля Python cfn-response , который автоматически устанавливается, только если лямбда-функция создается через CloudFormation, по какой-то странной причине.
handler
Функция довольно очевидна.Теперь вы можете протестировать лямбда-функцию, нажав кнопку «Тест» и выбрав «CloudFormation Create Request» в качестве примера шаблона. Вы должны увидеть в своем журнале, что переменные, переданные ему, возвращаются.
Используйте переменную в вашем шаблоне CloudFormation
Теперь, когда у нас есть эта лямбда-функция, мы можем использовать ее в шаблонах CloudFormation. Сначала запишите лямбда-функцию Arn (перейдите на домашнюю страницу lambda , нажмите на только что созданную функцию, Arn должен быть вверху справа, что-то вроде
arn:aws:lambda:region:12345:function:CloudFormationIdentity
).Теперь в вашем шаблоне, в разделе ресурсов, укажите ваши переменные, такие как:
Сначала я указываю
Identity
переменную, которая содержит Arn для лямбда-функции. Помещение этого в переменную здесь означает, что я должен указать это только один раз. Я делаю все мои переменные типаCustom::Variable
. CloudFormation позволяет использовать любое имя типа, начиная сCustom::
пользовательских ресурсов.Обратите внимание, что
Identity
переменная содержит Arn для лямбда-функции дважды. Один раз указать лямбда-функцию для использования. Второй раз в качестве значения переменной.Теперь, когда у меня есть
Identity
переменная, я могу определить новые переменные, используяServiceToken: !GetAtt [Identity, Arn]
(я думаю, что код JSON должен быть примерно таким"ServiceToken": {"Fn::GetAtt": ["Identity", "Arn"]}
). Я создаю 2 новые переменные, каждая с 2 полями: Имя и Арн. В остальной части моего шаблона я могу использовать!GetAtt [ClientBucketVar, Name]
или!GetAtt [ClientBucketVar, Arn]
когда мне это нужно.Слово предостережения
Если при работе с пользовательскими ресурсами происходит сбой лямбда-функции, вы зависаете от 1 до 2 часов, потому что CloudFormation ждет ответа от (сбойной) функции в течение часа, прежде чем сдаться. Поэтому, возможно, было бы неплохо указать короткое время ожидания для стека при разработке вашей лямбда-функции.
источник
cloudformation-tool
гема), поэтому я упаковываю создание лямбды в шаблон, а затем может использовать его напрямую вместо созданияIdentity
пользовательского ресурса. Смотрите здесь для моего кода: gist.github.com/guss77/2471e8789a644cac96992c4102936fb3У меня нет ответа, но я хочу отметить, что вы можете сэкономить много боли, используя
Fn::Sub
вместоFn::Join
Заменяет
источник
Нет, я попробовал, но вышел пустым. Способ, который имел смысл для меня, состоял в том, чтобы создать запись Mappings под названием «CustomVariables» и поместить в нее все мои переменные. Он работает для простых строк, но вы не можете использовать Intrinsics (Refs, Fn :: Joins и т. Д.) Внутри Mappings .
Работает:
Не будет работать:
Это всего лишь пример. Вы бы не поместили автономный Ref в переменную.
источник
Вы можете использовать вложенный стек, который разрешает все ваши переменные в его выходных данных, а затем использовать
Fn::GetAtt
для чтения выходных данных из этого стека.источник
Вы можете использовать вложенные шаблоны, в которых вы «разрешаете» все свои переменные во внешнем шаблоне и передаете их в другой шаблон.
источник