Произошла ошибка (ValidationError) при вызове операции UpdateStack: обновления не должны выполняться

Каков правильный синтаксис команды для проверки того, приведет ли конкретный вызов aws cloudformation update-stack к каким-либо изменениям?

Проблема заключается в том, что программа автоматизации, которая запускает команду aws cloudformation update-stack --stack-name ourstackname --template-body file://c:\path\to\ourtemplate.json --parameters ParameterKey=someKey,ParameterValue=someValue ..., дает следующую ошибку:

An error occurred (ValidationError) when calling the UpdateStack operation: No updates are to be performed.

Результатом является код ответа 254 http, который, как мы можем судить по эта ссылка на документацию, означает, что могло возникнуть множество возможных проблем. Таким образом, это НЕ поможет нам обработать этот код ответа 254.

Какой синтаксис команды aws cloudformation cli мы можем ввести вместо этого, чтобы процесс автоматизации получал код ответа 0 в тех случаях, когда не будут внесены изменения? Например, к команде aws cloudformation update-stack ... добавлен флаг --flag, чтобы возвращать 0, когда не вносятся изменения.

В качестве альтернативы, если бы какая-то команда предварительного просмотра возвращала 0, указывающую, что НИКАКИХ ИЗМЕНЕНИЙ НЕ БУДЕТ, тогда наша автоматизация могла бы просто воздержаться от вызова aws cloudformation update-stack ... в этой ситуации.

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

Можете ли вы привести какой-либо пример шаблона, который вы используете? ValidationError предполагают, что проблема в самом шаблоне, возможно, в его синтаксисе.

Marcin 19.03.2022 07:01

@CodeMed, можете ли вы просмотреть, поможет ли вам какой-либо из ответов?

tyron 22.03.2022 13:17

Пожалуйста, воздержитесь от использования блока цитат (>), если материал внутри него не является цитатой. «Цитата» — это высказывание другого человека или материал, содержащийся в книге, фильме, аудиозаписи, сценарии, периодическом издании и т. д. Цитаты, используемые просто в качестве выделения, затрудняют чтение сообщений, поскольку читатели должны вносить мысленные поправки в обычное значение. этого форматирования.

halfer 27.03.2022 11:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
137
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поскольку вы просите создать «предварительный просмотр», я предлагаю вам попробовать создать Изменить набор, просмотреть его вывод, а затем решить, хотите ли вы выполнить его, если будут перечислены некоторые изменения.

Приведенные ниже команды были протестированы в bash/zsh, вам может потребоваться немного настроить их в среде Windows (к сожалению, прямо сейчас у меня нет возможности протестировать их на компьютере с Windows).

# start the change-set and get its ID (note the extra change-set-name, output and query params)
myid=$(aws cloudformation create-change-set --change-set-name my-change --stack-name ourstackname --template-body file://ourtemplate.json --parameters ParameterKey=someKey,ParameterValue=someValue --output text --query Id)

# wait for your change-set to finish execution
aws cloudformation wait change-set-create-complete --change-set-name $myid 2> /dev/null

# get the result status in a variable
result_status=$(aws cloudformation describe-change-set --change-set-name $myid --output text --query Status)

# only executes the change-set if there were changes, aka Status is complete (if no changes, this will be FAILED)
[[ "$result_status" == "CREATE_COMPLETE" ]] && aws cloudformation execute-change-set --change-set-name $myid

# cleanup change-set afterwards if you want to re-use the name "my-change" from the 1st command, otherwise just leave it
aws cloudformation delete-change-set --change-set-name $myid

Обновлять: автор попросил Python, более отказоустойчивую версию реализации:

from typing import Dict, Tuple
import boto3
from botocore.exceptions import ClientError, WaiterError


def main():
    template_file = "../s3-bucket.yaml"

    with open(template_file) as template_fileobj:
        template_data = template_fileobj.read()

    client = boto3.client('cloudformation')
    changeset_applied = _create_and_execute_changeset(
        client, 'my-stack', 'my-changeset', template_data)
    print(changeset_applied)


def _create_and_execute_changeset(client: boto3.client, stack_name: str, changeset_name: str, template_body: str) -> bool:
    client.validate_template(TemplateBody=template_body)

    response_create_changeset = client.create_change_set(
        StackName=stack_name,
        ChangeSetName=changeset_name,
        TemplateBody=template_body,
    )
    changeset_id = response_create_changeset['Id']
    apply_changeset = True

    waiter = client.get_waiter('change_set_create_complete')
    try:
        waiter.wait(ChangeSetName=changeset_id)
    except WaiterError as ex:
        if ex.last_response['Status'] == 'FAILED' and ex.last_response['StatusReason'].startswith('The submitted information didn\'t contain changes'):
            apply_changeset = False
        else:
            raise

    if apply_changeset:
        client.execute_change_set(ChangeSetName=changeset_id)
        # executed changesets cleanup automatically
    else:
        # cleanup changeset not executed
        client.delete_change_set(ChangeSetName=changeset_id)

    return apply_changeset


if __name__ == '__main__':
    main()

@CodeMed ха, отличный вопрос! Если вы спрашиваете об этом, возможно, вы не знаете о несколько скрытой функции boto3: waiters. Я посмотрю, смогу ли я работать с версией этого кода, работающей на Python, но пока я собираюсь добавить хотя бы эту часть в свой ответ выше.

tyron 22.03.2022 22:25

Я не уверен, понимаю ли я ваш запрос сейчас... Когда вы говорите «простой питон», вы используете Python для вызова AWS cli вместо использования библиотек? Может быть, вы можете предоставить образцы того, что у вас есть, чтобы мы могли лучше понять...

tyron 23.03.2022 03:47

забыл отметить @CodeMed в своем комментарии

tyron 23.03.2022 18:26

@CodeMed Я говорю, что в настоящее время мне трудно понять, что вы ищете. В вашем вопросе есть команды CLI. CLI предназначен для запуска на терминале: bash, PowerShell, каком-то типе, но все же на терминале. Вы только что упомянули Python в комментарии здесь. Вызов API AWS из «python без библиотек» очень сложен, так как вам нужно обрабатывать аутентификацию. Поэтому я считаю, что в вашем рабочем процессе есть что-то, чем вы не делитесь. Вот почему я попросил вас предоставить пример кода того, что/как вы работаете, иначе вам будет сложно помочь.

tyron 23.03.2022 22:43

«Пожалуйста, покажите более устойчивый способ дождаться завершения создания набора изменений», что не так с текущим подходом в ответе?

tyron 23.03.2022 22:48

любая из этих команд вызовет ошибки в python. ваш код (aws cloudformation update-stack) выдаст ошибку, так как aws не определен. вы скрываете некоторые важные детали от вашей установки

tyron 24.03.2022 01:52

Давайте продолжить обсуждение в чате.

tyron 24.03.2022 01:53

@CodeMed Я снова обновил свой ответ. Мне придется не согласиться с вызовом subprocess в Python как «выполнение этого кода в python» (из вашего 1-го комментария здесь). Как вы сказали, на самом деле вы просто вызываете команды оболочки из Python, но это может быть любой язык. Если вам нужна отказоустойчивая реализация, я настоятельно рекомендую вам использовать собственные библиотеки (boto) и собственный код Python, чтобы вы могли анализировать и обрабатывать исключения. Я добавил полный рабочий (и отказоустойчивый) пример этого кода на Python. Если это не то, что вы ищете, я рекомендую вам просмотреть свой вопрос и быть более конкретным

tyron 25.03.2022 01:47

Мы не воспользовались вашим предложением boto, потому что нашли очень устойчивый подход с использованием простого Python, который использует меньше кода и не требует от наших пользователей добавления boto. Но мы помечаем ваш ответ как принятый, потому что вы потратили на него много времени, и потому что мы использовали ваши команды cli в качестве отправной точки для создания того, что мы фактически использовали.

CodeMed 25.03.2022 20:58

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

tyron 25.03.2022 21:13

Вместо aws cloudformation update-stack вы можете использовать команду aws cloudformation deploy.

Документация по развертыванию aws cloudformation

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

--no-execute-changeset (boolean) Indicates whether to execute the change set. Specify this flag if you want to view your stack changes before executing the change set. The command creates an AWS CloudFormation change set and then exits without executing the change set. After you view the change set, execute it to implement your changes.

--fail-on-empty-changeset | --no-fail-on-empty-changeset (boolean) Specify if the CLI should return a non-zero exit code if there are no changes to be made to the stack. The default behavior is to return a zero exit code.

Еще одно преимущество использования команды deploy заключается в том, что ее можно использовать для создания стека, а также для обновления стека, если он уже существует. Если вас конкретно интересуют различия между deploy и update-stack или create-stack, этот ответ к предыдущему вопросу содержит более подробную информацию.

Я думаю, что с deploy, если вы пройдете --no-execute-changeset --no-fail-on-empty-changeset, вы не будете знать, не было ли изменений или было бы успешно завершено даже с изменениями. И передача --no-execute-changeset --fail-on-empty-changeset приведет к той же проблеме, что и сегодня, код ошибки без особой информации. И вы все еще можете выполнить набор изменений позже. По моему опыту, deploy действительно полезен только в том случае, если вы хотите закрыть глаза и выполнять его всегда, иначе у вас будет более детальный контроль над другими командами.

tyron 20.03.2022 02:41

Другие вопросы по теме