boto / boto3

AWS SDK for Python
https://aws.amazon.com/sdk-for-python/
Apache License 2.0
8.99k stars 1.86k forks source link

Parameter validation failed, Invalid type for parameter when the parameter is correct #4154

Closed jyriatntt closed 3 months ago

jyriatntt commented 3 months ago

Describe the bug

When I create a list for an example and try to pass it to CloudFormation a_list = ["b", "c"] cloudformation.update_generated_template( GeneratedTemplateName=fw_stack_name, AddResources=a_list ) it fails on botocore.exceptions.ParamValidationError: Parameter validation failed: Invalid type for parameter AddResources, value: <function a_list at 0x102301580>, type: <class 'function'>, valid types: <class 'list'>, <class 'tuple'>

Expected Behavior

I would expect that botocore uses a_list as a 'list' and not as a 'function'. The fw_stack_name string variable works fine.

Current Behavior

$ ./runscript.py ✘ 1 2024-06-04 15:21:02,631 botocore.hooks [DEBUG] Event before-parameter-build.cloudformation.UpdateGeneratedTemplate: calling handler <function generate_idempotent_uuid at 0x103b7d760> 2024-06-04 15:21:02,631 botocore.regions [DEBUG] Calling endpoint provider with parameters: {'Region': 'us-east-1', 'UseDualStack': False, 'UseFIPS': False} 2024-06-04 15:21:02,632 botocore.regions [DEBUG] Endpoint provider result: https://cloudformation.us-east-1.amazonaws.com Traceback (most recent call last): File "/Users/test/runscript.py", line 108, in result = fw_stack() ^^^^^^^^^^ File "/Users/test/runscript.py", line 54, in fw_stack result = cloudformation.update_generated_template( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/lib/python3.12/site-packages/botocore/client.py", line 565, in _api_call return self._make_api_call(operation_name, kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/lib/python3.12/site-packages/botocore/client.py", line 974, in _make_api_call request_dict = self._convert_to_request_dict( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/lib/python3.12/site-packages/botocore/client.py", line 1048, in _convert_to_request_dict request_dict = self._serializer.serialize_to_request( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/lib/python3.12/site-packages/botocore/validate.py", line 381, in serialize_to_request raise ParamValidationError(report=report.generate_report()) botocore.exceptions.ParamValidationError: Parameter validation failed: Invalid type for parameter AddResources, value: <function fw_stack at 0x102301580>, type: <class 'function'>, valid types: <class 'list'>, <class 'tuple'>

Reproduction Steps

!/usr/bin/env python3

import boto3

fw_stack = [ { "ResourceType": "AWS::NetworkFirewall::Firewall", "ResourceIdentifier": { "FirewallArn": "arn:aws:network-firewall:us-east-1:xxxxxxxxxxxx:firewall/NetworkFirewall" } }, { "ResourceType": "AWS::NetworkFirewall::FirewallPolicy", "ResourceIdentifier": { "FirewallPolicyArn": "arn:aws:network-firewall:us-east-1:xxxxxxxxxxxx:firewall-policy/firewall-policy" } } ]

fw_stack_name = "fwstack"

result = cloudformation.create_generated_template( GeneratedTemplateName=fw_stack_name, TemplateConfiguration={ 'DeletionPolicy': 'DELETE', 'UpdateReplacePolicy': 'DELETE' } )

result = cloudformation.update_generated_template( GeneratedTemplateName=fw_stack_name, AddResources=fw_stack # This doesn't work, boto doesn't know how to add list resource from a variable )

Possible Solution

No response

Additional Information/Context

No response

SDK version used

1.34.114

Environment details (OS name and version, etc.)

MacOS 14.5 (M2 chip), boto3 in /opt/homebrew/lib/python3.12/site-packages (1.34.114)

tim-finnigan commented 3 months ago

Thanks for reaching out. Here is the create_generated_template documentation for reference: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudformation/client/create_generated_template.html

Per the documentation, theGeneratedTemplateName parameter should be a string, but you're passing a list instead. This works for me:

import boto3

resources_to_include = [
    {
        "ResourceType": "AWS::NetworkFirewall::Firewall",
        "ResourceIdentifier": {
            "FirewallArn": "arn:aws:network-firewall:us-east-1:xxxxxxxxxxxx:firewall/NetworkFirewall"
        }
    },
    {
        "ResourceType": "AWS::NetworkFirewall::FirewallPolicy",
        "ResourceIdentifier": {
            "FirewallPolicyArn": "arn:aws:network-firewall:us-east-1:xxxxxxxxxxxx:firewall-policy/firewall-policy"
        }
    }
]

generated_template_name = "my-generated-template"

cloudformation = boto3.client('cloudformation')

result = cloudformation.create_generated_template(
    Resources=resources_to_include,
    GeneratedTemplateName=generated_template_name,
    TemplateConfiguration={
        'DeletionPolicy': 'DELETE',
        'UpdateReplacePolicy': 'DELETE'
    }
)
print(result)

And once the template is generated I can run:

result = cloudformation.update_generated_template(
    GeneratedTemplateName=generated_template_name,
    AddResources=resources_to_include
)

print(result)

Converting to a Q&A discussion since there does not appear to be an issue with Boto3. For requests involving the underlying CloudFormation API (CreateGeneratedTemplate) please create an issue in our cross-SDK repository and someone can reach out to the service team on your behalf.