template.yml
Parameters:
Value7:
Type: String
Default: "077777777777"
Value8:
Type: String
Default: "088888888888"
Value9:
Type: String
Default: "099999999999"
Resources:
NestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: ./template_child.yml
template_child.yml
# This template is not so important
Resources:
Dummy:
Type: Custom::Whatever
Properties:
ServiceToken: whatever
Value1: whatever
$ uname -a
Darwin xxxxxxx 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64
$ aws --version
aws-cli/1.16.110 Python/3.7.2 Darwin/18.2.0 botocore/1.12.100
$ aws cloudformation package --s3-bucket BUCKET_NAME --template-file template.yml
Uploading to 137ce8b72427772da39a43ddc087908a.template 101 / 101.0 (100.00%)
Parameters:
Value7:
Type: String
Default: '077777777777'
Value8:
Type: String
Default: 088888888888
Value9:
Type: String
Default: 099999999999
Resources:
NestedStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/BUCKET_NAME/137ce8b72427772da39a43ddc087908a.template
Quotes of Value8
and Value9
are removed after aws cloudformation package
.
It seems that leads to the values interpreted as numbers during stack operation.
If I use the values for !Sub
, values will be like 9.9999999999E10
, which is unintended and cause errors.
https://github.com/aws/aws-cli/blob/develop/awscli/customizations/cloudformation/yamlhelper.py
$ python3
Python 3.7.2 (default, Feb 12 2019, 08:15:36)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from awscli.customizations.cloudformation.yamlhelper import yaml_parse, yaml_dump
>>> parsed = yaml_parse('sevens: "077777777777"\neights: "088888888888"')
>>> parsed
OrderedDict([('sevens', '077777777777'), ('eights', '088888888888')])
>>> yaml_dump(parsed)
"sevens: '077777777777'\neights: 088888888888\n"
It seems quotes are erased during dumping to yaml.
$ python3
Python 3.7.2 (default, Feb 12 2019, 08:15:36)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import yaml
>>> yaml
<module 'yaml' from '/usr/local/Cellar/awscli/1.16.110/libexec/lib/python3.7/site-packages/yaml/__init__.py'>
>>> yaml.dump({"sevens": "077777777777", "eights": "088888888888"}, default_flow_style=False)
"eight: 088888888888\nseven: '077777777777'\n"
Seems a bug of PyYAML?:thinking:
I thought PyYAML generates invalid yaml, but PyYAML parses correctly (as string type) without quotes.
>>> yaml.load("eights: 088888888888\nsevens: '077777777777'\n")
{'eights': '088888888888', 'sevens': '077777777777'}
I suspect either PyYAML or the yaml parser used in CloudFormation API is not following the yaml spec (related to octal base int type and string type without quotes) and causing this issue.
https://yaml.org/type/int.html
In any case, aws cloudformation package
should generates yaml that can be used for CloudFormation.
Any updates?
Please let me know if you need further information.
I guessed that CloudFormation API uses SnakeYAML from its behavior, so I filed an issue for SnakeYAML.
https://bitbucket.org/asomov/snakeyaml/issues/442/snakeyaml-act-differently-out-of-range
The SnakeYAML author says that it is a bug in YAML 1.1 spec...
I think aws-cli should dump strings in YAML with quotes for parser interoperability.
https://stackoverflow.com/questions/38369833/pyyaml-and-using-quotes-for-strings-only
We are looking into this issue. @sanathkr, what are your thoughts?
We are running into a similar issue. We have Account ID as the key in template.yaml:
...
Mappings:
AccountMap:
"098111111198":
Env: "dev"
"988111111198":
Env: "test"
"123456789012":
Env: "prod"
...
After the sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket BUCKET_NAME
, quotes around the first Account ID got stripped:
...
Mappings:
AccountMap:
098111111198:
Env: dev
'988111111198':
Env: test
'123456789012':
Env: prod
...
The subsequent aws cloudformation deploy --template-file packaged.yaml --stack-name STACK_NAME ...
thinks 098111111198
is a number and throws An error occurred (ValidationError) when calling the CreateChangeSet operation: Template format error: [/Mappings/AccountMap] map keys must be strings; received numeric [9.8111111198E10] instead
.
$ sam --version
SAM CLI, version 0.17.0
$ aws --version
aws-cli/1.16.150 Python/3.7.3 Darwin/18.5.0 botocore/1.12.140
$ python
Python 3.6.7 | packaged by conda-forge | (default, Feb 28 2019, 02:16:08)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto3
>>> boto3.__version__
'1.9.172'
We would appreciate suggestions to any workarounds. Thanks!
Having the exact same issue outlined by @beibeiyang above. Any updates?
I'm experiencing the same weird issue. Very weird. Things up to 7 are working, and 8 will break as per above issue.
I've also encountered the same issue (awscli 1.16.199), any updates or plans to produce updates?
Same issue here, when following instructions to create a bucket policy for us-east-2, using was-cli 1.16.260:
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#enable-access-logging
I've switched to use AWS CDK after all.
CDK is not affected by this issue, I suppose.
@justnance Is this still being worked on? Is there a workaround?
This breaks the creation of Cognito UserPool because the MFAConfiguration requires quotes surrounding the "OFF" value these are stripped off by the cli . Is there any workaround to force quotes ?
@idm-ryou Did you find a workaround in the sam template for account_id map lookup?
@lmayorga1980 I found a workaround. I had to move the reference to the offending numerical string to the top level template file (since I was using it in a nested stack), and then add --use-json
to the `aws cloudformation package command. This will cause the top level stack to be output as json instead of yaml.
Today I faced strange error with templates and parameters which were working without any issues:
An error occurred (ValidationError) when calling the CreateStack operation: Parameter 'EnableHA' must be one of AllowedValues
This EnableHA
has only two allowed values: "yes"
and "no"
, and my parameters json file defines it to "no"
.
Investigation showed that aws-cli 2 (2.0.7 and 2.0.9) converts these strings to just yes
and no
which have special meaning in YAML and so my supplied parameters don't pass validation.
This should be fixed ASAP.
We were having the same problem in our SAM template since our account starts with a '0' as well. I was able to get around it by using !Ref 'AWS::AccountId'
where I needed the account ID.
See here: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html
I have just run into the same issue when trying to stand up one AWS genomics' cloudformation stacks. It uses a parameter of type String
whose AllowedValues
are Yes
and No
. When I attempt to pass one of those strings using awscli2, I get a message that I must use one of the AllowedValues. It doesn't matter whether the value is quote when I pass the ParameterValue
. Interestingly, when I run validate-template
, this is in the output:
{
"ParameterKey": "ExistingBucket",
"DefaultValue": "false",
"NoEcho": false,
"Description": "Does this bucket already exist?"
}
So it appears that at some point yes and no become true and false. The workaround is to just pass the strings true
or false
.
Experiencing the same issue with account IDs as Map keys.
Most helpful comment
We are running into a similar issue. We have Account ID as the key in template.yaml:
template.yaml
After the
sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket BUCKET_NAME
, quotes around the first Account ID got stripped:packaged.yaml
The subsequent
aws cloudformation deploy --template-file packaged.yaml --stack-name STACK_NAME ...
thinks098111111198
is a number and throwsAn error occurred (ValidationError) when calling the CreateChangeSet operation: Template format error: [/Mappings/AccountMap] map keys must be strings; received numeric [9.8111111198E10] instead
.We would appreciate suggestions to any workarounds. Thanks!