Boto3云编排错误:模板格式错误:不支持的结构。

4

我无法将参数加载到Python boto3 Cloudformation客户端中。

以下是我的参数文件:

[
  {"ParameterKey": "pVpcId",   "ParameterValue": "vpc-XXXXXX"},
  {"ParameterKey": "pContact", "ParameterValue": "XDXDXX"},
  {"ParameterKey": "pCC",      "ParameterValue": "XXXXX" },
  {"ParameterKey": "pFormat",  "ParameterValue": "True"}
]

我将它以以下方式加载到程序中:
    with open(parameter_file, 'r') as infile:
        parameters=ast.literal_eval(infile.read())
        client = boto3.client('cloudformation',aws_access_key_id=access_key,aws_secret_access_key=secret_key,aws_session_token=session_token,region_name=region)

        response = client.create_stack(
            StackName=stack_name,
            TemplateURL=stack_url,
            Parameters=parameters
        )

当我使用Cloudformation建立一个boto3客户端并调用它时,出现了以下描述的错误。如果不带参数调用,则可以正常工作,因此问题肯定与参数文件有关。

    Traceback (most recent call last):
    File "cf_create_stack", line 85, in <module>
        Parameters=parameters
    File "/usr/lib/python2.7/site-packages/botocore/client.py", line 357, in _api_call
        return self._make_api_call(operation_name, kwargs)
    File "/usr/lib/python2.7/site-packages/botocore/client.py", line 661, in _make_api_call
        raise error_class(parsed_response, operation_name)
    botocore.exceptions.ClientError: An error occurred (ValidationError) when calling the CreateStack operation: Template format error: unsupported structure.

你尝试过从CLI执行同样的操作吗?https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html。 - asr9
以下是关于@swap709的反馈意见,我想要百分之百确定。 - Alex Harvey
3个回答

4

因此,TemplateBody参数期望CloudFormation模板文件的内容/字符串,而不仅仅是文件名。

以下内容应该可以令人满意地工作。

cf_template = open('batch-job-cft.yml').read()
cf_client.create_stack(StackName='Batch Job', TemplateBody=cf_template)

# OR

# Optimal usage would be as below
with open('batch-job-cft.yml', 'r') as cf_file:
    cft_template = cf_file.read()
    cf_client.create_stack(StackName='Batch Job', TemplateBody=cft_template)

谢谢,我卡在这里很久了。大多数示例都只传递“file://”,这在boto中不起作用。 - SlideM

1

我相信你提供的代码样例不可能得到那样的响应。

我认为你可能尝试了TemplateBody而不是TemplateURL

为了重现错误信息,请尝试这个简单的示例:

#!/usr/bin/env python

import boto3
import ast

parameter_file = 'parameters.json'

client = boto3.client('cloudformation')

with open(parameter_file, 'r') as infile:
    parameters = ast.literal_eval(infile.read())

response = client.create_stack(
    StackName='TestStack',
    TemplateBody='file://cloudformation.yml',
    Parameters=parameters
)

如果您将参数文件和模板放置在预期位置并运行此程序,则应该看到与您当前看到的完全相同的错误消息:
Traceback (most recent call last):
  File "test.py", line 17, in <module>
    Parameters=parameters
  File "/Users/alexharvey/git/home/python-test/virtualenv/lib/python2.7/site-packages/botocore/client.py", line 357, in _api_call                                     
    return self._make_api_call(operation_name, kwargs)
  File "/Users/alexharvey/git/home/python-test/virtualenv/lib/python2.7/site-packages/botocore/client.py", line 661, in _make_api_call                                
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ValidationError) when calling the CreateStack operation: Template format error: unsupported structure.            

请注意,这个错误信息来自于AWS API而非Boto3。
当你将一个file:// URI或者URL传递给TemplateBody参数时会导致该错误。
此外,如果你真的向TemplateURL传递了任何内容,我认为很可能无法得到那个响应。
另请参考:
- this相关答案,用于复制使用AWS CLI时出现的错误消息。 - API文档中记录了TemplateBody和TemplateURL的信息。

1
这是我解决问题的方法:
  1. 为了加载参数文件(它作为字典列表加载),我使用了以下代码:

    with open(parameter_file) as f: parameters=json.load(f)

    for l in parameters: l['UsePreviousValue']=eval('False')

  2. 为了传递 Cloudformation 模板,我使用了以下代码(基本上将其读取为字符串):

    with open(cloudformation_template) as g: template_body=g.read()

最后,我将这两个变量传递给 Cloudformation 客户端:

response = client.create_stack(
    StackName=stack_name,
    TemplateBody=template_body,
    Parameters=parameters
)

我遇到的问题是,boto3的'Cloudformation'客户端期望参数为“字典列表”,但对于cloudformation模板,它期望一个“字符串”。这非常令人沮丧,我正在尝试找到一种方法将此问题提高到AWS。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接