3
votes

Erreur Boto3 Cloudformation: Erreur de format de modèle: structure non prise en charge

Je ne parviens pas à charger les paramètres dans le client Cloudformation python boto3.

Voici mon fichier de paramètres:

    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.

Je le charge dans le programme dans le manière suivante:

    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
        )

Lorsque j'établis un client boto3 avec Cloudformation et que je l'appelle, j'obtiens l'erreur décrite ci-dessous. L'appel fonctionne sans les paramètres, donc c'est certainement quelque chose à voir avec le fichier de paramètres.

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


2 commentaires

Avez-vous essayé la même chose avec CLI? docs.aws.amazon.com/cli/latest/ reference / cloudformation /… .


Des commentaires sur le @ swap709 ci-dessous? Je voudrais être sûr à 100%.


3 Réponses :


0
votes

Je pense qu'il est impossible que vous ayez cette réponse basée sur l'exemple de code que vous avez fourni.

Je pense que vous avez peut-être essayé TemplateBody plutôt que TemplateURL ?

Pour reproduire le message d'erreur, essayez cet exemple simple:

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.            

Si vous placez le fichier de paramètres et le modèle aux emplacements prévus et exécutez ceci, vous devez puis voyez le message d'erreur exact que vous voyez:

#!/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
)

Notez que cette erreur:

Erreur de format de modèle: structure non prise en charge

Provient de l ' API AWS , pas Boto3.

L'erreur se produit lorsque vous transmettez un fichier: // URI ou URL du paramètre TemplateBody.

De plus, je pense qu'il est tout simplement impossible d'obtenir cette réponse si vous avez vraiment transmis quelque chose à TemplateURL.

Voir aussi:


0 commentaires

1
votes

Voici comment j'ai pu résoudre ce problème:

  1. Afin de charger le fichier de paramètres (qui se charge sous forme de liste de dictionnaires), j'avais le code suivant:

    avec open (parameter_file) comme f: paramètres = json.load (f)

    pour l dans les paramètres: l ['UsePreviousValue'] = eval ('False')

  2. Afin de transmettre le modèle Cloudformation, j'ai utilisé le code suivant (en le lisant essentiellement sous forme de chaîne):

    avec open (cloudformation_template) comme g: template_body = g.read ()

Enfin, j'ai passé les deux variables dans le client cloudformation:

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

Ce qui n'allait pas pour moi, c'est que le client boto3 'Cloudformation' attend un 'liste de dictionnaires' pour les paramètres mais attend une 'chaîne' pour le modèle cloudformation.

C'est très frustrant et j'essaie de trouver un moyen de faire remonter cela à AWS.


0 commentaires

3
votes

Le paramètre TemplateBody attend donc le contenu / str du fichier de modèle CloudFormation et pas seulement le nom de fichier.

Ce qui suit devrait fonctionner de manière satisfaisante.

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)


1 commentaires

Merci, a été coincé là-dessus pendant trop longtemps. La plupart des exemples transmettent simplement le 'file: //' qui ne fonctionne pas avec boto.