cloudtools / stacker

An AWS CloudFormation Stack orchestrator/manager.
http://stacker.readthedocs.io/en/stable/
BSD 2-Clause "Simplified" License
711 stars 167 forks source link

SSMStore - Must be <type 'str'>. Actual type <type 'unicode'>. #738

Open hduafg3 opened 5 years ago

hduafg3 commented 5 years ago

Stacker: stacker 1.7.0 Boto: boto3 1.9.187 Botocore: botocore 1.12.187

I'm using the ECS base for generating Fargate tasks. (https://github.com/cloudtools/stacker_blueprints/blob/master/stacker_blueprints/ecs.py)

I use ${ssmstore _____} throughout my stacks, but always in the Environment: blocks. Most frequently I store the path of the SSM parameter in an environment file, and call it like ${ssmstore ${example1_path}}.

I'm trying to use SSMStore in the Image: block of ECS, but get an error. Image: ${ecr_url}/company/example.api:${ssmstore eu-west-2@/prod/api/example-api/latesttag} - (Where latesttag in SSM = "ref-bh43r78gf9fge9hd")

[2019-07-10T09:38:36] Value for variable Image must be of type <type 'str'>. Actual type: <type 'unicode'>. Traceback (most recent call last): File "/usr/local/lib/python2.7/site-packages/stacker-1.7.0-py2.7.egg/stacker/plan.py", line 93, in _run_once status = self.fn(self.stack, status=self.status) File "/usr/local/lib/python2.7/site-packages/stacker-1.7.0-py2.7.egg/stacker/actions/build.py", line 326, in _launch_stack stack.resolve(self.context, self.provider) File "/usr/local/lib/python2.7/site-packages/stacker-1.7.0-py2.7.egg/stacker/stack.py", line 194, in resolve self.blueprint.resolve_variables(self.variables) File "/usr/local/lib/python2.7/site-packages/stacker-1.7.0-py2.7.egg/stacker/blueprints/base.py", line 452, in resolve_variables self.name File "/usr/local/lib/python2.7/site-packages/stacker-1.7.0-py2.7.egg/stacker/blueprints/base.py", line 226, in resolve_variable value = validate_variable_type(var_name, var_type, value) File "/usr/local/lib/python2.7/site-packages/stacker-1.7.0-py2.7.egg/stacker/blueprints/base.py", line 147, in validate_variable_type "type: %s." % (var_name, var_type, type(value)) ValueError: Value for variable Image must be of type <type 'str'>. Actual type: <type 'unicode'>. [2019-07-10T09:38:36] fargate-example-api: failed (Value for variable Image must be of type <type 'str'>. Actual type: <type 'unicode'>.)

I've tried manually typing the variable in AWS console, and through awscli. It seems to just be ssmstore inside the Images block, as there is no issues in the Environment blocks.

russellballestrini commented 5 years ago

Seems like our validator is being too picky. Looking at the docstring in the code it seems like the validator is supposed to try to cast the value into the Blueprint's expected type, but doesn't seem to be doing so.

I think a PR to this block https://github.com/cloudtools/stacker/blob/master/stacker/blueprints/base.py#L117-L150

with this patch


    else:
        if not isinstance(value, var_type):
        try:
                # try to dynamically cast the value to the blueprint's 
                # desired type.
                casted_value = type(var_type)(value)
        except TypeError:
            # cannot cast to the given value 
            # to the blueprint's desired type.
            casted_value = value
        if not isinstance(casted_value, var_type):
                raise ValueError(
                    "Value for variable %s must be of type %s. Actual "
                    "type: %s." % (var_name, var_type, type(value))
                )

may fix the issue, but we will also need a test case to reproduce the error and prove the patch fixes the defect.