如何在“资源”部分转义包含 $aws:username 的 HCL 字符串?

Posted

技术标签:

【中文标题】如何在“资源”部分转义包含 $aws:username 的 HCL 字符串?【英文标题】:How to escape HCL string containing $aws:username in "Resource" section?如何在“资源”部分转义包含 $aws:username 的 HCL 字符串? 【发布时间】:2017-07-10 10:42:42 【问题描述】:

如何在“资源”部分转义包含 $aws:username 的 HCL 字符串?

我目前使用 Terraform 版本 0.9.9 通过以下方式在 main.tf 文件中创建 AWS 策略:

resource "aws_iam_group_policy" "AllowIndividualUserToSeeTheirAccountInformation" 
      name  = "AllowIndividualUserToSeeTheirAccountInformation"
      group = "$aws_iam_group.pr_faas_developers.id"

      policy = <<EOF
    
      "Version": "2012-10-17",
      "Statement": [
        
          "Action": [
                "iam:ChangePassword",
                "iam:CreateLoginProfile",
                "iam:DeleteLoginProfile",
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary",
                "iam:GetLoginProfile",
                "iam:UpdateLoginProfile"
          ],
          "Effect": "Allow",
          "Resource":
          [
                "arn:aws:iam::XXXXXXXXX:user/$aws:username"
            ]

        
      ]
    
    EOF
    

这样做时,Terraform 会尝试插入 $aws:username 并且 terraform 将失败,如下所示

terraform.exe plan
Failed to load root config module: Error loading D:\amazonaws-root-master\main.t
f: Error reading config for aws_iam_group_policy[AllowIndividualUserToSeeTheirAc
countInformation]: parse error at 17:51: expected "" but found ":"

当我如下转义资源字符串时:

"Resource":
      [
            "arn:aws:iam::XXXXXXXXX:user/\\$\\aws\\:username\\"
        ]

"terraform plan""terraform apply" 可以正常工作,但 AWS 显示策略中的结果是:


  "Version": "2012-10-17",
  "Statement": [
    
      "Action": [
            "iam:ChangePassword",
            "iam:CreateLoginProfile",
            "iam:DeleteLoginProfile",
            "iam:GetAccountPasswordPolicy",
            "iam:GetAccountSummary",
            "iam:GetLoginProfile",
            "iam:UpdateLoginProfile"
      ],
      "Effect": "Allow",
      "Resource":
      [
            "arn:aws:iam::XXXXXXXXX:user/\\$\\aws:username\\"
        ]

    
  ]

这与预期的结果不同:

 
      "Version": "2012-10-17",
      "Statement": [
        
          "Action": [
                "iam:ChangePassword",
                "iam:CreateLoginProfile",
                "iam:DeleteLoginProfile",
                "iam:GetAccountPasswordPolicy",
                "iam:GetAccountSummary",
                "iam:GetLoginProfile",
                "iam:UpdateLoginProfile"
          ],
          "Effect": "Allow",
          "Resource":
          [
                "arn:aws:iam::XXXXXXXXX:user/$aws:username"
            ]

        
      ]
    

是否有任何解决方案可以在 terraform main.tf 文件中转义 "arn:aws:iam::XXXXXXXXX:user/$aws:username" 以获得所需的结果?

【问题讨论】:

【参考方案1】:

你可以用双倍美元修复它$$

参考:

terraform interpolation

您可以使用双美元符号转义插值:$$foo 将呈现为文字 $foo。

https://github.com/hashicorp/terraform/issues/2965

【讨论】:

【参考方案2】:

最近遇到类似的字符串文字问题,请将the response复制到此处以帮助更多人。

注意,这仍然适用于 Terraform 0.12。

“在带引号和 heredoc 字符串表达式中,Terraform 支持以 $% 开头的模板序列。”

“要在不开始模板序列的情况下直接包含这些序列,请将前导字符加倍:$$%%。”

请查看docs了解更多详情。

【讨论】:

【参考方案3】:

https://registry.terraform.io/providers/hashicorp/aws/2.69.0/docs/data-sources/iam_policy_document#context-variable-interpolation

IAM 策略文档格式允许将上下文变量插入到语句中的各种字符串中。本机 IAM 策略文档格式使用 $... 样式的语法,这与 Terraform 的插值语法相冲突,因此此数据源使用 &... 语法来处理应由 AWS 而不是 Terraform 处理的插值.

这样你就可以了

    resources = [
      "arn:aws:s3:::$var.s3_bucket_name/home/&aws:username",
      "arn:aws:s3:::$var.s3_bucket_name/home/&aws:username/*",
    ]

【讨论】:

【参考方案4】:

有两种解决方案:

    在 shell 脚本中使用额外的 $ 转义该变量。例如,PROJECT=$$project 将该变量添加为 project = "$project" 在 terraform 脚本中的文件变量列表下,它会将 $project 替换为 $project 并且脚本仍然可以工作。

【讨论】:

以上是关于如何在“资源”部分转义包含 $aws:username 的 HCL 字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何转义 JSON 字符串以将其包含在 URL 中?

如何在bash中回显包含未转义的美元符号的变量

浅谈 URI 及其转义

如何转义包含空格的路径

如何阅读包含转义引号的引用文本

ANSI 颜色转义序列字符出现在 String.length();