简体   繁体   English

映射的默认值 AWS CloudFormation

[英]Default value on mappings AWS CloudFormation

What would be a good strategy to have a default value on mappings?在映射上设置默认值的好策略是什么?

IE IE

I have a parameter called country我有一个名为country的参数

Based on that country I reference a DNS using mappings基于那个country我使用映射引用了一个 DNS

"Mappings" : {
   "DNS":{
     "us" : {"dns" : "mypage.us.com", "ttl" : "600"},
     "mx" : {"dns" : "mypage.default.com", "ttl" : "300"},
     "ar" : {"dns" : "mypage.default.com", "ttl" : "300"},
     "br" : {"dns" : "mypage.default.com", "ttl" : "300"}
   }
}

If us it's been mapped:如果us它已被映射:

{ "Fn::FindInMap" : [ "DNS", { "Ref" : "country" }, "dns" ]}

I get "mypage.us.com" for the other countries I've created a huge list of countries with a default value mypage.default.com , in the future, this values will be changing and we will be adding more countries, is there a better approach to this?我得到了其他国家的"mypage.us.com"我已经创建了一个巨大的国家列表,默认值是mypage.default.com ,将来,这个值将会改变,我们将添加更多国家,是有更好的方法吗?

The only way I was able to do this was to chain Fn::If statements instead of using the map.我能够做到这一点的唯一方法是链接Fn::If语句而不是使用映射。 I tried using a combination of Fn::If and Fn::FindInMap but Fn::FindInMap will always raise an error it if can't find the mapping.我尝试使用Fn::IfFn::FindInMap的组合,但如果找不到映射, Fn::FindInMap总是会引发错误。

Therefore the only solution for me was to resort to using something like the following (for me it was setting ecs memory based on instance type):因此,对我来说唯一的解决方案是求助于使用以下内容(对我来说,它是根据实例类型设置 ecs 内存):

Conditions:
  IsT2Micro: !Equals [!Ref InstanceType, "t2.micro"]
  IsT2Small: !Equals [!Ref InstanceType, "t2.small"]
  ...

taskdefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      ...
      Memory: !If [ IsT2Micro, 900, !If [ IsT2Small, 1900, !Ref "AWS::NoValue"]]

To elaborate on Steve Smith's answer.详细说明史蒂夫史密斯的答案。

Cloudformation always expects a valid mapping, even behind a missed logic gate. Cloudformation 始终期望有效的映射,即使是在遗漏的逻辑门之后。

You can combine !Sub and !If for a fair amount of flexibility though.您可以组合 !Sub 和 !If 以获得相当大的灵活性。

For example, we do this for dynamic staging ECS Env vars:例如,我们为动态暂存 ECS 环境变量执行此操作:

Parameters:

  Env:
    Type: String

  Branch:
    Type: String

  DevelopUrl:
    Type: String
    Default: "develop.example.com"

  MasterUrl:
    Type: String
    Default: "master.example.com"

  ...(ECS Resource)
          Environment:
            
            - !If
              - IsStaging
              - {
                  Name: SOME_CALLBACK_URL,
                  Value: !Sub [
                    "https://${Url}/some-callback-endpoint",
                    { Url: !If [ IsDevelop, !Ref DevelopUrl, !If [ IsMaster, !Ref MasterUrl, !GetAtt MyLoadBalancer.DNSName ] ] }
                  ]
                }
              - !Ref "AWS::NoValue"

Cloud Formation helps create AWS resources once in the beginning of their life. Cloud Formation 有助于在 AWS 资源的生命周期开始时创建它们。 You can also do updates with it, but I think in your case it sounds like you'll be better off building your DNS config logic into your application.您也可以使用它进行更新,但我认为在您的情况下,您最好将 DNS 配置逻辑构建到您的应用程序中。 Maybe create a Database table in DynamoDB with the mapping data.也许用映射数据在 DynamoDB 中创建一个数据库表。 You could pass the Country value into the servers as an environment variable, and have them query the DynamoDB table on launch based on their environment variable.您可以将 Country 值作为环境变量传递给服务器,并让它们在启动时根据环境变量查询 DynamoDB 表。

Alternatively, you can have Cloud Formation invoke a Lambda function when it launches a new stack to query DynamoDB to get the value of the DNS config based on the country so you don't have to keep modifying your stack JSON every time there's a new entry and don't have to change your application.或者,您可以让 Cloud Formation 在启动新堆栈时调用 Lambda 函数来查询 DynamoDB 以获取基于国家/地区的 DNS 配置值,这样您就不必在每次有新条目时不断修改堆栈 JSON并且不必更改您的应用程序。

In your mapping, add a default entry:在您的映射中,添加一个默认条目:

"Mappings" : {
   "DNS":{
     "us" : {"dns" : "mypage.us.com", "ttl" : "600"},
     "mx" : {"dns" : "mypage.mx.com", "ttl" : "300"},
     "default" : {"dns" : "mypage.default.com", "ttl" : "300"}
   }
}

Then create a condition (YAML):然后创建一个条件(YAML):

Conditions:
  HasSpecialDNS: !Or:
    - !Equals [!Ref country, "us"]
    - !Equals [!Ref country, "mx"]

Then change the 2nd parameter of FindInMap to:然后将 FindInMap 的第二个参数更改为:

{ "Fn::FindInMap" : [ "DNS", { "Fn::If": ["HasSpecialDNS", {"Ref" : "country"}, "default" ]}, "dns" ]}

Or YAML:或 YAML:

Fn::FindInMap:
  - DNS
  - !If ["HasSpecialDNS", !Ref country, "default" ]
  - "dns"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM