本文介绍了模板错误:每个 Fn::Sub 对象的上下文对象的每个值都必须是字符串或返回字符串的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在 uat env 中运行此模板时,我希望将 aws:SourceVpc 添加为字符串列表 [vpc-7830jkd"、vpc-a1236"] 和字符串vpc-1234"当我在 perf 中运行时.它在 perf env 中运行良好,但是当我在 uat 中运行时出现以下错误.

I want aws:SourceVpc to be added as list of string ["vpc-7830jkd", "vpc-a1236"] when i run this template in uat env and as string "vpc-1234"when i run in perf. It is working fine in perf env but when i run in uat i got below error.

模板错误:每个 Fn::Sub 对象的上下文对象的每个值都必须是字符串或返回字符串的函数.有什么建议吗?

Template error: every value of the context object of every Fn::Sub object must be a string or a function that returns a string. Any suggestions ?

这可以通过结合 select、join 和 findinmap 来实现吗.

Can this achieved by combining select, join and findinmap.

 Mappings:
  mVpcId:
   menv:
    perf: "vpc-1234"
    uat: "vpc-7830jkd,vpc-a1236"
 
 islowenv: !Equals [ !Ref Env, "perf" ]
 
 Parameters:
   Env:
    Type: String
 
 Resources:
 apigateway:
   Type: "AWS::ApiGateway::RestApi"
     Properties:
    Name: mygateway
   EndpointConfiguration:
     Types:
       - "PRIVATE"
   Policy: !Sub
     - |-
       {
         "Version": "2012-10-17",
         "Statement": [
           {
             "Effect": "Allow",
             "Principal": "*",
             "Action": "execute-api:Invoke",
             "Resource": [
               "execute-api:/*"
             ]
           },
           {
             "Effect": "Deny",
             "Principal": "*",
             "Action": "execute-api:Invoke",
             "Resource": [
               "execute-api:/*"
             ],
             "Condition": {
               "StringNotEquals": {
                 "aws:SourceVpc": "${myappid}"    --> i need this as list when run in uat
               }
             }
           }
         ]
       }
    - { myappid: !If [islowenv, !FindInMap [ "mVpcId", "menv",  !Ref "Env" ], !Split [ ",", !FindInMap [ "mVpcId", "menv",  !Ref "Env"] ]]}

推荐答案

既然你现在有条件并且你的 vpc 列表是硬编码的,你可以使用以下 SelectSub 生成有效的策略:

Since you have condition now and your vpc list is hardcoded, you can use the following combination of Select and Sub to produce valid policy:

Mappings:
  mVpcId:
   menv:
    perf: "vpc-1234"
    uat: "vpc-7830jkd,vpc-a1236"

Conditions:
 islowenv: !Equals [ !Ref Env, "perf" ]

Parameters:
   Env:
    Type: String
    AllowedValues: [perf,uat]

Resources:

 apigateway:
   Type: "AWS::ApiGateway::RestApi"
   Properties:
    Name: mygateway
    EndpointConfiguration:
      Types:
        - "PRIVATE"
    Policy: !Sub
        - |-
          {
            "Version": "2012-10-17",
            "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": "execute-api:Invoke",
                "Resource": [
                "execute-api:/*"
                ]
            },
            {
                "Effect": "Deny",
                "Principal": "*",
                "Action": "execute-api:Invoke",
                "Resource": [
                "execute-api:/*"
                ],
                "Condition": {
                "StringNotEquals": {
                    "aws:SourceVpc": ${myappid}
                }
               }
            }
            ]
          }
        - myappid:
           !If
             - islowenv
             - !Sub
               - "\"${value}\""
               - value: !FindInMap ["mVpcId", "menv",  !Ref "Env" ]
             - !Sub
               - "[\"${value1}\", \"${value2}\"]"
               - value1: !Select [0, !Split [ ",", !FindInMap [ "mVpcId", "menv",  !Ref "Env"] ]]
                 value2: !Select [1, !Split [ ",", !FindInMap [ "mVpcId", "menv",  !Ref "Env"] ]]

但是如果您需要它处理任何长度的任何 vpc 列表,那么您需要自定义资源或宏.

But if you need it to work with any vpc list of any length, then you need custom resources or macros.

这篇关于模板错误:每个 Fn::Sub 对象的上下文对象的每个值都必须是字符串或返回字符串的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 07:05