Назад | Перейти на главную страницу

Получение информации из одного стека CloudFormation для использования в другом

Я пытаюсь настроить конвейер сборки для веб-сервиса в AWS. План состоит в том, чтобы служба запускалась в группе автоматического масштабирования и использовала Jenkins для создания единственного экземпляра EC2, запуска тестов и, в случае успеха, создания образа экземпляра и передачи его существующей группе автоматического масштабирования.

Чтобы создать все необходимые для этого ресурсы, я создал два шаблона CloudFormation: один для создания группы автомасштабирования и окружающих ресурсов, а другой - для создания единственного тестируемого экземпляра.

Однако я заметил проблему: существуют разные базовые изображения для каждого региона и каждого типа экземпляра EC2. Это означает, что Дженкинсу необходимо знать регион и тип инстанса, для которого будет производиться сборка.

Идеальное решение будет способом выбрать целевой стек CloudFormation и получить оттуда информацию (регион, тип экземпляра и т. д.). Это означает, что если мы внесем какие-либо изменения в Auto Scale Group, они автоматически отразятся в сборке Jenkins. Если мы создали вторую группу, мы можем скопировать задание Jenkins и изменить один параметр, чтобы он указывал на новый стек. Но это не вариант ...

Вот возможные решения, которые я могу придумать, но ни одно из них мне не особенно нравится:

Мне кажется, что то, что я хочу делать, не должно быть таким трудным, но я не могу придумать лучший способ сделать это.

CloudFormation включает псевдопараметр AWS::Region где он может запрашивать регион, в котором он работает. Видеть http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html

Вы можете использовать сопоставления, чтобы получить список образов AMI, в котором вы выбираете свой AMI в зависимости от региона. Видеть http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html

Обычно выбор AMI не зависит от типа экземпляра. Однако я не знаком с вашим вариантом использования, поэтому это может иметь значение.

Что касается вашего рабочего процесса, я бы не стал «вносить изменения» в вашу группу автомасштабирования. Он должен пойти другим путем: внести изменения в шаблоны CloudFormation, которые, в свою очередь, обновят ваши стеки, чтобы обновить группы автомасштабирования.

Итак, вы бы:

  1. Создайте единый экземпляр из шаблона CFN, убедитесь, что он работает, и создайте новый AMI.
  2. Возьмите новый идентификатор изображения AMI и обновите шаблон CFN вашей группы Autoscale.
  3. Обновите свою группу Autoscale, обновив ее стек

Опасность внесения изменений непосредственно в вашу группу автомасштабирования заключается в том, что эти изменения не будут отражены в шаблоне стека. Если вам нужно было перестроить стек или сделать копию, в нем не будет этих изменений. В идеале ресурсы, созданные из стека CloudFormation, должны рассматриваться как доступные только для чтения и обновляться только путем внесения изменений в шаблон CFN.

Определите информацию, которую необходимо передать как выходные данные из первого стека. Использовать псевдопараметры для региона и др.

Когда вы создаете второй стек, вызовите description-stack для первого, чтобы получить выходные данные, и передайте значения в качестве параметров во второй стек.

Немного лучший вариант, чем перечисленные выше (и фактически возможный), - это использовать инструмент AWS CLI для получения информации о текущих стеках. Это можно обернуть в скрипт, чтобы взять возвращенный JSON и найти желаемые параметры / выходы.

Он по-прежнему немного запутывает его, перемещая его во внешний скрипт, а не помещая в шаблон CloudFormation, поэтому я собираюсь оставить вопрос открытым в надежде, что у кого-то есть лучший ответ.

Вот абсурдно простой пример:

<?php

$result = `aws cloudformation describe-stacks --stack-name=GROUPSTACKNAME`;
$stack = json_decode($result);
$stack = $stack->Stacks[0];

if(!$stack) {
    throw new Exception("Stack no found");
}

$parameters = [];
foreach($stack->Parameters as $param) {
    $parameters[$param->ParameterValue] = $param->ParameterKey;
}

echo http_build_query($parameters);