调用 UpdateStack 操作时发生错误(ValidationError):No updates are to be performed

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

检查对 aws cloudformation update-stack 的特定调用是否会导致进行任何更改的正确命令语法是什么?

我们遇到的问题是 运行s 一个 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 响应代码,我们可以从 this documentation link 中看出这意味着可能发生了很多可能的问题。所以它不会帮助我们处理 254 响应代码。

我们可以键入什么 aws cloudformation cli 命令语法来让自动化进程在不进行任何更改的情况下接收 0 响应代码?例如,在 aws cloudformation update-stack ... 命令中添加一个 --flag 到 return 0 时不做任何更改。

或者,如果有一些预览命令 returned 0 表明不会进行任何更改,那么我们的自动化可以简单地避免在这种情况下调用 aws cloudformation update-stack ...

Terraform,例如,当出现此用例时,默认情况下只是简单地成功,同时报告在 运行 之后没有进行任何更改。

既然您要求创建“预览”,我建议您尝试创建一个 Change Set,查看它的输出,然后决定是否要执行它以防列出一些更改。

以下命令已在 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()

您可以使用 aws cloudformation deploy 命令代替 aws cloudformation update-stack

Documentation for aws cloudformation deploy

根据您的确切要求,可以使用链接文档中描述的以下两个标志:

--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 命令的另一个优点是它可以用于创建堆栈以及更新堆栈(如果它已经存在)。如果您对 deployupdate-stackcreate-stack 之间的区别特别感兴趣, 上一个问题提供了更多详细信息。