Terraform-provider-aws: [aws_ssm_parameter] illegal char escape

Created on 28 Jan 2019  ·  5Comments  ·  Source: hashicorp/terraform-provider-aws

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Terraform Version

$ terraform -v
Terraform v0.11.7
+ provider.aws v1.57.0

Affected Resource(s)

  • resource "aws_ssm_parameter"

Terraform Configuration Files

resource "aws_ssm_parameter" "dev_url" {
  name  = "/dev/url"
  type  = "String"
  value = "https:\/\/www.example.com"
}

Panic Output

$ terraform apply

Error: Error parsing /tmp/main.tf: At 4:21: illegal char escape

Expected Behavior

Apply the change to set the ssm parameter key with value https:\/\/www.example.com

Actual Behavior

Steps to Reproduce

```
$ cat main.tf
resource "aws_ssm_parameter" "dev_url" {
name = "/dev/url"
type = "String"
value = "https://www.example.com"
}

$ terraform apply

Error: Error parsing /tmp/main.tf: At 4:21: illegal char escape

remove escape

$ cat main.tf
resource "aws_ssm_parameter" "dev_url" {
name = "/dev/url"
type = "String"
value = "https://www.example.com"
}

Terraform apply works fine.

I do need add `\/` in the value, and I can run aws cli to add it. But not from terraform

aws ssm put-parameter --name "/dev/usr" --type "String" --value "https://www.example.com" --overwrite
```

bug servicssm

Most helpful comment

@ozbillwang correct, string escaping behavior is handled in the configuration language parsing of all of Terraform and not specific to the Terraform AWS provider. In this case, using two back slashes in a Terraform string should be correct to generate a single back slash to the API.

If you look at the SSM CLI result from submitting the single back slash, the CLI returns the same escaping of a double back slash when using the normal JSON output format. Note that if we change the output to table, you see the expected single back slash result.

$ aws ssm put-parameter --name '/dev/url' --value 'https:\/\/www.example.com' --overwrite --type String
{
    "Version": 1
}
$ aws ssm get-parameter --name '/dev/url'
{
    "Parameter": {
        "Name": "/dev/url",
        "Type": "String",
        "Value": "https:\\/\\/www.example.com",
...
    }
}
$ aws ssm get-parameter --name '/dev/url' --output table
----------------------------------------------------------------------------------------------------------------------------------------------
|                                                                GetParameter                                                                |
+--------------------------------------------------------------------------------------------------------------------------------------------+
||                                                                 Parameter                                                                ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||                          ARN                          | LastModifiedDate  |   Name    |  Type   |           Value            |  Version  ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||  arn:aws:ssm:us-east-1:123456789012:parameter/dev/url |  1548829566.853   |  /dev/url |  String |  https:\/\/www.example.com |  1        ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|

If you put two raw slashes in the CLI, the CLI JSON output returns four:

$ aws ssm put-parameter --name '/dev/url' --value 'https:\\/\\/www.example.com' --overwrite --type String
{
    "Version": 2
}
$ aws ssm get-parameter --name '/dev/url'
{
    "Parameter": {
        "Name": "/dev/url",
        "Type": "String",
        "Value": "https:\\\\/\\\\/www.example.com",
...
    }
}
$ aws ssm get-parameter --name '/dev/url' --output table
------------------------------------------------------------------------------------------------------------------------------------------------
|                                                                 GetParameter                                                                 |
+----------------------------------------------------------------------------------------------------------------------------------------------+
||                                                                  Parameter                                                                 ||
|+-------------------------------------------------------+-------------------+-----------+---------+------------------------------+-----------+|
||                          ARN                          | LastModifiedDate  |   Name    |  Type   |            Value             |  Version  ||
|+-------------------------------------------------------+-------------------+-----------+---------+------------------------------+-----------+|
||  arn:aws:ssm:us-east-1:123456789012:parameter/dev/url |  1548829053.558   |  /dev/url |  String |  https:\\/\\/www.example.com |  2        ||
|+-------------------------------------------------------+-------------------+-----------+---------+------------------------------+-----------+|

Going back to the Terraform configuration:

resource "aws_ssm_parameter" "dev_url" {
  name  = "/dev/url"
  type  = "String"
  value = "https:\\/\\/www.example.com"
}

When applied generates the same response from the CLI as the single backslash example above:

$ aws ssm delete-parameter --name '/dev/url'
$ terraform apply
...
aws_ssm_parameter.dev_url: Creating...
  arn:    "" => "<computed>"
  key_id: "" => "<computed>"
  name:   "" => "/dev/url"
  type:   "" => "String"
  value:  "<sensitive>" => "<sensitive>"
aws_ssm_parameter.dev_url: Creation complete after 0s (ID: /dev/url)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
$ aws --region us-east-1 ssm get-parameter --name '/dev/url' --output table
----------------------------------------------------------------------------------------------------------------------------------------------
|                                                                GetParameter                                                                |
+--------------------------------------------------------------------------------------------------------------------------------------------+
||                                                                 Parameter                                                                ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||                          ARN                          | LastModifiedDate  |   Name    |  Type   |           Value            |  Version  ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||  arn:aws:ssm:us-east-1:123456789012:parameter/dev/url |  1548829723.599   |  /dev/url |  String |  https:\/\/www.example.com |  1        ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|

Terraform appears to be working correctly.

All 5 comments

I changed to

resource "aws_ssm_parameter" "dev_url" {
 name  = "/dev/url"
 type  = "String"
 value = "https:\\/\\/www.example.com"
}

This time, I can apply the change, but the value is with two back slash

aws ssm get-parameter --name "/dev/url"
{
    "Parameter": {
        "Name": "/dev/url",
        "LastModifiedDate": 1548827483.824,
        "Value": "https:\\/\\/www.example.com",
       ...
    }
}

But that's not what I need.

And below code doesn't work as well with same error illegal char escape

resource "aws_ssm_parameter" "dev_url" {
  name  = "/dev/url"
  type  = "String"
  value = "https:\\\/\\\/www.example.com"
}

It is the bug in core service, more than in aws provider

Below code can't pass terraform fmt and terraform init, get this error already: illegal char escape

variable "url" {
  default = "https:\/\/www.example.com"
}

@ozbillwang correct, string escaping behavior is handled in the configuration language parsing of all of Terraform and not specific to the Terraform AWS provider. In this case, using two back slashes in a Terraform string should be correct to generate a single back slash to the API.

If you look at the SSM CLI result from submitting the single back slash, the CLI returns the same escaping of a double back slash when using the normal JSON output format. Note that if we change the output to table, you see the expected single back slash result.

$ aws ssm put-parameter --name '/dev/url' --value 'https:\/\/www.example.com' --overwrite --type String
{
    "Version": 1
}
$ aws ssm get-parameter --name '/dev/url'
{
    "Parameter": {
        "Name": "/dev/url",
        "Type": "String",
        "Value": "https:\\/\\/www.example.com",
...
    }
}
$ aws ssm get-parameter --name '/dev/url' --output table
----------------------------------------------------------------------------------------------------------------------------------------------
|                                                                GetParameter                                                                |
+--------------------------------------------------------------------------------------------------------------------------------------------+
||                                                                 Parameter                                                                ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||                          ARN                          | LastModifiedDate  |   Name    |  Type   |           Value            |  Version  ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||  arn:aws:ssm:us-east-1:123456789012:parameter/dev/url |  1548829566.853   |  /dev/url |  String |  https:\/\/www.example.com |  1        ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|

If you put two raw slashes in the CLI, the CLI JSON output returns four:

$ aws ssm put-parameter --name '/dev/url' --value 'https:\\/\\/www.example.com' --overwrite --type String
{
    "Version": 2
}
$ aws ssm get-parameter --name '/dev/url'
{
    "Parameter": {
        "Name": "/dev/url",
        "Type": "String",
        "Value": "https:\\\\/\\\\/www.example.com",
...
    }
}
$ aws ssm get-parameter --name '/dev/url' --output table
------------------------------------------------------------------------------------------------------------------------------------------------
|                                                                 GetParameter                                                                 |
+----------------------------------------------------------------------------------------------------------------------------------------------+
||                                                                  Parameter                                                                 ||
|+-------------------------------------------------------+-------------------+-----------+---------+------------------------------+-----------+|
||                          ARN                          | LastModifiedDate  |   Name    |  Type   |            Value             |  Version  ||
|+-------------------------------------------------------+-------------------+-----------+---------+------------------------------+-----------+|
||  arn:aws:ssm:us-east-1:123456789012:parameter/dev/url |  1548829053.558   |  /dev/url |  String |  https:\\/\\/www.example.com |  2        ||
|+-------------------------------------------------------+-------------------+-----------+---------+------------------------------+-----------+|

Going back to the Terraform configuration:

resource "aws_ssm_parameter" "dev_url" {
  name  = "/dev/url"
  type  = "String"
  value = "https:\\/\\/www.example.com"
}

When applied generates the same response from the CLI as the single backslash example above:

$ aws ssm delete-parameter --name '/dev/url'
$ terraform apply
...
aws_ssm_parameter.dev_url: Creating...
  arn:    "" => "<computed>"
  key_id: "" => "<computed>"
  name:   "" => "/dev/url"
  type:   "" => "String"
  value:  "<sensitive>" => "<sensitive>"
aws_ssm_parameter.dev_url: Creation complete after 0s (ID: /dev/url)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
$ aws --region us-east-1 ssm get-parameter --name '/dev/url' --output table
----------------------------------------------------------------------------------------------------------------------------------------------
|                                                                GetParameter                                                                |
+--------------------------------------------------------------------------------------------------------------------------------------------+
||                                                                 Parameter                                                                ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||                          ARN                          | LastModifiedDate  |   Name    |  Type   |           Value            |  Version  ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|
||  arn:aws:ssm:us-east-1:123456789012:parameter/dev/url |  1548829723.599   |  /dev/url |  String |  https:\/\/www.example.com |  1        ||
|+-------------------------------------------------------+-------------------+-----------+---------+----------------------------+-----------+|

Terraform appears to be working correctly.

Thanks a lot, this explains all.

I change the HCL value with \\/, which it should be.

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

Was this page helpful?
0 / 5 - 0 ratings