3

我想t3.medium在所有环境和m5.large生产环境中创建 EC2 实例类型。

.ebextensions像这样使用(YAML):

选项1:

Mappings:
  EnvironmentMap:
    "production":
      TheType: "m5.large"
      SecurityGroup: "foo"
      ...
    "staging":
      TheType: "t3.medium"
      SecurityGroup: "bar"
      ...

option_settings:
  aws:autoscaling:launchconfiguration:
    IamInstanceProfile: "aws-elasticbeanstalk-ec2-role"
    InstanceType: !FindInMap
      - EnvironmentMap
      - !Ref 'AWSEBEnvironmentName'
      - TheType
    SecurityGroups:
      - {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "SecurityGroup"]}

选项 2:

    InstanceType: {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "EC2InstanceType"]}

选项 3:

    InstanceType:
      - {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "EC2InstanceType"]}

结果

选项 1 因 Yaml 无效而失败(但我从这个 AWS示例.

选项 2 和 3 因同样的问题而失败。FindInMap 函数未被“调用”: Invalid option value: '{"Fn::FindInMap":["EnvironmentMap","EC2InstanceType"]},{"Ref":"AWSEBEnvironmentName"}' (Namespace: 'aws:autoscaling:launchconfiguration', OptionName: 'InstanceType'): Value is not one of the allowed values: [c1.medium, c1.xlarge, c3.2xlarge, .... 它试图将整个函数/事物解释为字符串。

对于SecurityGroups它起作用的属性,因为InstanceType它不起作用。

我不能动态地做到这一点,我在 AWS doc、SO 或其他任何地方都找不到如何实现这一点。我会假设这是简单的东西。我错过了什么?


编辑:

选项 4:使用条件

Conditions:
  IsProduction: !Equals [ !Ref AWSEBEnvironmentName, production ]

option_settings:

  aws:autoscaling:launchconfiguration:
    InstanceType: !If [ IsProduction, m5.large, t3.medium ]
    SecurityGroups:
      - {"Fn::FindInMap": ["EnvironmentMap", {"Ref": "AWSEBEnvironmentName"}, "SecurityGroup"]}

错误:YAML exception: Invalid Yaml: could not determine a constructor for the tag !Equals in...

但这来自有关条件if的文档。


编辑2:

我最终发现该选项InstanceType过时,我们应该使用:

aws:ec2:instances
  InstanceTypes: "t3.medium"

但是很可惜,这也不能解决问题,因为我也不能在这里使用替换函数(Fn:findInMap)。

4

1 回答 1

1

FindInMap不起作用的原因option_settings是那里只允许使用四个内在函数(来自docs):

  • 参考
  • Fn::GetAtt
  • Fn::加入
  • Fn::GetOptionSetting

我不相信这SecurityGroups行得通。我认为您的脚本FindInMapSecurityGroups有机会被评估之前失败了。

但是, 我试图找到一种使用Resources的方法。我得到的关闭是以下config文件:

Mappings:
  EnvironmentMap:
    production:
      TheType: "t3.medium"
    staging:
      TheType: "t2.small"

Resources:
  AWSEBAutoScalingLaunchConfiguration:
    Type: AWS::AutoScaling::LaunchConfiguration
    Properties:
      InstanceType:
        ? "Fn::FindInMap"
        :
          - EnvironmentMap
          - 
            Ref: "AWSEBEnvironmentName"
          - TheType

尽管这更近了一步,但它最终也失败了。原因是当 EB 将我们的Resources配置文件与它自己的模板连接时,它会产生以下内容:

"InstanceType": {
  "Ref": "InstanceType", # <--- this should NOT be here :-(
  "Fn::FindInMap": [
    "EnvironmentMap",
    {
      "Ref": "AWSEBEnvironmentName"
    },
    "TheType"
  ]
},

代替

"InstanceType": {
  "Fn::FindInMap": [
    "EnvironmentMap",
    {
      "Ref": "AWSEBEnvironmentName"
    },
    "TheType"
  ]
},

发生这种情况是因为原始InstanceType(联合操作之前)是:

"InstanceType":{"Ref":"InstanceType"},

因此,EB并没有用我们的配置文件中提供的自定义替换,而是将它们合并。 InstanceTypeInstanceType

于 2020-05-28T06:00:07.803 回答