Stacker AwsvpcConfiguration 作为 yaml 传入并作为字符串接收

Stacker AwsvpcConfiguration passed in as yaml and recieved as str

我正在尝试隐藏 Stacker project (uses Troposphere) 和 运行,并且我已经能够创建多个资源,但未能找出子网部分。我尝试通过几种不同的方式将它们传递到我的蓝图 class 中,但我认为这个是最接近的,它类似于其他不会完全爆炸的实现。这个想法是接受像这样的子网的一些配置。

在我的 my_cluster.yaml 中,我有:

 stacks:
 ...
  - name: cluster-networks
    description: "Networks for an ECS cluster"
    class_path: blueprints.networks.Networks
    variables:
      Networks: 
        InternalComms:
          AssignPublicIp: False
          SecurityGroups: 
            - sg-id
          Subnets: 
            - subnet-id1
            - subnet-id2

为了阅读该配置,我有一个名为 blueprints/networks.py 的蓝图,其中包含:

class Networks(Blueprint):
"""Manages creation of networks for ECS clusters"""

# Variables that are passed from the my_cluster.yaml
VARIABLES = {
    "Networks": {
        "type": TroposphereType(ecs.AwsvpcConfiguration, many=True),
        "description": "Dictionary for ECS cluster networks"
    }
}

def create_template(self):
    """method that Stacker calls to manipulate the template(s)"""
    variables = self.get_variables()
    for config in variables['Networks']:
        network = ecs.NetworkConfiguration(config)
        t.add_resource(network)
        # do other useful stuff like set outputs

如果你想知道为什么我创建一个 AwsvpcConfiguration 对象然后从中创建一个 NetworkConfiguration 对象,原因是因为我试图通过使用 NetworkConfiguration 对象之前我采用了 AwsvpcConfiguration 对象,它也没有用。我使用这个 file 来指导我,因为它是定义这些对象的地方。下一步是 build 资源,所以当我通过 运行 这个命令执行此操作时:

stacker build path/to/my.env path/to/my_cluster.yaml

我收到一条错误消息:

stacker.exceptions.ValidatorError: Validator 'AwsvpcConfiguration.create' 
failed for variable 'Networks' with value 
'{'InternalComms': {'AssignPublicIp': False, 'SecurityGroups': ['sg-id'], 'Subnets': ['subnet-id1', 'subnet-id2']}}': 
TypeError: _from_dict() argument after ** must be a mapping, not str

这可能是我在 stacker、yaml 和 python 方面缺乏技能,但我已经难住了,已经有一天左右的时间了。

我无法弄清楚如何将 yaml 中的配置作为字典传递到蓝图中,就像我以相同的方式对在 AWS 领域成功创建的其他资源所做的那样。如果你能指出我的错误,我将非常感激,并且一定会告诉圣诞老人你是多么的好。

对流层 maintainer/stacker 作者在这里。所以有几件事:

  1. 您想使用 TroposphereType(ecs.NetworkConfiguration, many=True),因为这是您要创建的对象类型。
  2. ecs.NetworkConfiguration (https://github.com/cloudtools/troposphere/blob/master/troposphere/ecs.py#L71) is a AWSProperty type, which means the values inside of it, if using "many" needs to be a list of dictionaries per: http://stacker.readthedocs.io/en/latest/blueprints.html#property-types

所以我认为你想要的在你的配置中

variables: Networks: - AwsvpcConfiguration: AssignPublicIp: False SecurityGroups: - sg-id Subnets: - subnet-id1 - subnet-id2

这是因为 TroposphereType 期望您传入类型期望的确切参数。 NetworkConfiguration 需要一个键 AwsvpcConfiguration,并且您传递的值是 AwsvcpConfiguration 对象所期望的值。

现在更大的问题是您希望如何使用这些对象。在 Cloudformation/troposphere 中,属性 类型不是自己创建的 - 它们用作实际资源的属性 - 在本例中是 ecs.Service 类型。您不打算将服务包含在同一蓝图中吗?如果没有,您打算如何与这些服务所在的其他蓝图共享这些属性?

更合适的做法可能是拥有一个构建服务的蓝图 NetworkConfiguration。然后,如果您希望使用该蓝图在多个堆栈之间轻松共享相同的 NetworkConfiguration,您可以使用 YAML 锚做一些事情,例如:

common_network_configuration: &common_network_configuration - AwsvpcConfiguration: AssignPublicIp: False SecurityGroups: - sg-id Subnets: - subnet-id1 - subnet-id2

然后在任何你想要的变量中使用它,比如:

variables: << : *common_network_configuration

我希望这是有道理的 - 如果您有任何问题,您也可以随时通过 stacker Slack 联系我们:https://empire-slack.herokuapp.com/

玩得开心!